Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp
35233 views
1
//===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// Provides the Expression parsing implementation.
11
///
12
/// Expressions in C99 basically consist of a bunch of binary operators with
13
/// unary operators and other random stuff at the leaves.
14
///
15
/// In the C99 grammar, these unary operators bind tightest and are represented
16
/// as the 'cast-expression' production. Everything else is either a binary
17
/// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are
18
/// handled by ParseCastExpression, the higher level pieces are handled by
19
/// ParseBinaryExpression.
20
///
21
//===----------------------------------------------------------------------===//
22
23
#include "clang/AST/ASTContext.h"
24
#include "clang/AST/ExprCXX.h"
25
#include "clang/Basic/PrettyStackTrace.h"
26
#include "clang/Lex/LiteralSupport.h"
27
#include "clang/Parse/Parser.h"
28
#include "clang/Parse/RAIIObjectsForParser.h"
29
#include "clang/Sema/DeclSpec.h"
30
#include "clang/Sema/EnterExpressionEvaluationContext.h"
31
#include "clang/Sema/ParsedTemplate.h"
32
#include "clang/Sema/Scope.h"
33
#include "clang/Sema/SemaCUDA.h"
34
#include "clang/Sema/SemaCodeCompletion.h"
35
#include "clang/Sema/SemaObjC.h"
36
#include "clang/Sema/SemaOpenACC.h"
37
#include "clang/Sema/SemaOpenMP.h"
38
#include "clang/Sema/SemaSYCL.h"
39
#include "clang/Sema/TypoCorrection.h"
40
#include "llvm/ADT/SmallVector.h"
41
#include <optional>
42
using namespace clang;
43
44
/// Simple precedence-based parser for binary/ternary operators.
45
///
46
/// Note: we diverge from the C99 grammar when parsing the assignment-expression
47
/// production. C99 specifies that the LHS of an assignment operator should be
48
/// parsed as a unary-expression, but consistency dictates that it be a
49
/// conditional-expession. In practice, the important thing here is that the
50
/// LHS of an assignment has to be an l-value, which productions between
51
/// unary-expression and conditional-expression don't produce. Because we want
52
/// consistency, we parse the LHS as a conditional-expression, then check for
53
/// l-value-ness in semantic analysis stages.
54
///
55
/// \verbatim
56
/// pm-expression: [C++ 5.5]
57
/// cast-expression
58
/// pm-expression '.*' cast-expression
59
/// pm-expression '->*' cast-expression
60
///
61
/// multiplicative-expression: [C99 6.5.5]
62
/// Note: in C++, apply pm-expression instead of cast-expression
63
/// cast-expression
64
/// multiplicative-expression '*' cast-expression
65
/// multiplicative-expression '/' cast-expression
66
/// multiplicative-expression '%' cast-expression
67
///
68
/// additive-expression: [C99 6.5.6]
69
/// multiplicative-expression
70
/// additive-expression '+' multiplicative-expression
71
/// additive-expression '-' multiplicative-expression
72
///
73
/// shift-expression: [C99 6.5.7]
74
/// additive-expression
75
/// shift-expression '<<' additive-expression
76
/// shift-expression '>>' additive-expression
77
///
78
/// compare-expression: [C++20 expr.spaceship]
79
/// shift-expression
80
/// compare-expression '<=>' shift-expression
81
///
82
/// relational-expression: [C99 6.5.8]
83
/// compare-expression
84
/// relational-expression '<' compare-expression
85
/// relational-expression '>' compare-expression
86
/// relational-expression '<=' compare-expression
87
/// relational-expression '>=' compare-expression
88
///
89
/// equality-expression: [C99 6.5.9]
90
/// relational-expression
91
/// equality-expression '==' relational-expression
92
/// equality-expression '!=' relational-expression
93
///
94
/// AND-expression: [C99 6.5.10]
95
/// equality-expression
96
/// AND-expression '&' equality-expression
97
///
98
/// exclusive-OR-expression: [C99 6.5.11]
99
/// AND-expression
100
/// exclusive-OR-expression '^' AND-expression
101
///
102
/// inclusive-OR-expression: [C99 6.5.12]
103
/// exclusive-OR-expression
104
/// inclusive-OR-expression '|' exclusive-OR-expression
105
///
106
/// logical-AND-expression: [C99 6.5.13]
107
/// inclusive-OR-expression
108
/// logical-AND-expression '&&' inclusive-OR-expression
109
///
110
/// logical-OR-expression: [C99 6.5.14]
111
/// logical-AND-expression
112
/// logical-OR-expression '||' logical-AND-expression
113
///
114
/// conditional-expression: [C99 6.5.15]
115
/// logical-OR-expression
116
/// logical-OR-expression '?' expression ':' conditional-expression
117
/// [GNU] logical-OR-expression '?' ':' conditional-expression
118
/// [C++] the third operand is an assignment-expression
119
///
120
/// assignment-expression: [C99 6.5.16]
121
/// conditional-expression
122
/// unary-expression assignment-operator assignment-expression
123
/// [C++] throw-expression [C++ 15]
124
///
125
/// assignment-operator: one of
126
/// = *= /= %= += -= <<= >>= &= ^= |=
127
///
128
/// expression: [C99 6.5.17]
129
/// assignment-expression ...[opt]
130
/// expression ',' assignment-expression ...[opt]
131
/// \endverbatim
132
ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
133
ExprResult LHS(ParseAssignmentExpression(isTypeCast));
134
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
135
}
136
137
/// This routine is called when the '@' is seen and consumed.
138
/// Current token is an Identifier and is not a 'try'. This
139
/// routine is necessary to disambiguate \@try-statement from,
140
/// for example, \@encode-expression.
141
///
142
ExprResult
143
Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
144
ExprResult LHS(ParseObjCAtExpression(AtLoc));
145
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
146
}
147
148
/// This routine is called when a leading '__extension__' is seen and
149
/// consumed. This is necessary because the token gets consumed in the
150
/// process of disambiguating between an expression and a declaration.
151
ExprResult
152
Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
153
ExprResult LHS(true);
154
{
155
// Silence extension warnings in the sub-expression
156
ExtensionRAIIObject O(Diags);
157
158
LHS = ParseCastExpression(AnyCastExpr);
159
}
160
161
if (!LHS.isInvalid())
162
LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
163
LHS.get());
164
165
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
166
}
167
168
/// Parse an expr that doesn't include (top-level) commas.
169
ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
170
if (Tok.is(tok::code_completion)) {
171
cutOffParsing();
172
Actions.CodeCompletion().CodeCompleteExpression(
173
getCurScope(), PreferredType.get(Tok.getLocation()));
174
return ExprError();
175
}
176
177
if (Tok.is(tok::kw_throw))
178
return ParseThrowExpression();
179
if (Tok.is(tok::kw_co_yield))
180
return ParseCoyieldExpression();
181
182
ExprResult LHS = ParseCastExpression(AnyCastExpr,
183
/*isAddressOfOperand=*/false,
184
isTypeCast);
185
return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
186
}
187
188
ExprResult Parser::ParseConditionalExpression() {
189
if (Tok.is(tok::code_completion)) {
190
cutOffParsing();
191
Actions.CodeCompletion().CodeCompleteExpression(
192
getCurScope(), PreferredType.get(Tok.getLocation()));
193
return ExprError();
194
}
195
196
ExprResult LHS = ParseCastExpression(
197
AnyCastExpr, /*isAddressOfOperand=*/false, NotTypeCast);
198
return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
199
}
200
201
/// Parse an assignment expression where part of an Objective-C message
202
/// send has already been parsed.
203
///
204
/// In this case \p LBracLoc indicates the location of the '[' of the message
205
/// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating
206
/// the receiver of the message.
207
///
208
/// Since this handles full assignment-expression's, it handles postfix
209
/// expressions and other binary operators for these expressions as well.
210
ExprResult
211
Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
212
SourceLocation SuperLoc,
213
ParsedType ReceiverType,
214
Expr *ReceiverExpr) {
215
ExprResult R
216
= ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
217
ReceiverType, ReceiverExpr);
218
R = ParsePostfixExpressionSuffix(R);
219
return ParseRHSOfBinaryExpression(R, prec::Assignment);
220
}
221
222
ExprResult
223
Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) {
224
assert(Actions.ExprEvalContexts.back().Context ==
225
Sema::ExpressionEvaluationContext::ConstantEvaluated &&
226
"Call this function only if your ExpressionEvaluationContext is "
227
"already ConstantEvaluated");
228
ExprResult LHS(ParseCastExpression(AnyCastExpr, false, isTypeCast));
229
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
230
return Actions.ActOnConstantExpression(Res);
231
}
232
233
ExprResult Parser::ParseConstantExpression() {
234
// C++03 [basic.def.odr]p2:
235
// An expression is potentially evaluated unless it appears where an
236
// integral constant expression is required (see 5.19) [...].
237
// C++98 and C++11 have no such rule, but this is only a defect in C++98.
238
EnterExpressionEvaluationContext ConstantEvaluated(
239
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
240
return ParseConstantExpressionInExprEvalContext(NotTypeCast);
241
}
242
243
ExprResult Parser::ParseArrayBoundExpression() {
244
EnterExpressionEvaluationContext ConstantEvaluated(
245
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
246
// If we parse the bound of a VLA... we parse a non-constant
247
// constant-expression!
248
Actions.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
249
return ParseConstantExpressionInExprEvalContext(NotTypeCast);
250
}
251
252
ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
253
EnterExpressionEvaluationContext ConstantEvaluated(
254
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
255
ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
256
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
257
return Actions.ActOnCaseExpr(CaseLoc, Res);
258
}
259
260
/// Parse a constraint-expression.
261
///
262
/// \verbatim
263
/// constraint-expression: C++2a[temp.constr.decl]p1
264
/// logical-or-expression
265
/// \endverbatim
266
ExprResult Parser::ParseConstraintExpression() {
267
EnterExpressionEvaluationContext ConstantEvaluated(
268
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
269
ExprResult LHS(ParseCastExpression(AnyCastExpr));
270
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
271
if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) {
272
Actions.CorrectDelayedTyposInExpr(Res);
273
return ExprError();
274
}
275
return Res;
276
}
277
278
/// \brief Parse a constraint-logical-and-expression.
279
///
280
/// \verbatim
281
/// C++2a[temp.constr.decl]p1
282
/// constraint-logical-and-expression:
283
/// primary-expression
284
/// constraint-logical-and-expression '&&' primary-expression
285
///
286
/// \endverbatim
287
ExprResult
288
Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
289
EnterExpressionEvaluationContext ConstantEvaluated(
290
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
291
bool NotPrimaryExpression = false;
292
auto ParsePrimary = [&] () {
293
ExprResult E = ParseCastExpression(PrimaryExprOnly,
294
/*isAddressOfOperand=*/false,
295
/*isTypeCast=*/NotTypeCast,
296
/*isVectorLiteral=*/false,
297
&NotPrimaryExpression);
298
if (E.isInvalid())
299
return ExprError();
300
auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) {
301
E = ParsePostfixExpressionSuffix(E);
302
// Use InclusiveOr, the precedence just after '&&' to not parse the
303
// next arguments to the logical and.
304
E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr);
305
if (!E.isInvalid())
306
Diag(E.get()->getExprLoc(),
307
Note
308
? diag::note_unparenthesized_non_primary_expr_in_requires_clause
309
: diag::err_unparenthesized_non_primary_expr_in_requires_clause)
310
<< FixItHint::CreateInsertion(E.get()->getBeginLoc(), "(")
311
<< FixItHint::CreateInsertion(
312
PP.getLocForEndOfToken(E.get()->getEndLoc()), ")")
313
<< E.get()->getSourceRange();
314
return E;
315
};
316
317
if (NotPrimaryExpression ||
318
// Check if the following tokens must be a part of a non-primary
319
// expression
320
getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
321
/*CPlusPlus11=*/true) > prec::LogicalAnd ||
322
// Postfix operators other than '(' (which will be checked for in
323
// CheckConstraintExpression).
324
Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) ||
325
(Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) {
326
E = RecoverFromNonPrimary(E, /*Note=*/false);
327
if (E.isInvalid())
328
return ExprError();
329
NotPrimaryExpression = false;
330
}
331
bool PossibleNonPrimary;
332
bool IsConstraintExpr =
333
Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary,
334
IsTrailingRequiresClause);
335
if (!IsConstraintExpr || PossibleNonPrimary) {
336
// Atomic constraint might be an unparenthesized non-primary expression
337
// (such as a binary operator), in which case we might get here (e.g. in
338
// 'requires 0 + 1 && true' we would now be at '+', and parse and ignore
339
// the rest of the addition expression). Try to parse the rest of it here.
340
if (PossibleNonPrimary)
341
E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr);
342
Actions.CorrectDelayedTyposInExpr(E);
343
return ExprError();
344
}
345
return E;
346
};
347
ExprResult LHS = ParsePrimary();
348
if (LHS.isInvalid())
349
return ExprError();
350
while (Tok.is(tok::ampamp)) {
351
SourceLocation LogicalAndLoc = ConsumeToken();
352
ExprResult RHS = ParsePrimary();
353
if (RHS.isInvalid()) {
354
Actions.CorrectDelayedTyposInExpr(LHS);
355
return ExprError();
356
}
357
ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc,
358
tok::ampamp, LHS.get(), RHS.get());
359
if (!Op.isUsable()) {
360
Actions.CorrectDelayedTyposInExpr(RHS);
361
Actions.CorrectDelayedTyposInExpr(LHS);
362
return ExprError();
363
}
364
LHS = Op;
365
}
366
return LHS;
367
}
368
369
/// \brief Parse a constraint-logical-or-expression.
370
///
371
/// \verbatim
372
/// C++2a[temp.constr.decl]p1
373
/// constraint-logical-or-expression:
374
/// constraint-logical-and-expression
375
/// constraint-logical-or-expression '||'
376
/// constraint-logical-and-expression
377
///
378
/// \endverbatim
379
ExprResult
380
Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) {
381
ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause));
382
if (!LHS.isUsable())
383
return ExprError();
384
while (Tok.is(tok::pipepipe)) {
385
SourceLocation LogicalOrLoc = ConsumeToken();
386
ExprResult RHS =
387
ParseConstraintLogicalAndExpression(IsTrailingRequiresClause);
388
if (!RHS.isUsable()) {
389
Actions.CorrectDelayedTyposInExpr(LHS);
390
return ExprError();
391
}
392
ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc,
393
tok::pipepipe, LHS.get(), RHS.get());
394
if (!Op.isUsable()) {
395
Actions.CorrectDelayedTyposInExpr(RHS);
396
Actions.CorrectDelayedTyposInExpr(LHS);
397
return ExprError();
398
}
399
LHS = Op;
400
}
401
return LHS;
402
}
403
404
bool Parser::isNotExpressionStart() {
405
tok::TokenKind K = Tok.getKind();
406
if (K == tok::l_brace || K == tok::r_brace ||
407
K == tok::kw_for || K == tok::kw_while ||
408
K == tok::kw_if || K == tok::kw_else ||
409
K == tok::kw_goto || K == tok::kw_try)
410
return true;
411
// If this is a decl-specifier, we can't be at the start of an expression.
412
return isKnownToBeDeclarationSpecifier();
413
}
414
415
bool Parser::isFoldOperator(prec::Level Level) const {
416
return Level > prec::Unknown && Level != prec::Conditional &&
417
Level != prec::Spaceship;
418
}
419
420
bool Parser::isFoldOperator(tok::TokenKind Kind) const {
421
return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true));
422
}
423
424
/// Parse a binary expression that starts with \p LHS and has a
425
/// precedence of at least \p MinPrec.
426
ExprResult
427
Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
428
prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
429
GreaterThanIsOperator,
430
getLangOpts().CPlusPlus11);
431
SourceLocation ColonLoc;
432
433
auto SavedType = PreferredType;
434
while (true) {
435
// Every iteration may rely on a preferred type for the whole expression.
436
PreferredType = SavedType;
437
// If this token has a lower precedence than we are allowed to parse (e.g.
438
// because we are called recursively, or because the token is not a binop),
439
// then we are done!
440
if (NextTokPrec < MinPrec)
441
return LHS;
442
443
// Consume the operator, saving the operator token for error reporting.
444
Token OpToken = Tok;
445
ConsumeToken();
446
447
if (OpToken.is(tok::caretcaret)) {
448
return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or));
449
}
450
451
// If we're potentially in a template-id, we may now be able to determine
452
// whether we're actually in one or not.
453
if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
454
tok::greatergreatergreater) &&
455
checkPotentialAngleBracketDelimiter(OpToken))
456
return ExprError();
457
458
// Bail out when encountering a comma followed by a token which can't
459
// possibly be the start of an expression. For instance:
460
// int f() { return 1, }
461
// We can't do this before consuming the comma, because
462
// isNotExpressionStart() looks at the token stream.
463
if (OpToken.is(tok::comma) && isNotExpressionStart()) {
464
PP.EnterToken(Tok, /*IsReinject*/true);
465
Tok = OpToken;
466
return LHS;
467
}
468
469
// If the next token is an ellipsis, then this is a fold-expression. Leave
470
// it alone so we can handle it in the paren expression.
471
if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
472
// FIXME: We can't check this via lookahead before we consume the token
473
// because that tickles a lexer bug.
474
PP.EnterToken(Tok, /*IsReinject*/true);
475
Tok = OpToken;
476
return LHS;
477
}
478
479
// In Objective-C++, alternative operator tokens can be used as keyword args
480
// in message expressions. Unconsume the token so that it can reinterpreted
481
// as an identifier in ParseObjCMessageExpressionBody. i.e., we support:
482
// [foo meth:0 and:0];
483
// [foo not_eq];
484
if (getLangOpts().ObjC && getLangOpts().CPlusPlus &&
485
Tok.isOneOf(tok::colon, tok::r_square) &&
486
OpToken.getIdentifierInfo() != nullptr) {
487
PP.EnterToken(Tok, /*IsReinject*/true);
488
Tok = OpToken;
489
return LHS;
490
}
491
492
// Special case handling for the ternary operator.
493
ExprResult TernaryMiddle(true);
494
if (NextTokPrec == prec::Conditional) {
495
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
496
// Parse a braced-init-list here for error recovery purposes.
497
SourceLocation BraceLoc = Tok.getLocation();
498
TernaryMiddle = ParseBraceInitializer();
499
if (!TernaryMiddle.isInvalid()) {
500
Diag(BraceLoc, diag::err_init_list_bin_op)
501
<< /*RHS*/ 1 << PP.getSpelling(OpToken)
502
<< Actions.getExprRange(TernaryMiddle.get());
503
TernaryMiddle = ExprError();
504
}
505
} else if (Tok.isNot(tok::colon)) {
506
// Don't parse FOO:BAR as if it were a typo for FOO::BAR.
507
ColonProtectionRAIIObject X(*this);
508
509
// Handle this production specially:
510
// logical-OR-expression '?' expression ':' conditional-expression
511
// In particular, the RHS of the '?' is 'expression', not
512
// 'logical-OR-expression' as we might expect.
513
TernaryMiddle = ParseExpression();
514
} else {
515
// Special case handling of "X ? Y : Z" where Y is empty:
516
// logical-OR-expression '?' ':' conditional-expression [GNU]
517
TernaryMiddle = nullptr;
518
Diag(Tok, diag::ext_gnu_conditional_expr);
519
}
520
521
if (TernaryMiddle.isInvalid()) {
522
Actions.CorrectDelayedTyposInExpr(LHS);
523
LHS = ExprError();
524
TernaryMiddle = nullptr;
525
}
526
527
if (!TryConsumeToken(tok::colon, ColonLoc)) {
528
// Otherwise, we're missing a ':'. Assume that this was a typo that
529
// the user forgot. If we're not in a macro expansion, we can suggest
530
// a fixit hint. If there were two spaces before the current token,
531
// suggest inserting the colon in between them, otherwise insert ": ".
532
SourceLocation FILoc = Tok.getLocation();
533
const char *FIText = ": ";
534
const SourceManager &SM = PP.getSourceManager();
535
if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) {
536
assert(FILoc.isFileID());
537
bool IsInvalid = false;
538
const char *SourcePtr =
539
SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid);
540
if (!IsInvalid && *SourcePtr == ' ') {
541
SourcePtr =
542
SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid);
543
if (!IsInvalid && *SourcePtr == ' ') {
544
FILoc = FILoc.getLocWithOffset(-1);
545
FIText = ":";
546
}
547
}
548
}
549
550
Diag(Tok, diag::err_expected)
551
<< tok::colon << FixItHint::CreateInsertion(FILoc, FIText);
552
Diag(OpToken, diag::note_matching) << tok::question;
553
ColonLoc = Tok.getLocation();
554
}
555
}
556
557
PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(),
558
OpToken.getKind());
559
// Parse another leaf here for the RHS of the operator.
560
// ParseCastExpression works here because all RHS expressions in C have it
561
// as a prefix, at least. However, in C++, an assignment-expression could
562
// be a throw-expression, which is not a valid cast-expression.
563
// Therefore we need some special-casing here.
564
// Also note that the third operand of the conditional operator is
565
// an assignment-expression in C++, and in C++11, we can have a
566
// braced-init-list on the RHS of an assignment. For better diagnostics,
567
// parse as if we were allowed braced-init-lists everywhere, and check that
568
// they only appear on the RHS of assignments later.
569
ExprResult RHS;
570
bool RHSIsInitList = false;
571
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
572
RHS = ParseBraceInitializer();
573
RHSIsInitList = true;
574
} else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional)
575
RHS = ParseAssignmentExpression();
576
else
577
RHS = ParseCastExpression(AnyCastExpr);
578
579
if (RHS.isInvalid()) {
580
// FIXME: Errors generated by the delayed typo correction should be
581
// printed before errors from parsing the RHS, not after.
582
Actions.CorrectDelayedTyposInExpr(LHS);
583
if (TernaryMiddle.isUsable())
584
TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
585
LHS = ExprError();
586
}
587
588
// Remember the precedence of this operator and get the precedence of the
589
// operator immediately to the right of the RHS.
590
prec::Level ThisPrec = NextTokPrec;
591
NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
592
getLangOpts().CPlusPlus11);
593
594
// Assignment and conditional expressions are right-associative.
595
bool isRightAssoc = ThisPrec == prec::Conditional ||
596
ThisPrec == prec::Assignment;
597
598
// Get the precedence of the operator to the right of the RHS. If it binds
599
// more tightly with RHS than we do, evaluate it completely first.
600
if (ThisPrec < NextTokPrec ||
601
(ThisPrec == NextTokPrec && isRightAssoc)) {
602
if (!RHS.isInvalid() && RHSIsInitList) {
603
Diag(Tok, diag::err_init_list_bin_op)
604
<< /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get());
605
RHS = ExprError();
606
}
607
// If this is left-associative, only parse things on the RHS that bind
608
// more tightly than the current operator. If it is left-associative, it
609
// is okay, to bind exactly as tightly. For example, compile A=B=C=D as
610
// A=(B=(C=D)), where each paren is a level of recursion here.
611
// The function takes ownership of the RHS.
612
RHS = ParseRHSOfBinaryExpression(RHS,
613
static_cast<prec::Level>(ThisPrec + !isRightAssoc));
614
RHSIsInitList = false;
615
616
if (RHS.isInvalid()) {
617
// FIXME: Errors generated by the delayed typo correction should be
618
// printed before errors from ParseRHSOfBinaryExpression, not after.
619
Actions.CorrectDelayedTyposInExpr(LHS);
620
if (TernaryMiddle.isUsable())
621
TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
622
LHS = ExprError();
623
}
624
625
NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
626
getLangOpts().CPlusPlus11);
627
}
628
629
if (!RHS.isInvalid() && RHSIsInitList) {
630
if (ThisPrec == prec::Assignment) {
631
Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
632
<< Actions.getExprRange(RHS.get());
633
} else if (ColonLoc.isValid()) {
634
Diag(ColonLoc, diag::err_init_list_bin_op)
635
<< /*RHS*/1 << ":"
636
<< Actions.getExprRange(RHS.get());
637
LHS = ExprError();
638
} else {
639
Diag(OpToken, diag::err_init_list_bin_op)
640
<< /*RHS*/1 << PP.getSpelling(OpToken)
641
<< Actions.getExprRange(RHS.get());
642
LHS = ExprError();
643
}
644
}
645
646
ExprResult OrigLHS = LHS;
647
if (!LHS.isInvalid()) {
648
// Combine the LHS and RHS into the LHS (e.g. build AST).
649
if (TernaryMiddle.isInvalid()) {
650
// If we're using '>>' as an operator within a template
651
// argument list (in C++98), suggest the addition of
652
// parentheses so that the code remains well-formed in C++0x.
653
if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater))
654
SuggestParentheses(OpToken.getLocation(),
655
diag::warn_cxx11_right_shift_in_template_arg,
656
SourceRange(Actions.getExprRange(LHS.get()).getBegin(),
657
Actions.getExprRange(RHS.get()).getEnd()));
658
659
ExprResult BinOp =
660
Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
661
OpToken.getKind(), LHS.get(), RHS.get());
662
if (BinOp.isInvalid())
663
BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(),
664
RHS.get()->getEndLoc(),
665
{LHS.get(), RHS.get()});
666
667
LHS = BinOp;
668
} else {
669
ExprResult CondOp = Actions.ActOnConditionalOp(
670
OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(),
671
RHS.get());
672
if (CondOp.isInvalid()) {
673
std::vector<clang::Expr *> Args;
674
// TernaryMiddle can be null for the GNU conditional expr extension.
675
if (TernaryMiddle.get())
676
Args = {LHS.get(), TernaryMiddle.get(), RHS.get()};
677
else
678
Args = {LHS.get(), RHS.get()};
679
CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(),
680
RHS.get()->getEndLoc(), Args);
681
}
682
683
LHS = CondOp;
684
}
685
// In this case, ActOnBinOp or ActOnConditionalOp performed the
686
// CorrectDelayedTyposInExpr check.
687
if (!getLangOpts().CPlusPlus)
688
continue;
689
}
690
691
// Ensure potential typos aren't left undiagnosed.
692
if (LHS.isInvalid()) {
693
Actions.CorrectDelayedTyposInExpr(OrigLHS);
694
Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
695
Actions.CorrectDelayedTyposInExpr(RHS);
696
}
697
}
698
}
699
700
/// Parse a cast-expression, unary-expression or primary-expression, based
701
/// on \p ExprType.
702
///
703
/// \p isAddressOfOperand exists because an id-expression that is the
704
/// operand of address-of gets special treatment due to member pointers.
705
///
706
ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
707
bool isAddressOfOperand,
708
TypeCastState isTypeCast,
709
bool isVectorLiteral,
710
bool *NotPrimaryExpression) {
711
bool NotCastExpr;
712
ExprResult Res = ParseCastExpression(ParseKind,
713
isAddressOfOperand,
714
NotCastExpr,
715
isTypeCast,
716
isVectorLiteral,
717
NotPrimaryExpression);
718
if (NotCastExpr)
719
Diag(Tok, diag::err_expected_expression);
720
return Res;
721
}
722
723
namespace {
724
class CastExpressionIdValidator final : public CorrectionCandidateCallback {
725
public:
726
CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes)
727
: NextToken(Next), AllowNonTypes(AllowNonTypes) {
728
WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
729
}
730
731
bool ValidateCandidate(const TypoCorrection &candidate) override {
732
NamedDecl *ND = candidate.getCorrectionDecl();
733
if (!ND)
734
return candidate.isKeyword();
735
736
if (isa<TypeDecl>(ND))
737
return WantTypeSpecifiers;
738
739
if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate))
740
return false;
741
742
if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period))
743
return true;
744
745
for (auto *C : candidate) {
746
NamedDecl *ND = C->getUnderlyingDecl();
747
if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND))
748
return true;
749
}
750
return false;
751
}
752
753
std::unique_ptr<CorrectionCandidateCallback> clone() override {
754
return std::make_unique<CastExpressionIdValidator>(*this);
755
}
756
757
private:
758
Token NextToken;
759
bool AllowNonTypes;
760
};
761
}
762
763
bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
764
tok::TokenKind *Kind) {
765
if (RevertibleTypeTraits.empty()) {
766
// Revertible type trait is a feature for backwards compatibility with older
767
// standard libraries that declare their own structs with the same name as
768
// the builtins listed below. New builtins should NOT be added to this list.
769
#define RTT_JOIN(X, Y) X##Y
770
#define REVERTIBLE_TYPE_TRAIT(Name) \
771
RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] = RTT_JOIN(tok::kw_, Name)
772
773
REVERTIBLE_TYPE_TRAIT(__is_abstract);
774
REVERTIBLE_TYPE_TRAIT(__is_aggregate);
775
REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
776
REVERTIBLE_TYPE_TRAIT(__is_array);
777
REVERTIBLE_TYPE_TRAIT(__is_assignable);
778
REVERTIBLE_TYPE_TRAIT(__is_base_of);
779
REVERTIBLE_TYPE_TRAIT(__is_bounded_array);
780
REVERTIBLE_TYPE_TRAIT(__is_class);
781
REVERTIBLE_TYPE_TRAIT(__is_complete_type);
782
REVERTIBLE_TYPE_TRAIT(__is_compound);
783
REVERTIBLE_TYPE_TRAIT(__is_const);
784
REVERTIBLE_TYPE_TRAIT(__is_constructible);
785
REVERTIBLE_TYPE_TRAIT(__is_convertible);
786
REVERTIBLE_TYPE_TRAIT(__is_convertible_to);
787
REVERTIBLE_TYPE_TRAIT(__is_destructible);
788
REVERTIBLE_TYPE_TRAIT(__is_empty);
789
REVERTIBLE_TYPE_TRAIT(__is_enum);
790
REVERTIBLE_TYPE_TRAIT(__is_floating_point);
791
REVERTIBLE_TYPE_TRAIT(__is_final);
792
REVERTIBLE_TYPE_TRAIT(__is_function);
793
REVERTIBLE_TYPE_TRAIT(__is_fundamental);
794
REVERTIBLE_TYPE_TRAIT(__is_integral);
795
REVERTIBLE_TYPE_TRAIT(__is_interface_class);
796
REVERTIBLE_TYPE_TRAIT(__is_literal);
797
REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr);
798
REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference);
799
REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
800
REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer);
801
REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
802
REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
803
REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
804
REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
805
REVERTIBLE_TYPE_TRAIT(__is_nullptr);
806
REVERTIBLE_TYPE_TRAIT(__is_object);
807
REVERTIBLE_TYPE_TRAIT(__is_pod);
808
REVERTIBLE_TYPE_TRAIT(__is_pointer);
809
REVERTIBLE_TYPE_TRAIT(__is_polymorphic);
810
REVERTIBLE_TYPE_TRAIT(__is_reference);
811
REVERTIBLE_TYPE_TRAIT(__is_referenceable);
812
REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr);
813
REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
814
REVERTIBLE_TYPE_TRAIT(__is_same);
815
REVERTIBLE_TYPE_TRAIT(__is_scalar);
816
REVERTIBLE_TYPE_TRAIT(__is_scoped_enum);
817
REVERTIBLE_TYPE_TRAIT(__is_sealed);
818
REVERTIBLE_TYPE_TRAIT(__is_signed);
819
REVERTIBLE_TYPE_TRAIT(__is_standard_layout);
820
REVERTIBLE_TYPE_TRAIT(__is_trivial);
821
REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
822
REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
823
REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
824
REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
825
REVERTIBLE_TYPE_TRAIT(__is_union);
826
REVERTIBLE_TYPE_TRAIT(__is_unsigned);
827
REVERTIBLE_TYPE_TRAIT(__is_void);
828
REVERTIBLE_TYPE_TRAIT(__is_volatile);
829
REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary);
830
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
831
REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
832
#include "clang/Basic/TransformTypeTraits.def"
833
#undef REVERTIBLE_TYPE_TRAIT
834
#undef RTT_JOIN
835
}
836
llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known =
837
RevertibleTypeTraits.find(II);
838
if (Known != RevertibleTypeTraits.end()) {
839
if (Kind)
840
*Kind = Known->second;
841
return true;
842
}
843
return false;
844
}
845
846
ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() {
847
SourceLocation Loc = ConsumeToken();
848
849
BalancedDelimiterTracker T(*this, tok::l_paren);
850
if (T.expectAndConsume())
851
return ExprError();
852
853
TypeResult Ty = ParseTypeName();
854
if (Ty.isInvalid()) {
855
SkipUntil(tok::r_paren, StopAtSemi);
856
return ExprError();
857
}
858
859
SourceLocation EndLoc = Tok.getLocation();
860
T.consumeClose();
861
return Actions.ActOnUnaryExprOrTypeTraitExpr(
862
Loc, UETT_PtrAuthTypeDiscriminator,
863
/*isType=*/true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc));
864
}
865
866
/// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
867
/// a unary-expression.
868
///
869
/// \p isAddressOfOperand exists because an id-expression that is the operand
870
/// of address-of gets special treatment due to member pointers. NotCastExpr
871
/// is set to true if the token is not the start of a cast-expression, and no
872
/// diagnostic is emitted in this case and no tokens are consumed.
873
///
874
/// \verbatim
875
/// cast-expression: [C99 6.5.4]
876
/// unary-expression
877
/// '(' type-name ')' cast-expression
878
///
879
/// unary-expression: [C99 6.5.3]
880
/// postfix-expression
881
/// '++' unary-expression
882
/// '--' unary-expression
883
/// [Coro] 'co_await' cast-expression
884
/// unary-operator cast-expression
885
/// 'sizeof' unary-expression
886
/// 'sizeof' '(' type-name ')'
887
/// [C++11] 'sizeof' '...' '(' identifier ')'
888
/// [GNU] '__alignof' unary-expression
889
/// [GNU] '__alignof' '(' type-name ')'
890
/// [C11] '_Alignof' '(' type-name ')'
891
/// [C++11] 'alignof' '(' type-id ')'
892
/// [GNU] '&&' identifier
893
/// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7]
894
/// [C++] new-expression
895
/// [C++] delete-expression
896
///
897
/// unary-operator: one of
898
/// '&' '*' '+' '-' '~' '!'
899
/// [GNU] '__extension__' '__real' '__imag'
900
///
901
/// primary-expression: [C99 6.5.1]
902
/// [C99] identifier
903
/// [C++] id-expression
904
/// constant
905
/// string-literal
906
/// [C++] boolean-literal [C++ 2.13.5]
907
/// [C++11] 'nullptr' [C++11 2.14.7]
908
/// [C++11] user-defined-literal
909
/// '(' expression ')'
910
/// [C11] generic-selection
911
/// [C++2a] requires-expression
912
/// '__func__' [C99 6.4.2.2]
913
/// [GNU] '__FUNCTION__'
914
/// [MS] '__FUNCDNAME__'
915
/// [MS] 'L__FUNCTION__'
916
/// [MS] '__FUNCSIG__'
917
/// [MS] 'L__FUNCSIG__'
918
/// [GNU] '__PRETTY_FUNCTION__'
919
/// [GNU] '(' compound-statement ')'
920
/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
921
/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
922
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
923
/// assign-expr ')'
924
/// [GNU] '__builtin_FILE' '(' ')'
925
/// [CLANG] '__builtin_FILE_NAME' '(' ')'
926
/// [GNU] '__builtin_FUNCTION' '(' ')'
927
/// [MS] '__builtin_FUNCSIG' '(' ')'
928
/// [GNU] '__builtin_LINE' '(' ')'
929
/// [CLANG] '__builtin_COLUMN' '(' ')'
930
/// [GNU] '__builtin_source_location' '(' ')'
931
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
932
/// [GNU] '__null'
933
/// [OBJC] '[' objc-message-expr ']'
934
/// [OBJC] '\@selector' '(' objc-selector-arg ')'
935
/// [OBJC] '\@protocol' '(' identifier ')'
936
/// [OBJC] '\@encode' '(' type-name ')'
937
/// [OBJC] objc-string-literal
938
/// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
939
/// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3]
940
/// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
941
/// [C++11] typename-specifier braced-init-list [C++11 5.2.3]
942
/// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
943
/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
944
/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
945
/// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
946
/// [C++] 'typeid' '(' expression ')' [C++ 5.2p1]
947
/// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1]
948
/// [C++] 'this' [C++ 9.3.2]
949
/// [G++] unary-type-trait '(' type-id ')'
950
/// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO]
951
/// [EMBT] array-type-trait '(' type-id ',' integer ')'
952
/// [clang] '^' block-literal
953
///
954
/// constant: [C99 6.4.4]
955
/// integer-constant
956
/// floating-constant
957
/// enumeration-constant -> identifier
958
/// character-constant
959
///
960
/// id-expression: [C++ 5.1]
961
/// unqualified-id
962
/// qualified-id
963
///
964
/// unqualified-id: [C++ 5.1]
965
/// identifier
966
/// operator-function-id
967
/// conversion-function-id
968
/// '~' class-name
969
/// template-id
970
///
971
/// new-expression: [C++ 5.3.4]
972
/// '::'[opt] 'new' new-placement[opt] new-type-id
973
/// new-initializer[opt]
974
/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
975
/// new-initializer[opt]
976
///
977
/// delete-expression: [C++ 5.3.5]
978
/// '::'[opt] 'delete' cast-expression
979
/// '::'[opt] 'delete' '[' ']' cast-expression
980
///
981
/// [GNU/Embarcadero] unary-type-trait:
982
/// '__is_arithmetic'
983
/// '__is_floating_point'
984
/// '__is_integral'
985
/// '__is_lvalue_expr'
986
/// '__is_rvalue_expr'
987
/// '__is_complete_type'
988
/// '__is_void'
989
/// '__is_array'
990
/// '__is_function'
991
/// '__is_reference'
992
/// '__is_lvalue_reference'
993
/// '__is_rvalue_reference'
994
/// '__is_fundamental'
995
/// '__is_object'
996
/// '__is_scalar'
997
/// '__is_compound'
998
/// '__is_pointer'
999
/// '__is_member_object_pointer'
1000
/// '__is_member_function_pointer'
1001
/// '__is_member_pointer'
1002
/// '__is_const'
1003
/// '__is_volatile'
1004
/// '__is_trivial'
1005
/// '__is_standard_layout'
1006
/// '__is_signed'
1007
/// '__is_unsigned'
1008
///
1009
/// [GNU] unary-type-trait:
1010
/// '__has_nothrow_assign'
1011
/// '__has_nothrow_copy'
1012
/// '__has_nothrow_constructor'
1013
/// '__has_trivial_assign' [TODO]
1014
/// '__has_trivial_copy' [TODO]
1015
/// '__has_trivial_constructor'
1016
/// '__has_trivial_destructor'
1017
/// '__has_virtual_destructor'
1018
/// '__is_abstract' [TODO]
1019
/// '__is_class'
1020
/// '__is_empty' [TODO]
1021
/// '__is_enum'
1022
/// '__is_final'
1023
/// '__is_pod'
1024
/// '__is_polymorphic'
1025
/// '__is_sealed' [MS]
1026
/// '__is_trivial'
1027
/// '__is_union'
1028
/// '__has_unique_object_representations'
1029
///
1030
/// [Clang] unary-type-trait:
1031
/// '__is_aggregate'
1032
/// '__trivially_copyable'
1033
///
1034
/// binary-type-trait:
1035
/// [GNU] '__is_base_of'
1036
/// [MS] '__is_convertible_to'
1037
/// '__is_convertible'
1038
/// '__is_same'
1039
///
1040
/// [Embarcadero] array-type-trait:
1041
/// '__array_rank'
1042
/// '__array_extent'
1043
///
1044
/// [Embarcadero] expression-trait:
1045
/// '__is_lvalue_expr'
1046
/// '__is_rvalue_expr'
1047
/// \endverbatim
1048
///
1049
ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
1050
bool isAddressOfOperand,
1051
bool &NotCastExpr,
1052
TypeCastState isTypeCast,
1053
bool isVectorLiteral,
1054
bool *NotPrimaryExpression) {
1055
ExprResult Res;
1056
tok::TokenKind SavedKind = Tok.getKind();
1057
auto SavedType = PreferredType;
1058
NotCastExpr = false;
1059
1060
// Are postfix-expression suffix operators permitted after this
1061
// cast-expression? If not, and we find some, we'll parse them anyway and
1062
// diagnose them.
1063
bool AllowSuffix = true;
1064
1065
// This handles all of cast-expression, unary-expression, postfix-expression,
1066
// and primary-expression. We handle them together like this for efficiency
1067
// and to simplify handling of an expression starting with a '(' token: which
1068
// may be one of a parenthesized expression, cast-expression, compound literal
1069
// expression, or statement expression.
1070
//
1071
// If the parsed tokens consist of a primary-expression, the cases below
1072
// break out of the switch; at the end we call ParsePostfixExpressionSuffix
1073
// to handle the postfix expression suffixes. Cases that cannot be followed
1074
// by postfix exprs should set AllowSuffix to false.
1075
switch (SavedKind) {
1076
case tok::l_paren: {
1077
// If this expression is limited to being a unary-expression, the paren can
1078
// not start a cast expression.
1079
ParenParseOption ParenExprType;
1080
switch (ParseKind) {
1081
case CastParseKind::UnaryExprOnly:
1082
assert(getLangOpts().CPlusPlus && "not possible to get here in C");
1083
[[fallthrough]];
1084
case CastParseKind::AnyCastExpr:
1085
ParenExprType = ParenParseOption::CastExpr;
1086
break;
1087
case CastParseKind::PrimaryExprOnly:
1088
ParenExprType = FoldExpr;
1089
break;
1090
}
1091
ParsedType CastTy;
1092
SourceLocation RParenLoc;
1093
Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
1094
isTypeCast == IsTypeCast, CastTy, RParenLoc);
1095
1096
// FIXME: What should we do if a vector literal is followed by a
1097
// postfix-expression suffix? Usually postfix operators are permitted on
1098
// literals.
1099
if (isVectorLiteral)
1100
return Res;
1101
1102
switch (ParenExprType) {
1103
case SimpleExpr: break; // Nothing else to do.
1104
case CompoundStmt: break; // Nothing else to do.
1105
case CompoundLiteral:
1106
// We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
1107
// postfix-expression exist, parse them now.
1108
break;
1109
case CastExpr:
1110
// We have parsed the cast-expression and no postfix-expr pieces are
1111
// following.
1112
return Res;
1113
case FoldExpr:
1114
// We only parsed a fold-expression. There might be postfix-expr pieces
1115
// afterwards; parse them now.
1116
break;
1117
}
1118
1119
break;
1120
}
1121
1122
// primary-expression
1123
case tok::numeric_constant:
1124
case tok::binary_data:
1125
// constant: integer-constant
1126
// constant: floating-constant
1127
1128
Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope());
1129
ConsumeToken();
1130
break;
1131
1132
case tok::kw_true:
1133
case tok::kw_false:
1134
Res = ParseCXXBoolLiteral();
1135
break;
1136
1137
case tok::kw___objc_yes:
1138
case tok::kw___objc_no:
1139
Res = ParseObjCBoolLiteral();
1140
break;
1141
1142
case tok::kw_nullptr:
1143
if (getLangOpts().CPlusPlus)
1144
Diag(Tok, diag::warn_cxx98_compat_nullptr);
1145
else
1146
Diag(Tok, getLangOpts().C23 ? diag::warn_c23_compat_keyword
1147
: diag::ext_c_nullptr) << Tok.getName();
1148
1149
Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
1150
break;
1151
1152
case tok::annot_primary_expr:
1153
case tok::annot_overload_set:
1154
Res = getExprAnnotation(Tok);
1155
if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set)
1156
Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get());
1157
ConsumeAnnotationToken();
1158
if (!Res.isInvalid() && Tok.is(tok::less))
1159
checkPotentialAngleBracket(Res);
1160
break;
1161
1162
case tok::annot_non_type:
1163
case tok::annot_non_type_dependent:
1164
case tok::annot_non_type_undeclared: {
1165
CXXScopeSpec SS;
1166
Token Replacement;
1167
Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
1168
assert(!Res.isUnset() &&
1169
"should not perform typo correction on annotation token");
1170
break;
1171
}
1172
1173
case tok::annot_embed: {
1174
injectEmbedTokens();
1175
return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1176
isVectorLiteral, NotPrimaryExpression);
1177
}
1178
1179
case tok::kw___super:
1180
case tok::kw_decltype:
1181
// Annotate the token and tail recurse.
1182
if (TryAnnotateTypeOrScopeToken())
1183
return ExprError();
1184
assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super));
1185
return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1186
isVectorLiteral, NotPrimaryExpression);
1187
1188
case tok::identifier:
1189
ParseIdentifier: { // primary-expression: identifier
1190
// unqualified-id: identifier
1191
// constant: enumeration-constant
1192
// Turn a potentially qualified name into a annot_typename or
1193
// annot_cxxscope if it would be valid. This handles things like x::y, etc.
1194
if (getLangOpts().CPlusPlus) {
1195
// Avoid the unnecessary parse-time lookup in the common case
1196
// where the syntax forbids a type.
1197
Token Next = NextToken();
1198
1199
if (Next.is(tok::ellipsis) && Tok.is(tok::identifier) &&
1200
GetLookAheadToken(2).is(tok::l_square)) {
1201
// Annotate the token and tail recurse.
1202
// If the token is not annotated, then it might be an expression pack
1203
// indexing
1204
if (!TryAnnotateTypeOrScopeToken() &&
1205
Tok.is(tok::annot_pack_indexing_type))
1206
return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1207
isVectorLiteral, NotPrimaryExpression);
1208
}
1209
1210
// If this identifier was reverted from a token ID, and the next token
1211
// is a parenthesis, this is likely to be a use of a type trait. Check
1212
// those tokens.
1213
else if (Next.is(tok::l_paren) && Tok.is(tok::identifier) &&
1214
Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
1215
IdentifierInfo *II = Tok.getIdentifierInfo();
1216
tok::TokenKind Kind;
1217
if (isRevertibleTypeTrait(II, &Kind)) {
1218
Tok.setKind(Kind);
1219
return ParseCastExpression(ParseKind, isAddressOfOperand,
1220
NotCastExpr, isTypeCast,
1221
isVectorLiteral, NotPrimaryExpression);
1222
}
1223
}
1224
1225
else if ((!ColonIsSacred && Next.is(tok::colon)) ||
1226
Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren,
1227
tok::l_brace)) {
1228
// If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1229
if (TryAnnotateTypeOrScopeToken())
1230
return ExprError();
1231
if (!Tok.is(tok::identifier))
1232
return ParseCastExpression(ParseKind, isAddressOfOperand,
1233
NotCastExpr, isTypeCast,
1234
isVectorLiteral,
1235
NotPrimaryExpression);
1236
}
1237
}
1238
1239
// Consume the identifier so that we can see if it is followed by a '(' or
1240
// '.'.
1241
IdentifierInfo &II = *Tok.getIdentifierInfo();
1242
SourceLocation ILoc = ConsumeToken();
1243
1244
// Support 'Class.property' and 'super.property' notation.
1245
if (getLangOpts().ObjC && Tok.is(tok::period) &&
1246
(Actions.getTypeName(II, ILoc, getCurScope()) ||
1247
// Allow the base to be 'super' if in an objc-method.
1248
(&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
1249
ConsumeToken();
1250
1251
if (Tok.is(tok::code_completion) && &II != Ident_super) {
1252
cutOffParsing();
1253
Actions.CodeCompletion().CodeCompleteObjCClassPropertyRefExpr(
1254
getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
1255
return ExprError();
1256
}
1257
// Allow either an identifier or the keyword 'class' (in C++).
1258
if (Tok.isNot(tok::identifier) &&
1259
!(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) {
1260
Diag(Tok, diag::err_expected_property_name);
1261
return ExprError();
1262
}
1263
IdentifierInfo &PropertyName = *Tok.getIdentifierInfo();
1264
SourceLocation PropertyLoc = ConsumeToken();
1265
1266
Res = Actions.ObjC().ActOnClassPropertyRefExpr(II, PropertyName, ILoc,
1267
PropertyLoc);
1268
break;
1269
}
1270
1271
// In an Objective-C method, if we have "super" followed by an identifier,
1272
// the token sequence is ill-formed. However, if there's a ':' or ']' after
1273
// that identifier, this is probably a message send with a missing open
1274
// bracket. Treat it as such.
1275
if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression &&
1276
getCurScope()->isInObjcMethodScope() &&
1277
((Tok.is(tok::identifier) &&
1278
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) ||
1279
Tok.is(tok::code_completion))) {
1280
Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr,
1281
nullptr);
1282
break;
1283
}
1284
1285
// If we have an Objective-C class name followed by an identifier
1286
// and either ':' or ']', this is an Objective-C class message
1287
// send that's missing the opening '['. Recovery
1288
// appropriately. Also take this path if we're performing code
1289
// completion after an Objective-C class name.
1290
if (getLangOpts().ObjC &&
1291
((Tok.is(tok::identifier) && !InMessageExpression) ||
1292
Tok.is(tok::code_completion))) {
1293
const Token& Next = NextToken();
1294
if (Tok.is(tok::code_completion) ||
1295
Next.is(tok::colon) || Next.is(tok::r_square))
1296
if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
1297
if (Typ.get()->isObjCObjectOrInterfaceType()) {
1298
// Fake up a Declarator to use with ActOnTypeName.
1299
DeclSpec DS(AttrFactory);
1300
DS.SetRangeStart(ILoc);
1301
DS.SetRangeEnd(ILoc);
1302
const char *PrevSpec = nullptr;
1303
unsigned DiagID;
1304
DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
1305
Actions.getASTContext().getPrintingPolicy());
1306
1307
Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1308
DeclaratorContext::TypeName);
1309
TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo);
1310
if (Ty.isInvalid())
1311
break;
1312
1313
Res = ParseObjCMessageExpressionBody(SourceLocation(),
1314
SourceLocation(),
1315
Ty.get(), nullptr);
1316
break;
1317
}
1318
}
1319
1320
// Make sure to pass down the right value for isAddressOfOperand.
1321
if (isAddressOfOperand && isPostfixExpressionSuffixStart())
1322
isAddressOfOperand = false;
1323
1324
// Function designators are allowed to be undeclared (C99 6.5.1p2), so we
1325
// need to know whether or not this identifier is a function designator or
1326
// not.
1327
UnqualifiedId Name;
1328
CXXScopeSpec ScopeSpec;
1329
SourceLocation TemplateKWLoc;
1330
Token Replacement;
1331
CastExpressionIdValidator Validator(
1332
/*Next=*/Tok,
1333
/*AllowTypes=*/isTypeCast != NotTypeCast,
1334
/*AllowNonTypes=*/isTypeCast != IsTypeCast);
1335
Validator.IsAddressOfOperand = isAddressOfOperand;
1336
if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) {
1337
Validator.WantExpressionKeywords = false;
1338
Validator.WantRemainingKeywords = false;
1339
} else {
1340
Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren);
1341
}
1342
Name.setIdentifier(&II, ILoc);
1343
Res = Actions.ActOnIdExpression(
1344
getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
1345
isAddressOfOperand, &Validator,
1346
/*IsInlineAsmIdentifier=*/false,
1347
Tok.is(tok::r_paren) ? nullptr : &Replacement);
1348
if (!Res.isInvalid() && Res.isUnset()) {
1349
UnconsumeToken(Replacement);
1350
return ParseCastExpression(ParseKind, isAddressOfOperand,
1351
NotCastExpr, isTypeCast,
1352
/*isVectorLiteral=*/false,
1353
NotPrimaryExpression);
1354
}
1355
Res = tryParseCXXPackIndexingExpression(Res);
1356
if (!Res.isInvalid() && Tok.is(tok::less))
1357
checkPotentialAngleBracket(Res);
1358
break;
1359
}
1360
case tok::char_constant: // constant: character-constant
1361
case tok::wide_char_constant:
1362
case tok::utf8_char_constant:
1363
case tok::utf16_char_constant:
1364
case tok::utf32_char_constant:
1365
Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope());
1366
ConsumeToken();
1367
break;
1368
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
1369
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
1370
case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS]
1371
case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS]
1372
case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
1373
case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS]
1374
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
1375
// Function local predefined macros are represented by PredefinedExpr except
1376
// when Microsoft extensions are enabled and one of these macros is adjacent
1377
// to a string literal or another one of these macros.
1378
if (!(getLangOpts().MicrosoftExt &&
1379
tokenIsLikeStringLiteral(Tok, getLangOpts()) &&
1380
tokenIsLikeStringLiteral(NextToken(), getLangOpts()))) {
1381
Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
1382
ConsumeToken();
1383
break;
1384
}
1385
[[fallthrough]]; // treat MS function local macros as concatenable strings
1386
case tok::string_literal: // primary-expression: string-literal
1387
case tok::wide_string_literal:
1388
case tok::utf8_string_literal:
1389
case tok::utf16_string_literal:
1390
case tok::utf32_string_literal:
1391
Res = ParseStringLiteralExpression(true);
1392
break;
1393
case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1]
1394
Res = ParseGenericSelectionExpression();
1395
break;
1396
case tok::kw___builtin_available:
1397
Res = ParseAvailabilityCheckExpr(Tok.getLocation());
1398
break;
1399
case tok::kw___builtin_va_arg:
1400
case tok::kw___builtin_offsetof:
1401
case tok::kw___builtin_choose_expr:
1402
case tok::kw___builtin_astype: // primary-expression: [OCL] as_type()
1403
case tok::kw___builtin_convertvector:
1404
case tok::kw___builtin_COLUMN:
1405
case tok::kw___builtin_FILE:
1406
case tok::kw___builtin_FILE_NAME:
1407
case tok::kw___builtin_FUNCTION:
1408
case tok::kw___builtin_FUNCSIG:
1409
case tok::kw___builtin_LINE:
1410
case tok::kw___builtin_source_location:
1411
if (NotPrimaryExpression)
1412
*NotPrimaryExpression = true;
1413
// This parses the complete suffix; we can return early.
1414
return ParseBuiltinPrimaryExpression();
1415
case tok::kw___null:
1416
Res = Actions.ActOnGNUNullExpr(ConsumeToken());
1417
break;
1418
1419
case tok::plusplus: // unary-expression: '++' unary-expression [C99]
1420
case tok::minusminus: { // unary-expression: '--' unary-expression [C99]
1421
if (NotPrimaryExpression)
1422
*NotPrimaryExpression = true;
1423
// C++ [expr.unary] has:
1424
// unary-expression:
1425
// ++ cast-expression
1426
// -- cast-expression
1427
Token SavedTok = Tok;
1428
ConsumeToken();
1429
1430
PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(),
1431
SavedTok.getLocation());
1432
// One special case is implicitly handled here: if the preceding tokens are
1433
// an ambiguous cast expression, such as "(T())++", then we recurse to
1434
// determine whether the '++' is prefix or postfix.
1435
Res = ParseCastExpression(getLangOpts().CPlusPlus ?
1436
UnaryExprOnly : AnyCastExpr,
1437
/*isAddressOfOperand*/false, NotCastExpr,
1438
NotTypeCast);
1439
if (NotCastExpr) {
1440
// If we return with NotCastExpr = true, we must not consume any tokens,
1441
// so put the token back where we found it.
1442
assert(Res.isInvalid());
1443
UnconsumeToken(SavedTok);
1444
return ExprError();
1445
}
1446
if (!Res.isInvalid()) {
1447
Expr *Arg = Res.get();
1448
Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(),
1449
SavedKind, Arg);
1450
if (Res.isInvalid())
1451
Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(),
1452
Arg->getEndLoc(), Arg);
1453
}
1454
return Res;
1455
}
1456
case tok::amp: { // unary-expression: '&' cast-expression
1457
if (NotPrimaryExpression)
1458
*NotPrimaryExpression = true;
1459
// Special treatment because of member pointers
1460
SourceLocation SavedLoc = ConsumeToken();
1461
PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc);
1462
1463
Res = ParseCastExpression(AnyCastExpr, /*isAddressOfOperand=*/true);
1464
if (!Res.isInvalid()) {
1465
Expr *Arg = Res.get();
1466
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg);
1467
if (Res.isInvalid())
1468
Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(),
1469
Arg);
1470
}
1471
return Res;
1472
}
1473
1474
case tok::star: // unary-expression: '*' cast-expression
1475
case tok::plus: // unary-expression: '+' cast-expression
1476
case tok::minus: // unary-expression: '-' cast-expression
1477
case tok::tilde: // unary-expression: '~' cast-expression
1478
case tok::exclaim: // unary-expression: '!' cast-expression
1479
case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
1480
case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
1481
if (NotPrimaryExpression)
1482
*NotPrimaryExpression = true;
1483
SourceLocation SavedLoc = ConsumeToken();
1484
PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc);
1485
Res = ParseCastExpression(AnyCastExpr);
1486
if (!Res.isInvalid()) {
1487
Expr *Arg = Res.get();
1488
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg,
1489
isAddressOfOperand);
1490
if (Res.isInvalid())
1491
Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg);
1492
}
1493
return Res;
1494
}
1495
1496
case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression
1497
if (NotPrimaryExpression)
1498
*NotPrimaryExpression = true;
1499
SourceLocation CoawaitLoc = ConsumeToken();
1500
Res = ParseCastExpression(AnyCastExpr);
1501
if (!Res.isInvalid())
1502
Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get());
1503
return Res;
1504
}
1505
1506
case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
1507
// __extension__ silences extension warnings in the subexpression.
1508
if (NotPrimaryExpression)
1509
*NotPrimaryExpression = true;
1510
ExtensionRAIIObject O(Diags); // Use RAII to do this.
1511
SourceLocation SavedLoc = ConsumeToken();
1512
Res = ParseCastExpression(AnyCastExpr);
1513
if (!Res.isInvalid())
1514
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
1515
return Res;
1516
}
1517
case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')'
1518
diagnoseUseOfC11Keyword(Tok);
1519
[[fallthrough]];
1520
case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')'
1521
case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
1522
// unary-expression: '__alignof' '(' type-name ')'
1523
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
1524
// unary-expression: 'sizeof' '(' type-name ')'
1525
// unary-expression: '__datasizeof' unary-expression
1526
// unary-expression: '__datasizeof' '(' type-name ')'
1527
case tok::kw___datasizeof:
1528
case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression
1529
// unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')'
1530
case tok::kw___builtin_omp_required_simd_align:
1531
case tok::kw___builtin_vectorelements:
1532
if (NotPrimaryExpression)
1533
*NotPrimaryExpression = true;
1534
AllowSuffix = false;
1535
Res = ParseUnaryExprOrTypeTraitExpression();
1536
break;
1537
case tok::ampamp: { // unary-expression: '&&' identifier
1538
if (NotPrimaryExpression)
1539
*NotPrimaryExpression = true;
1540
SourceLocation AmpAmpLoc = ConsumeToken();
1541
if (Tok.isNot(tok::identifier))
1542
return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
1543
1544
if (getCurScope()->getFnParent() == nullptr)
1545
return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
1546
1547
Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
1548
LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
1549
Tok.getLocation());
1550
Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD);
1551
ConsumeToken();
1552
AllowSuffix = false;
1553
break;
1554
}
1555
case tok::kw_const_cast:
1556
case tok::kw_dynamic_cast:
1557
case tok::kw_reinterpret_cast:
1558
case tok::kw_static_cast:
1559
case tok::kw_addrspace_cast:
1560
if (NotPrimaryExpression)
1561
*NotPrimaryExpression = true;
1562
Res = ParseCXXCasts();
1563
break;
1564
case tok::kw___builtin_bit_cast:
1565
if (NotPrimaryExpression)
1566
*NotPrimaryExpression = true;
1567
Res = ParseBuiltinBitCast();
1568
break;
1569
case tok::kw_typeid:
1570
if (NotPrimaryExpression)
1571
*NotPrimaryExpression = true;
1572
Res = ParseCXXTypeid();
1573
break;
1574
case tok::kw___uuidof:
1575
if (NotPrimaryExpression)
1576
*NotPrimaryExpression = true;
1577
Res = ParseCXXUuidof();
1578
break;
1579
case tok::kw_this:
1580
Res = ParseCXXThis();
1581
break;
1582
case tok::kw___builtin_sycl_unique_stable_name:
1583
Res = ParseSYCLUniqueStableNameExpression();
1584
break;
1585
1586
case tok::annot_typename:
1587
if (isStartOfObjCClassMessageMissingOpenBracket()) {
1588
TypeResult Type = getTypeAnnotation(Tok);
1589
1590
// Fake up a Declarator to use with ActOnTypeName.
1591
DeclSpec DS(AttrFactory);
1592
DS.SetRangeStart(Tok.getLocation());
1593
DS.SetRangeEnd(Tok.getLastLoc());
1594
1595
const char *PrevSpec = nullptr;
1596
unsigned DiagID;
1597
DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(),
1598
PrevSpec, DiagID, Type,
1599
Actions.getASTContext().getPrintingPolicy());
1600
1601
Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1602
DeclaratorContext::TypeName);
1603
TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo);
1604
if (Ty.isInvalid())
1605
break;
1606
1607
ConsumeAnnotationToken();
1608
Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1609
Ty.get(), nullptr);
1610
break;
1611
}
1612
[[fallthrough]];
1613
1614
case tok::annot_decltype:
1615
case tok::annot_pack_indexing_type:
1616
case tok::kw_char:
1617
case tok::kw_wchar_t:
1618
case tok::kw_char8_t:
1619
case tok::kw_char16_t:
1620
case tok::kw_char32_t:
1621
case tok::kw_bool:
1622
case tok::kw_short:
1623
case tok::kw_int:
1624
case tok::kw_long:
1625
case tok::kw___int64:
1626
case tok::kw___int128:
1627
case tok::kw__ExtInt:
1628
case tok::kw__BitInt:
1629
case tok::kw_signed:
1630
case tok::kw_unsigned:
1631
case tok::kw_half:
1632
case tok::kw_float:
1633
case tok::kw_double:
1634
case tok::kw___bf16:
1635
case tok::kw__Float16:
1636
case tok::kw___float128:
1637
case tok::kw___ibm128:
1638
case tok::kw_void:
1639
case tok::kw_auto:
1640
case tok::kw_typename:
1641
case tok::kw_typeof:
1642
case tok::kw___vector:
1643
case tok::kw__Accum:
1644
case tok::kw__Fract:
1645
case tok::kw__Sat:
1646
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1647
#include "clang/Basic/OpenCLImageTypes.def"
1648
{
1649
if (!getLangOpts().CPlusPlus) {
1650
Diag(Tok, diag::err_expected_expression);
1651
return ExprError();
1652
}
1653
1654
// Everything henceforth is a postfix-expression.
1655
if (NotPrimaryExpression)
1656
*NotPrimaryExpression = true;
1657
1658
if (SavedKind == tok::kw_typename) {
1659
// postfix-expression: typename-specifier '(' expression-list[opt] ')'
1660
// typename-specifier braced-init-list
1661
if (TryAnnotateTypeOrScopeToken())
1662
return ExprError();
1663
1664
if (!Tok.isSimpleTypeSpecifier(getLangOpts()))
1665
// We are trying to parse a simple-type-specifier but might not get such
1666
// a token after error recovery.
1667
return ExprError();
1668
}
1669
1670
// postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
1671
// simple-type-specifier braced-init-list
1672
//
1673
DeclSpec DS(AttrFactory);
1674
1675
ParseCXXSimpleTypeSpecifier(DS);
1676
if (Tok.isNot(tok::l_paren) &&
1677
(!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace)))
1678
return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
1679
<< DS.getSourceRange());
1680
1681
if (Tok.is(tok::l_brace))
1682
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1683
1684
Res = ParseCXXTypeConstructExpression(DS);
1685
break;
1686
}
1687
1688
case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
1689
// If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1690
// (We can end up in this situation after tentative parsing.)
1691
if (TryAnnotateTypeOrScopeToken())
1692
return ExprError();
1693
if (!Tok.is(tok::annot_cxxscope))
1694
return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1695
isTypeCast, isVectorLiteral,
1696
NotPrimaryExpression);
1697
1698
Token Next = NextToken();
1699
if (Next.is(tok::annot_template_id)) {
1700
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
1701
if (TemplateId->Kind == TNK_Type_template) {
1702
// We have a qualified template-id that we know refers to a
1703
// type, translate it into a type and continue parsing as a
1704
// cast expression.
1705
CXXScopeSpec SS;
1706
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1707
/*ObjectHasErrors=*/false,
1708
/*EnteringContext=*/false);
1709
AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes);
1710
return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1711
isTypeCast, isVectorLiteral,
1712
NotPrimaryExpression);
1713
}
1714
}
1715
1716
// Parse as an id-expression.
1717
Res = ParseCXXIdExpression(isAddressOfOperand);
1718
break;
1719
}
1720
1721
case tok::annot_template_id: { // [C++] template-id
1722
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1723
if (TemplateId->Kind == TNK_Type_template) {
1724
// We have a template-id that we know refers to a type,
1725
// translate it into a type and continue parsing as a cast
1726
// expression.
1727
CXXScopeSpec SS;
1728
AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes);
1729
return ParseCastExpression(ParseKind, isAddressOfOperand,
1730
NotCastExpr, isTypeCast, isVectorLiteral,
1731
NotPrimaryExpression);
1732
}
1733
1734
// Fall through to treat the template-id as an id-expression.
1735
[[fallthrough]];
1736
}
1737
1738
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
1739
Res = ParseCXXIdExpression(isAddressOfOperand);
1740
break;
1741
1742
case tok::coloncolon: {
1743
// ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken
1744
// annotates the token, tail recurse.
1745
if (TryAnnotateTypeOrScopeToken())
1746
return ExprError();
1747
if (!Tok.is(tok::coloncolon))
1748
return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
1749
isVectorLiteral, NotPrimaryExpression);
1750
1751
// ::new -> [C++] new-expression
1752
// ::delete -> [C++] delete-expression
1753
SourceLocation CCLoc = ConsumeToken();
1754
if (Tok.is(tok::kw_new)) {
1755
if (NotPrimaryExpression)
1756
*NotPrimaryExpression = true;
1757
Res = ParseCXXNewExpression(true, CCLoc);
1758
AllowSuffix = false;
1759
break;
1760
}
1761
if (Tok.is(tok::kw_delete)) {
1762
if (NotPrimaryExpression)
1763
*NotPrimaryExpression = true;
1764
Res = ParseCXXDeleteExpression(true, CCLoc);
1765
AllowSuffix = false;
1766
break;
1767
}
1768
1769
// This is not a type name or scope specifier, it is an invalid expression.
1770
Diag(CCLoc, diag::err_expected_expression);
1771
return ExprError();
1772
}
1773
1774
case tok::kw_new: // [C++] new-expression
1775
if (NotPrimaryExpression)
1776
*NotPrimaryExpression = true;
1777
Res = ParseCXXNewExpression(false, Tok.getLocation());
1778
AllowSuffix = false;
1779
break;
1780
1781
case tok::kw_delete: // [C++] delete-expression
1782
if (NotPrimaryExpression)
1783
*NotPrimaryExpression = true;
1784
Res = ParseCXXDeleteExpression(false, Tok.getLocation());
1785
AllowSuffix = false;
1786
break;
1787
1788
case tok::kw_requires: // [C++2a] requires-expression
1789
Res = ParseRequiresExpression();
1790
AllowSuffix = false;
1791
break;
1792
1793
case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')'
1794
if (NotPrimaryExpression)
1795
*NotPrimaryExpression = true;
1796
Diag(Tok, diag::warn_cxx98_compat_noexcept_expr);
1797
SourceLocation KeyLoc = ConsumeToken();
1798
BalancedDelimiterTracker T(*this, tok::l_paren);
1799
1800
if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept"))
1801
return ExprError();
1802
// C++11 [expr.unary.noexcept]p1:
1803
// The noexcept operator determines whether the evaluation of its operand,
1804
// which is an unevaluated operand, can throw an exception.
1805
EnterExpressionEvaluationContext Unevaluated(
1806
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1807
Res = ParseExpression();
1808
1809
T.consumeClose();
1810
1811
if (!Res.isInvalid())
1812
Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(),
1813
T.getCloseLocation());
1814
AllowSuffix = false;
1815
break;
1816
}
1817
1818
#define TYPE_TRAIT(N,Spelling,K) \
1819
case tok::kw_##Spelling:
1820
#include "clang/Basic/TokenKinds.def"
1821
Res = ParseTypeTrait();
1822
break;
1823
1824
case tok::kw___array_rank:
1825
case tok::kw___array_extent:
1826
if (NotPrimaryExpression)
1827
*NotPrimaryExpression = true;
1828
Res = ParseArrayTypeTrait();
1829
break;
1830
1831
case tok::kw___builtin_ptrauth_type_discriminator:
1832
return ParseBuiltinPtrauthTypeDiscriminator();
1833
1834
case tok::kw___is_lvalue_expr:
1835
case tok::kw___is_rvalue_expr:
1836
if (NotPrimaryExpression)
1837
*NotPrimaryExpression = true;
1838
Res = ParseExpressionTrait();
1839
break;
1840
1841
case tok::at: {
1842
if (NotPrimaryExpression)
1843
*NotPrimaryExpression = true;
1844
SourceLocation AtLoc = ConsumeToken();
1845
return ParseObjCAtExpression(AtLoc);
1846
}
1847
case tok::caret:
1848
Res = ParseBlockLiteralExpression();
1849
break;
1850
case tok::code_completion: {
1851
cutOffParsing();
1852
Actions.CodeCompletion().CodeCompleteExpression(
1853
getCurScope(), PreferredType.get(Tok.getLocation()));
1854
return ExprError();
1855
}
1856
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1857
#include "clang/Basic/TransformTypeTraits.def"
1858
// HACK: libstdc++ uses some of the transform-type-traits as alias
1859
// templates, so we need to work around this.
1860
if (!NextToken().is(tok::l_paren)) {
1861
Tok.setKind(tok::identifier);
1862
Diag(Tok, diag::ext_keyword_as_ident)
1863
<< Tok.getIdentifierInfo()->getName() << 0;
1864
goto ParseIdentifier;
1865
}
1866
goto ExpectedExpression;
1867
case tok::l_square:
1868
if (getLangOpts().CPlusPlus) {
1869
if (getLangOpts().ObjC) {
1870
// C++11 lambda expressions and Objective-C message sends both start with a
1871
// square bracket. There are three possibilities here:
1872
// we have a valid lambda expression, we have an invalid lambda
1873
// expression, or we have something that doesn't appear to be a lambda.
1874
// If we're in the last case, we fall back to ParseObjCMessageExpression.
1875
Res = TryParseLambdaExpression();
1876
if (!Res.isInvalid() && !Res.get()) {
1877
// We assume Objective-C++ message expressions are not
1878
// primary-expressions.
1879
if (NotPrimaryExpression)
1880
*NotPrimaryExpression = true;
1881
Res = ParseObjCMessageExpression();
1882
}
1883
break;
1884
}
1885
Res = ParseLambdaExpression();
1886
break;
1887
}
1888
if (getLangOpts().ObjC) {
1889
Res = ParseObjCMessageExpression();
1890
break;
1891
}
1892
[[fallthrough]];
1893
default:
1894
ExpectedExpression:
1895
NotCastExpr = true;
1896
return ExprError();
1897
}
1898
1899
// Check to see whether Res is a function designator only. If it is and we
1900
// are compiling for OpenCL, we need to return an error as this implies
1901
// that the address of the function is being taken, which is illegal in CL.
1902
1903
if (ParseKind == PrimaryExprOnly)
1904
// This is strictly a primary-expression - no postfix-expr pieces should be
1905
// parsed.
1906
return Res;
1907
1908
if (!AllowSuffix) {
1909
// FIXME: Don't parse a primary-expression suffix if we encountered a parse
1910
// error already.
1911
if (Res.isInvalid())
1912
return Res;
1913
1914
switch (Tok.getKind()) {
1915
case tok::l_square:
1916
case tok::l_paren:
1917
case tok::plusplus:
1918
case tok::minusminus:
1919
// "expected ';'" or similar is probably the right diagnostic here. Let
1920
// the caller decide what to do.
1921
if (Tok.isAtStartOfLine())
1922
return Res;
1923
1924
[[fallthrough]];
1925
case tok::period:
1926
case tok::arrow:
1927
break;
1928
1929
default:
1930
return Res;
1931
}
1932
1933
// This was a unary-expression for which a postfix-expression suffix is
1934
// not permitted by the grammar (eg, a sizeof expression or
1935
// new-expression or similar). Diagnose but parse the suffix anyway.
1936
Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens)
1937
<< Tok.getKind() << Res.get()->getSourceRange()
1938
<< FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(")
1939
<< FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation),
1940
")");
1941
}
1942
1943
// These can be followed by postfix-expr pieces.
1944
PreferredType = SavedType;
1945
Res = ParsePostfixExpressionSuffix(Res);
1946
if (getLangOpts().OpenCL &&
1947
!getActions().getOpenCLOptions().isAvailableOption(
1948
"__cl_clang_function_pointers", getLangOpts()))
1949
if (Expr *PostfixExpr = Res.get()) {
1950
QualType Ty = PostfixExpr->getType();
1951
if (!Ty.isNull() && Ty->isFunctionType()) {
1952
Diag(PostfixExpr->getExprLoc(),
1953
diag::err_opencl_taking_function_address_parser);
1954
return ExprError();
1955
}
1956
}
1957
1958
return Res;
1959
}
1960
1961
/// Once the leading part of a postfix-expression is parsed, this
1962
/// method parses any suffixes that apply.
1963
///
1964
/// \verbatim
1965
/// postfix-expression: [C99 6.5.2]
1966
/// primary-expression
1967
/// postfix-expression '[' expression ']'
1968
/// postfix-expression '[' braced-init-list ']'
1969
/// postfix-expression '[' expression-list [opt] ']' [C++23 12.4.5]
1970
/// postfix-expression '(' argument-expression-list[opt] ')'
1971
/// postfix-expression '.' identifier
1972
/// postfix-expression '->' identifier
1973
/// postfix-expression '++'
1974
/// postfix-expression '--'
1975
/// '(' type-name ')' '{' initializer-list '}'
1976
/// '(' type-name ')' '{' initializer-list ',' '}'
1977
///
1978
/// argument-expression-list: [C99 6.5.2]
1979
/// argument-expression ...[opt]
1980
/// argument-expression-list ',' assignment-expression ...[opt]
1981
/// \endverbatim
1982
ExprResult
1983
Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
1984
// Now that the primary-expression piece of the postfix-expression has been
1985
// parsed, see if there are any postfix-expression pieces here.
1986
SourceLocation Loc;
1987
auto SavedType = PreferredType;
1988
while (true) {
1989
// Each iteration relies on preferred type for the whole expression.
1990
PreferredType = SavedType;
1991
switch (Tok.getKind()) {
1992
case tok::code_completion:
1993
if (InMessageExpression)
1994
return LHS;
1995
1996
cutOffParsing();
1997
Actions.CodeCompletion().CodeCompletePostfixExpression(
1998
getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
1999
return ExprError();
2000
2001
case tok::identifier:
2002
// If we see identifier: after an expression, and we're not already in a
2003
// message send, then this is probably a message send with a missing
2004
// opening bracket '['.
2005
if (getLangOpts().ObjC && !InMessageExpression &&
2006
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
2007
LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
2008
nullptr, LHS.get());
2009
break;
2010
}
2011
// Fall through; this isn't a message send.
2012
[[fallthrough]];
2013
2014
default: // Not a postfix-expression suffix.
2015
return LHS;
2016
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
2017
// If we have a array postfix expression that starts on a new line and
2018
// Objective-C is enabled, it is highly likely that the user forgot a
2019
// semicolon after the base expression and that the array postfix-expr is
2020
// actually another message send. In this case, do some look-ahead to see
2021
// if the contents of the square brackets are obviously not a valid
2022
// expression and recover by pretending there is no suffix.
2023
if (getLangOpts().ObjC && Tok.isAtStartOfLine() &&
2024
isSimpleObjCMessageExpression())
2025
return LHS;
2026
2027
// Reject array indices starting with a lambda-expression. '[[' is
2028
// reserved for attributes.
2029
if (CheckProhibitedCXX11Attribute()) {
2030
(void)Actions.CorrectDelayedTyposInExpr(LHS);
2031
return ExprError();
2032
}
2033
BalancedDelimiterTracker T(*this, tok::l_square);
2034
T.consumeOpen();
2035
Loc = T.getOpenLocation();
2036
ExprResult Length, Stride;
2037
SourceLocation ColonLocFirst, ColonLocSecond;
2038
ExprVector ArgExprs;
2039
bool HasError = false;
2040
PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get());
2041
2042
// We try to parse a list of indexes in all language mode first
2043
// and, in we find 0 or one index, we try to parse an OpenMP/OpenACC array
2044
// section. This allow us to support C++23 multi dimensional subscript and
2045
// OpenMP/OpenACC sections in the same language mode.
2046
if ((!getLangOpts().OpenMP && !AllowOpenACCArraySections) ||
2047
Tok.isNot(tok::colon)) {
2048
if (!getLangOpts().CPlusPlus23) {
2049
ExprResult Idx;
2050
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
2051
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2052
Idx = ParseBraceInitializer();
2053
} else {
2054
Idx = ParseExpression(); // May be a comma expression
2055
}
2056
LHS = Actions.CorrectDelayedTyposInExpr(LHS);
2057
Idx = Actions.CorrectDelayedTyposInExpr(Idx);
2058
if (Idx.isInvalid()) {
2059
HasError = true;
2060
} else {
2061
ArgExprs.push_back(Idx.get());
2062
}
2063
} else if (Tok.isNot(tok::r_square)) {
2064
if (ParseExpressionList(ArgExprs)) {
2065
LHS = Actions.CorrectDelayedTyposInExpr(LHS);
2066
HasError = true;
2067
}
2068
}
2069
}
2070
2071
// Handle OpenACC first, since 'AllowOpenACCArraySections' is only enabled
2072
// when actively parsing a 'var' in a 'var-list' during clause/'cache'
2073
// parsing, so it is the most specific, and best allows us to handle
2074
// OpenACC and OpenMP at the same time.
2075
if (ArgExprs.size() <= 1 && AllowOpenACCArraySections) {
2076
ColonProtectionRAIIObject RAII(*this);
2077
if (Tok.is(tok::colon)) {
2078
// Consume ':'
2079
ColonLocFirst = ConsumeToken();
2080
if (Tok.isNot(tok::r_square))
2081
Length = Actions.CorrectDelayedTyposInExpr(ParseExpression());
2082
}
2083
} else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) {
2084
ColonProtectionRAIIObject RAII(*this);
2085
if (Tok.is(tok::colon)) {
2086
// Consume ':'
2087
ColonLocFirst = ConsumeToken();
2088
if (Tok.isNot(tok::r_square) &&
2089
(getLangOpts().OpenMP < 50 ||
2090
((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) {
2091
Length = ParseExpression();
2092
Length = Actions.CorrectDelayedTyposInExpr(Length);
2093
}
2094
}
2095
if (getLangOpts().OpenMP >= 50 &&
2096
(OMPClauseKind == llvm::omp::Clause::OMPC_to ||
2097
OMPClauseKind == llvm::omp::Clause::OMPC_from) &&
2098
Tok.is(tok::colon)) {
2099
// Consume ':'
2100
ColonLocSecond = ConsumeToken();
2101
if (Tok.isNot(tok::r_square)) {
2102
Stride = ParseExpression();
2103
}
2104
}
2105
}
2106
2107
SourceLocation RLoc = Tok.getLocation();
2108
LHS = Actions.CorrectDelayedTyposInExpr(LHS);
2109
2110
if (!LHS.isInvalid() && !HasError && !Length.isInvalid() &&
2111
!Stride.isInvalid() && Tok.is(tok::r_square)) {
2112
if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) {
2113
// Like above, AllowOpenACCArraySections is 'more specific' and only
2114
// enabled when actively parsing a 'var' in a 'var-list' during
2115
// clause/'cache' construct parsing, so it is more specific. So we
2116
// should do it first, so that the correct node gets created.
2117
if (AllowOpenACCArraySections) {
2118
assert(!Stride.isUsable() && !ColonLocSecond.isValid() &&
2119
"Stride/second colon not allowed for OpenACC");
2120
LHS = Actions.OpenACC().ActOnArraySectionExpr(
2121
LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
2122
ColonLocFirst, Length.get(), RLoc);
2123
} else {
2124
LHS = Actions.OpenMP().ActOnOMPArraySectionExpr(
2125
LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
2126
ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(),
2127
RLoc);
2128
}
2129
} else {
2130
LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc,
2131
ArgExprs, RLoc);
2132
}
2133
} else {
2134
LHS = ExprError();
2135
}
2136
2137
// Match the ']'.
2138
T.consumeClose();
2139
break;
2140
}
2141
2142
case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
2143
case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>'
2144
// '(' argument-expression-list[opt] ')'
2145
tok::TokenKind OpKind = Tok.getKind();
2146
InMessageExpressionRAIIObject InMessage(*this, false);
2147
2148
Expr *ExecConfig = nullptr;
2149
2150
BalancedDelimiterTracker PT(*this, tok::l_paren);
2151
2152
if (OpKind == tok::lesslessless) {
2153
ExprVector ExecConfigExprs;
2154
SourceLocation OpenLoc = ConsumeToken();
2155
2156
if (ParseSimpleExpressionList(ExecConfigExprs)) {
2157
(void)Actions.CorrectDelayedTyposInExpr(LHS);
2158
LHS = ExprError();
2159
}
2160
2161
SourceLocation CloseLoc;
2162
if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) {
2163
} else if (LHS.isInvalid()) {
2164
SkipUntil(tok::greatergreatergreater, StopAtSemi);
2165
} else {
2166
// There was an error closing the brackets
2167
Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
2168
Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
2169
SkipUntil(tok::greatergreatergreater, StopAtSemi);
2170
LHS = ExprError();
2171
}
2172
2173
if (!LHS.isInvalid()) {
2174
if (ExpectAndConsume(tok::l_paren))
2175
LHS = ExprError();
2176
else
2177
Loc = PrevTokLocation;
2178
}
2179
2180
if (!LHS.isInvalid()) {
2181
ExprResult ECResult = Actions.CUDA().ActOnExecConfigExpr(
2182
getCurScope(), OpenLoc, ExecConfigExprs, CloseLoc);
2183
if (ECResult.isInvalid())
2184
LHS = ExprError();
2185
else
2186
ExecConfig = ECResult.get();
2187
}
2188
} else {
2189
PT.consumeOpen();
2190
Loc = PT.getOpenLocation();
2191
}
2192
2193
ExprVector ArgExprs;
2194
auto RunSignatureHelp = [&]() -> QualType {
2195
QualType PreferredType =
2196
Actions.CodeCompletion().ProduceCallSignatureHelp(
2197
LHS.get(), ArgExprs, PT.getOpenLocation());
2198
CalledSignatureHelp = true;
2199
return PreferredType;
2200
};
2201
if (OpKind == tok::l_paren || !LHS.isInvalid()) {
2202
if (Tok.isNot(tok::r_paren)) {
2203
if (ParseExpressionList(ArgExprs, [&] {
2204
PreferredType.enterFunctionArgument(Tok.getLocation(),
2205
RunSignatureHelp);
2206
})) {
2207
(void)Actions.CorrectDelayedTyposInExpr(LHS);
2208
// If we got an error when parsing expression list, we don't call
2209
// the CodeCompleteCall handler inside the parser. So call it here
2210
// to make sure we get overload suggestions even when we are in the
2211
// middle of a parameter.
2212
if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
2213
RunSignatureHelp();
2214
LHS = ExprError();
2215
} else if (LHS.isInvalid()) {
2216
for (auto &E : ArgExprs)
2217
Actions.CorrectDelayedTyposInExpr(E);
2218
}
2219
}
2220
}
2221
2222
// Match the ')'.
2223
if (LHS.isInvalid()) {
2224
SkipUntil(tok::r_paren, StopAtSemi);
2225
} else if (Tok.isNot(tok::r_paren)) {
2226
bool HadDelayedTypo = false;
2227
if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get())
2228
HadDelayedTypo = true;
2229
for (auto &E : ArgExprs)
2230
if (Actions.CorrectDelayedTyposInExpr(E).get() != E)
2231
HadDelayedTypo = true;
2232
// If there were delayed typos in the LHS or ArgExprs, call SkipUntil
2233
// instead of PT.consumeClose() to avoid emitting extra diagnostics for
2234
// the unmatched l_paren.
2235
if (HadDelayedTypo)
2236
SkipUntil(tok::r_paren, StopAtSemi);
2237
else
2238
PT.consumeClose();
2239
LHS = ExprError();
2240
} else {
2241
Expr *Fn = LHS.get();
2242
SourceLocation RParLoc = Tok.getLocation();
2243
LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc,
2244
ExecConfig);
2245
if (LHS.isInvalid()) {
2246
ArgExprs.insert(ArgExprs.begin(), Fn);
2247
LHS =
2248
Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs);
2249
}
2250
PT.consumeClose();
2251
}
2252
2253
break;
2254
}
2255
case tok::arrow:
2256
case tok::period: {
2257
// postfix-expression: p-e '->' template[opt] id-expression
2258
// postfix-expression: p-e '.' template[opt] id-expression
2259
tok::TokenKind OpKind = Tok.getKind();
2260
SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token.
2261
2262
CXXScopeSpec SS;
2263
ParsedType ObjectType;
2264
bool MayBePseudoDestructor = false;
2265
Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr;
2266
2267
PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS);
2268
2269
if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
2270
Expr *Base = OrigLHS;
2271
const Type* BaseType = Base->getType().getTypePtrOrNull();
2272
if (BaseType && Tok.is(tok::l_paren) &&
2273
(BaseType->isFunctionType() ||
2274
BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) {
2275
Diag(OpLoc, diag::err_function_is_not_record)
2276
<< OpKind << Base->getSourceRange()
2277
<< FixItHint::CreateRemoval(OpLoc);
2278
return ParsePostfixExpressionSuffix(Base);
2279
}
2280
2281
LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc,
2282
OpKind, ObjectType,
2283
MayBePseudoDestructor);
2284
if (LHS.isInvalid()) {
2285
// Clang will try to perform expression based completion as a
2286
// fallback, which is confusing in case of member references. So we
2287
// stop here without any completions.
2288
if (Tok.is(tok::code_completion)) {
2289
cutOffParsing();
2290
return ExprError();
2291
}
2292
break;
2293
}
2294
ParseOptionalCXXScopeSpecifier(
2295
SS, ObjectType, LHS.get() && LHS.get()->containsErrors(),
2296
/*EnteringContext=*/false, &MayBePseudoDestructor);
2297
if (SS.isNotEmpty())
2298
ObjectType = nullptr;
2299
}
2300
2301
if (Tok.is(tok::code_completion)) {
2302
tok::TokenKind CorrectedOpKind =
2303
OpKind == tok::arrow ? tok::period : tok::arrow;
2304
ExprResult CorrectedLHS(/*Invalid=*/true);
2305
if (getLangOpts().CPlusPlus && OrigLHS) {
2306
// FIXME: Creating a TentativeAnalysisScope from outside Sema is a
2307
// hack.
2308
Sema::TentativeAnalysisScope Trap(Actions);
2309
CorrectedLHS = Actions.ActOnStartCXXMemberReference(
2310
getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType,
2311
MayBePseudoDestructor);
2312
}
2313
2314
Expr *Base = LHS.get();
2315
Expr *CorrectedBase = CorrectedLHS.get();
2316
if (!CorrectedBase && !getLangOpts().CPlusPlus)
2317
CorrectedBase = Base;
2318
2319
// Code completion for a member access expression.
2320
cutOffParsing();
2321
Actions.CodeCompletion().CodeCompleteMemberReferenceExpr(
2322
getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
2323
Base && ExprStatementTokLoc == Base->getBeginLoc(),
2324
PreferredType.get(Tok.getLocation()));
2325
2326
return ExprError();
2327
}
2328
2329
if (MayBePseudoDestructor && !LHS.isInvalid()) {
2330
LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
2331
ObjectType);
2332
break;
2333
}
2334
2335
// Either the action has told us that this cannot be a
2336
// pseudo-destructor expression (based on the type of base
2337
// expression), or we didn't see a '~' in the right place. We
2338
// can still parse a destructor name here, but in that case it
2339
// names a real destructor.
2340
// Allow explicit constructor calls in Microsoft mode.
2341
// FIXME: Add support for explicit call of template constructor.
2342
SourceLocation TemplateKWLoc;
2343
UnqualifiedId Name;
2344
if (getLangOpts().ObjC && OpKind == tok::period &&
2345
Tok.is(tok::kw_class)) {
2346
// Objective-C++:
2347
// After a '.' in a member access expression, treat the keyword
2348
// 'class' as if it were an identifier.
2349
//
2350
// This hack allows property access to the 'class' method because it is
2351
// such a common method name. For other C++ keywords that are
2352
// Objective-C method names, one must use the message send syntax.
2353
IdentifierInfo *Id = Tok.getIdentifierInfo();
2354
SourceLocation Loc = ConsumeToken();
2355
Name.setIdentifier(Id, Loc);
2356
} else if (ParseUnqualifiedId(
2357
SS, ObjectType, LHS.get() && LHS.get()->containsErrors(),
2358
/*EnteringContext=*/false,
2359
/*AllowDestructorName=*/true,
2360
/*AllowConstructorName=*/
2361
getLangOpts().MicrosoftExt && SS.isNotEmpty(),
2362
/*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) {
2363
(void)Actions.CorrectDelayedTyposInExpr(LHS);
2364
LHS = ExprError();
2365
}
2366
2367
if (!LHS.isInvalid())
2368
LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
2369
OpKind, SS, TemplateKWLoc, Name,
2370
CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
2371
: nullptr);
2372
if (!LHS.isInvalid()) {
2373
if (Tok.is(tok::less))
2374
checkPotentialAngleBracket(LHS);
2375
} else if (OrigLHS && Name.isValid()) {
2376
// Preserve the LHS if the RHS is an invalid member.
2377
LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(),
2378
Name.getEndLoc(), {OrigLHS});
2379
}
2380
break;
2381
}
2382
case tok::plusplus: // postfix-expression: postfix-expression '++'
2383
case tok::minusminus: // postfix-expression: postfix-expression '--'
2384
if (!LHS.isInvalid()) {
2385
Expr *Arg = LHS.get();
2386
LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(),
2387
Tok.getKind(), Arg);
2388
if (LHS.isInvalid())
2389
LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(),
2390
Tok.getLocation(), Arg);
2391
}
2392
ConsumeToken();
2393
break;
2394
}
2395
}
2396
}
2397
2398
/// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/
2399
/// vec_step and we are at the start of an expression or a parenthesized
2400
/// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the
2401
/// expression (isCastExpr == false) or the type (isCastExpr == true).
2402
///
2403
/// \verbatim
2404
/// unary-expression: [C99 6.5.3]
2405
/// 'sizeof' unary-expression
2406
/// 'sizeof' '(' type-name ')'
2407
/// [Clang] '__datasizeof' unary-expression
2408
/// [Clang] '__datasizeof' '(' type-name ')'
2409
/// [GNU] '__alignof' unary-expression
2410
/// [GNU] '__alignof' '(' type-name ')'
2411
/// [C11] '_Alignof' '(' type-name ')'
2412
/// [C++0x] 'alignof' '(' type-id ')'
2413
///
2414
/// [GNU] typeof-specifier:
2415
/// typeof ( expressions )
2416
/// typeof ( type-name )
2417
/// [GNU/C++] typeof unary-expression
2418
/// [C23] typeof-specifier:
2419
/// typeof '(' typeof-specifier-argument ')'
2420
/// typeof_unqual '(' typeof-specifier-argument ')'
2421
///
2422
/// typeof-specifier-argument:
2423
/// expression
2424
/// type-name
2425
///
2426
/// [OpenCL 1.1 6.11.12] vec_step built-in function:
2427
/// vec_step ( expressions )
2428
/// vec_step ( type-name )
2429
/// \endverbatim
2430
ExprResult
2431
Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
2432
bool &isCastExpr,
2433
ParsedType &CastTy,
2434
SourceRange &CastRange) {
2435
2436
assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof,
2437
tok::kw___datasizeof, tok::kw___alignof, tok::kw_alignof,
2438
tok::kw__Alignof, tok::kw_vec_step,
2439
tok::kw___builtin_omp_required_simd_align,
2440
tok::kw___builtin_vectorelements) &&
2441
"Not a typeof/sizeof/alignof/vec_step expression!");
2442
2443
ExprResult Operand;
2444
2445
// If the operand doesn't start with an '(', it must be an expression.
2446
if (Tok.isNot(tok::l_paren)) {
2447
// If construct allows a form without parenthesis, user may forget to put
2448
// pathenthesis around type name.
2449
if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2450
tok::kw_alignof, tok::kw__Alignof)) {
2451
if (isTypeIdUnambiguously()) {
2452
DeclSpec DS(AttrFactory);
2453
ParseSpecifierQualifierList(DS);
2454
Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
2455
DeclaratorContext::TypeName);
2456
ParseDeclarator(DeclaratorInfo);
2457
2458
SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation());
2459
SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation);
2460
if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) {
2461
Diag(OpTok.getLocation(),
2462
diag::err_expected_parentheses_around_typename)
2463
<< OpTok.getName();
2464
} else {
2465
Diag(LParenLoc, diag::err_expected_parentheses_around_typename)
2466
<< OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(")
2467
<< FixItHint::CreateInsertion(RParenLoc, ")");
2468
}
2469
isCastExpr = true;
2470
return ExprEmpty();
2471
}
2472
}
2473
2474
isCastExpr = false;
2475
if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
2476
!getLangOpts().CPlusPlus) {
2477
Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo()
2478
<< tok::l_paren;
2479
return ExprError();
2480
}
2481
2482
Operand = ParseCastExpression(UnaryExprOnly);
2483
} else {
2484
// If it starts with a '(', we know that it is either a parenthesized
2485
// type-name, or it is a unary-expression that starts with a compound
2486
// literal, or starts with a primary-expression that is a parenthesized
2487
// expression.
2488
ParenParseOption ExprType = CastExpr;
2489
SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
2490
2491
Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
2492
false, CastTy, RParenLoc);
2493
CastRange = SourceRange(LParenLoc, RParenLoc);
2494
2495
// If ParseParenExpression parsed a '(typename)' sequence only, then this is
2496
// a type.
2497
if (ExprType == CastExpr) {
2498
isCastExpr = true;
2499
return ExprEmpty();
2500
}
2501
2502
if (getLangOpts().CPlusPlus ||
2503
!OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) {
2504
// GNU typeof in C requires the expression to be parenthesized. Not so for
2505
// sizeof/alignof or in C++. Therefore, the parenthesized expression is
2506
// the start of a unary-expression, but doesn't include any postfix
2507
// pieces. Parse these now if present.
2508
if (!Operand.isInvalid())
2509
Operand = ParsePostfixExpressionSuffix(Operand.get());
2510
}
2511
}
2512
2513
// If we get here, the operand to the typeof/sizeof/alignof was an expression.
2514
isCastExpr = false;
2515
return Operand;
2516
}
2517
2518
/// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as
2519
/// a parameter.
2520
ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
2521
assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) &&
2522
"Not __builtin_sycl_unique_stable_name");
2523
2524
SourceLocation OpLoc = ConsumeToken();
2525
BalancedDelimiterTracker T(*this, tok::l_paren);
2526
2527
// __builtin_sycl_unique_stable_name expressions are always parenthesized.
2528
if (T.expectAndConsume(diag::err_expected_lparen_after,
2529
"__builtin_sycl_unique_stable_name"))
2530
return ExprError();
2531
2532
TypeResult Ty = ParseTypeName();
2533
2534
if (Ty.isInvalid()) {
2535
T.skipToEnd();
2536
return ExprError();
2537
}
2538
2539
if (T.consumeClose())
2540
return ExprError();
2541
2542
return Actions.SYCL().ActOnUniqueStableNameExpr(
2543
OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get());
2544
}
2545
2546
/// Parse a sizeof or alignof expression.
2547
///
2548
/// \verbatim
2549
/// unary-expression: [C99 6.5.3]
2550
/// 'sizeof' unary-expression
2551
/// 'sizeof' '(' type-name ')'
2552
/// [C++11] 'sizeof' '...' '(' identifier ')'
2553
/// [Clang] '__datasizeof' unary-expression
2554
/// [Clang] '__datasizeof' '(' type-name ')'
2555
/// [GNU] '__alignof' unary-expression
2556
/// [GNU] '__alignof' '(' type-name ')'
2557
/// [C11] '_Alignof' '(' type-name ')'
2558
/// [C++11] 'alignof' '(' type-id ')'
2559
/// \endverbatim
2560
ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
2561
assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2562
tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step,
2563
tok::kw___builtin_omp_required_simd_align,
2564
tok::kw___builtin_vectorelements) &&
2565
"Not a sizeof/alignof/vec_step expression!");
2566
Token OpTok = Tok;
2567
ConsumeToken();
2568
2569
// [C++11] 'sizeof' '...' '(' identifier ')'
2570
if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
2571
SourceLocation EllipsisLoc = ConsumeToken();
2572
SourceLocation LParenLoc, RParenLoc;
2573
IdentifierInfo *Name = nullptr;
2574
SourceLocation NameLoc;
2575
if (Tok.is(tok::l_paren)) {
2576
BalancedDelimiterTracker T(*this, tok::l_paren);
2577
T.consumeOpen();
2578
LParenLoc = T.getOpenLocation();
2579
if (Tok.is(tok::identifier)) {
2580
Name = Tok.getIdentifierInfo();
2581
NameLoc = ConsumeToken();
2582
T.consumeClose();
2583
RParenLoc = T.getCloseLocation();
2584
if (RParenLoc.isInvalid())
2585
RParenLoc = PP.getLocForEndOfToken(NameLoc);
2586
} else {
2587
Diag(Tok, diag::err_expected_parameter_pack);
2588
SkipUntil(tok::r_paren, StopAtSemi);
2589
}
2590
} else if (Tok.is(tok::identifier)) {
2591
Name = Tok.getIdentifierInfo();
2592
NameLoc = ConsumeToken();
2593
LParenLoc = PP.getLocForEndOfToken(EllipsisLoc);
2594
RParenLoc = PP.getLocForEndOfToken(NameLoc);
2595
Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack)
2596
<< Name
2597
<< FixItHint::CreateInsertion(LParenLoc, "(")
2598
<< FixItHint::CreateInsertion(RParenLoc, ")");
2599
} else {
2600
Diag(Tok, diag::err_sizeof_parameter_pack);
2601
}
2602
2603
if (!Name)
2604
return ExprError();
2605
2606
EnterExpressionEvaluationContext Unevaluated(
2607
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
2608
Sema::ReuseLambdaContextDecl);
2609
2610
return Actions.ActOnSizeofParameterPackExpr(getCurScope(),
2611
OpTok.getLocation(),
2612
*Name, NameLoc,
2613
RParenLoc);
2614
}
2615
2616
if (getLangOpts().CPlusPlus &&
2617
OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2618
Diag(OpTok, diag::warn_cxx98_compat_alignof);
2619
else if (getLangOpts().C23 && OpTok.is(tok::kw_alignof))
2620
Diag(OpTok, diag::warn_c23_compat_keyword) << OpTok.getName();
2621
2622
EnterExpressionEvaluationContext Unevaluated(
2623
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
2624
Sema::ReuseLambdaContextDecl);
2625
2626
bool isCastExpr;
2627
ParsedType CastTy;
2628
SourceRange CastRange;
2629
ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok,
2630
isCastExpr,
2631
CastTy,
2632
CastRange);
2633
2634
UnaryExprOrTypeTrait ExprKind = UETT_SizeOf;
2635
switch (OpTok.getKind()) {
2636
case tok::kw_alignof:
2637
case tok::kw__Alignof:
2638
ExprKind = UETT_AlignOf;
2639
break;
2640
case tok::kw___alignof:
2641
ExprKind = UETT_PreferredAlignOf;
2642
break;
2643
case tok::kw_vec_step:
2644
ExprKind = UETT_VecStep;
2645
break;
2646
case tok::kw___builtin_omp_required_simd_align:
2647
ExprKind = UETT_OpenMPRequiredSimdAlign;
2648
break;
2649
case tok::kw___datasizeof:
2650
ExprKind = UETT_DataSizeOf;
2651
break;
2652
case tok::kw___builtin_vectorelements:
2653
ExprKind = UETT_VectorElements;
2654
break;
2655
default:
2656
break;
2657
}
2658
2659
if (isCastExpr)
2660
return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
2661
ExprKind,
2662
/*IsType=*/true,
2663
CastTy.getAsOpaquePtr(),
2664
CastRange);
2665
2666
if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2667
Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo();
2668
2669
// If we get here, the operand to the sizeof/alignof was an expression.
2670
if (!Operand.isInvalid())
2671
Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
2672
ExprKind,
2673
/*IsType=*/false,
2674
Operand.get(),
2675
CastRange);
2676
return Operand;
2677
}
2678
2679
/// ParseBuiltinPrimaryExpression
2680
///
2681
/// \verbatim
2682
/// primary-expression: [C99 6.5.1]
2683
/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
2684
/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
2685
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
2686
/// assign-expr ')'
2687
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
2688
/// [GNU] '__builtin_FILE' '(' ')'
2689
/// [CLANG] '__builtin_FILE_NAME' '(' ')'
2690
/// [GNU] '__builtin_FUNCTION' '(' ')'
2691
/// [MS] '__builtin_FUNCSIG' '(' ')'
2692
/// [GNU] '__builtin_LINE' '(' ')'
2693
/// [CLANG] '__builtin_COLUMN' '(' ')'
2694
/// [GNU] '__builtin_source_location' '(' ')'
2695
/// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')'
2696
///
2697
/// [GNU] offsetof-member-designator:
2698
/// [GNU] identifier
2699
/// [GNU] offsetof-member-designator '.' identifier
2700
/// [GNU] offsetof-member-designator '[' expression ']'
2701
/// \endverbatim
2702
ExprResult Parser::ParseBuiltinPrimaryExpression() {
2703
ExprResult Res;
2704
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
2705
2706
tok::TokenKind T = Tok.getKind();
2707
SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier.
2708
2709
// All of these start with an open paren.
2710
if (Tok.isNot(tok::l_paren))
2711
return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII
2712
<< tok::l_paren);
2713
2714
BalancedDelimiterTracker PT(*this, tok::l_paren);
2715
PT.consumeOpen();
2716
2717
// TODO: Build AST.
2718
2719
switch (T) {
2720
default: llvm_unreachable("Not a builtin primary expression!");
2721
case tok::kw___builtin_va_arg: {
2722
ExprResult Expr(ParseAssignmentExpression());
2723
2724
if (ExpectAndConsume(tok::comma)) {
2725
SkipUntil(tok::r_paren, StopAtSemi);
2726
Expr = ExprError();
2727
}
2728
2729
TypeResult Ty = ParseTypeName();
2730
2731
if (Tok.isNot(tok::r_paren)) {
2732
Diag(Tok, diag::err_expected) << tok::r_paren;
2733
Expr = ExprError();
2734
}
2735
2736
if (Expr.isInvalid() || Ty.isInvalid())
2737
Res = ExprError();
2738
else
2739
Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen());
2740
break;
2741
}
2742
case tok::kw___builtin_offsetof: {
2743
SourceLocation TypeLoc = Tok.getLocation();
2744
auto OOK = Sema::OffsetOfKind::OOK_Builtin;
2745
if (Tok.getLocation().isMacroID()) {
2746
StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
2747
Tok.getLocation(), PP.getSourceManager(), getLangOpts());
2748
if (MacroName == "offsetof")
2749
OOK = Sema::OffsetOfKind::OOK_Macro;
2750
}
2751
TypeResult Ty;
2752
{
2753
OffsetOfStateRAIIObject InOffsetof(*this, OOK);
2754
Ty = ParseTypeName();
2755
if (Ty.isInvalid()) {
2756
SkipUntil(tok::r_paren, StopAtSemi);
2757
return ExprError();
2758
}
2759
}
2760
2761
if (ExpectAndConsume(tok::comma)) {
2762
SkipUntil(tok::r_paren, StopAtSemi);
2763
return ExprError();
2764
}
2765
2766
// We must have at least one identifier here.
2767
if (Tok.isNot(tok::identifier)) {
2768
Diag(Tok, diag::err_expected) << tok::identifier;
2769
SkipUntil(tok::r_paren, StopAtSemi);
2770
return ExprError();
2771
}
2772
2773
// Keep track of the various subcomponents we see.
2774
SmallVector<Sema::OffsetOfComponent, 4> Comps;
2775
2776
Comps.push_back(Sema::OffsetOfComponent());
2777
Comps.back().isBrackets = false;
2778
Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2779
Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
2780
2781
// FIXME: This loop leaks the index expressions on error.
2782
while (true) {
2783
if (Tok.is(tok::period)) {
2784
// offsetof-member-designator: offsetof-member-designator '.' identifier
2785
Comps.push_back(Sema::OffsetOfComponent());
2786
Comps.back().isBrackets = false;
2787
Comps.back().LocStart = ConsumeToken();
2788
2789
if (Tok.isNot(tok::identifier)) {
2790
Diag(Tok, diag::err_expected) << tok::identifier;
2791
SkipUntil(tok::r_paren, StopAtSemi);
2792
return ExprError();
2793
}
2794
Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2795
Comps.back().LocEnd = ConsumeToken();
2796
} else if (Tok.is(tok::l_square)) {
2797
if (CheckProhibitedCXX11Attribute())
2798
return ExprError();
2799
2800
// offsetof-member-designator: offsetof-member-design '[' expression ']'
2801
Comps.push_back(Sema::OffsetOfComponent());
2802
Comps.back().isBrackets = true;
2803
BalancedDelimiterTracker ST(*this, tok::l_square);
2804
ST.consumeOpen();
2805
Comps.back().LocStart = ST.getOpenLocation();
2806
Res = ParseExpression();
2807
if (Res.isInvalid()) {
2808
SkipUntil(tok::r_paren, StopAtSemi);
2809
return Res;
2810
}
2811
Comps.back().U.E = Res.get();
2812
2813
ST.consumeClose();
2814
Comps.back().LocEnd = ST.getCloseLocation();
2815
} else {
2816
if (Tok.isNot(tok::r_paren)) {
2817
PT.consumeClose();
2818
Res = ExprError();
2819
} else if (Ty.isInvalid()) {
2820
Res = ExprError();
2821
} else {
2822
PT.consumeClose();
2823
Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc,
2824
Ty.get(), Comps,
2825
PT.getCloseLocation());
2826
}
2827
break;
2828
}
2829
}
2830
break;
2831
}
2832
case tok::kw___builtin_choose_expr: {
2833
ExprResult Cond(ParseAssignmentExpression());
2834
if (Cond.isInvalid()) {
2835
SkipUntil(tok::r_paren, StopAtSemi);
2836
return Cond;
2837
}
2838
if (ExpectAndConsume(tok::comma)) {
2839
SkipUntil(tok::r_paren, StopAtSemi);
2840
return ExprError();
2841
}
2842
2843
ExprResult Expr1(ParseAssignmentExpression());
2844
if (Expr1.isInvalid()) {
2845
SkipUntil(tok::r_paren, StopAtSemi);
2846
return Expr1;
2847
}
2848
if (ExpectAndConsume(tok::comma)) {
2849
SkipUntil(tok::r_paren, StopAtSemi);
2850
return ExprError();
2851
}
2852
2853
ExprResult Expr2(ParseAssignmentExpression());
2854
if (Expr2.isInvalid()) {
2855
SkipUntil(tok::r_paren, StopAtSemi);
2856
return Expr2;
2857
}
2858
if (Tok.isNot(tok::r_paren)) {
2859
Diag(Tok, diag::err_expected) << tok::r_paren;
2860
return ExprError();
2861
}
2862
Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
2863
Expr2.get(), ConsumeParen());
2864
break;
2865
}
2866
case tok::kw___builtin_astype: {
2867
// The first argument is an expression to be converted, followed by a comma.
2868
ExprResult Expr(ParseAssignmentExpression());
2869
if (Expr.isInvalid()) {
2870
SkipUntil(tok::r_paren, StopAtSemi);
2871
return ExprError();
2872
}
2873
2874
if (ExpectAndConsume(tok::comma)) {
2875
SkipUntil(tok::r_paren, StopAtSemi);
2876
return ExprError();
2877
}
2878
2879
// Second argument is the type to bitcast to.
2880
TypeResult DestTy = ParseTypeName();
2881
if (DestTy.isInvalid())
2882
return ExprError();
2883
2884
// Attempt to consume the r-paren.
2885
if (Tok.isNot(tok::r_paren)) {
2886
Diag(Tok, diag::err_expected) << tok::r_paren;
2887
SkipUntil(tok::r_paren, StopAtSemi);
2888
return ExprError();
2889
}
2890
2891
Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc,
2892
ConsumeParen());
2893
break;
2894
}
2895
case tok::kw___builtin_convertvector: {
2896
// The first argument is an expression to be converted, followed by a comma.
2897
ExprResult Expr(ParseAssignmentExpression());
2898
if (Expr.isInvalid()) {
2899
SkipUntil(tok::r_paren, StopAtSemi);
2900
return ExprError();
2901
}
2902
2903
if (ExpectAndConsume(tok::comma)) {
2904
SkipUntil(tok::r_paren, StopAtSemi);
2905
return ExprError();
2906
}
2907
2908
// Second argument is the type to bitcast to.
2909
TypeResult DestTy = ParseTypeName();
2910
if (DestTy.isInvalid())
2911
return ExprError();
2912
2913
// Attempt to consume the r-paren.
2914
if (Tok.isNot(tok::r_paren)) {
2915
Diag(Tok, diag::err_expected) << tok::r_paren;
2916
SkipUntil(tok::r_paren, StopAtSemi);
2917
return ExprError();
2918
}
2919
2920
Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc,
2921
ConsumeParen());
2922
break;
2923
}
2924
case tok::kw___builtin_COLUMN:
2925
case tok::kw___builtin_FILE:
2926
case tok::kw___builtin_FILE_NAME:
2927
case tok::kw___builtin_FUNCTION:
2928
case tok::kw___builtin_FUNCSIG:
2929
case tok::kw___builtin_LINE:
2930
case tok::kw___builtin_source_location: {
2931
// Attempt to consume the r-paren.
2932
if (Tok.isNot(tok::r_paren)) {
2933
Diag(Tok, diag::err_expected) << tok::r_paren;
2934
SkipUntil(tok::r_paren, StopAtSemi);
2935
return ExprError();
2936
}
2937
SourceLocIdentKind Kind = [&] {
2938
switch (T) {
2939
case tok::kw___builtin_FILE:
2940
return SourceLocIdentKind::File;
2941
case tok::kw___builtin_FILE_NAME:
2942
return SourceLocIdentKind::FileName;
2943
case tok::kw___builtin_FUNCTION:
2944
return SourceLocIdentKind::Function;
2945
case tok::kw___builtin_FUNCSIG:
2946
return SourceLocIdentKind::FuncSig;
2947
case tok::kw___builtin_LINE:
2948
return SourceLocIdentKind::Line;
2949
case tok::kw___builtin_COLUMN:
2950
return SourceLocIdentKind::Column;
2951
case tok::kw___builtin_source_location:
2952
return SourceLocIdentKind::SourceLocStruct;
2953
default:
2954
llvm_unreachable("invalid keyword");
2955
}
2956
}();
2957
Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen());
2958
break;
2959
}
2960
}
2961
2962
if (Res.isInvalid())
2963
return ExprError();
2964
2965
// These can be followed by postfix-expr pieces because they are
2966
// primary-expressions.
2967
return ParsePostfixExpressionSuffix(Res.get());
2968
}
2969
2970
bool Parser::tryParseOpenMPArrayShapingCastPart() {
2971
assert(Tok.is(tok::l_square) && "Expected open bracket");
2972
bool ErrorFound = true;
2973
TentativeParsingAction TPA(*this);
2974
do {
2975
if (Tok.isNot(tok::l_square))
2976
break;
2977
// Consume '['
2978
ConsumeBracket();
2979
// Skip inner expression.
2980
while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end,
2981
StopAtSemi | StopBeforeMatch))
2982
;
2983
if (Tok.isNot(tok::r_square))
2984
break;
2985
// Consume ']'
2986
ConsumeBracket();
2987
// Found ')' - done.
2988
if (Tok.is(tok::r_paren)) {
2989
ErrorFound = false;
2990
break;
2991
}
2992
} while (Tok.isNot(tok::annot_pragma_openmp_end));
2993
TPA.Revert();
2994
return !ErrorFound;
2995
}
2996
2997
/// ParseParenExpression - This parses the unit that starts with a '(' token,
2998
/// based on what is allowed by ExprType. The actual thing parsed is returned
2999
/// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
3000
/// not the parsed cast-expression.
3001
///
3002
/// \verbatim
3003
/// primary-expression: [C99 6.5.1]
3004
/// '(' expression ')'
3005
/// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
3006
/// postfix-expression: [C99 6.5.2]
3007
/// '(' type-name ')' '{' initializer-list '}'
3008
/// '(' type-name ')' '{' initializer-list ',' '}'
3009
/// cast-expression: [C99 6.5.4]
3010
/// '(' type-name ')' cast-expression
3011
/// [ARC] bridged-cast-expression
3012
/// [ARC] bridged-cast-expression:
3013
/// (__bridge type-name) cast-expression
3014
/// (__bridge_transfer type-name) cast-expression
3015
/// (__bridge_retained type-name) cast-expression
3016
/// fold-expression: [C++1z]
3017
/// '(' cast-expression fold-operator '...' ')'
3018
/// '(' '...' fold-operator cast-expression ')'
3019
/// '(' cast-expression fold-operator '...'
3020
/// fold-operator cast-expression ')'
3021
/// [OPENMP] Array shaping operation
3022
/// '(' '[' expression ']' { '[' expression ']' } cast-expression
3023
/// \endverbatim
3024
ExprResult
3025
Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
3026
bool isTypeCast, ParsedType &CastTy,
3027
SourceLocation &RParenLoc) {
3028
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
3029
ColonProtectionRAIIObject ColonProtection(*this, false);
3030
BalancedDelimiterTracker T(*this, tok::l_paren);
3031
if (T.consumeOpen())
3032
return ExprError();
3033
SourceLocation OpenLoc = T.getOpenLocation();
3034
3035
PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
3036
3037
ExprResult Result(true);
3038
bool isAmbiguousTypeId;
3039
CastTy = nullptr;
3040
3041
if (Tok.is(tok::code_completion)) {
3042
cutOffParsing();
3043
Actions.CodeCompletion().CodeCompleteExpression(
3044
getCurScope(), PreferredType.get(Tok.getLocation()),
3045
/*IsParenthesized=*/ExprType >= CompoundLiteral);
3046
return ExprError();
3047
}
3048
3049
// Diagnose use of bridge casts in non-arc mode.
3050
bool BridgeCast = (getLangOpts().ObjC &&
3051
Tok.isOneOf(tok::kw___bridge,
3052
tok::kw___bridge_transfer,
3053
tok::kw___bridge_retained,
3054
tok::kw___bridge_retain));
3055
if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
3056
if (!TryConsumeToken(tok::kw___bridge)) {
3057
StringRef BridgeCastName = Tok.getName();
3058
SourceLocation BridgeKeywordLoc = ConsumeToken();
3059
if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
3060
Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
3061
<< BridgeCastName
3062
<< FixItHint::CreateReplacement(BridgeKeywordLoc, "");
3063
}
3064
BridgeCast = false;
3065
}
3066
3067
// None of these cases should fall through with an invalid Result
3068
// unless they've already reported an error.
3069
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
3070
Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro
3071
: diag::ext_gnu_statement_expr);
3072
3073
checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin);
3074
3075
if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
3076
Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
3077
} else {
3078
// Find the nearest non-record decl context. Variables declared in a
3079
// statement expression behave as if they were declared in the enclosing
3080
// function, block, or other code construct.
3081
DeclContext *CodeDC = Actions.CurContext;
3082
while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) {
3083
CodeDC = CodeDC->getParent();
3084
assert(CodeDC && !CodeDC->isFileContext() &&
3085
"statement expr not in code context");
3086
}
3087
Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false);
3088
3089
Actions.ActOnStartStmtExpr();
3090
3091
StmtResult Stmt(ParseCompoundStatement(true));
3092
ExprType = CompoundStmt;
3093
3094
// If the substmt parsed correctly, build the AST node.
3095
if (!Stmt.isInvalid()) {
3096
Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(),
3097
Tok.getLocation());
3098
} else {
3099
Actions.ActOnStmtExprError();
3100
}
3101
}
3102
} else if (ExprType >= CompoundLiteral && BridgeCast) {
3103
tok::TokenKind tokenKind = Tok.getKind();
3104
SourceLocation BridgeKeywordLoc = ConsumeToken();
3105
3106
// Parse an Objective-C ARC ownership cast expression.
3107
ObjCBridgeCastKind Kind;
3108
if (tokenKind == tok::kw___bridge)
3109
Kind = OBC_Bridge;
3110
else if (tokenKind == tok::kw___bridge_transfer)
3111
Kind = OBC_BridgeTransfer;
3112
else if (tokenKind == tok::kw___bridge_retained)
3113
Kind = OBC_BridgeRetained;
3114
else {
3115
// As a hopefully temporary workaround, allow __bridge_retain as
3116
// a synonym for __bridge_retained, but only in system headers.
3117
assert(tokenKind == tok::kw___bridge_retain);
3118
Kind = OBC_BridgeRetained;
3119
if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
3120
Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
3121
<< FixItHint::CreateReplacement(BridgeKeywordLoc,
3122
"__bridge_retained");
3123
}
3124
3125
TypeResult Ty = ParseTypeName();
3126
T.consumeClose();
3127
ColonProtection.restore();
3128
RParenLoc = T.getCloseLocation();
3129
3130
PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get());
3131
ExprResult SubExpr = ParseCastExpression(AnyCastExpr);
3132
3133
if (Ty.isInvalid() || SubExpr.isInvalid())
3134
return ExprError();
3135
3136
return Actions.ObjC().ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind,
3137
BridgeKeywordLoc, Ty.get(),
3138
RParenLoc, SubExpr.get());
3139
} else if (ExprType >= CompoundLiteral &&
3140
isTypeIdInParens(isAmbiguousTypeId)) {
3141
3142
// Otherwise, this is a compound literal expression or cast expression.
3143
3144
// In C++, if the type-id is ambiguous we disambiguate based on context.
3145
// If stopIfCastExpr is true the context is a typeof/sizeof/alignof
3146
// in which case we should treat it as type-id.
3147
// if stopIfCastExpr is false, we need to determine the context past the
3148
// parens, so we defer to ParseCXXAmbiguousParenExpression for that.
3149
if (isAmbiguousTypeId && !stopIfCastExpr) {
3150
ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
3151
ColonProtection);
3152
RParenLoc = T.getCloseLocation();
3153
return res;
3154
}
3155
3156
// Parse the type declarator.
3157
DeclSpec DS(AttrFactory);
3158
ParseSpecifierQualifierList(DS);
3159
Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
3160
DeclaratorContext::TypeName);
3161
ParseDeclarator(DeclaratorInfo);
3162
3163
// If our type is followed by an identifier and either ':' or ']', then
3164
// this is probably an Objective-C message send where the leading '[' is
3165
// missing. Recover as if that were the case.
3166
if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
3167
!InMessageExpression && getLangOpts().ObjC &&
3168
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
3169
TypeResult Ty;
3170
{
3171
InMessageExpressionRAIIObject InMessage(*this, false);
3172
Ty = Actions.ActOnTypeName(DeclaratorInfo);
3173
}
3174
Result = ParseObjCMessageExpressionBody(SourceLocation(),
3175
SourceLocation(),
3176
Ty.get(), nullptr);
3177
} else {
3178
// Match the ')'.
3179
T.consumeClose();
3180
ColonProtection.restore();
3181
RParenLoc = T.getCloseLocation();
3182
if (Tok.is(tok::l_brace)) {
3183
ExprType = CompoundLiteral;
3184
TypeResult Ty;
3185
{
3186
InMessageExpressionRAIIObject InMessage(*this, false);
3187
Ty = Actions.ActOnTypeName(DeclaratorInfo);
3188
}
3189
return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
3190
}
3191
3192
if (Tok.is(tok::l_paren)) {
3193
// This could be OpenCL vector Literals
3194
if (getLangOpts().OpenCL)
3195
{
3196
TypeResult Ty;
3197
{
3198
InMessageExpressionRAIIObject InMessage(*this, false);
3199
Ty = Actions.ActOnTypeName(DeclaratorInfo);
3200
}
3201
if(Ty.isInvalid())
3202
{
3203
return ExprError();
3204
}
3205
QualType QT = Ty.get().get().getCanonicalType();
3206
if (QT->isVectorType())
3207
{
3208
// We parsed '(' vector-type-name ')' followed by '('
3209
3210
// Parse the cast-expression that follows it next.
3211
// isVectorLiteral = true will make sure we don't parse any
3212
// Postfix expression yet
3213
Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr,
3214
/*isAddressOfOperand=*/false,
3215
/*isTypeCast=*/IsTypeCast,
3216
/*isVectorLiteral=*/true);
3217
3218
if (!Result.isInvalid()) {
3219
Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
3220
DeclaratorInfo, CastTy,
3221
RParenLoc, Result.get());
3222
}
3223
3224
// After we performed the cast we can check for postfix-expr pieces.
3225
if (!Result.isInvalid()) {
3226
Result = ParsePostfixExpressionSuffix(Result);
3227
}
3228
3229
return Result;
3230
}
3231
}
3232
}
3233
3234
if (ExprType == CastExpr) {
3235
// We parsed '(' type-name ')' and the thing after it wasn't a '{'.
3236
3237
if (DeclaratorInfo.isInvalidType())
3238
return ExprError();
3239
3240
// Note that this doesn't parse the subsequent cast-expression, it just
3241
// returns the parsed type to the callee.
3242
if (stopIfCastExpr) {
3243
TypeResult Ty;
3244
{
3245
InMessageExpressionRAIIObject InMessage(*this, false);
3246
Ty = Actions.ActOnTypeName(DeclaratorInfo);
3247
}
3248
CastTy = Ty.get();
3249
return ExprResult();
3250
}
3251
3252
// Reject the cast of super idiom in ObjC.
3253
if (Tok.is(tok::identifier) && getLangOpts().ObjC &&
3254
Tok.getIdentifierInfo() == Ident_super &&
3255
getCurScope()->isInObjcMethodScope() &&
3256
GetLookAheadToken(1).isNot(tok::period)) {
3257
Diag(Tok.getLocation(), diag::err_illegal_super_cast)
3258
<< SourceRange(OpenLoc, RParenLoc);
3259
return ExprError();
3260
}
3261
3262
PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get());
3263
// Parse the cast-expression that follows it next.
3264
// TODO: For cast expression with CastTy.
3265
Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr,
3266
/*isAddressOfOperand=*/false,
3267
/*isTypeCast=*/IsTypeCast);
3268
if (!Result.isInvalid()) {
3269
Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
3270
DeclaratorInfo, CastTy,
3271
RParenLoc, Result.get());
3272
}
3273
return Result;
3274
}
3275
3276
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
3277
return ExprError();
3278
}
3279
} else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) &&
3280
isFoldOperator(NextToken().getKind())) {
3281
ExprType = FoldExpr;
3282
return ParseFoldExpression(ExprResult(), T);
3283
} else if (isTypeCast) {
3284
// Parse the expression-list.
3285
InMessageExpressionRAIIObject InMessage(*this, false);
3286
ExprVector ArgExprs;
3287
3288
if (!ParseSimpleExpressionList(ArgExprs)) {
3289
// FIXME: If we ever support comma expressions as operands to
3290
// fold-expressions, we'll need to allow multiple ArgExprs here.
3291
if (ExprType >= FoldExpr && ArgExprs.size() == 1 &&
3292
isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
3293
ExprType = FoldExpr;
3294
return ParseFoldExpression(ArgExprs[0], T);
3295
}
3296
3297
ExprType = SimpleExpr;
3298
Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
3299
ArgExprs);
3300
}
3301
} else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing &&
3302
ExprType == CastExpr && Tok.is(tok::l_square) &&
3303
tryParseOpenMPArrayShapingCastPart()) {
3304
bool ErrorFound = false;
3305
SmallVector<Expr *, 4> OMPDimensions;
3306
SmallVector<SourceRange, 4> OMPBracketsRanges;
3307
do {
3308
BalancedDelimiterTracker TS(*this, tok::l_square);
3309
TS.consumeOpen();
3310
ExprResult NumElements =
3311
Actions.CorrectDelayedTyposInExpr(ParseExpression());
3312
if (!NumElements.isUsable()) {
3313
ErrorFound = true;
3314
while (!SkipUntil(tok::r_square, tok::r_paren,
3315
StopAtSemi | StopBeforeMatch))
3316
;
3317
}
3318
TS.consumeClose();
3319
OMPDimensions.push_back(NumElements.get());
3320
OMPBracketsRanges.push_back(TS.getRange());
3321
} while (Tok.isNot(tok::r_paren));
3322
// Match the ')'.
3323
T.consumeClose();
3324
RParenLoc = T.getCloseLocation();
3325
Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3326
if (ErrorFound) {
3327
Result = ExprError();
3328
} else if (!Result.isInvalid()) {
3329
Result = Actions.OpenMP().ActOnOMPArrayShapingExpr(
3330
Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges);
3331
}
3332
return Result;
3333
} else {
3334
InMessageExpressionRAIIObject InMessage(*this, false);
3335
3336
Result = ParseExpression(MaybeTypeCast);
3337
if (!getLangOpts().CPlusPlus && Result.isUsable()) {
3338
// Correct typos in non-C++ code earlier so that implicit-cast-like
3339
// expressions are parsed correctly.
3340
Result = Actions.CorrectDelayedTyposInExpr(Result);
3341
}
3342
3343
if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) &&
3344
NextToken().is(tok::ellipsis)) {
3345
ExprType = FoldExpr;
3346
return ParseFoldExpression(Result, T);
3347
}
3348
ExprType = SimpleExpr;
3349
3350
// Don't build a paren expression unless we actually match a ')'.
3351
if (!Result.isInvalid() && Tok.is(tok::r_paren))
3352
Result =
3353
Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get());
3354
}
3355
3356
// Match the ')'.
3357
if (Result.isInvalid()) {
3358
SkipUntil(tok::r_paren, StopAtSemi);
3359
return ExprError();
3360
}
3361
3362
T.consumeClose();
3363
RParenLoc = T.getCloseLocation();
3364
return Result;
3365
}
3366
3367
/// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
3368
/// and we are at the left brace.
3369
///
3370
/// \verbatim
3371
/// postfix-expression: [C99 6.5.2]
3372
/// '(' type-name ')' '{' initializer-list '}'
3373
/// '(' type-name ')' '{' initializer-list ',' '}'
3374
/// \endverbatim
3375
ExprResult
3376
Parser::ParseCompoundLiteralExpression(ParsedType Ty,
3377
SourceLocation LParenLoc,
3378
SourceLocation RParenLoc) {
3379
assert(Tok.is(tok::l_brace) && "Not a compound literal!");
3380
if (!getLangOpts().C99) // Compound literals don't exist in C90.
3381
Diag(LParenLoc, diag::ext_c99_compound_literal);
3382
PreferredType.enterTypeCast(Tok.getLocation(), Ty.get());
3383
ExprResult Result = ParseInitializer();
3384
if (!Result.isInvalid() && Ty)
3385
return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
3386
return Result;
3387
}
3388
3389
/// ParseStringLiteralExpression - This handles the various token types that
3390
/// form string literals, and also handles string concatenation [C99 5.1.1.2,
3391
/// translation phase #6].
3392
///
3393
/// \verbatim
3394
/// primary-expression: [C99 6.5.1]
3395
/// string-literal
3396
/// \verbatim
3397
ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) {
3398
return ParseStringLiteralExpression(AllowUserDefinedLiteral,
3399
/*Unevaluated=*/false);
3400
}
3401
3402
ExprResult Parser::ParseUnevaluatedStringLiteralExpression() {
3403
return ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false,
3404
/*Unevaluated=*/true);
3405
}
3406
3407
ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
3408
bool Unevaluated) {
3409
assert(tokenIsLikeStringLiteral(Tok, getLangOpts()) &&
3410
"Not a string-literal-like token!");
3411
3412
// String concatenation.
3413
// Note: some keywords like __FUNCTION__ are not considered to be strings
3414
// for concatenation purposes, unless Microsoft extensions are enabled.
3415
SmallVector<Token, 4> StringToks;
3416
3417
do {
3418
StringToks.push_back(Tok);
3419
ConsumeAnyToken();
3420
} while (tokenIsLikeStringLiteral(Tok, getLangOpts()));
3421
3422
if (Unevaluated) {
3423
assert(!AllowUserDefinedLiteral && "UDL are always evaluated");
3424
return Actions.ActOnUnevaluatedStringLiteral(StringToks);
3425
}
3426
3427
// Pass the set of string tokens, ready for concatenation, to the actions.
3428
return Actions.ActOnStringLiteral(StringToks,
3429
AllowUserDefinedLiteral ? getCurScope()
3430
: nullptr);
3431
}
3432
3433
/// ParseGenericSelectionExpression - Parse a C11 generic-selection
3434
/// [C11 6.5.1.1].
3435
///
3436
/// \verbatim
3437
/// generic-selection:
3438
/// _Generic ( assignment-expression , generic-assoc-list )
3439
/// generic-assoc-list:
3440
/// generic-association
3441
/// generic-assoc-list , generic-association
3442
/// generic-association:
3443
/// type-name : assignment-expression
3444
/// default : assignment-expression
3445
/// \endverbatim
3446
///
3447
/// As an extension, Clang also accepts:
3448
/// \verbatim
3449
/// generic-selection:
3450
/// _Generic ( type-name, generic-assoc-list )
3451
/// \endverbatim
3452
ExprResult Parser::ParseGenericSelectionExpression() {
3453
assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
3454
3455
diagnoseUseOfC11Keyword(Tok);
3456
3457
SourceLocation KeyLoc = ConsumeToken();
3458
BalancedDelimiterTracker T(*this, tok::l_paren);
3459
if (T.expectAndConsume())
3460
return ExprError();
3461
3462
// We either have a controlling expression or we have a controlling type, and
3463
// we need to figure out which it is.
3464
TypeResult ControllingType;
3465
ExprResult ControllingExpr;
3466
if (isTypeIdForGenericSelection()) {
3467
ControllingType = ParseTypeName();
3468
if (ControllingType.isInvalid()) {
3469
SkipUntil(tok::r_paren, StopAtSemi);
3470
return ExprError();
3471
}
3472
const auto *LIT = cast<LocInfoType>(ControllingType.get().get());
3473
SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
3474
Diag(Loc, getLangOpts().C2y ? diag::warn_c2y_compat_generic_with_type_arg
3475
: diag::ext_c2y_generic_with_type_arg);
3476
} else {
3477
// C11 6.5.1.1p3 "The controlling expression of a generic selection is
3478
// not evaluated."
3479
EnterExpressionEvaluationContext Unevaluated(
3480
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
3481
ControllingExpr =
3482
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3483
if (ControllingExpr.isInvalid()) {
3484
SkipUntil(tok::r_paren, StopAtSemi);
3485
return ExprError();
3486
}
3487
}
3488
3489
if (ExpectAndConsume(tok::comma)) {
3490
SkipUntil(tok::r_paren, StopAtSemi);
3491
return ExprError();
3492
}
3493
3494
SourceLocation DefaultLoc;
3495
SmallVector<ParsedType, 12> Types;
3496
ExprVector Exprs;
3497
do {
3498
ParsedType Ty;
3499
if (Tok.is(tok::kw_default)) {
3500
// C11 6.5.1.1p2 "A generic selection shall have no more than one default
3501
// generic association."
3502
if (!DefaultLoc.isInvalid()) {
3503
Diag(Tok, diag::err_duplicate_default_assoc);
3504
Diag(DefaultLoc, diag::note_previous_default_assoc);
3505
SkipUntil(tok::r_paren, StopAtSemi);
3506
return ExprError();
3507
}
3508
DefaultLoc = ConsumeToken();
3509
Ty = nullptr;
3510
} else {
3511
ColonProtectionRAIIObject X(*this);
3512
TypeResult TR = ParseTypeName(nullptr, DeclaratorContext::Association);
3513
if (TR.isInvalid()) {
3514
SkipUntil(tok::r_paren, StopAtSemi);
3515
return ExprError();
3516
}
3517
Ty = TR.get();
3518
}
3519
Types.push_back(Ty);
3520
3521
if (ExpectAndConsume(tok::colon)) {
3522
SkipUntil(tok::r_paren, StopAtSemi);
3523
return ExprError();
3524
}
3525
3526
// FIXME: These expressions should be parsed in a potentially potentially
3527
// evaluated context.
3528
ExprResult ER(
3529
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
3530
if (ER.isInvalid()) {
3531
SkipUntil(tok::r_paren, StopAtSemi);
3532
return ExprError();
3533
}
3534
Exprs.push_back(ER.get());
3535
} while (TryConsumeToken(tok::comma));
3536
3537
T.consumeClose();
3538
if (T.getCloseLocation().isInvalid())
3539
return ExprError();
3540
3541
void *ExprOrTy = ControllingExpr.isUsable()
3542
? ControllingExpr.get()
3543
: ControllingType.get().getAsOpaquePtr();
3544
3545
return Actions.ActOnGenericSelectionExpr(
3546
KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(),
3547
ExprOrTy, Types, Exprs);
3548
}
3549
3550
/// Parse A C++1z fold-expression after the opening paren and optional
3551
/// left-hand-side expression.
3552
///
3553
/// \verbatim
3554
/// fold-expression:
3555
/// ( cast-expression fold-operator ... )
3556
/// ( ... fold-operator cast-expression )
3557
/// ( cast-expression fold-operator ... fold-operator cast-expression )
3558
ExprResult Parser::ParseFoldExpression(ExprResult LHS,
3559
BalancedDelimiterTracker &T) {
3560
if (LHS.isInvalid()) {
3561
T.skipToEnd();
3562
return true;
3563
}
3564
3565
tok::TokenKind Kind = tok::unknown;
3566
SourceLocation FirstOpLoc;
3567
if (LHS.isUsable()) {
3568
Kind = Tok.getKind();
3569
assert(isFoldOperator(Kind) && "missing fold-operator");
3570
FirstOpLoc = ConsumeToken();
3571
}
3572
3573
assert(Tok.is(tok::ellipsis) && "not a fold-expression");
3574
SourceLocation EllipsisLoc = ConsumeToken();
3575
3576
ExprResult RHS;
3577
if (Tok.isNot(tok::r_paren)) {
3578
if (!isFoldOperator(Tok.getKind()))
3579
return Diag(Tok.getLocation(), diag::err_expected_fold_operator);
3580
3581
if (Kind != tok::unknown && Tok.getKind() != Kind)
3582
Diag(Tok.getLocation(), diag::err_fold_operator_mismatch)
3583
<< SourceRange(FirstOpLoc);
3584
Kind = Tok.getKind();
3585
ConsumeToken();
3586
3587
RHS = ParseExpression();
3588
if (RHS.isInvalid()) {
3589
T.skipToEnd();
3590
return true;
3591
}
3592
}
3593
3594
Diag(EllipsisLoc, getLangOpts().CPlusPlus17
3595
? diag::warn_cxx14_compat_fold_expression
3596
: diag::ext_fold_expression);
3597
3598
T.consumeClose();
3599
return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(),
3600
Kind, EllipsisLoc, RHS.get(),
3601
T.getCloseLocation());
3602
}
3603
3604
void Parser::injectEmbedTokens() {
3605
EmbedAnnotationData *Data =
3606
reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue());
3607
MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(
3608
Data->BinaryData.size() * 2 - 1),
3609
Data->BinaryData.size() * 2 - 1);
3610
unsigned I = 0;
3611
for (auto &Byte : Data->BinaryData) {
3612
Toks[I].startToken();
3613
Toks[I].setKind(tok::binary_data);
3614
Toks[I].setLocation(Tok.getLocation());
3615
Toks[I].setLength(1);
3616
Toks[I].setLiteralData(&Byte);
3617
if (I != ((Data->BinaryData.size() - 1) * 2)) {
3618
Toks[I + 1].startToken();
3619
Toks[I + 1].setKind(tok::comma);
3620
Toks[I + 1].setLocation(Tok.getLocation());
3621
}
3622
I += 2;
3623
}
3624
PP.EnterTokenStream(std::move(Toks), /*DisableMacroExpansion=*/true,
3625
/*IsReinject=*/true);
3626
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
3627
}
3628
3629
/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
3630
///
3631
/// \verbatim
3632
/// argument-expression-list:
3633
/// assignment-expression
3634
/// argument-expression-list , assignment-expression
3635
///
3636
/// [C++] expression-list:
3637
/// [C++] assignment-expression
3638
/// [C++] expression-list , assignment-expression
3639
///
3640
/// [C++0x] expression-list:
3641
/// [C++0x] initializer-list
3642
///
3643
/// [C++0x] initializer-list
3644
/// [C++0x] initializer-clause ...[opt]
3645
/// [C++0x] initializer-list , initializer-clause ...[opt]
3646
///
3647
/// [C++0x] initializer-clause:
3648
/// [C++0x] assignment-expression
3649
/// [C++0x] braced-init-list
3650
/// \endverbatim
3651
bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
3652
llvm::function_ref<void()> ExpressionStarts,
3653
bool FailImmediatelyOnInvalidExpr,
3654
bool EarlyTypoCorrection) {
3655
bool SawError = false;
3656
while (true) {
3657
if (ExpressionStarts)
3658
ExpressionStarts();
3659
3660
ExprResult Expr;
3661
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
3662
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3663
Expr = ParseBraceInitializer();
3664
} else
3665
Expr = ParseAssignmentExpression();
3666
3667
if (EarlyTypoCorrection)
3668
Expr = Actions.CorrectDelayedTyposInExpr(Expr);
3669
3670
if (Tok.is(tok::ellipsis))
3671
Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
3672
else if (Tok.is(tok::code_completion)) {
3673
// There's nothing to suggest in here as we parsed a full expression.
3674
// Instead fail and propagate the error since caller might have something
3675
// the suggest, e.g. signature help in function call. Note that this is
3676
// performed before pushing the \p Expr, so that signature help can report
3677
// current argument correctly.
3678
SawError = true;
3679
cutOffParsing();
3680
break;
3681
}
3682
if (Expr.isInvalid()) {
3683
SawError = true;
3684
if (FailImmediatelyOnInvalidExpr)
3685
break;
3686
SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
3687
} else {
3688
Exprs.push_back(Expr.get());
3689
}
3690
3691
if (Tok.isNot(tok::comma))
3692
break;
3693
// Move to the next argument, remember where the comma was.
3694
Token Comma = Tok;
3695
ConsumeToken();
3696
checkPotentialAngleBracketDelimiter(Comma);
3697
}
3698
if (SawError) {
3699
// Ensure typos get diagnosed when errors were encountered while parsing the
3700
// expression list.
3701
for (auto &E : Exprs) {
3702
ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E);
3703
if (Expr.isUsable()) E = Expr.get();
3704
}
3705
}
3706
return SawError;
3707
}
3708
3709
/// ParseSimpleExpressionList - A simple comma-separated list of expressions,
3710
/// used for misc language extensions.
3711
///
3712
/// \verbatim
3713
/// simple-expression-list:
3714
/// assignment-expression
3715
/// simple-expression-list , assignment-expression
3716
/// \endverbatim
3717
bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) {
3718
while (true) {
3719
ExprResult Expr = ParseAssignmentExpression();
3720
if (Expr.isInvalid())
3721
return true;
3722
3723
Exprs.push_back(Expr.get());
3724
3725
// We might be parsing the LHS of a fold-expression. If we reached the fold
3726
// operator, stop.
3727
if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis))
3728
return false;
3729
3730
// Move to the next argument, remember where the comma was.
3731
Token Comma = Tok;
3732
ConsumeToken();
3733
checkPotentialAngleBracketDelimiter(Comma);
3734
}
3735
}
3736
3737
/// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
3738
///
3739
/// \verbatim
3740
/// [clang] block-id:
3741
/// [clang] specifier-qualifier-list block-declarator
3742
/// \endverbatim
3743
void Parser::ParseBlockId(SourceLocation CaretLoc) {
3744
if (Tok.is(tok::code_completion)) {
3745
cutOffParsing();
3746
Actions.CodeCompletion().CodeCompleteOrdinaryName(
3747
getCurScope(), SemaCodeCompletion::PCC_Type);
3748
return;
3749
}
3750
3751
// Parse the specifier-qualifier-list piece.
3752
DeclSpec DS(AttrFactory);
3753
ParseSpecifierQualifierList(DS);
3754
3755
// Parse the block-declarator.
3756
Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
3757
DeclaratorContext::BlockLiteral);
3758
DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
3759
ParseDeclarator(DeclaratorInfo);
3760
3761
MaybeParseGNUAttributes(DeclaratorInfo);
3762
3763
// Inform sema that we are starting a block.
3764
Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
3765
}
3766
3767
/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
3768
/// like ^(int x){ return x+1; }
3769
///
3770
/// \verbatim
3771
/// block-literal:
3772
/// [clang] '^' block-args[opt] compound-statement
3773
/// [clang] '^' block-id compound-statement
3774
/// [clang] block-args:
3775
/// [clang] '(' parameter-list ')'
3776
/// \endverbatim
3777
ExprResult Parser::ParseBlockLiteralExpression() {
3778
assert(Tok.is(tok::caret) && "block literal starts with ^");
3779
SourceLocation CaretLoc = ConsumeToken();
3780
3781
PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc,
3782
"block literal parsing");
3783
3784
// Enter a scope to hold everything within the block. This includes the
3785
// argument decls, decls within the compound expression, etc. This also
3786
// allows determining whether a variable reference inside the block is
3787
// within or outside of the block.
3788
ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
3789
Scope::CompoundStmtScope | Scope::DeclScope);
3790
3791
// Inform sema that we are starting a block.
3792
Actions.ActOnBlockStart(CaretLoc, getCurScope());
3793
3794
// Parse the return type if present.
3795
DeclSpec DS(AttrFactory);
3796
Declarator ParamInfo(DS, ParsedAttributesView::none(),
3797
DeclaratorContext::BlockLiteral);
3798
ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
3799
// FIXME: Since the return type isn't actually parsed, it can't be used to
3800
// fill ParamInfo with an initial valid range, so do it manually.
3801
ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
3802
3803
// If this block has arguments, parse them. There is no ambiguity here with
3804
// the expression case, because the expression case requires a parameter list.
3805
if (Tok.is(tok::l_paren)) {
3806
ParseParenDeclarator(ParamInfo);
3807
// Parse the pieces after the identifier as if we had "int(...)".
3808
// SetIdentifier sets the source range end, but in this case we're past
3809
// that location.
3810
SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
3811
ParamInfo.SetIdentifier(nullptr, CaretLoc);
3812
ParamInfo.SetRangeEnd(Tmp);
3813
if (ParamInfo.isInvalidType()) {
3814
// If there was an error parsing the arguments, they may have
3815
// tried to use ^(x+y) which requires an argument list. Just
3816
// skip the whole block literal.
3817
Actions.ActOnBlockError(CaretLoc, getCurScope());
3818
return ExprError();
3819
}
3820
3821
MaybeParseGNUAttributes(ParamInfo);
3822
3823
// Inform sema that we are starting a block.
3824
Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3825
} else if (!Tok.is(tok::l_brace)) {
3826
ParseBlockId(CaretLoc);
3827
} else {
3828
// Otherwise, pretend we saw (void).
3829
SourceLocation NoLoc;
3830
ParamInfo.AddTypeInfo(
3831
DeclaratorChunk::getFunction(/*HasProto=*/true,
3832
/*IsAmbiguous=*/false,
3833
/*RParenLoc=*/NoLoc,
3834
/*ArgInfo=*/nullptr,
3835
/*NumParams=*/0,
3836
/*EllipsisLoc=*/NoLoc,
3837
/*RParenLoc=*/NoLoc,
3838
/*RefQualifierIsLvalueRef=*/true,
3839
/*RefQualifierLoc=*/NoLoc,
3840
/*MutableLoc=*/NoLoc, EST_None,
3841
/*ESpecRange=*/SourceRange(),
3842
/*Exceptions=*/nullptr,
3843
/*ExceptionRanges=*/nullptr,
3844
/*NumExceptions=*/0,
3845
/*NoexceptExpr=*/nullptr,
3846
/*ExceptionSpecTokens=*/nullptr,
3847
/*DeclsInPrototype=*/std::nullopt,
3848
CaretLoc, CaretLoc, ParamInfo),
3849
CaretLoc);
3850
3851
MaybeParseGNUAttributes(ParamInfo);
3852
3853
// Inform sema that we are starting a block.
3854
Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3855
}
3856
3857
3858
ExprResult Result(true);
3859
if (!Tok.is(tok::l_brace)) {
3860
// Saw something like: ^expr
3861
Diag(Tok, diag::err_expected_expression);
3862
Actions.ActOnBlockError(CaretLoc, getCurScope());
3863
return ExprError();
3864
}
3865
3866
StmtResult Stmt(ParseCompoundStatementBody());
3867
BlockScope.Exit();
3868
if (!Stmt.isInvalid())
3869
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
3870
else
3871
Actions.ActOnBlockError(CaretLoc, getCurScope());
3872
return Result;
3873
}
3874
3875
/// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
3876
///
3877
/// '__objc_yes'
3878
/// '__objc_no'
3879
ExprResult Parser::ParseObjCBoolLiteral() {
3880
tok::TokenKind Kind = Tok.getKind();
3881
return Actions.ObjC().ActOnObjCBoolLiteral(ConsumeToken(), Kind);
3882
}
3883
3884
/// Validate availability spec list, emitting diagnostics if necessary. Returns
3885
/// true if invalid.
3886
static bool CheckAvailabilitySpecList(Parser &P,
3887
ArrayRef<AvailabilitySpec> AvailSpecs) {
3888
llvm::SmallSet<StringRef, 4> Platforms;
3889
bool HasOtherPlatformSpec = false;
3890
bool Valid = true;
3891
for (const auto &Spec : AvailSpecs) {
3892
if (Spec.isOtherPlatformSpec()) {
3893
if (HasOtherPlatformSpec) {
3894
P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star);
3895
Valid = false;
3896
}
3897
3898
HasOtherPlatformSpec = true;
3899
continue;
3900
}
3901
3902
bool Inserted = Platforms.insert(Spec.getPlatform()).second;
3903
if (!Inserted) {
3904
// Rule out multiple version specs referring to the same platform.
3905
// For example, we emit an error for:
3906
// @available(macos 10.10, macos 10.11, *)
3907
StringRef Platform = Spec.getPlatform();
3908
P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform)
3909
<< Spec.getEndLoc() << Platform;
3910
Valid = false;
3911
}
3912
}
3913
3914
if (!HasOtherPlatformSpec) {
3915
SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc();
3916
P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required)
3917
<< FixItHint::CreateInsertion(InsertWildcardLoc, ", *");
3918
return true;
3919
}
3920
3921
return !Valid;
3922
}
3923
3924
/// Parse availability query specification.
3925
///
3926
/// availability-spec:
3927
/// '*'
3928
/// identifier version-tuple
3929
std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
3930
if (Tok.is(tok::star)) {
3931
return AvailabilitySpec(ConsumeToken());
3932
} else {
3933
// Parse the platform name.
3934
if (Tok.is(tok::code_completion)) {
3935
cutOffParsing();
3936
Actions.CodeCompletion().CodeCompleteAvailabilityPlatformName();
3937
return std::nullopt;
3938
}
3939
if (Tok.isNot(tok::identifier)) {
3940
Diag(Tok, diag::err_avail_query_expected_platform_name);
3941
return std::nullopt;
3942
}
3943
3944
IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc();
3945
SourceRange VersionRange;
3946
VersionTuple Version = ParseVersionTuple(VersionRange);
3947
3948
if (Version.empty())
3949
return std::nullopt;
3950
3951
StringRef GivenPlatform = PlatformIdentifier->Ident->getName();
3952
StringRef Platform =
3953
AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
3954
3955
if (AvailabilityAttr::getPrettyPlatformName(Platform).empty() ||
3956
(GivenPlatform.contains("xros") || GivenPlatform.contains("xrOS"))) {
3957
Diag(PlatformIdentifier->Loc,
3958
diag::err_avail_query_unrecognized_platform_name)
3959
<< GivenPlatform;
3960
return std::nullopt;
3961
}
3962
3963
return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc,
3964
VersionRange.getEnd());
3965
}
3966
}
3967
3968
ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) {
3969
assert(Tok.is(tok::kw___builtin_available) ||
3970
Tok.isObjCAtKeyword(tok::objc_available));
3971
3972
// Eat the available or __builtin_available.
3973
ConsumeToken();
3974
3975
BalancedDelimiterTracker Parens(*this, tok::l_paren);
3976
if (Parens.expectAndConsume())
3977
return ExprError();
3978
3979
SmallVector<AvailabilitySpec, 4> AvailSpecs;
3980
bool HasError = false;
3981
while (true) {
3982
std::optional<AvailabilitySpec> Spec = ParseAvailabilitySpec();
3983
if (!Spec)
3984
HasError = true;
3985
else
3986
AvailSpecs.push_back(*Spec);
3987
3988
if (!TryConsumeToken(tok::comma))
3989
break;
3990
}
3991
3992
if (HasError) {
3993
SkipUntil(tok::r_paren, StopAtSemi);
3994
return ExprError();
3995
}
3996
3997
CheckAvailabilitySpecList(*this, AvailSpecs);
3998
3999
if (Parens.consumeClose())
4000
return ExprError();
4001
4002
return Actions.ObjC().ActOnObjCAvailabilityCheckExpr(
4003
AvailSpecs, BeginLoc, Parens.getCloseLocation());
4004
}
4005
4006