1 //===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// Provides the Expression parsing implementation.
12 /// Expressions in C99 basically consist of a bunch of binary operators with
13 /// unary operators and other random stuff at the leaves.
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.
21 //===----------------------------------------------------------------------===//
23 #include "clang/Parse/Parser.h"
24 #include "clang/AST/ASTContext.h"
25 #include "clang/AST/ExprCXX.h"
26 #include "clang/Basic/PrettyStackTrace.h"
27 #include "clang/Parse/RAIIObjectsForParser.h"
28 #include "clang/Sema/DeclSpec.h"
29 #include "clang/Sema/ParsedTemplate.h"
30 #include "clang/Sema/Scope.h"
31 #include "clang/Sema/TypoCorrection.h"
32 #include "llvm/ADT/SmallVector.h"
34 using namespace clang
;
36 /// Simple precedence-based parser for binary/ternary operators.
38 /// Note: we diverge from the C99 grammar when parsing the assignment-expression
39 /// production. C99 specifies that the LHS of an assignment operator should be
40 /// parsed as a unary-expression, but consistency dictates that it be a
41 /// conditional-expession. In practice, the important thing here is that the
42 /// LHS of an assignment has to be an l-value, which productions between
43 /// unary-expression and conditional-expression don't produce. Because we want
44 /// consistency, we parse the LHS as a conditional-expression, then check for
45 /// l-value-ness in semantic analysis stages.
48 /// pm-expression: [C++ 5.5]
50 /// pm-expression '.*' cast-expression
51 /// pm-expression '->*' cast-expression
53 /// multiplicative-expression: [C99 6.5.5]
54 /// Note: in C++, apply pm-expression instead of cast-expression
56 /// multiplicative-expression '*' cast-expression
57 /// multiplicative-expression '/' cast-expression
58 /// multiplicative-expression '%' cast-expression
60 /// additive-expression: [C99 6.5.6]
61 /// multiplicative-expression
62 /// additive-expression '+' multiplicative-expression
63 /// additive-expression '-' multiplicative-expression
65 /// shift-expression: [C99 6.5.7]
66 /// additive-expression
67 /// shift-expression '<<' additive-expression
68 /// shift-expression '>>' additive-expression
70 /// compare-expression: [C++20 expr.spaceship]
72 /// compare-expression '<=>' shift-expression
74 /// relational-expression: [C99 6.5.8]
75 /// compare-expression
76 /// relational-expression '<' compare-expression
77 /// relational-expression '>' compare-expression
78 /// relational-expression '<=' compare-expression
79 /// relational-expression '>=' compare-expression
81 /// equality-expression: [C99 6.5.9]
82 /// relational-expression
83 /// equality-expression '==' relational-expression
84 /// equality-expression '!=' relational-expression
86 /// AND-expression: [C99 6.5.10]
87 /// equality-expression
88 /// AND-expression '&' equality-expression
90 /// exclusive-OR-expression: [C99 6.5.11]
92 /// exclusive-OR-expression '^' AND-expression
94 /// inclusive-OR-expression: [C99 6.5.12]
95 /// exclusive-OR-expression
96 /// inclusive-OR-expression '|' exclusive-OR-expression
98 /// logical-AND-expression: [C99 6.5.13]
99 /// inclusive-OR-expression
100 /// logical-AND-expression '&&' inclusive-OR-expression
102 /// logical-OR-expression: [C99 6.5.14]
103 /// logical-AND-expression
104 /// logical-OR-expression '||' logical-AND-expression
106 /// conditional-expression: [C99 6.5.15]
107 /// logical-OR-expression
108 /// logical-OR-expression '?' expression ':' conditional-expression
109 /// [GNU] logical-OR-expression '?' ':' conditional-expression
110 /// [C++] the third operand is an assignment-expression
112 /// assignment-expression: [C99 6.5.16]
113 /// conditional-expression
114 /// unary-expression assignment-operator assignment-expression
115 /// [C++] throw-expression [C++ 15]
117 /// assignment-operator: one of
118 /// = *= /= %= += -= <<= >>= &= ^= |=
120 /// expression: [C99 6.5.17]
121 /// assignment-expression ...[opt]
122 /// expression ',' assignment-expression ...[opt]
124 ExprResult
Parser::ParseExpression(TypeCastState isTypeCast
) {
125 ExprResult
LHS(ParseAssignmentExpression(isTypeCast
));
126 return ParseRHSOfBinaryExpression(LHS
, prec::Comma
);
129 /// This routine is called when the '@' is seen and consumed.
130 /// Current token is an Identifier and is not a 'try'. This
131 /// routine is necessary to disambiguate \@try-statement from,
132 /// for example, \@encode-expression.
135 Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc
) {
136 ExprResult
LHS(ParseObjCAtExpression(AtLoc
));
137 return ParseRHSOfBinaryExpression(LHS
, prec::Comma
);
140 /// This routine is called when a leading '__extension__' is seen and
141 /// consumed. This is necessary because the token gets consumed in the
142 /// process of disambiguating between an expression and a declaration.
144 Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc
) {
145 ExprResult
LHS(true);
147 // Silence extension warnings in the sub-expression
148 ExtensionRAIIObject
O(Diags
);
150 LHS
= ParseCastExpression(AnyCastExpr
);
153 if (!LHS
.isInvalid())
154 LHS
= Actions
.ActOnUnaryOp(getCurScope(), ExtLoc
, tok::kw___extension__
,
157 return ParseRHSOfBinaryExpression(LHS
, prec::Comma
);
160 /// Parse an expr that doesn't include (top-level) commas.
161 ExprResult
Parser::ParseAssignmentExpression(TypeCastState isTypeCast
) {
162 if (Tok
.is(tok::code_completion
)) {
164 Actions
.CodeCompleteExpression(getCurScope(),
165 PreferredType
.get(Tok
.getLocation()));
169 if (Tok
.is(tok::kw_throw
))
170 return ParseThrowExpression();
171 if (Tok
.is(tok::kw_co_yield
))
172 return ParseCoyieldExpression();
174 ExprResult LHS
= ParseCastExpression(AnyCastExpr
,
175 /*isAddressOfOperand=*/false,
177 return ParseRHSOfBinaryExpression(LHS
, prec::Assignment
);
180 /// Parse an assignment expression where part of an Objective-C message
181 /// send has already been parsed.
183 /// In this case \p LBracLoc indicates the location of the '[' of the message
184 /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating
185 /// the receiver of the message.
187 /// Since this handles full assignment-expression's, it handles postfix
188 /// expressions and other binary operators for these expressions as well.
190 Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc
,
191 SourceLocation SuperLoc
,
192 ParsedType ReceiverType
,
193 Expr
*ReceiverExpr
) {
195 = ParseObjCMessageExpressionBody(LBracLoc
, SuperLoc
,
196 ReceiverType
, ReceiverExpr
);
197 R
= ParsePostfixExpressionSuffix(R
);
198 return ParseRHSOfBinaryExpression(R
, prec::Assignment
);
202 Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast
) {
203 assert(Actions
.ExprEvalContexts
.back().Context
==
204 Sema::ExpressionEvaluationContext::ConstantEvaluated
&&
205 "Call this function only if your ExpressionEvaluationContext is "
206 "already ConstantEvaluated");
207 ExprResult
LHS(ParseCastExpression(AnyCastExpr
, false, isTypeCast
));
208 ExprResult
Res(ParseRHSOfBinaryExpression(LHS
, prec::Conditional
));
209 return Actions
.ActOnConstantExpression(Res
);
212 ExprResult
Parser::ParseConstantExpression() {
213 // C++03 [basic.def.odr]p2:
214 // An expression is potentially evaluated unless it appears where an
215 // integral constant expression is required (see 5.19) [...].
216 // C++98 and C++11 have no such rule, but this is only a defect in C++98.
217 EnterExpressionEvaluationContext
ConstantEvaluated(
218 Actions
, Sema::ExpressionEvaluationContext::ConstantEvaluated
);
219 return ParseConstantExpressionInExprEvalContext(NotTypeCast
);
222 ExprResult
Parser::ParseCaseExpression(SourceLocation CaseLoc
) {
223 EnterExpressionEvaluationContext
ConstantEvaluated(
224 Actions
, Sema::ExpressionEvaluationContext::ConstantEvaluated
);
225 ExprResult
LHS(ParseCastExpression(AnyCastExpr
, false, NotTypeCast
));
226 ExprResult
Res(ParseRHSOfBinaryExpression(LHS
, prec::Conditional
));
227 return Actions
.ActOnCaseExpr(CaseLoc
, Res
);
230 /// Parse a constraint-expression.
233 /// constraint-expression: C++2a[temp.constr.decl]p1
234 /// logical-or-expression
236 ExprResult
Parser::ParseConstraintExpression() {
237 EnterExpressionEvaluationContext
ConstantEvaluated(
238 Actions
, Sema::ExpressionEvaluationContext::Unevaluated
);
239 ExprResult
LHS(ParseCastExpression(AnyCastExpr
));
240 ExprResult
Res(ParseRHSOfBinaryExpression(LHS
, prec::LogicalOr
));
241 if (Res
.isUsable() && !Actions
.CheckConstraintExpression(Res
.get())) {
242 Actions
.CorrectDelayedTyposInExpr(Res
);
248 /// \brief Parse a constraint-logical-and-expression.
251 /// C++2a[temp.constr.decl]p1
252 /// constraint-logical-and-expression:
253 /// primary-expression
254 /// constraint-logical-and-expression '&&' primary-expression
258 Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause
) {
259 EnterExpressionEvaluationContext
ConstantEvaluated(
260 Actions
, Sema::ExpressionEvaluationContext::Unevaluated
);
261 bool NotPrimaryExpression
= false;
262 auto ParsePrimary
= [&] () {
263 ExprResult E
= ParseCastExpression(PrimaryExprOnly
,
264 /*isAddressOfOperand=*/false,
265 /*isTypeCast=*/NotTypeCast
,
266 /*isVectorLiteral=*/false,
267 &NotPrimaryExpression
);
270 auto RecoverFromNonPrimary
= [&] (ExprResult E
, bool Note
) {
271 E
= ParsePostfixExpressionSuffix(E
);
272 // Use InclusiveOr, the precedence just after '&&' to not parse the
273 // next arguments to the logical and.
274 E
= ParseRHSOfBinaryExpression(E
, prec::InclusiveOr
);
276 Diag(E
.get()->getExprLoc(),
278 ? diag::note_unparenthesized_non_primary_expr_in_requires_clause
279 : diag::err_unparenthesized_non_primary_expr_in_requires_clause
)
280 << FixItHint::CreateInsertion(E
.get()->getBeginLoc(), "(")
281 << FixItHint::CreateInsertion(
282 PP
.getLocForEndOfToken(E
.get()->getEndLoc()), ")")
283 << E
.get()->getSourceRange();
287 if (NotPrimaryExpression
||
288 // Check if the following tokens must be a part of a non-primary
290 getBinOpPrecedence(Tok
.getKind(), GreaterThanIsOperator
,
291 /*CPlusPlus11=*/true) > prec::LogicalAnd
||
292 // Postfix operators other than '(' (which will be checked for in
293 // CheckConstraintExpression).
294 Tok
.isOneOf(tok::period
, tok::plusplus
, tok::minusminus
) ||
295 (Tok
.is(tok::l_square
) && !NextToken().is(tok::l_square
))) {
296 E
= RecoverFromNonPrimary(E
, /*Note=*/false);
299 NotPrimaryExpression
= false;
301 bool PossibleNonPrimary
;
302 bool IsConstraintExpr
=
303 Actions
.CheckConstraintExpression(E
.get(), Tok
, &PossibleNonPrimary
,
304 IsTrailingRequiresClause
);
305 if (!IsConstraintExpr
|| PossibleNonPrimary
) {
306 // Atomic constraint might be an unparenthesized non-primary expression
307 // (such as a binary operator), in which case we might get here (e.g. in
308 // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore
309 // the rest of the addition expression). Try to parse the rest of it here.
310 if (PossibleNonPrimary
)
311 E
= RecoverFromNonPrimary(E
, /*Note=*/!IsConstraintExpr
);
312 Actions
.CorrectDelayedTyposInExpr(E
);
317 ExprResult LHS
= ParsePrimary();
320 while (Tok
.is(tok::ampamp
)) {
321 SourceLocation LogicalAndLoc
= ConsumeToken();
322 ExprResult RHS
= ParsePrimary();
323 if (RHS
.isInvalid()) {
324 Actions
.CorrectDelayedTyposInExpr(LHS
);
327 ExprResult Op
= Actions
.ActOnBinOp(getCurScope(), LogicalAndLoc
,
328 tok::ampamp
, LHS
.get(), RHS
.get());
329 if (!Op
.isUsable()) {
330 Actions
.CorrectDelayedTyposInExpr(RHS
);
331 Actions
.CorrectDelayedTyposInExpr(LHS
);
339 /// \brief Parse a constraint-logical-or-expression.
342 /// C++2a[temp.constr.decl]p1
343 /// constraint-logical-or-expression:
344 /// constraint-logical-and-expression
345 /// constraint-logical-or-expression '||'
346 /// constraint-logical-and-expression
350 Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause
) {
351 ExprResult
LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause
));
354 while (Tok
.is(tok::pipepipe
)) {
355 SourceLocation LogicalOrLoc
= ConsumeToken();
357 ParseConstraintLogicalAndExpression(IsTrailingRequiresClause
);
358 if (!RHS
.isUsable()) {
359 Actions
.CorrectDelayedTyposInExpr(LHS
);
362 ExprResult Op
= Actions
.ActOnBinOp(getCurScope(), LogicalOrLoc
,
363 tok::pipepipe
, LHS
.get(), RHS
.get());
364 if (!Op
.isUsable()) {
365 Actions
.CorrectDelayedTyposInExpr(RHS
);
366 Actions
.CorrectDelayedTyposInExpr(LHS
);
374 bool Parser::isNotExpressionStart() {
375 tok::TokenKind K
= Tok
.getKind();
376 if (K
== tok::l_brace
|| K
== tok::r_brace
||
377 K
== tok::kw_for
|| K
== tok::kw_while
||
378 K
== tok::kw_if
|| K
== tok::kw_else
||
379 K
== tok::kw_goto
|| K
== tok::kw_try
)
381 // If this is a decl-specifier, we can't be at the start of an expression.
382 return isKnownToBeDeclarationSpecifier();
385 bool Parser::isFoldOperator(prec::Level Level
) const {
386 return Level
> prec::Unknown
&& Level
!= prec::Conditional
&&
387 Level
!= prec::Spaceship
;
390 bool Parser::isFoldOperator(tok::TokenKind Kind
) const {
391 return isFoldOperator(getBinOpPrecedence(Kind
, GreaterThanIsOperator
, true));
394 /// Parse a binary expression that starts with \p LHS and has a
395 /// precedence of at least \p MinPrec.
397 Parser::ParseRHSOfBinaryExpression(ExprResult LHS
, prec::Level MinPrec
) {
398 prec::Level NextTokPrec
= getBinOpPrecedence(Tok
.getKind(),
399 GreaterThanIsOperator
,
400 getLangOpts().CPlusPlus11
);
401 SourceLocation ColonLoc
;
403 auto SavedType
= PreferredType
;
405 // Every iteration may rely on a preferred type for the whole expression.
406 PreferredType
= SavedType
;
407 // If this token has a lower precedence than we are allowed to parse (e.g.
408 // because we are called recursively, or because the token is not a binop),
410 if (NextTokPrec
< MinPrec
)
413 // Consume the operator, saving the operator token for error reporting.
417 if (OpToken
.is(tok::caretcaret
)) {
418 return ExprError(Diag(Tok
, diag::err_opencl_logical_exclusive_or
));
421 // If we're potentially in a template-id, we may now be able to determine
422 // whether we're actually in one or not.
423 if (OpToken
.isOneOf(tok::comma
, tok::greater
, tok::greatergreater
,
424 tok::greatergreatergreater
) &&
425 checkPotentialAngleBracketDelimiter(OpToken
))
428 // Bail out when encountering a comma followed by a token which can't
429 // possibly be the start of an expression. For instance:
430 // int f() { return 1, }
431 // We can't do this before consuming the comma, because
432 // isNotExpressionStart() looks at the token stream.
433 if (OpToken
.is(tok::comma
) && isNotExpressionStart()) {
434 PP
.EnterToken(Tok
, /*IsReinject*/true);
439 // If the next token is an ellipsis, then this is a fold-expression. Leave
440 // it alone so we can handle it in the paren expression.
441 if (isFoldOperator(NextTokPrec
) && Tok
.is(tok::ellipsis
)) {
442 // FIXME: We can't check this via lookahead before we consume the token
443 // because that tickles a lexer bug.
444 PP
.EnterToken(Tok
, /*IsReinject*/true);
449 // In Objective-C++, alternative operator tokens can be used as keyword args
450 // in message expressions. Unconsume the token so that it can reinterpreted
451 // as an identifier in ParseObjCMessageExpressionBody. i.e., we support:
452 // [foo meth:0 and:0];
454 if (getLangOpts().ObjC
&& getLangOpts().CPlusPlus
&&
455 Tok
.isOneOf(tok::colon
, tok::r_square
) &&
456 OpToken
.getIdentifierInfo() != nullptr) {
457 PP
.EnterToken(Tok
, /*IsReinject*/true);
462 // Special case handling for the ternary operator.
463 ExprResult
TernaryMiddle(true);
464 if (NextTokPrec
== prec::Conditional
) {
465 if (getLangOpts().CPlusPlus11
&& Tok
.is(tok::l_brace
)) {
466 // Parse a braced-init-list here for error recovery purposes.
467 SourceLocation BraceLoc
= Tok
.getLocation();
468 TernaryMiddle
= ParseBraceInitializer();
469 if (!TernaryMiddle
.isInvalid()) {
470 Diag(BraceLoc
, diag::err_init_list_bin_op
)
471 << /*RHS*/ 1 << PP
.getSpelling(OpToken
)
472 << Actions
.getExprRange(TernaryMiddle
.get());
473 TernaryMiddle
= ExprError();
475 } else if (Tok
.isNot(tok::colon
)) {
476 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
477 ColonProtectionRAIIObject
X(*this);
479 // Handle this production specially:
480 // logical-OR-expression '?' expression ':' conditional-expression
481 // In particular, the RHS of the '?' is 'expression', not
482 // 'logical-OR-expression' as we might expect.
483 TernaryMiddle
= ParseExpression();
485 // Special case handling of "X ? Y : Z" where Y is empty:
486 // logical-OR-expression '?' ':' conditional-expression [GNU]
487 TernaryMiddle
= nullptr;
488 Diag(Tok
, diag::ext_gnu_conditional_expr
);
491 if (TernaryMiddle
.isInvalid()) {
492 Actions
.CorrectDelayedTyposInExpr(LHS
);
494 TernaryMiddle
= nullptr;
497 if (!TryConsumeToken(tok::colon
, ColonLoc
)) {
498 // Otherwise, we're missing a ':'. Assume that this was a typo that
499 // the user forgot. If we're not in a macro expansion, we can suggest
500 // a fixit hint. If there were two spaces before the current token,
501 // suggest inserting the colon in between them, otherwise insert ": ".
502 SourceLocation FILoc
= Tok
.getLocation();
503 const char *FIText
= ": ";
504 const SourceManager
&SM
= PP
.getSourceManager();
505 if (FILoc
.isFileID() || PP
.isAtStartOfMacroExpansion(FILoc
, &FILoc
)) {
506 assert(FILoc
.isFileID());
507 bool IsInvalid
= false;
508 const char *SourcePtr
=
509 SM
.getCharacterData(FILoc
.getLocWithOffset(-1), &IsInvalid
);
510 if (!IsInvalid
&& *SourcePtr
== ' ') {
512 SM
.getCharacterData(FILoc
.getLocWithOffset(-2), &IsInvalid
);
513 if (!IsInvalid
&& *SourcePtr
== ' ') {
514 FILoc
= FILoc
.getLocWithOffset(-1);
520 Diag(Tok
, diag::err_expected
)
521 << tok::colon
<< FixItHint::CreateInsertion(FILoc
, FIText
);
522 Diag(OpToken
, diag::note_matching
) << tok::question
;
523 ColonLoc
= Tok
.getLocation();
527 PreferredType
.enterBinary(Actions
, Tok
.getLocation(), LHS
.get(),
529 // Parse another leaf here for the RHS of the operator.
530 // ParseCastExpression works here because all RHS expressions in C have it
531 // as a prefix, at least. However, in C++, an assignment-expression could
532 // be a throw-expression, which is not a valid cast-expression.
533 // Therefore we need some special-casing here.
534 // Also note that the third operand of the conditional operator is
535 // an assignment-expression in C++, and in C++11, we can have a
536 // braced-init-list on the RHS of an assignment. For better diagnostics,
537 // parse as if we were allowed braced-init-lists everywhere, and check that
538 // they only appear on the RHS of assignments later.
540 bool RHSIsInitList
= false;
541 if (getLangOpts().CPlusPlus11
&& Tok
.is(tok::l_brace
)) {
542 RHS
= ParseBraceInitializer();
543 RHSIsInitList
= true;
544 } else if (getLangOpts().CPlusPlus
&& NextTokPrec
<= prec::Conditional
)
545 RHS
= ParseAssignmentExpression();
547 RHS
= ParseCastExpression(AnyCastExpr
);
549 if (RHS
.isInvalid()) {
550 // FIXME: Errors generated by the delayed typo correction should be
551 // printed before errors from parsing the RHS, not after.
552 Actions
.CorrectDelayedTyposInExpr(LHS
);
553 if (TernaryMiddle
.isUsable())
554 TernaryMiddle
= Actions
.CorrectDelayedTyposInExpr(TernaryMiddle
);
558 // Remember the precedence of this operator and get the precedence of the
559 // operator immediately to the right of the RHS.
560 prec::Level ThisPrec
= NextTokPrec
;
561 NextTokPrec
= getBinOpPrecedence(Tok
.getKind(), GreaterThanIsOperator
,
562 getLangOpts().CPlusPlus11
);
564 // Assignment and conditional expressions are right-associative.
565 bool isRightAssoc
= ThisPrec
== prec::Conditional
||
566 ThisPrec
== prec::Assignment
;
568 // Get the precedence of the operator to the right of the RHS. If it binds
569 // more tightly with RHS than we do, evaluate it completely first.
570 if (ThisPrec
< NextTokPrec
||
571 (ThisPrec
== NextTokPrec
&& isRightAssoc
)) {
572 if (!RHS
.isInvalid() && RHSIsInitList
) {
573 Diag(Tok
, diag::err_init_list_bin_op
)
574 << /*LHS*/0 << PP
.getSpelling(Tok
) << Actions
.getExprRange(RHS
.get());
577 // If this is left-associative, only parse things on the RHS that bind
578 // more tightly than the current operator. If it is left-associative, it
579 // is okay, to bind exactly as tightly. For example, compile A=B=C=D as
580 // A=(B=(C=D)), where each paren is a level of recursion here.
581 // The function takes ownership of the RHS.
582 RHS
= ParseRHSOfBinaryExpression(RHS
,
583 static_cast<prec::Level
>(ThisPrec
+ !isRightAssoc
));
584 RHSIsInitList
= false;
586 if (RHS
.isInvalid()) {
587 // FIXME: Errors generated by the delayed typo correction should be
588 // printed before errors from ParseRHSOfBinaryExpression, not after.
589 Actions
.CorrectDelayedTyposInExpr(LHS
);
590 if (TernaryMiddle
.isUsable())
591 TernaryMiddle
= Actions
.CorrectDelayedTyposInExpr(TernaryMiddle
);
595 NextTokPrec
= getBinOpPrecedence(Tok
.getKind(), GreaterThanIsOperator
,
596 getLangOpts().CPlusPlus11
);
599 if (!RHS
.isInvalid() && RHSIsInitList
) {
600 if (ThisPrec
== prec::Assignment
) {
601 Diag(OpToken
, diag::warn_cxx98_compat_generalized_initializer_lists
)
602 << Actions
.getExprRange(RHS
.get());
603 } else if (ColonLoc
.isValid()) {
604 Diag(ColonLoc
, diag::err_init_list_bin_op
)
606 << Actions
.getExprRange(RHS
.get());
609 Diag(OpToken
, diag::err_init_list_bin_op
)
610 << /*RHS*/1 << PP
.getSpelling(OpToken
)
611 << Actions
.getExprRange(RHS
.get());
616 ExprResult OrigLHS
= LHS
;
617 if (!LHS
.isInvalid()) {
618 // Combine the LHS and RHS into the LHS (e.g. build AST).
619 if (TernaryMiddle
.isInvalid()) {
620 // If we're using '>>' as an operator within a template
621 // argument list (in C++98), suggest the addition of
622 // parentheses so that the code remains well-formed in C++0x.
623 if (!GreaterThanIsOperator
&& OpToken
.is(tok::greatergreater
))
624 SuggestParentheses(OpToken
.getLocation(),
625 diag::warn_cxx11_right_shift_in_template_arg
,
626 SourceRange(Actions
.getExprRange(LHS
.get()).getBegin(),
627 Actions
.getExprRange(RHS
.get()).getEnd()));
630 Actions
.ActOnBinOp(getCurScope(), OpToken
.getLocation(),
631 OpToken
.getKind(), LHS
.get(), RHS
.get());
632 if (BinOp
.isInvalid())
633 BinOp
= Actions
.CreateRecoveryExpr(LHS
.get()->getBeginLoc(),
634 RHS
.get()->getEndLoc(),
635 {LHS
.get(), RHS
.get()});
639 ExprResult CondOp
= Actions
.ActOnConditionalOp(
640 OpToken
.getLocation(), ColonLoc
, LHS
.get(), TernaryMiddle
.get(),
642 if (CondOp
.isInvalid()) {
643 std::vector
<clang::Expr
*> Args
;
644 // TernaryMiddle can be null for the GNU conditional expr extension.
645 if (TernaryMiddle
.get())
646 Args
= {LHS
.get(), TernaryMiddle
.get(), RHS
.get()};
648 Args
= {LHS
.get(), RHS
.get()};
649 CondOp
= Actions
.CreateRecoveryExpr(LHS
.get()->getBeginLoc(),
650 RHS
.get()->getEndLoc(), Args
);
655 // In this case, ActOnBinOp or ActOnConditionalOp performed the
656 // CorrectDelayedTyposInExpr check.
657 if (!getLangOpts().CPlusPlus
)
661 // Ensure potential typos aren't left undiagnosed.
662 if (LHS
.isInvalid()) {
663 Actions
.CorrectDelayedTyposInExpr(OrigLHS
);
664 Actions
.CorrectDelayedTyposInExpr(TernaryMiddle
);
665 Actions
.CorrectDelayedTyposInExpr(RHS
);
670 /// Parse a cast-expression, unary-expression or primary-expression, based
673 /// \p isAddressOfOperand exists because an id-expression that is the
674 /// operand of address-of gets special treatment due to member pointers.
676 ExprResult
Parser::ParseCastExpression(CastParseKind ParseKind
,
677 bool isAddressOfOperand
,
678 TypeCastState isTypeCast
,
679 bool isVectorLiteral
,
680 bool *NotPrimaryExpression
) {
682 ExprResult Res
= ParseCastExpression(ParseKind
,
687 NotPrimaryExpression
);
689 Diag(Tok
, diag::err_expected_expression
);
694 class CastExpressionIdValidator final
: public CorrectionCandidateCallback
{
696 CastExpressionIdValidator(Token Next
, bool AllowTypes
, bool AllowNonTypes
)
697 : NextToken(Next
), AllowNonTypes(AllowNonTypes
) {
698 WantTypeSpecifiers
= WantFunctionLikeCasts
= AllowTypes
;
701 bool ValidateCandidate(const TypoCorrection
&candidate
) override
{
702 NamedDecl
*ND
= candidate
.getCorrectionDecl();
704 return candidate
.isKeyword();
706 if (isa
<TypeDecl
>(ND
))
707 return WantTypeSpecifiers
;
709 if (!AllowNonTypes
|| !CorrectionCandidateCallback::ValidateCandidate(candidate
))
712 if (!NextToken
.isOneOf(tok::equal
, tok::arrow
, tok::period
))
715 for (auto *C
: candidate
) {
716 NamedDecl
*ND
= C
->getUnderlyingDecl();
717 if (isa
<ValueDecl
>(ND
) && !isa
<FunctionDecl
>(ND
))
723 std::unique_ptr
<CorrectionCandidateCallback
> clone() override
{
724 return std::make_unique
<CastExpressionIdValidator
>(*this);
733 /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
734 /// a unary-expression.
736 /// \p isAddressOfOperand exists because an id-expression that is the operand
737 /// of address-of gets special treatment due to member pointers. NotCastExpr
738 /// is set to true if the token is not the start of a cast-expression, and no
739 /// diagnostic is emitted in this case and no tokens are consumed.
742 /// cast-expression: [C99 6.5.4]
744 /// '(' type-name ')' cast-expression
746 /// unary-expression: [C99 6.5.3]
747 /// postfix-expression
748 /// '++' unary-expression
749 /// '--' unary-expression
750 /// [Coro] 'co_await' cast-expression
751 /// unary-operator cast-expression
752 /// 'sizeof' unary-expression
753 /// 'sizeof' '(' type-name ')'
754 /// [C++11] 'sizeof' '...' '(' identifier ')'
755 /// [GNU] '__alignof' unary-expression
756 /// [GNU] '__alignof' '(' type-name ')'
757 /// [C11] '_Alignof' '(' type-name ')'
758 /// [C++11] 'alignof' '(' type-id ')'
759 /// [GNU] '&&' identifier
760 /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7]
761 /// [C++] new-expression
762 /// [C++] delete-expression
764 /// unary-operator: one of
765 /// '&' '*' '+' '-' '~' '!'
766 /// [GNU] '__extension__' '__real' '__imag'
768 /// primary-expression: [C99 6.5.1]
770 /// [C++] id-expression
773 /// [C++] boolean-literal [C++ 2.13.5]
774 /// [C++11] 'nullptr' [C++11 2.14.7]
775 /// [C++11] user-defined-literal
776 /// '(' expression ')'
777 /// [C11] generic-selection
778 /// [C++2a] requires-expression
779 /// '__func__' [C99 6.4.2.2]
780 /// [GNU] '__FUNCTION__'
781 /// [MS] '__FUNCDNAME__'
782 /// [MS] 'L__FUNCTION__'
783 /// [MS] '__FUNCSIG__'
784 /// [MS] 'L__FUNCSIG__'
785 /// [GNU] '__PRETTY_FUNCTION__'
786 /// [GNU] '(' compound-statement ')'
787 /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
788 /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
789 /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
791 /// [GNU] '__builtin_FILE' '(' ')'
792 /// [GNU] '__builtin_FUNCTION' '(' ')'
793 /// [GNU] '__builtin_LINE' '(' ')'
794 /// [CLANG] '__builtin_COLUMN' '(' ')'
795 /// [GNU] '__builtin_source_location' '(' ')'
796 /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
798 /// [OBJC] '[' objc-message-expr ']'
799 /// [OBJC] '\@selector' '(' objc-selector-arg ')'
800 /// [OBJC] '\@protocol' '(' identifier ')'
801 /// [OBJC] '\@encode' '(' type-name ')'
802 /// [OBJC] objc-string-literal
803 /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
804 /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3]
805 /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
806 /// [C++11] typename-specifier braced-init-list [C++11 5.2.3]
807 /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
808 /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
809 /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
810 /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
811 /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1]
812 /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1]
813 /// [C++] 'this' [C++ 9.3.2]
814 /// [G++] unary-type-trait '(' type-id ')'
815 /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO]
816 /// [EMBT] array-type-trait '(' type-id ',' integer ')'
817 /// [clang] '^' block-literal
819 /// constant: [C99 6.4.4]
821 /// floating-constant
822 /// enumeration-constant -> identifier
823 /// character-constant
825 /// id-expression: [C++ 5.1]
829 /// unqualified-id: [C++ 5.1]
831 /// operator-function-id
832 /// conversion-function-id
836 /// new-expression: [C++ 5.3.4]
837 /// '::'[opt] 'new' new-placement[opt] new-type-id
838 /// new-initializer[opt]
839 /// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
840 /// new-initializer[opt]
842 /// delete-expression: [C++ 5.3.5]
843 /// '::'[opt] 'delete' cast-expression
844 /// '::'[opt] 'delete' '[' ']' cast-expression
846 /// [GNU/Embarcadero] unary-type-trait:
847 /// '__is_arithmetic'
848 /// '__is_floating_point'
850 /// '__is_lvalue_expr'
851 /// '__is_rvalue_expr'
852 /// '__is_complete_type'
857 /// '__is_lvalue_reference'
858 /// '__is_rvalue_reference'
859 /// '__is_fundamental'
864 /// '__is_member_object_pointer'
865 /// '__is_member_function_pointer'
866 /// '__is_member_pointer'
870 /// '__is_standard_layout'
874 /// [GNU] unary-type-trait:
875 /// '__has_nothrow_assign'
876 /// '__has_nothrow_copy'
877 /// '__has_nothrow_constructor'
878 /// '__has_trivial_assign' [TODO]
879 /// '__has_trivial_copy' [TODO]
880 /// '__has_trivial_constructor'
881 /// '__has_trivial_destructor'
882 /// '__has_virtual_destructor'
883 /// '__is_abstract' [TODO]
885 /// '__is_empty' [TODO]
889 /// '__is_polymorphic'
890 /// '__is_sealed' [MS]
893 /// '__has_unique_object_representations'
895 /// [Clang] unary-type-trait:
897 /// '__trivially_copyable'
899 /// binary-type-trait:
900 /// [GNU] '__is_base_of'
901 /// [MS] '__is_convertible_to'
902 /// '__is_convertible'
905 /// [Embarcadero] array-type-trait:
909 /// [Embarcadero] expression-trait:
910 /// '__is_lvalue_expr'
911 /// '__is_rvalue_expr'
914 ExprResult
Parser::ParseCastExpression(CastParseKind ParseKind
,
915 bool isAddressOfOperand
,
917 TypeCastState isTypeCast
,
918 bool isVectorLiteral
,
919 bool *NotPrimaryExpression
) {
921 tok::TokenKind SavedKind
= Tok
.getKind();
922 auto SavedType
= PreferredType
;
925 // Are postfix-expression suffix operators permitted after this
926 // cast-expression? If not, and we find some, we'll parse them anyway and
928 bool AllowSuffix
= true;
930 // This handles all of cast-expression, unary-expression, postfix-expression,
931 // and primary-expression. We handle them together like this for efficiency
932 // and to simplify handling of an expression starting with a '(' token: which
933 // may be one of a parenthesized expression, cast-expression, compound literal
934 // expression, or statement expression.
936 // If the parsed tokens consist of a primary-expression, the cases below
937 // break out of the switch; at the end we call ParsePostfixExpressionSuffix
938 // to handle the postfix expression suffixes. Cases that cannot be followed
939 // by postfix exprs should set AllowSuffix to false.
942 // If this expression is limited to being a unary-expression, the paren can
943 // not start a cast expression.
944 ParenParseOption ParenExprType
;
946 case CastParseKind::UnaryExprOnly
:
947 assert(getLangOpts().CPlusPlus
&& "not possible to get here in C");
949 case CastParseKind::AnyCastExpr
:
950 ParenExprType
= ParenParseOption::CastExpr
;
952 case CastParseKind::PrimaryExprOnly
:
953 ParenExprType
= FoldExpr
;
957 SourceLocation RParenLoc
;
958 Res
= ParseParenExpression(ParenExprType
, false/*stopIfCastExr*/,
959 isTypeCast
== IsTypeCast
, CastTy
, RParenLoc
);
961 // FIXME: What should we do if a vector literal is followed by a
962 // postfix-expression suffix? Usually postfix operators are permitted on
967 switch (ParenExprType
) {
968 case SimpleExpr
: break; // Nothing else to do.
969 case CompoundStmt
: break; // Nothing else to do.
970 case CompoundLiteral
:
971 // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
972 // postfix-expression exist, parse them now.
975 // We have parsed the cast-expression and no postfix-expr pieces are
979 // We only parsed a fold-expression. There might be postfix-expr pieces
980 // afterwards; parse them now.
987 // primary-expression
988 case tok::numeric_constant
:
989 // constant: integer-constant
990 // constant: floating-constant
992 Res
= Actions
.ActOnNumericConstant(Tok
, /*UDLScope*/getCurScope());
998 Res
= ParseCXXBoolLiteral();
1001 case tok::kw___objc_yes
:
1002 case tok::kw___objc_no
:
1003 Res
= ParseObjCBoolLiteral();
1006 case tok::kw_nullptr
:
1007 if (getLangOpts().CPlusPlus
)
1008 Diag(Tok
, diag::warn_cxx98_compat_nullptr
);
1010 Diag(Tok
, getLangOpts().C2x
? diag::warn_c17_compat_nullptr
1011 : diag::ext_c_nullptr
);
1013 Res
= Actions
.ActOnCXXNullPtrLiteral(ConsumeToken());
1016 case tok::annot_primary_expr
:
1017 case tok::annot_overload_set
:
1018 Res
= getExprAnnotation(Tok
);
1019 if (!Res
.isInvalid() && Tok
.getKind() == tok::annot_overload_set
)
1020 Res
= Actions
.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res
.get());
1021 ConsumeAnnotationToken();
1022 if (!Res
.isInvalid() && Tok
.is(tok::less
))
1023 checkPotentialAngleBracket(Res
);
1026 case tok::annot_non_type
:
1027 case tok::annot_non_type_dependent
:
1028 case tok::annot_non_type_undeclared
: {
1031 Res
= tryParseCXXIdExpression(SS
, isAddressOfOperand
, Replacement
);
1032 assert(!Res
.isUnset() &&
1033 "should not perform typo correction on annotation token");
1037 case tok::kw___super
:
1038 case tok::kw_decltype
:
1039 // Annotate the token and tail recurse.
1040 if (TryAnnotateTypeOrScopeToken())
1042 assert(Tok
.isNot(tok::kw_decltype
) && Tok
.isNot(tok::kw___super
));
1043 return ParseCastExpression(ParseKind
, isAddressOfOperand
, isTypeCast
,
1044 isVectorLiteral
, NotPrimaryExpression
);
1046 case tok::identifier
:
1047 ParseIdentifier
: { // primary-expression: identifier
1048 // unqualified-id: identifier
1049 // constant: enumeration-constant
1050 // Turn a potentially qualified name into a annot_typename or
1051 // annot_cxxscope if it would be valid. This handles things like x::y, etc.
1052 if (getLangOpts().CPlusPlus
) {
1053 // Avoid the unnecessary parse-time lookup in the common case
1054 // where the syntax forbids a type.
1055 const Token
&Next
= NextToken();
1057 // If this identifier was reverted from a token ID, and the next token
1058 // is a parenthesis, this is likely to be a use of a type trait. Check
1060 if (Next
.is(tok::l_paren
) &&
1061 Tok
.is(tok::identifier
) &&
1062 Tok
.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
1063 IdentifierInfo
*II
= Tok
.getIdentifierInfo();
1064 // Build up the mapping of revertible type traits, for future use.
1065 if (RevertibleTypeTraits
.empty()) {
1066 #define RTT_JOIN(X,Y) X##Y
1067 #define REVERTIBLE_TYPE_TRAIT(Name) \
1068 RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \
1069 = RTT_JOIN(tok::kw_,Name)
1071 REVERTIBLE_TYPE_TRAIT(__is_abstract
);
1072 REVERTIBLE_TYPE_TRAIT(__is_aggregate
);
1073 REVERTIBLE_TYPE_TRAIT(__is_arithmetic
);
1074 REVERTIBLE_TYPE_TRAIT(__is_array
);
1075 REVERTIBLE_TYPE_TRAIT(__is_assignable
);
1076 REVERTIBLE_TYPE_TRAIT(__is_base_of
);
1077 REVERTIBLE_TYPE_TRAIT(__is_bounded_array
);
1078 REVERTIBLE_TYPE_TRAIT(__is_class
);
1079 REVERTIBLE_TYPE_TRAIT(__is_complete_type
);
1080 REVERTIBLE_TYPE_TRAIT(__is_compound
);
1081 REVERTIBLE_TYPE_TRAIT(__is_const
);
1082 REVERTIBLE_TYPE_TRAIT(__is_constructible
);
1083 REVERTIBLE_TYPE_TRAIT(__is_convertible
);
1084 REVERTIBLE_TYPE_TRAIT(__is_convertible_to
);
1085 REVERTIBLE_TYPE_TRAIT(__is_destructible
);
1086 REVERTIBLE_TYPE_TRAIT(__is_empty
);
1087 REVERTIBLE_TYPE_TRAIT(__is_enum
);
1088 REVERTIBLE_TYPE_TRAIT(__is_floating_point
);
1089 REVERTIBLE_TYPE_TRAIT(__is_final
);
1090 REVERTIBLE_TYPE_TRAIT(__is_function
);
1091 REVERTIBLE_TYPE_TRAIT(__is_fundamental
);
1092 REVERTIBLE_TYPE_TRAIT(__is_integral
);
1093 REVERTIBLE_TYPE_TRAIT(__is_interface_class
);
1094 REVERTIBLE_TYPE_TRAIT(__is_literal
);
1095 REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr
);
1096 REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference
);
1097 REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer
);
1098 REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer
);
1099 REVERTIBLE_TYPE_TRAIT(__is_member_pointer
);
1100 REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable
);
1101 REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible
);
1102 REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible
);
1103 REVERTIBLE_TYPE_TRAIT(__is_nullptr
);
1104 REVERTIBLE_TYPE_TRAIT(__is_object
);
1105 REVERTIBLE_TYPE_TRAIT(__is_pod
);
1106 REVERTIBLE_TYPE_TRAIT(__is_pointer
);
1107 REVERTIBLE_TYPE_TRAIT(__is_polymorphic
);
1108 REVERTIBLE_TYPE_TRAIT(__is_reference
);
1109 REVERTIBLE_TYPE_TRAIT(__is_referenceable
);
1110 REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr
);
1111 REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference
);
1112 REVERTIBLE_TYPE_TRAIT(__is_same
);
1113 REVERTIBLE_TYPE_TRAIT(__is_scalar
);
1114 REVERTIBLE_TYPE_TRAIT(__is_scoped_enum
);
1115 REVERTIBLE_TYPE_TRAIT(__is_sealed
);
1116 REVERTIBLE_TYPE_TRAIT(__is_signed
);
1117 REVERTIBLE_TYPE_TRAIT(__is_standard_layout
);
1118 REVERTIBLE_TYPE_TRAIT(__is_trivial
);
1119 REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable
);
1120 REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible
);
1121 REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable
);
1122 REVERTIBLE_TYPE_TRAIT(__is_unbounded_array
);
1123 REVERTIBLE_TYPE_TRAIT(__is_union
);
1124 REVERTIBLE_TYPE_TRAIT(__is_unsigned
);
1125 REVERTIBLE_TYPE_TRAIT(__is_void
);
1126 REVERTIBLE_TYPE_TRAIT(__is_volatile
);
1127 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
1128 REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
1129 #include "clang/Basic/TransformTypeTraits.def"
1130 #undef REVERTIBLE_TYPE_TRAIT
1134 // If we find that this is in fact the name of a type trait,
1135 // update the token kind in place and parse again to treat it as
1136 // the appropriate kind of type trait.
1137 llvm::SmallDenseMap
<IdentifierInfo
*, tok::TokenKind
>::iterator Known
1138 = RevertibleTypeTraits
.find(II
);
1139 if (Known
!= RevertibleTypeTraits
.end()) {
1140 Tok
.setKind(Known
->second
);
1141 return ParseCastExpression(ParseKind
, isAddressOfOperand
,
1142 NotCastExpr
, isTypeCast
,
1143 isVectorLiteral
, NotPrimaryExpression
);
1147 if ((!ColonIsSacred
&& Next
.is(tok::colon
)) ||
1148 Next
.isOneOf(tok::coloncolon
, tok::less
, tok::l_paren
,
1150 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1151 if (TryAnnotateTypeOrScopeToken())
1153 if (!Tok
.is(tok::identifier
))
1154 return ParseCastExpression(ParseKind
, isAddressOfOperand
,
1155 NotCastExpr
, isTypeCast
,
1157 NotPrimaryExpression
);
1161 // Consume the identifier so that we can see if it is followed by a '(' or
1163 IdentifierInfo
&II
= *Tok
.getIdentifierInfo();
1164 SourceLocation ILoc
= ConsumeToken();
1166 // Support 'Class.property' and 'super.property' notation.
1167 if (getLangOpts().ObjC
&& Tok
.is(tok::period
) &&
1168 (Actions
.getTypeName(II
, ILoc
, getCurScope()) ||
1169 // Allow the base to be 'super' if in an objc-method.
1170 (&II
== Ident_super
&& getCurScope()->isInObjcMethodScope()))) {
1173 if (Tok
.is(tok::code_completion
) && &II
!= Ident_super
) {
1175 Actions
.CodeCompleteObjCClassPropertyRefExpr(
1176 getCurScope(), II
, ILoc
, ExprStatementTokLoc
== ILoc
);
1179 // Allow either an identifier or the keyword 'class' (in C++).
1180 if (Tok
.isNot(tok::identifier
) &&
1181 !(getLangOpts().CPlusPlus
&& Tok
.is(tok::kw_class
))) {
1182 Diag(Tok
, diag::err_expected_property_name
);
1185 IdentifierInfo
&PropertyName
= *Tok
.getIdentifierInfo();
1186 SourceLocation PropertyLoc
= ConsumeToken();
1188 Res
= Actions
.ActOnClassPropertyRefExpr(II
, PropertyName
,
1193 // In an Objective-C method, if we have "super" followed by an identifier,
1194 // the token sequence is ill-formed. However, if there's a ':' or ']' after
1195 // that identifier, this is probably a message send with a missing open
1196 // bracket. Treat it as such.
1197 if (getLangOpts().ObjC
&& &II
== Ident_super
&& !InMessageExpression
&&
1198 getCurScope()->isInObjcMethodScope() &&
1199 ((Tok
.is(tok::identifier
) &&
1200 (NextToken().is(tok::colon
) || NextToken().is(tok::r_square
))) ||
1201 Tok
.is(tok::code_completion
))) {
1202 Res
= ParseObjCMessageExpressionBody(SourceLocation(), ILoc
, nullptr,
1207 // If we have an Objective-C class name followed by an identifier
1208 // and either ':' or ']', this is an Objective-C class message
1209 // send that's missing the opening '['. Recovery
1210 // appropriately. Also take this path if we're performing code
1211 // completion after an Objective-C class name.
1212 if (getLangOpts().ObjC
&&
1213 ((Tok
.is(tok::identifier
) && !InMessageExpression
) ||
1214 Tok
.is(tok::code_completion
))) {
1215 const Token
& Next
= NextToken();
1216 if (Tok
.is(tok::code_completion
) ||
1217 Next
.is(tok::colon
) || Next
.is(tok::r_square
))
1218 if (ParsedType Typ
= Actions
.getTypeName(II
, ILoc
, getCurScope()))
1219 if (Typ
.get()->isObjCObjectOrInterfaceType()) {
1220 // Fake up a Declarator to use with ActOnTypeName.
1221 DeclSpec
DS(AttrFactory
);
1222 DS
.SetRangeStart(ILoc
);
1223 DS
.SetRangeEnd(ILoc
);
1224 const char *PrevSpec
= nullptr;
1226 DS
.SetTypeSpecType(TST_typename
, ILoc
, PrevSpec
, DiagID
, Typ
,
1227 Actions
.getASTContext().getPrintingPolicy());
1229 Declarator
DeclaratorInfo(DS
, ParsedAttributesView::none(),
1230 DeclaratorContext::TypeName
);
1231 TypeResult Ty
= Actions
.ActOnTypeName(getCurScope(),
1236 Res
= ParseObjCMessageExpressionBody(SourceLocation(),
1243 // Make sure to pass down the right value for isAddressOfOperand.
1244 if (isAddressOfOperand
&& isPostfixExpressionSuffixStart())
1245 isAddressOfOperand
= false;
1247 // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
1248 // need to know whether or not this identifier is a function designator or
1251 CXXScopeSpec ScopeSpec
;
1252 SourceLocation TemplateKWLoc
;
1254 CastExpressionIdValidator
Validator(
1256 /*AllowTypes=*/isTypeCast
!= NotTypeCast
,
1257 /*AllowNonTypes=*/isTypeCast
!= IsTypeCast
);
1258 Validator
.IsAddressOfOperand
= isAddressOfOperand
;
1259 if (Tok
.isOneOf(tok::periodstar
, tok::arrowstar
)) {
1260 Validator
.WantExpressionKeywords
= false;
1261 Validator
.WantRemainingKeywords
= false;
1263 Validator
.WantRemainingKeywords
= Tok
.isNot(tok::r_paren
);
1265 Name
.setIdentifier(&II
, ILoc
);
1266 Res
= Actions
.ActOnIdExpression(
1267 getCurScope(), ScopeSpec
, TemplateKWLoc
, Name
, Tok
.is(tok::l_paren
),
1268 isAddressOfOperand
, &Validator
,
1269 /*IsInlineAsmIdentifier=*/false,
1270 Tok
.is(tok::r_paren
) ? nullptr : &Replacement
);
1271 if (!Res
.isInvalid() && Res
.isUnset()) {
1272 UnconsumeToken(Replacement
);
1273 return ParseCastExpression(ParseKind
, isAddressOfOperand
,
1274 NotCastExpr
, isTypeCast
,
1275 /*isVectorLiteral=*/false,
1276 NotPrimaryExpression
);
1278 if (!Res
.isInvalid() && Tok
.is(tok::less
))
1279 checkPotentialAngleBracket(Res
);
1282 case tok::char_constant
: // constant: character-constant
1283 case tok::wide_char_constant
:
1284 case tok::utf8_char_constant
:
1285 case tok::utf16_char_constant
:
1286 case tok::utf32_char_constant
:
1287 Res
= Actions
.ActOnCharacterConstant(Tok
, /*UDLScope*/getCurScope());
1290 case tok::kw___func__
: // primary-expression: __func__ [C99 6.4.2.2]
1291 case tok::kw___FUNCTION__
: // primary-expression: __FUNCTION__ [GNU]
1292 case tok::kw___FUNCDNAME__
: // primary-expression: __FUNCDNAME__ [MS]
1293 case tok::kw___FUNCSIG__
: // primary-expression: __FUNCSIG__ [MS]
1294 case tok::kw_L__FUNCTION__
: // primary-expression: L__FUNCTION__ [MS]
1295 case tok::kw_L__FUNCSIG__
: // primary-expression: L__FUNCSIG__ [MS]
1296 case tok::kw___PRETTY_FUNCTION__
: // primary-expression: __P..Y_F..N__ [GNU]
1297 Res
= Actions
.ActOnPredefinedExpr(Tok
.getLocation(), SavedKind
);
1300 case tok::string_literal
: // primary-expression: string-literal
1301 case tok::wide_string_literal
:
1302 case tok::utf8_string_literal
:
1303 case tok::utf16_string_literal
:
1304 case tok::utf32_string_literal
:
1305 Res
= ParseStringLiteralExpression(true);
1307 case tok::kw__Generic
: // primary-expression: generic-selection [C11 6.5.1]
1308 Res
= ParseGenericSelectionExpression();
1310 case tok::kw___builtin_available
:
1311 Res
= ParseAvailabilityCheckExpr(Tok
.getLocation());
1313 case tok::kw___builtin_va_arg
:
1314 case tok::kw___builtin_offsetof
:
1315 case tok::kw___builtin_choose_expr
:
1316 case tok::kw___builtin_astype
: // primary-expression: [OCL] as_type()
1317 case tok::kw___builtin_convertvector
:
1318 case tok::kw___builtin_COLUMN
:
1319 case tok::kw___builtin_FILE
:
1320 case tok::kw___builtin_FUNCTION
:
1321 case tok::kw___builtin_LINE
:
1322 case tok::kw___builtin_source_location
:
1323 if (NotPrimaryExpression
)
1324 *NotPrimaryExpression
= true;
1325 // This parses the complete suffix; we can return early.
1326 return ParseBuiltinPrimaryExpression();
1327 case tok::kw___null
:
1328 Res
= Actions
.ActOnGNUNullExpr(ConsumeToken());
1331 case tok::plusplus
: // unary-expression: '++' unary-expression [C99]
1332 case tok::minusminus
: { // unary-expression: '--' unary-expression [C99]
1333 if (NotPrimaryExpression
)
1334 *NotPrimaryExpression
= true;
1335 // C++ [expr.unary] has:
1336 // unary-expression:
1337 // ++ cast-expression
1338 // -- cast-expression
1339 Token SavedTok
= Tok
;
1342 PreferredType
.enterUnary(Actions
, Tok
.getLocation(), SavedTok
.getKind(),
1343 SavedTok
.getLocation());
1344 // One special case is implicitly handled here: if the preceding tokens are
1345 // an ambiguous cast expression, such as "(T())++", then we recurse to
1346 // determine whether the '++' is prefix or postfix.
1347 Res
= ParseCastExpression(getLangOpts().CPlusPlus
?
1348 UnaryExprOnly
: AnyCastExpr
,
1349 /*isAddressOfOperand*/false, NotCastExpr
,
1352 // If we return with NotCastExpr = true, we must not consume any tokens,
1353 // so put the token back where we found it.
1354 assert(Res
.isInvalid());
1355 UnconsumeToken(SavedTok
);
1358 if (!Res
.isInvalid()) {
1359 Expr
*Arg
= Res
.get();
1360 Res
= Actions
.ActOnUnaryOp(getCurScope(), SavedTok
.getLocation(),
1362 if (Res
.isInvalid())
1363 Res
= Actions
.CreateRecoveryExpr(SavedTok
.getLocation(),
1364 Arg
->getEndLoc(), Arg
);
1368 case tok::amp
: { // unary-expression: '&' cast-expression
1369 if (NotPrimaryExpression
)
1370 *NotPrimaryExpression
= true;
1371 // Special treatment because of member pointers
1372 SourceLocation SavedLoc
= ConsumeToken();
1373 PreferredType
.enterUnary(Actions
, Tok
.getLocation(), tok::amp
, SavedLoc
);
1375 Res
= ParseCastExpression(AnyCastExpr
, /*isAddressOfOperand=*/true);
1376 if (!Res
.isInvalid()) {
1377 Expr
*Arg
= Res
.get();
1378 Res
= Actions
.ActOnUnaryOp(getCurScope(), SavedLoc
, SavedKind
, Arg
);
1379 if (Res
.isInvalid())
1380 Res
= Actions
.CreateRecoveryExpr(Tok
.getLocation(), Arg
->getEndLoc(),
1386 case tok::star
: // unary-expression: '*' cast-expression
1387 case tok::plus
: // unary-expression: '+' cast-expression
1388 case tok::minus
: // unary-expression: '-' cast-expression
1389 case tok::tilde
: // unary-expression: '~' cast-expression
1390 case tok::exclaim
: // unary-expression: '!' cast-expression
1391 case tok::kw___real
: // unary-expression: '__real' cast-expression [GNU]
1392 case tok::kw___imag
: { // unary-expression: '__imag' cast-expression [GNU]
1393 if (NotPrimaryExpression
)
1394 *NotPrimaryExpression
= true;
1395 SourceLocation SavedLoc
= ConsumeToken();
1396 PreferredType
.enterUnary(Actions
, Tok
.getLocation(), SavedKind
, SavedLoc
);
1397 Res
= ParseCastExpression(AnyCastExpr
);
1398 if (!Res
.isInvalid()) {
1399 Expr
*Arg
= Res
.get();
1400 Res
= Actions
.ActOnUnaryOp(getCurScope(), SavedLoc
, SavedKind
, Arg
,
1401 isAddressOfOperand
);
1402 if (Res
.isInvalid())
1403 Res
= Actions
.CreateRecoveryExpr(SavedLoc
, Arg
->getEndLoc(), Arg
);
1408 case tok::kw_co_await
: { // unary-expression: 'co_await' cast-expression
1409 if (NotPrimaryExpression
)
1410 *NotPrimaryExpression
= true;
1411 SourceLocation CoawaitLoc
= ConsumeToken();
1412 Res
= ParseCastExpression(AnyCastExpr
);
1413 if (!Res
.isInvalid())
1414 Res
= Actions
.ActOnCoawaitExpr(getCurScope(), CoawaitLoc
, Res
.get());
1418 case tok::kw___extension__
:{//unary-expression:'__extension__' cast-expr [GNU]
1419 // __extension__ silences extension warnings in the subexpression.
1420 if (NotPrimaryExpression
)
1421 *NotPrimaryExpression
= true;
1422 ExtensionRAIIObject
O(Diags
); // Use RAII to do this.
1423 SourceLocation SavedLoc
= ConsumeToken();
1424 Res
= ParseCastExpression(AnyCastExpr
);
1425 if (!Res
.isInvalid())
1426 Res
= Actions
.ActOnUnaryOp(getCurScope(), SavedLoc
, SavedKind
, Res
.get());
1429 case tok::kw__Alignof
: // unary-expression: '_Alignof' '(' type-name ')'
1430 if (!getLangOpts().C11
)
1431 Diag(Tok
, diag::ext_c11_feature
) << Tok
.getName();
1433 case tok::kw_alignof
: // unary-expression: 'alignof' '(' type-id ')'
1434 case tok::kw___alignof
: // unary-expression: '__alignof' unary-expression
1435 // unary-expression: '__alignof' '(' type-name ')'
1436 case tok::kw_sizeof
: // unary-expression: 'sizeof' unary-expression
1437 // unary-expression: 'sizeof' '(' type-name ')'
1438 case tok::kw_vec_step
: // unary-expression: OpenCL 'vec_step' expression
1439 // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')'
1440 case tok::kw___builtin_omp_required_simd_align
:
1441 if (NotPrimaryExpression
)
1442 *NotPrimaryExpression
= true;
1443 AllowSuffix
= false;
1444 Res
= ParseUnaryExprOrTypeTraitExpression();
1446 case tok::ampamp
: { // unary-expression: '&&' identifier
1447 if (NotPrimaryExpression
)
1448 *NotPrimaryExpression
= true;
1449 SourceLocation AmpAmpLoc
= ConsumeToken();
1450 if (Tok
.isNot(tok::identifier
))
1451 return ExprError(Diag(Tok
, diag::err_expected
) << tok::identifier
);
1453 if (getCurScope()->getFnParent() == nullptr)
1454 return ExprError(Diag(Tok
, diag::err_address_of_label_outside_fn
));
1456 Diag(AmpAmpLoc
, diag::ext_gnu_address_of_label
);
1457 LabelDecl
*LD
= Actions
.LookupOrCreateLabel(Tok
.getIdentifierInfo(),
1459 Res
= Actions
.ActOnAddrLabel(AmpAmpLoc
, Tok
.getLocation(), LD
);
1461 AllowSuffix
= false;
1464 case tok::kw_const_cast
:
1465 case tok::kw_dynamic_cast
:
1466 case tok::kw_reinterpret_cast
:
1467 case tok::kw_static_cast
:
1468 case tok::kw_addrspace_cast
:
1469 if (NotPrimaryExpression
)
1470 *NotPrimaryExpression
= true;
1471 Res
= ParseCXXCasts();
1473 case tok::kw___builtin_bit_cast
:
1474 if (NotPrimaryExpression
)
1475 *NotPrimaryExpression
= true;
1476 Res
= ParseBuiltinBitCast();
1478 case tok::kw_typeid
:
1479 if (NotPrimaryExpression
)
1480 *NotPrimaryExpression
= true;
1481 Res
= ParseCXXTypeid();
1483 case tok::kw___uuidof
:
1484 if (NotPrimaryExpression
)
1485 *NotPrimaryExpression
= true;
1486 Res
= ParseCXXUuidof();
1489 Res
= ParseCXXThis();
1491 case tok::kw___builtin_sycl_unique_stable_name
:
1492 Res
= ParseSYCLUniqueStableNameExpression();
1495 case tok::annot_typename
:
1496 if (isStartOfObjCClassMessageMissingOpenBracket()) {
1497 TypeResult Type
= getTypeAnnotation(Tok
);
1499 // Fake up a Declarator to use with ActOnTypeName.
1500 DeclSpec
DS(AttrFactory
);
1501 DS
.SetRangeStart(Tok
.getLocation());
1502 DS
.SetRangeEnd(Tok
.getLastLoc());
1504 const char *PrevSpec
= nullptr;
1506 DS
.SetTypeSpecType(TST_typename
, Tok
.getAnnotationEndLoc(),
1507 PrevSpec
, DiagID
, Type
,
1508 Actions
.getASTContext().getPrintingPolicy());
1510 Declarator
DeclaratorInfo(DS
, ParsedAttributesView::none(),
1511 DeclaratorContext::TypeName
);
1512 TypeResult Ty
= Actions
.ActOnTypeName(getCurScope(), DeclaratorInfo
);
1516 ConsumeAnnotationToken();
1517 Res
= ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1523 case tok::annot_decltype
:
1525 case tok::kw_wchar_t
:
1526 case tok::kw_char8_t
:
1527 case tok::kw_char16_t
:
1528 case tok::kw_char32_t
:
1533 case tok::kw___int64
:
1534 case tok::kw___int128
:
1535 case tok::kw__ExtInt
:
1536 case tok::kw__BitInt
:
1537 case tok::kw_signed
:
1538 case tok::kw_unsigned
:
1541 case tok::kw_double
:
1542 case tok::kw___bf16
:
1543 case tok::kw__Float16
:
1544 case tok::kw___float128
:
1545 case tok::kw___ibm128
:
1548 case tok::kw_typename
:
1549 case tok::kw_typeof
:
1550 case tok::kw___vector
:
1551 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1552 #include "clang/Basic/OpenCLImageTypes.def"
1554 if (!getLangOpts().CPlusPlus
) {
1555 Diag(Tok
, diag::err_expected_expression
);
1559 // Everything henceforth is a postfix-expression.
1560 if (NotPrimaryExpression
)
1561 *NotPrimaryExpression
= true;
1563 if (SavedKind
== tok::kw_typename
) {
1564 // postfix-expression: typename-specifier '(' expression-list[opt] ')'
1565 // typename-specifier braced-init-list
1566 if (TryAnnotateTypeOrScopeToken())
1569 if (!Actions
.isSimpleTypeSpecifier(Tok
.getKind()))
1570 // We are trying to parse a simple-type-specifier but might not get such
1571 // a token after error recovery.
1575 // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
1576 // simple-type-specifier braced-init-list
1578 DeclSpec
DS(AttrFactory
);
1580 ParseCXXSimpleTypeSpecifier(DS
);
1581 if (Tok
.isNot(tok::l_paren
) &&
1582 (!getLangOpts().CPlusPlus11
|| Tok
.isNot(tok::l_brace
)))
1583 return ExprError(Diag(Tok
, diag::err_expected_lparen_after_type
)
1584 << DS
.getSourceRange());
1586 if (Tok
.is(tok::l_brace
))
1587 Diag(Tok
, diag::warn_cxx98_compat_generalized_initializer_lists
);
1589 Res
= ParseCXXTypeConstructExpression(DS
);
1593 case tok::annot_cxxscope
: { // [C++] id-expression: qualified-id
1594 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1595 // (We can end up in this situation after tentative parsing.)
1596 if (TryAnnotateTypeOrScopeToken())
1598 if (!Tok
.is(tok::annot_cxxscope
))
1599 return ParseCastExpression(ParseKind
, isAddressOfOperand
, NotCastExpr
,
1600 isTypeCast
, isVectorLiteral
,
1601 NotPrimaryExpression
);
1603 Token Next
= NextToken();
1604 if (Next
.is(tok::annot_template_id
)) {
1605 TemplateIdAnnotation
*TemplateId
= takeTemplateIdAnnotation(Next
);
1606 if (TemplateId
->Kind
== TNK_Type_template
) {
1607 // We have a qualified template-id that we know refers to a
1608 // type, translate it into a type and continue parsing as a
1611 ParseOptionalCXXScopeSpecifier(SS
, /*ObjectType=*/nullptr,
1612 /*ObjectHasErrors=*/false,
1613 /*EnteringContext=*/false);
1614 AnnotateTemplateIdTokenAsType(SS
, ImplicitTypenameContext::Yes
);
1615 return ParseCastExpression(ParseKind
, isAddressOfOperand
, NotCastExpr
,
1616 isTypeCast
, isVectorLiteral
,
1617 NotPrimaryExpression
);
1621 // Parse as an id-expression.
1622 Res
= ParseCXXIdExpression(isAddressOfOperand
);
1626 case tok::annot_template_id
: { // [C++] template-id
1627 TemplateIdAnnotation
*TemplateId
= takeTemplateIdAnnotation(Tok
);
1628 if (TemplateId
->Kind
== TNK_Type_template
) {
1629 // We have a template-id that we know refers to a type,
1630 // translate it into a type and continue parsing as a cast
1633 AnnotateTemplateIdTokenAsType(SS
, ImplicitTypenameContext::Yes
);
1634 return ParseCastExpression(ParseKind
, isAddressOfOperand
,
1635 NotCastExpr
, isTypeCast
, isVectorLiteral
,
1636 NotPrimaryExpression
);
1639 // Fall through to treat the template-id as an id-expression.
1643 case tok::kw_operator
: // [C++] id-expression: operator/conversion-function-id
1644 Res
= ParseCXXIdExpression(isAddressOfOperand
);
1647 case tok::coloncolon
: {
1648 // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken
1649 // annotates the token, tail recurse.
1650 if (TryAnnotateTypeOrScopeToken())
1652 if (!Tok
.is(tok::coloncolon
))
1653 return ParseCastExpression(ParseKind
, isAddressOfOperand
, isTypeCast
,
1654 isVectorLiteral
, NotPrimaryExpression
);
1656 // ::new -> [C++] new-expression
1657 // ::delete -> [C++] delete-expression
1658 SourceLocation CCLoc
= ConsumeToken();
1659 if (Tok
.is(tok::kw_new
)) {
1660 if (NotPrimaryExpression
)
1661 *NotPrimaryExpression
= true;
1662 Res
= ParseCXXNewExpression(true, CCLoc
);
1663 AllowSuffix
= false;
1666 if (Tok
.is(tok::kw_delete
)) {
1667 if (NotPrimaryExpression
)
1668 *NotPrimaryExpression
= true;
1669 Res
= ParseCXXDeleteExpression(true, CCLoc
);
1670 AllowSuffix
= false;
1674 // This is not a type name or scope specifier, it is an invalid expression.
1675 Diag(CCLoc
, diag::err_expected_expression
);
1679 case tok::kw_new
: // [C++] new-expression
1680 if (NotPrimaryExpression
)
1681 *NotPrimaryExpression
= true;
1682 Res
= ParseCXXNewExpression(false, Tok
.getLocation());
1683 AllowSuffix
= false;
1686 case tok::kw_delete
: // [C++] delete-expression
1687 if (NotPrimaryExpression
)
1688 *NotPrimaryExpression
= true;
1689 Res
= ParseCXXDeleteExpression(false, Tok
.getLocation());
1690 AllowSuffix
= false;
1693 case tok::kw_requires
: // [C++2a] requires-expression
1694 Res
= ParseRequiresExpression();
1695 AllowSuffix
= false;
1698 case tok::kw_noexcept
: { // [C++0x] 'noexcept' '(' expression ')'
1699 if (NotPrimaryExpression
)
1700 *NotPrimaryExpression
= true;
1701 Diag(Tok
, diag::warn_cxx98_compat_noexcept_expr
);
1702 SourceLocation KeyLoc
= ConsumeToken();
1703 BalancedDelimiterTracker
T(*this, tok::l_paren
);
1705 if (T
.expectAndConsume(diag::err_expected_lparen_after
, "noexcept"))
1707 // C++11 [expr.unary.noexcept]p1:
1708 // The noexcept operator determines whether the evaluation of its operand,
1709 // which is an unevaluated operand, can throw an exception.
1710 EnterExpressionEvaluationContext
Unevaluated(
1711 Actions
, Sema::ExpressionEvaluationContext::Unevaluated
);
1712 Res
= ParseExpression();
1716 if (!Res
.isInvalid())
1717 Res
= Actions
.ActOnNoexceptExpr(KeyLoc
, T
.getOpenLocation(), Res
.get(),
1718 T
.getCloseLocation());
1719 AllowSuffix
= false;
1723 #define TYPE_TRAIT(N,Spelling,K) \
1724 case tok::kw_##Spelling:
1725 #include "clang/Basic/TokenKinds.def"
1726 Res
= ParseTypeTrait();
1729 case tok::kw___array_rank
:
1730 case tok::kw___array_extent
:
1731 if (NotPrimaryExpression
)
1732 *NotPrimaryExpression
= true;
1733 Res
= ParseArrayTypeTrait();
1736 case tok::kw___is_lvalue_expr
:
1737 case tok::kw___is_rvalue_expr
:
1738 if (NotPrimaryExpression
)
1739 *NotPrimaryExpression
= true;
1740 Res
= ParseExpressionTrait();
1744 if (NotPrimaryExpression
)
1745 *NotPrimaryExpression
= true;
1746 SourceLocation AtLoc
= ConsumeToken();
1747 return ParseObjCAtExpression(AtLoc
);
1750 Res
= ParseBlockLiteralExpression();
1752 case tok::code_completion
: {
1754 Actions
.CodeCompleteExpression(getCurScope(),
1755 PreferredType
.get(Tok
.getLocation()));
1758 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1759 #include "clang/Basic/TransformTypeTraits.def"
1760 // HACK: libstdc++ uses some of the transform-type-traits as alias
1761 // templates, so we need to work around this.
1762 if (!NextToken().is(tok::l_paren
)) {
1763 Tok
.setKind(tok::identifier
);
1764 Diag(Tok
, diag::ext_keyword_as_ident
)
1765 << Tok
.getIdentifierInfo()->getName() << 0;
1766 goto ParseIdentifier
;
1768 goto ExpectedExpression
;
1770 if (getLangOpts().CPlusPlus11
) {
1771 if (getLangOpts().ObjC
) {
1772 // C++11 lambda expressions and Objective-C message sends both start with a
1773 // square bracket. There are three possibilities here:
1774 // we have a valid lambda expression, we have an invalid lambda
1775 // expression, or we have something that doesn't appear to be a lambda.
1776 // If we're in the last case, we fall back to ParseObjCMessageExpression.
1777 Res
= TryParseLambdaExpression();
1778 if (!Res
.isInvalid() && !Res
.get()) {
1779 // We assume Objective-C++ message expressions are not
1780 // primary-expressions.
1781 if (NotPrimaryExpression
)
1782 *NotPrimaryExpression
= true;
1783 Res
= ParseObjCMessageExpression();
1787 Res
= ParseLambdaExpression();
1790 if (getLangOpts().ObjC
) {
1791 Res
= ParseObjCMessageExpression();
1801 // Check to see whether Res is a function designator only. If it is and we
1802 // are compiling for OpenCL, we need to return an error as this implies
1803 // that the address of the function is being taken, which is illegal in CL.
1805 if (ParseKind
== PrimaryExprOnly
)
1806 // This is strictly a primary-expression - no postfix-expr pieces should be
1811 // FIXME: Don't parse a primary-expression suffix if we encountered a parse
1813 if (Res
.isInvalid())
1816 switch (Tok
.getKind()) {
1820 case tok::minusminus
:
1821 // "expected ';'" or similar is probably the right diagnostic here. Let
1822 // the caller decide what to do.
1823 if (Tok
.isAtStartOfLine())
1835 // This was a unary-expression for which a postfix-expression suffix is
1836 // not permitted by the grammar (eg, a sizeof expression or
1837 // new-expression or similar). Diagnose but parse the suffix anyway.
1838 Diag(Tok
.getLocation(), diag::err_postfix_after_unary_requires_parens
)
1839 << Tok
.getKind() << Res
.get()->getSourceRange()
1840 << FixItHint::CreateInsertion(Res
.get()->getBeginLoc(), "(")
1841 << FixItHint::CreateInsertion(PP
.getLocForEndOfToken(PrevTokLocation
),
1845 // These can be followed by postfix-expr pieces.
1846 PreferredType
= SavedType
;
1847 Res
= ParsePostfixExpressionSuffix(Res
);
1848 if (getLangOpts().OpenCL
&&
1849 !getActions().getOpenCLOptions().isAvailableOption(
1850 "__cl_clang_function_pointers", getLangOpts()))
1851 if (Expr
*PostfixExpr
= Res
.get()) {
1852 QualType Ty
= PostfixExpr
->getType();
1853 if (!Ty
.isNull() && Ty
->isFunctionType()) {
1854 Diag(PostfixExpr
->getExprLoc(),
1855 diag::err_opencl_taking_function_address_parser
);
1863 /// Once the leading part of a postfix-expression is parsed, this
1864 /// method parses any suffixes that apply.
1867 /// postfix-expression: [C99 6.5.2]
1868 /// primary-expression
1869 /// postfix-expression '[' expression ']'
1870 /// postfix-expression '[' braced-init-list ']'
1871 /// postfix-expression '[' expression-list [opt] ']' [C++2b 12.4.5]
1872 /// postfix-expression '(' argument-expression-list[opt] ')'
1873 /// postfix-expression '.' identifier
1874 /// postfix-expression '->' identifier
1875 /// postfix-expression '++'
1876 /// postfix-expression '--'
1877 /// '(' type-name ')' '{' initializer-list '}'
1878 /// '(' type-name ')' '{' initializer-list ',' '}'
1880 /// argument-expression-list: [C99 6.5.2]
1881 /// argument-expression ...[opt]
1882 /// argument-expression-list ',' assignment-expression ...[opt]
1885 Parser::ParsePostfixExpressionSuffix(ExprResult LHS
) {
1886 // Now that the primary-expression piece of the postfix-expression has been
1887 // parsed, see if there are any postfix-expression pieces here.
1889 auto SavedType
= PreferredType
;
1891 // Each iteration relies on preferred type for the whole expression.
1892 PreferredType
= SavedType
;
1893 switch (Tok
.getKind()) {
1894 case tok::code_completion
:
1895 if (InMessageExpression
)
1899 Actions
.CodeCompletePostfixExpression(
1900 getCurScope(), LHS
, PreferredType
.get(Tok
.getLocation()));
1903 case tok::identifier
:
1904 // If we see identifier: after an expression, and we're not already in a
1905 // message send, then this is probably a message send with a missing
1906 // opening bracket '['.
1907 if (getLangOpts().ObjC
&& !InMessageExpression
&&
1908 (NextToken().is(tok::colon
) || NextToken().is(tok::r_square
))) {
1909 LHS
= ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1910 nullptr, LHS
.get());
1913 // Fall through; this isn't a message send.
1916 default: // Not a postfix-expression suffix.
1918 case tok::l_square
: { // postfix-expression: p-e '[' expression ']'
1919 // If we have a array postfix expression that starts on a new line and
1920 // Objective-C is enabled, it is highly likely that the user forgot a
1921 // semicolon after the base expression and that the array postfix-expr is
1922 // actually another message send. In this case, do some look-ahead to see
1923 // if the contents of the square brackets are obviously not a valid
1924 // expression and recover by pretending there is no suffix.
1925 if (getLangOpts().ObjC
&& Tok
.isAtStartOfLine() &&
1926 isSimpleObjCMessageExpression())
1929 // Reject array indices starting with a lambda-expression. '[[' is
1930 // reserved for attributes.
1931 if (CheckProhibitedCXX11Attribute()) {
1932 (void)Actions
.CorrectDelayedTyposInExpr(LHS
);
1935 BalancedDelimiterTracker
T(*this, tok::l_square
);
1937 Loc
= T
.getOpenLocation();
1938 ExprResult Length
, Stride
;
1939 SourceLocation ColonLocFirst
, ColonLocSecond
;
1940 ExprVector ArgExprs
;
1941 bool HasError
= false;
1942 PreferredType
.enterSubscript(Actions
, Tok
.getLocation(), LHS
.get());
1944 // We try to parse a list of indexes in all language mode first
1945 // and, in we find 0 or one index, we try to parse an OpenMP array
1946 // section. This allow us to support C++2b multi dimensional subscript and
1947 // OpenMp sections in the same language mode.
1948 if (!getLangOpts().OpenMP
|| Tok
.isNot(tok::colon
)) {
1949 if (!getLangOpts().CPlusPlus2b
) {
1951 if (getLangOpts().CPlusPlus11
&& Tok
.is(tok::l_brace
)) {
1952 Diag(Tok
, diag::warn_cxx98_compat_generalized_initializer_lists
);
1953 Idx
= ParseBraceInitializer();
1955 Idx
= ParseExpression(); // May be a comma expression
1957 LHS
= Actions
.CorrectDelayedTyposInExpr(LHS
);
1958 Idx
= Actions
.CorrectDelayedTyposInExpr(Idx
);
1959 if (Idx
.isInvalid()) {
1962 ArgExprs
.push_back(Idx
.get());
1964 } else if (Tok
.isNot(tok::r_square
)) {
1965 if (ParseExpressionList(ArgExprs
)) {
1966 LHS
= Actions
.CorrectDelayedTyposInExpr(LHS
);
1972 if (ArgExprs
.size() <= 1 && getLangOpts().OpenMP
) {
1973 ColonProtectionRAIIObject
RAII(*this);
1974 if (Tok
.is(tok::colon
)) {
1976 ColonLocFirst
= ConsumeToken();
1977 if (Tok
.isNot(tok::r_square
) &&
1978 (getLangOpts().OpenMP
< 50 ||
1979 ((Tok
.isNot(tok::colon
) && getLangOpts().OpenMP
>= 50)))) {
1980 Length
= ParseExpression();
1981 Length
= Actions
.CorrectDelayedTyposInExpr(Length
);
1984 if (getLangOpts().OpenMP
>= 50 &&
1985 (OMPClauseKind
== llvm::omp::Clause::OMPC_to
||
1986 OMPClauseKind
== llvm::omp::Clause::OMPC_from
) &&
1987 Tok
.is(tok::colon
)) {
1989 ColonLocSecond
= ConsumeToken();
1990 if (Tok
.isNot(tok::r_square
)) {
1991 Stride
= ParseExpression();
1996 SourceLocation RLoc
= Tok
.getLocation();
1997 LHS
= Actions
.CorrectDelayedTyposInExpr(LHS
);
1999 if (!LHS
.isInvalid() && !HasError
&& !Length
.isInvalid() &&
2000 !Stride
.isInvalid() && Tok
.is(tok::r_square
)) {
2001 if (ColonLocFirst
.isValid() || ColonLocSecond
.isValid()) {
2002 LHS
= Actions
.ActOnOMPArraySectionExpr(
2003 LHS
.get(), Loc
, ArgExprs
.empty() ? nullptr : ArgExprs
[0],
2004 ColonLocFirst
, ColonLocSecond
, Length
.get(), Stride
.get(), RLoc
);
2006 LHS
= Actions
.ActOnArraySubscriptExpr(getCurScope(), LHS
.get(), Loc
,
2018 case tok::l_paren
: // p-e: p-e '(' argument-expression-list[opt] ')'
2019 case tok::lesslessless
: { // p-e: p-e '<<<' argument-expression-list '>>>'
2020 // '(' argument-expression-list[opt] ')'
2021 tok::TokenKind OpKind
= Tok
.getKind();
2022 InMessageExpressionRAIIObject
InMessage(*this, false);
2024 Expr
*ExecConfig
= nullptr;
2026 BalancedDelimiterTracker
PT(*this, tok::l_paren
);
2028 if (OpKind
== tok::lesslessless
) {
2029 ExprVector ExecConfigExprs
;
2030 SourceLocation OpenLoc
= ConsumeToken();
2032 if (ParseSimpleExpressionList(ExecConfigExprs
)) {
2033 (void)Actions
.CorrectDelayedTyposInExpr(LHS
);
2037 SourceLocation CloseLoc
;
2038 if (TryConsumeToken(tok::greatergreatergreater
, CloseLoc
)) {
2039 } else if (LHS
.isInvalid()) {
2040 SkipUntil(tok::greatergreatergreater
, StopAtSemi
);
2042 // There was an error closing the brackets
2043 Diag(Tok
, diag::err_expected
) << tok::greatergreatergreater
;
2044 Diag(OpenLoc
, diag::note_matching
) << tok::lesslessless
;
2045 SkipUntil(tok::greatergreatergreater
, StopAtSemi
);
2049 if (!LHS
.isInvalid()) {
2050 if (ExpectAndConsume(tok::l_paren
))
2053 Loc
= PrevTokLocation
;
2056 if (!LHS
.isInvalid()) {
2057 ExprResult ECResult
= Actions
.ActOnCUDAExecConfigExpr(getCurScope(),
2061 if (ECResult
.isInvalid())
2064 ExecConfig
= ECResult
.get();
2068 Loc
= PT
.getOpenLocation();
2071 ExprVector ArgExprs
;
2072 auto RunSignatureHelp
= [&]() -> QualType
{
2073 QualType PreferredType
= Actions
.ProduceCallSignatureHelp(
2074 LHS
.get(), ArgExprs
, PT
.getOpenLocation());
2075 CalledSignatureHelp
= true;
2076 return PreferredType
;
2078 if (OpKind
== tok::l_paren
|| !LHS
.isInvalid()) {
2079 if (Tok
.isNot(tok::r_paren
)) {
2080 if (ParseExpressionList(ArgExprs
, [&] {
2081 PreferredType
.enterFunctionArgument(Tok
.getLocation(),
2084 (void)Actions
.CorrectDelayedTyposInExpr(LHS
);
2085 // If we got an error when parsing expression list, we don't call
2086 // the CodeCompleteCall handler inside the parser. So call it here
2087 // to make sure we get overload suggestions even when we are in the
2088 // middle of a parameter.
2089 if (PP
.isCodeCompletionReached() && !CalledSignatureHelp
)
2092 } else if (LHS
.isInvalid()) {
2093 for (auto &E
: ArgExprs
)
2094 Actions
.CorrectDelayedTyposInExpr(E
);
2100 if (LHS
.isInvalid()) {
2101 SkipUntil(tok::r_paren
, StopAtSemi
);
2102 } else if (Tok
.isNot(tok::r_paren
)) {
2103 bool HadDelayedTypo
= false;
2104 if (Actions
.CorrectDelayedTyposInExpr(LHS
).get() != LHS
.get())
2105 HadDelayedTypo
= true;
2106 for (auto &E
: ArgExprs
)
2107 if (Actions
.CorrectDelayedTyposInExpr(E
).get() != E
)
2108 HadDelayedTypo
= true;
2109 // If there were delayed typos in the LHS or ArgExprs, call SkipUntil
2110 // instead of PT.consumeClose() to avoid emitting extra diagnostics for
2111 // the unmatched l_paren.
2113 SkipUntil(tok::r_paren
, StopAtSemi
);
2118 Expr
*Fn
= LHS
.get();
2119 SourceLocation RParLoc
= Tok
.getLocation();
2120 LHS
= Actions
.ActOnCallExpr(getCurScope(), Fn
, Loc
, ArgExprs
, RParLoc
,
2122 if (LHS
.isInvalid()) {
2123 ArgExprs
.insert(ArgExprs
.begin(), Fn
);
2125 Actions
.CreateRecoveryExpr(Fn
->getBeginLoc(), RParLoc
, ArgExprs
);
2134 // postfix-expression: p-e '->' template[opt] id-expression
2135 // postfix-expression: p-e '.' template[opt] id-expression
2136 tok::TokenKind OpKind
= Tok
.getKind();
2137 SourceLocation OpLoc
= ConsumeToken(); // Eat the "." or "->" token.
2140 ParsedType ObjectType
;
2141 bool MayBePseudoDestructor
= false;
2142 Expr
* OrigLHS
= !LHS
.isInvalid() ? LHS
.get() : nullptr;
2144 PreferredType
.enterMemAccess(Actions
, Tok
.getLocation(), OrigLHS
);
2146 if (getLangOpts().CPlusPlus
&& !LHS
.isInvalid()) {
2147 Expr
*Base
= OrigLHS
;
2148 const Type
* BaseType
= Base
->getType().getTypePtrOrNull();
2149 if (BaseType
&& Tok
.is(tok::l_paren
) &&
2150 (BaseType
->isFunctionType() ||
2151 BaseType
->isSpecificPlaceholderType(BuiltinType::BoundMember
))) {
2152 Diag(OpLoc
, diag::err_function_is_not_record
)
2153 << OpKind
<< Base
->getSourceRange()
2154 << FixItHint::CreateRemoval(OpLoc
);
2155 return ParsePostfixExpressionSuffix(Base
);
2158 LHS
= Actions
.ActOnStartCXXMemberReference(getCurScope(), Base
, OpLoc
,
2160 MayBePseudoDestructor
);
2161 if (LHS
.isInvalid()) {
2162 // Clang will try to perform expression based completion as a
2163 // fallback, which is confusing in case of member references. So we
2164 // stop here without any completions.
2165 if (Tok
.is(tok::code_completion
)) {
2171 ParseOptionalCXXScopeSpecifier(
2172 SS
, ObjectType
, LHS
.get() && LHS
.get()->containsErrors(),
2173 /*EnteringContext=*/false, &MayBePseudoDestructor
);
2174 if (SS
.isNotEmpty())
2175 ObjectType
= nullptr;
2178 if (Tok
.is(tok::code_completion
)) {
2179 tok::TokenKind CorrectedOpKind
=
2180 OpKind
== tok::arrow
? tok::period
: tok::arrow
;
2181 ExprResult
CorrectedLHS(/*Invalid=*/true);
2182 if (getLangOpts().CPlusPlus
&& OrigLHS
) {
2183 // FIXME: Creating a TentativeAnalysisScope from outside Sema is a
2185 Sema::TentativeAnalysisScope
Trap(Actions
);
2186 CorrectedLHS
= Actions
.ActOnStartCXXMemberReference(
2187 getCurScope(), OrigLHS
, OpLoc
, CorrectedOpKind
, ObjectType
,
2188 MayBePseudoDestructor
);
2191 Expr
*Base
= LHS
.get();
2192 Expr
*CorrectedBase
= CorrectedLHS
.get();
2193 if (!CorrectedBase
&& !getLangOpts().CPlusPlus
)
2194 CorrectedBase
= Base
;
2196 // Code completion for a member access expression.
2198 Actions
.CodeCompleteMemberReferenceExpr(
2199 getCurScope(), Base
, CorrectedBase
, OpLoc
, OpKind
== tok::arrow
,
2200 Base
&& ExprStatementTokLoc
== Base
->getBeginLoc(),
2201 PreferredType
.get(Tok
.getLocation()));
2206 if (MayBePseudoDestructor
&& !LHS
.isInvalid()) {
2207 LHS
= ParseCXXPseudoDestructor(LHS
.get(), OpLoc
, OpKind
, SS
,
2212 // Either the action has told us that this cannot be a
2213 // pseudo-destructor expression (based on the type of base
2214 // expression), or we didn't see a '~' in the right place. We
2215 // can still parse a destructor name here, but in that case it
2216 // names a real destructor.
2217 // Allow explicit constructor calls in Microsoft mode.
2218 // FIXME: Add support for explicit call of template constructor.
2219 SourceLocation TemplateKWLoc
;
2221 if (getLangOpts().ObjC
&& OpKind
== tok::period
&&
2222 Tok
.is(tok::kw_class
)) {
2224 // After a '.' in a member access expression, treat the keyword
2225 // 'class' as if it were an identifier.
2227 // This hack allows property access to the 'class' method because it is
2228 // such a common method name. For other C++ keywords that are
2229 // Objective-C method names, one must use the message send syntax.
2230 IdentifierInfo
*Id
= Tok
.getIdentifierInfo();
2231 SourceLocation Loc
= ConsumeToken();
2232 Name
.setIdentifier(Id
, Loc
);
2233 } else if (ParseUnqualifiedId(
2234 SS
, ObjectType
, LHS
.get() && LHS
.get()->containsErrors(),
2235 /*EnteringContext=*/false,
2236 /*AllowDestructorName=*/true,
2237 /*AllowConstructorName=*/
2238 getLangOpts().MicrosoftExt
&& SS
.isNotEmpty(),
2239 /*AllowDeductionGuide=*/false, &TemplateKWLoc
, Name
)) {
2240 (void)Actions
.CorrectDelayedTyposInExpr(LHS
);
2244 if (!LHS
.isInvalid())
2245 LHS
= Actions
.ActOnMemberAccessExpr(getCurScope(), LHS
.get(), OpLoc
,
2246 OpKind
, SS
, TemplateKWLoc
, Name
,
2247 CurParsedObjCImpl
? CurParsedObjCImpl
->Dcl
2249 if (!LHS
.isInvalid()) {
2250 if (Tok
.is(tok::less
))
2251 checkPotentialAngleBracket(LHS
);
2252 } else if (OrigLHS
&& Name
.isValid()) {
2253 // Preserve the LHS if the RHS is an invalid member.
2254 LHS
= Actions
.CreateRecoveryExpr(OrigLHS
->getBeginLoc(),
2255 Name
.getEndLoc(), {OrigLHS
});
2259 case tok::plusplus
: // postfix-expression: postfix-expression '++'
2260 case tok::minusminus
: // postfix-expression: postfix-expression '--'
2261 if (!LHS
.isInvalid()) {
2262 Expr
*Arg
= LHS
.get();
2263 LHS
= Actions
.ActOnPostfixUnaryOp(getCurScope(), Tok
.getLocation(),
2264 Tok
.getKind(), Arg
);
2265 if (LHS
.isInvalid())
2266 LHS
= Actions
.CreateRecoveryExpr(Arg
->getBeginLoc(),
2267 Tok
.getLocation(), Arg
);
2275 /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/
2276 /// vec_step and we are at the start of an expression or a parenthesized
2277 /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the
2278 /// expression (isCastExpr == false) or the type (isCastExpr == true).
2281 /// unary-expression: [C99 6.5.3]
2282 /// 'sizeof' unary-expression
2283 /// 'sizeof' '(' type-name ')'
2284 /// [GNU] '__alignof' unary-expression
2285 /// [GNU] '__alignof' '(' type-name ')'
2286 /// [C11] '_Alignof' '(' type-name ')'
2287 /// [C++0x] 'alignof' '(' type-id ')'
2289 /// [GNU] typeof-specifier:
2290 /// typeof ( expressions )
2291 /// typeof ( type-name )
2292 /// [GNU/C++] typeof unary-expression
2293 /// [C2x] typeof-specifier:
2294 /// typeof '(' typeof-specifier-argument ')'
2295 /// typeof_unqual '(' typeof-specifier-argument ')'
2297 /// typeof-specifier-argument:
2301 /// [OpenCL 1.1 6.11.12] vec_step built-in function:
2302 /// vec_step ( expressions )
2303 /// vec_step ( type-name )
2306 Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token
&OpTok
,
2309 SourceRange
&CastRange
) {
2311 assert(OpTok
.isOneOf(tok::kw_typeof
, tok::kw_typeof_unqual
, tok::kw_sizeof
,
2312 tok::kw___alignof
, tok::kw_alignof
, tok::kw__Alignof
,
2314 tok::kw___builtin_omp_required_simd_align
) &&
2315 "Not a typeof/sizeof/alignof/vec_step expression!");
2319 // If the operand doesn't start with an '(', it must be an expression.
2320 if (Tok
.isNot(tok::l_paren
)) {
2321 // If construct allows a form without parenthesis, user may forget to put
2322 // pathenthesis around type name.
2323 if (OpTok
.isOneOf(tok::kw_sizeof
, tok::kw___alignof
, tok::kw_alignof
,
2324 tok::kw__Alignof
)) {
2325 if (isTypeIdUnambiguously()) {
2326 DeclSpec
DS(AttrFactory
);
2327 ParseSpecifierQualifierList(DS
);
2328 Declarator
DeclaratorInfo(DS
, ParsedAttributesView::none(),
2329 DeclaratorContext::TypeName
);
2330 ParseDeclarator(DeclaratorInfo
);
2332 SourceLocation LParenLoc
= PP
.getLocForEndOfToken(OpTok
.getLocation());
2333 SourceLocation RParenLoc
= PP
.getLocForEndOfToken(PrevTokLocation
);
2334 if (LParenLoc
.isInvalid() || RParenLoc
.isInvalid()) {
2335 Diag(OpTok
.getLocation(),
2336 diag::err_expected_parentheses_around_typename
)
2339 Diag(LParenLoc
, diag::err_expected_parentheses_around_typename
)
2340 << OpTok
.getName() << FixItHint::CreateInsertion(LParenLoc
, "(")
2341 << FixItHint::CreateInsertion(RParenLoc
, ")");
2349 if (OpTok
.isOneOf(tok::kw_typeof
, tok::kw_typeof_unqual
) &&
2350 !getLangOpts().CPlusPlus
) {
2351 Diag(Tok
, diag::err_expected_after
) << OpTok
.getIdentifierInfo()
2356 Operand
= ParseCastExpression(UnaryExprOnly
);
2358 // If it starts with a '(', we know that it is either a parenthesized
2359 // type-name, or it is a unary-expression that starts with a compound
2360 // literal, or starts with a primary-expression that is a parenthesized
2362 ParenParseOption ExprType
= CastExpr
;
2363 SourceLocation LParenLoc
= Tok
.getLocation(), RParenLoc
;
2365 Operand
= ParseParenExpression(ExprType
, true/*stopIfCastExpr*/,
2366 false, CastTy
, RParenLoc
);
2367 CastRange
= SourceRange(LParenLoc
, RParenLoc
);
2369 // If ParseParenExpression parsed a '(typename)' sequence only, then this is
2371 if (ExprType
== CastExpr
) {
2376 if (getLangOpts().CPlusPlus
||
2377 !OpTok
.isOneOf(tok::kw_typeof
, tok::kw_typeof_unqual
)) {
2378 // GNU typeof in C requires the expression to be parenthesized. Not so for
2379 // sizeof/alignof or in C++. Therefore, the parenthesized expression is
2380 // the start of a unary-expression, but doesn't include any postfix
2381 // pieces. Parse these now if present.
2382 if (!Operand
.isInvalid())
2383 Operand
= ParsePostfixExpressionSuffix(Operand
.get());
2387 // If we get here, the operand to the typeof/sizeof/alignof was an expression.
2392 /// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as
2394 ExprResult
Parser::ParseSYCLUniqueStableNameExpression() {
2395 assert(Tok
.is(tok::kw___builtin_sycl_unique_stable_name
) &&
2396 "Not __builtin_sycl_unique_stable_name");
2398 SourceLocation OpLoc
= ConsumeToken();
2399 BalancedDelimiterTracker
T(*this, tok::l_paren
);
2401 // __builtin_sycl_unique_stable_name expressions are always parenthesized.
2402 if (T
.expectAndConsume(diag::err_expected_lparen_after
,
2403 "__builtin_sycl_unique_stable_name"))
2406 TypeResult Ty
= ParseTypeName();
2408 if (Ty
.isInvalid()) {
2413 if (T
.consumeClose())
2416 return Actions
.ActOnSYCLUniqueStableNameExpr(OpLoc
, T
.getOpenLocation(),
2417 T
.getCloseLocation(), Ty
.get());
2420 /// Parse a sizeof or alignof expression.
2423 /// unary-expression: [C99 6.5.3]
2424 /// 'sizeof' unary-expression
2425 /// 'sizeof' '(' type-name ')'
2426 /// [C++11] 'sizeof' '...' '(' identifier ')'
2427 /// [GNU] '__alignof' unary-expression
2428 /// [GNU] '__alignof' '(' type-name ')'
2429 /// [C11] '_Alignof' '(' type-name ')'
2430 /// [C++11] 'alignof' '(' type-id ')'
2432 ExprResult
Parser::ParseUnaryExprOrTypeTraitExpression() {
2433 assert(Tok
.isOneOf(tok::kw_sizeof
, tok::kw___alignof
, tok::kw_alignof
,
2434 tok::kw__Alignof
, tok::kw_vec_step
,
2435 tok::kw___builtin_omp_required_simd_align
) &&
2436 "Not a sizeof/alignof/vec_step expression!");
2440 // [C++11] 'sizeof' '...' '(' identifier ')'
2441 if (Tok
.is(tok::ellipsis
) && OpTok
.is(tok::kw_sizeof
)) {
2442 SourceLocation EllipsisLoc
= ConsumeToken();
2443 SourceLocation LParenLoc
, RParenLoc
;
2444 IdentifierInfo
*Name
= nullptr;
2445 SourceLocation NameLoc
;
2446 if (Tok
.is(tok::l_paren
)) {
2447 BalancedDelimiterTracker
T(*this, tok::l_paren
);
2449 LParenLoc
= T
.getOpenLocation();
2450 if (Tok
.is(tok::identifier
)) {
2451 Name
= Tok
.getIdentifierInfo();
2452 NameLoc
= ConsumeToken();
2454 RParenLoc
= T
.getCloseLocation();
2455 if (RParenLoc
.isInvalid())
2456 RParenLoc
= PP
.getLocForEndOfToken(NameLoc
);
2458 Diag(Tok
, diag::err_expected_parameter_pack
);
2459 SkipUntil(tok::r_paren
, StopAtSemi
);
2461 } else if (Tok
.is(tok::identifier
)) {
2462 Name
= Tok
.getIdentifierInfo();
2463 NameLoc
= ConsumeToken();
2464 LParenLoc
= PP
.getLocForEndOfToken(EllipsisLoc
);
2465 RParenLoc
= PP
.getLocForEndOfToken(NameLoc
);
2466 Diag(LParenLoc
, diag::err_paren_sizeof_parameter_pack
)
2468 << FixItHint::CreateInsertion(LParenLoc
, "(")
2469 << FixItHint::CreateInsertion(RParenLoc
, ")");
2471 Diag(Tok
, diag::err_sizeof_parameter_pack
);
2477 EnterExpressionEvaluationContext
Unevaluated(
2478 Actions
, Sema::ExpressionEvaluationContext::Unevaluated
,
2479 Sema::ReuseLambdaContextDecl
);
2481 return Actions
.ActOnSizeofParameterPackExpr(getCurScope(),
2482 OpTok
.getLocation(),
2487 if (OpTok
.isOneOf(tok::kw_alignof
, tok::kw__Alignof
))
2488 Diag(OpTok
, diag::warn_cxx98_compat_alignof
);
2490 EnterExpressionEvaluationContext
Unevaluated(
2491 Actions
, Sema::ExpressionEvaluationContext::Unevaluated
,
2492 Sema::ReuseLambdaContextDecl
);
2496 SourceRange CastRange
;
2497 ExprResult Operand
= ParseExprAfterUnaryExprOrTypeTrait(OpTok
,
2502 UnaryExprOrTypeTrait ExprKind
= UETT_SizeOf
;
2503 if (OpTok
.isOneOf(tok::kw_alignof
, tok::kw__Alignof
))
2504 ExprKind
= UETT_AlignOf
;
2505 else if (OpTok
.is(tok::kw___alignof
))
2506 ExprKind
= UETT_PreferredAlignOf
;
2507 else if (OpTok
.is(tok::kw_vec_step
))
2508 ExprKind
= UETT_VecStep
;
2509 else if (OpTok
.is(tok::kw___builtin_omp_required_simd_align
))
2510 ExprKind
= UETT_OpenMPRequiredSimdAlign
;
2513 return Actions
.ActOnUnaryExprOrTypeTraitExpr(OpTok
.getLocation(),
2516 CastTy
.getAsOpaquePtr(),
2519 if (OpTok
.isOneOf(tok::kw_alignof
, tok::kw__Alignof
))
2520 Diag(OpTok
, diag::ext_alignof_expr
) << OpTok
.getIdentifierInfo();
2522 // If we get here, the operand to the sizeof/alignof was an expression.
2523 if (!Operand
.isInvalid())
2524 Operand
= Actions
.ActOnUnaryExprOrTypeTraitExpr(OpTok
.getLocation(),
2532 /// ParseBuiltinPrimaryExpression
2535 /// primary-expression: [C99 6.5.1]
2536 /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
2537 /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
2538 /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
2540 /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
2541 /// [GNU] '__builtin_FILE' '(' ')'
2542 /// [GNU] '__builtin_FUNCTION' '(' ')'
2543 /// [GNU] '__builtin_LINE' '(' ')'
2544 /// [CLANG] '__builtin_COLUMN' '(' ')'
2545 /// [GNU] '__builtin_source_location' '(' ')'
2546 /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')'
2548 /// [GNU] offsetof-member-designator:
2549 /// [GNU] identifier
2550 /// [GNU] offsetof-member-designator '.' identifier
2551 /// [GNU] offsetof-member-designator '[' expression ']'
2553 ExprResult
Parser::ParseBuiltinPrimaryExpression() {
2555 const IdentifierInfo
*BuiltinII
= Tok
.getIdentifierInfo();
2557 tok::TokenKind T
= Tok
.getKind();
2558 SourceLocation StartLoc
= ConsumeToken(); // Eat the builtin identifier.
2560 // All of these start with an open paren.
2561 if (Tok
.isNot(tok::l_paren
))
2562 return ExprError(Diag(Tok
, diag::err_expected_after
) << BuiltinII
2565 BalancedDelimiterTracker
PT(*this, tok::l_paren
);
2571 default: llvm_unreachable("Not a builtin primary expression!");
2572 case tok::kw___builtin_va_arg
: {
2573 ExprResult
Expr(ParseAssignmentExpression());
2575 if (ExpectAndConsume(tok::comma
)) {
2576 SkipUntil(tok::r_paren
, StopAtSemi
);
2580 TypeResult Ty
= ParseTypeName();
2582 if (Tok
.isNot(tok::r_paren
)) {
2583 Diag(Tok
, diag::err_expected
) << tok::r_paren
;
2587 if (Expr
.isInvalid() || Ty
.isInvalid())
2590 Res
= Actions
.ActOnVAArg(StartLoc
, Expr
.get(), Ty
.get(), ConsumeParen());
2593 case tok::kw___builtin_offsetof
: {
2594 SourceLocation TypeLoc
= Tok
.getLocation();
2595 auto OOK
= Sema::OffsetOfKind::OOK_Builtin
;
2596 if (Tok
.getLocation().isMacroID()) {
2597 StringRef MacroName
= Lexer::getImmediateMacroNameForDiagnostics(
2598 Tok
.getLocation(), PP
.getSourceManager(), getLangOpts());
2599 if (MacroName
== "offsetof")
2600 OOK
= Sema::OffsetOfKind::OOK_Macro
;
2604 OffsetOfStateRAIIObject
InOffsetof(*this, OOK
);
2605 Ty
= ParseTypeName();
2606 if (Ty
.isInvalid()) {
2607 SkipUntil(tok::r_paren
, StopAtSemi
);
2612 if (ExpectAndConsume(tok::comma
)) {
2613 SkipUntil(tok::r_paren
, StopAtSemi
);
2617 // We must have at least one identifier here.
2618 if (Tok
.isNot(tok::identifier
)) {
2619 Diag(Tok
, diag::err_expected
) << tok::identifier
;
2620 SkipUntil(tok::r_paren
, StopAtSemi
);
2624 // Keep track of the various subcomponents we see.
2625 SmallVector
<Sema::OffsetOfComponent
, 4> Comps
;
2627 Comps
.push_back(Sema::OffsetOfComponent());
2628 Comps
.back().isBrackets
= false;
2629 Comps
.back().U
.IdentInfo
= Tok
.getIdentifierInfo();
2630 Comps
.back().LocStart
= Comps
.back().LocEnd
= ConsumeToken();
2632 // FIXME: This loop leaks the index expressions on error.
2634 if (Tok
.is(tok::period
)) {
2635 // offsetof-member-designator: offsetof-member-designator '.' identifier
2636 Comps
.push_back(Sema::OffsetOfComponent());
2637 Comps
.back().isBrackets
= false;
2638 Comps
.back().LocStart
= ConsumeToken();
2640 if (Tok
.isNot(tok::identifier
)) {
2641 Diag(Tok
, diag::err_expected
) << tok::identifier
;
2642 SkipUntil(tok::r_paren
, StopAtSemi
);
2645 Comps
.back().U
.IdentInfo
= Tok
.getIdentifierInfo();
2646 Comps
.back().LocEnd
= ConsumeToken();
2647 } else if (Tok
.is(tok::l_square
)) {
2648 if (CheckProhibitedCXX11Attribute())
2651 // offsetof-member-designator: offsetof-member-design '[' expression ']'
2652 Comps
.push_back(Sema::OffsetOfComponent());
2653 Comps
.back().isBrackets
= true;
2654 BalancedDelimiterTracker
ST(*this, tok::l_square
);
2656 Comps
.back().LocStart
= ST
.getOpenLocation();
2657 Res
= ParseExpression();
2658 if (Res
.isInvalid()) {
2659 SkipUntil(tok::r_paren
, StopAtSemi
);
2662 Comps
.back().U
.E
= Res
.get();
2665 Comps
.back().LocEnd
= ST
.getCloseLocation();
2667 if (Tok
.isNot(tok::r_paren
)) {
2670 } else if (Ty
.isInvalid()) {
2674 Res
= Actions
.ActOnBuiltinOffsetOf(getCurScope(), StartLoc
, TypeLoc
,
2676 PT
.getCloseLocation());
2683 case tok::kw___builtin_choose_expr
: {
2684 ExprResult
Cond(ParseAssignmentExpression());
2685 if (Cond
.isInvalid()) {
2686 SkipUntil(tok::r_paren
, StopAtSemi
);
2689 if (ExpectAndConsume(tok::comma
)) {
2690 SkipUntil(tok::r_paren
, StopAtSemi
);
2694 ExprResult
Expr1(ParseAssignmentExpression());
2695 if (Expr1
.isInvalid()) {
2696 SkipUntil(tok::r_paren
, StopAtSemi
);
2699 if (ExpectAndConsume(tok::comma
)) {
2700 SkipUntil(tok::r_paren
, StopAtSemi
);
2704 ExprResult
Expr2(ParseAssignmentExpression());
2705 if (Expr2
.isInvalid()) {
2706 SkipUntil(tok::r_paren
, StopAtSemi
);
2709 if (Tok
.isNot(tok::r_paren
)) {
2710 Diag(Tok
, diag::err_expected
) << tok::r_paren
;
2713 Res
= Actions
.ActOnChooseExpr(StartLoc
, Cond
.get(), Expr1
.get(),
2714 Expr2
.get(), ConsumeParen());
2717 case tok::kw___builtin_astype
: {
2718 // The first argument is an expression to be converted, followed by a comma.
2719 ExprResult
Expr(ParseAssignmentExpression());
2720 if (Expr
.isInvalid()) {
2721 SkipUntil(tok::r_paren
, StopAtSemi
);
2725 if (ExpectAndConsume(tok::comma
)) {
2726 SkipUntil(tok::r_paren
, StopAtSemi
);
2730 // Second argument is the type to bitcast to.
2731 TypeResult DestTy
= ParseTypeName();
2732 if (DestTy
.isInvalid())
2735 // Attempt to consume the r-paren.
2736 if (Tok
.isNot(tok::r_paren
)) {
2737 Diag(Tok
, diag::err_expected
) << tok::r_paren
;
2738 SkipUntil(tok::r_paren
, StopAtSemi
);
2742 Res
= Actions
.ActOnAsTypeExpr(Expr
.get(), DestTy
.get(), StartLoc
,
2746 case tok::kw___builtin_convertvector
: {
2747 // The first argument is an expression to be converted, followed by a comma.
2748 ExprResult
Expr(ParseAssignmentExpression());
2749 if (Expr
.isInvalid()) {
2750 SkipUntil(tok::r_paren
, StopAtSemi
);
2754 if (ExpectAndConsume(tok::comma
)) {
2755 SkipUntil(tok::r_paren
, StopAtSemi
);
2759 // Second argument is the type to bitcast to.
2760 TypeResult DestTy
= ParseTypeName();
2761 if (DestTy
.isInvalid())
2764 // Attempt to consume the r-paren.
2765 if (Tok
.isNot(tok::r_paren
)) {
2766 Diag(Tok
, diag::err_expected
) << tok::r_paren
;
2767 SkipUntil(tok::r_paren
, StopAtSemi
);
2771 Res
= Actions
.ActOnConvertVectorExpr(Expr
.get(), DestTy
.get(), StartLoc
,
2775 case tok::kw___builtin_COLUMN
:
2776 case tok::kw___builtin_FILE
:
2777 case tok::kw___builtin_FUNCTION
:
2778 case tok::kw___builtin_LINE
:
2779 case tok::kw___builtin_source_location
: {
2780 // Attempt to consume the r-paren.
2781 if (Tok
.isNot(tok::r_paren
)) {
2782 Diag(Tok
, diag::err_expected
) << tok::r_paren
;
2783 SkipUntil(tok::r_paren
, StopAtSemi
);
2786 SourceLocExpr::IdentKind Kind
= [&] {
2788 case tok::kw___builtin_FILE
:
2789 return SourceLocExpr::File
;
2790 case tok::kw___builtin_FUNCTION
:
2791 return SourceLocExpr::Function
;
2792 case tok::kw___builtin_LINE
:
2793 return SourceLocExpr::Line
;
2794 case tok::kw___builtin_COLUMN
:
2795 return SourceLocExpr::Column
;
2796 case tok::kw___builtin_source_location
:
2797 return SourceLocExpr::SourceLocStruct
;
2799 llvm_unreachable("invalid keyword");
2802 Res
= Actions
.ActOnSourceLocExpr(Kind
, StartLoc
, ConsumeParen());
2807 if (Res
.isInvalid())
2810 // These can be followed by postfix-expr pieces because they are
2811 // primary-expressions.
2812 return ParsePostfixExpressionSuffix(Res
.get());
2815 bool Parser::tryParseOpenMPArrayShapingCastPart() {
2816 assert(Tok
.is(tok::l_square
) && "Expected open bracket");
2817 bool ErrorFound
= true;
2818 TentativeParsingAction
TPA(*this);
2820 if (Tok
.isNot(tok::l_square
))
2824 // Skip inner expression.
2825 while (!SkipUntil(tok::r_square
, tok::annot_pragma_openmp_end
,
2826 StopAtSemi
| StopBeforeMatch
))
2828 if (Tok
.isNot(tok::r_square
))
2832 // Found ')' - done.
2833 if (Tok
.is(tok::r_paren
)) {
2837 } while (Tok
.isNot(tok::annot_pragma_openmp_end
));
2842 /// ParseParenExpression - This parses the unit that starts with a '(' token,
2843 /// based on what is allowed by ExprType. The actual thing parsed is returned
2844 /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
2845 /// not the parsed cast-expression.
2848 /// primary-expression: [C99 6.5.1]
2849 /// '(' expression ')'
2850 /// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
2851 /// postfix-expression: [C99 6.5.2]
2852 /// '(' type-name ')' '{' initializer-list '}'
2853 /// '(' type-name ')' '{' initializer-list ',' '}'
2854 /// cast-expression: [C99 6.5.4]
2855 /// '(' type-name ')' cast-expression
2856 /// [ARC] bridged-cast-expression
2857 /// [ARC] bridged-cast-expression:
2858 /// (__bridge type-name) cast-expression
2859 /// (__bridge_transfer type-name) cast-expression
2860 /// (__bridge_retained type-name) cast-expression
2861 /// fold-expression: [C++1z]
2862 /// '(' cast-expression fold-operator '...' ')'
2863 /// '(' '...' fold-operator cast-expression ')'
2864 /// '(' cast-expression fold-operator '...'
2865 /// fold-operator cast-expression ')'
2866 /// [OPENMP] Array shaping operation
2867 /// '(' '[' expression ']' { '[' expression ']' } cast-expression
2870 Parser::ParseParenExpression(ParenParseOption
&ExprType
, bool stopIfCastExpr
,
2871 bool isTypeCast
, ParsedType
&CastTy
,
2872 SourceLocation
&RParenLoc
) {
2873 assert(Tok
.is(tok::l_paren
) && "Not a paren expr!");
2874 ColonProtectionRAIIObject
ColonProtection(*this, false);
2875 BalancedDelimiterTracker
T(*this, tok::l_paren
);
2876 if (T
.consumeOpen())
2878 SourceLocation OpenLoc
= T
.getOpenLocation();
2880 PreferredType
.enterParenExpr(Tok
.getLocation(), OpenLoc
);
2882 ExprResult
Result(true);
2883 bool isAmbiguousTypeId
;
2886 if (Tok
.is(tok::code_completion
)) {
2888 Actions
.CodeCompleteExpression(
2889 getCurScope(), PreferredType
.get(Tok
.getLocation()),
2890 /*IsParenthesized=*/ExprType
>= CompoundLiteral
);
2894 // Diagnose use of bridge casts in non-arc mode.
2895 bool BridgeCast
= (getLangOpts().ObjC
&&
2896 Tok
.isOneOf(tok::kw___bridge
,
2897 tok::kw___bridge_transfer
,
2898 tok::kw___bridge_retained
,
2899 tok::kw___bridge_retain
));
2900 if (BridgeCast
&& !getLangOpts().ObjCAutoRefCount
) {
2901 if (!TryConsumeToken(tok::kw___bridge
)) {
2902 StringRef BridgeCastName
= Tok
.getName();
2903 SourceLocation BridgeKeywordLoc
= ConsumeToken();
2904 if (!PP
.getSourceManager().isInSystemHeader(BridgeKeywordLoc
))
2905 Diag(BridgeKeywordLoc
, diag::warn_arc_bridge_cast_nonarc
)
2907 << FixItHint::CreateReplacement(BridgeKeywordLoc
, "");
2912 // None of these cases should fall through with an invalid Result
2913 // unless they've already reported an error.
2914 if (ExprType
>= CompoundStmt
&& Tok
.is(tok::l_brace
)) {
2915 Diag(Tok
, OpenLoc
.isMacroID() ? diag::ext_gnu_statement_expr_macro
2916 : diag::ext_gnu_statement_expr
);
2918 checkCompoundToken(OpenLoc
, tok::l_paren
, CompoundToken::StmtExprBegin
);
2920 if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
2921 Result
= ExprError(Diag(OpenLoc
, diag::err_stmtexpr_file_scope
));
2923 // Find the nearest non-record decl context. Variables declared in a
2924 // statement expression behave as if they were declared in the enclosing
2925 // function, block, or other code construct.
2926 DeclContext
*CodeDC
= Actions
.CurContext
;
2927 while (CodeDC
->isRecord() || isa
<EnumDecl
>(CodeDC
)) {
2928 CodeDC
= CodeDC
->getParent();
2929 assert(CodeDC
&& !CodeDC
->isFileContext() &&
2930 "statement expr not in code context");
2932 Sema::ContextRAII
SavedContext(Actions
, CodeDC
, /*NewThisContext=*/false);
2934 Actions
.ActOnStartStmtExpr();
2936 StmtResult
Stmt(ParseCompoundStatement(true));
2937 ExprType
= CompoundStmt
;
2939 // If the substmt parsed correctly, build the AST node.
2940 if (!Stmt
.isInvalid()) {
2941 Result
= Actions
.ActOnStmtExpr(getCurScope(), OpenLoc
, Stmt
.get(),
2944 Actions
.ActOnStmtExprError();
2947 } else if (ExprType
>= CompoundLiteral
&& BridgeCast
) {
2948 tok::TokenKind tokenKind
= Tok
.getKind();
2949 SourceLocation BridgeKeywordLoc
= ConsumeToken();
2951 // Parse an Objective-C ARC ownership cast expression.
2952 ObjCBridgeCastKind Kind
;
2953 if (tokenKind
== tok::kw___bridge
)
2955 else if (tokenKind
== tok::kw___bridge_transfer
)
2956 Kind
= OBC_BridgeTransfer
;
2957 else if (tokenKind
== tok::kw___bridge_retained
)
2958 Kind
= OBC_BridgeRetained
;
2960 // As a hopefully temporary workaround, allow __bridge_retain as
2961 // a synonym for __bridge_retained, but only in system headers.
2962 assert(tokenKind
== tok::kw___bridge_retain
);
2963 Kind
= OBC_BridgeRetained
;
2964 if (!PP
.getSourceManager().isInSystemHeader(BridgeKeywordLoc
))
2965 Diag(BridgeKeywordLoc
, diag::err_arc_bridge_retain
)
2966 << FixItHint::CreateReplacement(BridgeKeywordLoc
,
2967 "__bridge_retained");
2970 TypeResult Ty
= ParseTypeName();
2972 ColonProtection
.restore();
2973 RParenLoc
= T
.getCloseLocation();
2975 PreferredType
.enterTypeCast(Tok
.getLocation(), Ty
.get().get());
2976 ExprResult SubExpr
= ParseCastExpression(AnyCastExpr
);
2978 if (Ty
.isInvalid() || SubExpr
.isInvalid())
2981 return Actions
.ActOnObjCBridgedCast(getCurScope(), OpenLoc
, Kind
,
2982 BridgeKeywordLoc
, Ty
.get(),
2983 RParenLoc
, SubExpr
.get());
2984 } else if (ExprType
>= CompoundLiteral
&&
2985 isTypeIdInParens(isAmbiguousTypeId
)) {
2987 // Otherwise, this is a compound literal expression or cast expression.
2989 // In C++, if the type-id is ambiguous we disambiguate based on context.
2990 // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
2991 // in which case we should treat it as type-id.
2992 // if stopIfCastExpr is false, we need to determine the context past the
2993 // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
2994 if (isAmbiguousTypeId
&& !stopIfCastExpr
) {
2995 ExprResult res
= ParseCXXAmbiguousParenExpression(ExprType
, CastTy
, T
,
2997 RParenLoc
= T
.getCloseLocation();
3001 // Parse the type declarator.
3002 DeclSpec
DS(AttrFactory
);
3003 ParseSpecifierQualifierList(DS
);
3004 Declarator
DeclaratorInfo(DS
, ParsedAttributesView::none(),
3005 DeclaratorContext::TypeName
);
3006 ParseDeclarator(DeclaratorInfo
);
3008 // If our type is followed by an identifier and either ':' or ']', then
3009 // this is probably an Objective-C message send where the leading '[' is
3010 // missing. Recover as if that were the case.
3011 if (!DeclaratorInfo
.isInvalidType() && Tok
.is(tok::identifier
) &&
3012 !InMessageExpression
&& getLangOpts().ObjC
&&
3013 (NextToken().is(tok::colon
) || NextToken().is(tok::r_square
))) {
3016 InMessageExpressionRAIIObject
InMessage(*this, false);
3017 Ty
= Actions
.ActOnTypeName(getCurScope(), DeclaratorInfo
);
3019 Result
= ParseObjCMessageExpressionBody(SourceLocation(),
3025 ColonProtection
.restore();
3026 RParenLoc
= T
.getCloseLocation();
3027 if (Tok
.is(tok::l_brace
)) {
3028 ExprType
= CompoundLiteral
;
3031 InMessageExpressionRAIIObject
InMessage(*this, false);
3032 Ty
= Actions
.ActOnTypeName(getCurScope(), DeclaratorInfo
);
3034 return ParseCompoundLiteralExpression(Ty
.get(), OpenLoc
, RParenLoc
);
3037 if (Tok
.is(tok::l_paren
)) {
3038 // This could be OpenCL vector Literals
3039 if (getLangOpts().OpenCL
)
3043 InMessageExpressionRAIIObject
InMessage(*this, false);
3044 Ty
= Actions
.ActOnTypeName(getCurScope(), DeclaratorInfo
);
3050 QualType QT
= Ty
.get().get().getCanonicalType();
3051 if (QT
->isVectorType())
3053 // We parsed '(' vector-type-name ')' followed by '('
3055 // Parse the cast-expression that follows it next.
3056 // isVectorLiteral = true will make sure we don't parse any
3057 // Postfix expression yet
3058 Result
= ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr
,
3059 /*isAddressOfOperand=*/false,
3060 /*isTypeCast=*/IsTypeCast
,
3061 /*isVectorLiteral=*/true);
3063 if (!Result
.isInvalid()) {
3064 Result
= Actions
.ActOnCastExpr(getCurScope(), OpenLoc
,
3065 DeclaratorInfo
, CastTy
,
3066 RParenLoc
, Result
.get());
3069 // After we performed the cast we can check for postfix-expr pieces.
3070 if (!Result
.isInvalid()) {
3071 Result
= ParsePostfixExpressionSuffix(Result
);
3079 if (ExprType
== CastExpr
) {
3080 // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
3082 if (DeclaratorInfo
.isInvalidType())
3085 // Note that this doesn't parse the subsequent cast-expression, it just
3086 // returns the parsed type to the callee.
3087 if (stopIfCastExpr
) {
3090 InMessageExpressionRAIIObject
InMessage(*this, false);
3091 Ty
= Actions
.ActOnTypeName(getCurScope(), DeclaratorInfo
);
3094 return ExprResult();
3097 // Reject the cast of super idiom in ObjC.
3098 if (Tok
.is(tok::identifier
) && getLangOpts().ObjC
&&
3099 Tok
.getIdentifierInfo() == Ident_super
&&
3100 getCurScope()->isInObjcMethodScope() &&
3101 GetLookAheadToken(1).isNot(tok::period
)) {
3102 Diag(Tok
.getLocation(), diag::err_illegal_super_cast
)
3103 << SourceRange(OpenLoc
, RParenLoc
);
3107 PreferredType
.enterTypeCast(Tok
.getLocation(), CastTy
.get());
3108 // Parse the cast-expression that follows it next.
3109 // TODO: For cast expression with CastTy.
3110 Result
= ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr
,
3111 /*isAddressOfOperand=*/false,
3112 /*isTypeCast=*/IsTypeCast
);
3113 if (!Result
.isInvalid()) {
3114 Result
= Actions
.ActOnCastExpr(getCurScope(), OpenLoc
,
3115 DeclaratorInfo
, CastTy
,
3116 RParenLoc
, Result
.get());
3121 Diag(Tok
, diag::err_expected_lbrace_in_compound_literal
);
3124 } else if (ExprType
>= FoldExpr
&& Tok
.is(tok::ellipsis
) &&
3125 isFoldOperator(NextToken().getKind())) {
3126 ExprType
= FoldExpr
;
3127 return ParseFoldExpression(ExprResult(), T
);
3128 } else if (isTypeCast
) {
3129 // Parse the expression-list.
3130 InMessageExpressionRAIIObject
InMessage(*this, false);
3131 ExprVector ArgExprs
;
3133 if (!ParseSimpleExpressionList(ArgExprs
)) {
3134 // FIXME: If we ever support comma expressions as operands to
3135 // fold-expressions, we'll need to allow multiple ArgExprs here.
3136 if (ExprType
>= FoldExpr
&& ArgExprs
.size() == 1 &&
3137 isFoldOperator(Tok
.getKind()) && NextToken().is(tok::ellipsis
)) {
3138 ExprType
= FoldExpr
;
3139 return ParseFoldExpression(ArgExprs
[0], T
);
3142 ExprType
= SimpleExpr
;
3143 Result
= Actions
.ActOnParenListExpr(OpenLoc
, Tok
.getLocation(),
3146 } else if (getLangOpts().OpenMP
>= 50 && OpenMPDirectiveParsing
&&
3147 ExprType
== CastExpr
&& Tok
.is(tok::l_square
) &&
3148 tryParseOpenMPArrayShapingCastPart()) {
3149 bool ErrorFound
= false;
3150 SmallVector
<Expr
*, 4> OMPDimensions
;
3151 SmallVector
<SourceRange
, 4> OMPBracketsRanges
;
3153 BalancedDelimiterTracker
TS(*this, tok::l_square
);
3155 ExprResult NumElements
=
3156 Actions
.CorrectDelayedTyposInExpr(ParseExpression());
3157 if (!NumElements
.isUsable()) {
3159 while (!SkipUntil(tok::r_square
, tok::r_paren
,
3160 StopAtSemi
| StopBeforeMatch
))
3164 OMPDimensions
.push_back(NumElements
.get());
3165 OMPBracketsRanges
.push_back(TS
.getRange());
3166 } while (Tok
.isNot(tok::r_paren
));
3169 RParenLoc
= T
.getCloseLocation();
3170 Result
= Actions
.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3172 Result
= ExprError();
3173 } else if (!Result
.isInvalid()) {
3174 Result
= Actions
.ActOnOMPArrayShapingExpr(
3175 Result
.get(), OpenLoc
, RParenLoc
, OMPDimensions
, OMPBracketsRanges
);
3179 InMessageExpressionRAIIObject
InMessage(*this, false);
3181 Result
= ParseExpression(MaybeTypeCast
);
3182 if (!getLangOpts().CPlusPlus
&& Result
.isUsable()) {
3183 // Correct typos in non-C++ code earlier so that implicit-cast-like
3184 // expressions are parsed correctly.
3185 Result
= Actions
.CorrectDelayedTyposInExpr(Result
);
3188 if (ExprType
>= FoldExpr
&& isFoldOperator(Tok
.getKind()) &&
3189 NextToken().is(tok::ellipsis
)) {
3190 ExprType
= FoldExpr
;
3191 return ParseFoldExpression(Result
, T
);
3193 ExprType
= SimpleExpr
;
3195 // Don't build a paren expression unless we actually match a ')'.
3196 if (!Result
.isInvalid() && Tok
.is(tok::r_paren
))
3198 Actions
.ActOnParenExpr(OpenLoc
, Tok
.getLocation(), Result
.get());
3202 if (Result
.isInvalid()) {
3203 SkipUntil(tok::r_paren
, StopAtSemi
);
3208 RParenLoc
= T
.getCloseLocation();
3212 /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
3213 /// and we are at the left brace.
3216 /// postfix-expression: [C99 6.5.2]
3217 /// '(' type-name ')' '{' initializer-list '}'
3218 /// '(' type-name ')' '{' initializer-list ',' '}'
3221 Parser::ParseCompoundLiteralExpression(ParsedType Ty
,
3222 SourceLocation LParenLoc
,
3223 SourceLocation RParenLoc
) {
3224 assert(Tok
.is(tok::l_brace
) && "Not a compound literal!");
3225 if (!getLangOpts().C99
) // Compound literals don't exist in C90.
3226 Diag(LParenLoc
, diag::ext_c99_compound_literal
);
3227 PreferredType
.enterTypeCast(Tok
.getLocation(), Ty
.get());
3228 ExprResult Result
= ParseInitializer();
3229 if (!Result
.isInvalid() && Ty
)
3230 return Actions
.ActOnCompoundLiteral(LParenLoc
, Ty
, RParenLoc
, Result
.get());
3234 /// ParseStringLiteralExpression - This handles the various token types that
3235 /// form string literals, and also handles string concatenation [C99 5.1.1.2,
3236 /// translation phase #6].
3239 /// primary-expression: [C99 6.5.1]
3242 ExprResult
Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral
) {
3243 assert(isTokenStringLiteral() && "Not a string literal!");
3245 // String concat. Note that keywords like __func__ and __FUNCTION__ are not
3246 // considered to be strings for concatenation purposes.
3247 SmallVector
<Token
, 4> StringToks
;
3250 StringToks
.push_back(Tok
);
3251 ConsumeStringToken();
3252 } while (isTokenStringLiteral());
3254 // Pass the set of string tokens, ready for concatenation, to the actions.
3255 return Actions
.ActOnStringLiteral(StringToks
,
3256 AllowUserDefinedLiteral
? getCurScope()
3260 /// ParseGenericSelectionExpression - Parse a C11 generic-selection
3264 /// generic-selection:
3265 /// _Generic ( assignment-expression , generic-assoc-list )
3266 /// generic-assoc-list:
3267 /// generic-association
3268 /// generic-assoc-list , generic-association
3269 /// generic-association:
3270 /// type-name : assignment-expression
3271 /// default : assignment-expression
3273 ExprResult
Parser::ParseGenericSelectionExpression() {
3274 assert(Tok
.is(tok::kw__Generic
) && "_Generic keyword expected");
3275 if (!getLangOpts().C11
)
3276 Diag(Tok
, diag::ext_c11_feature
) << Tok
.getName();
3278 SourceLocation KeyLoc
= ConsumeToken();
3279 BalancedDelimiterTracker
T(*this, tok::l_paren
);
3280 if (T
.expectAndConsume())
3283 ExprResult ControllingExpr
;
3285 // C11 6.5.1.1p3 "The controlling expression of a generic selection is
3287 EnterExpressionEvaluationContext
Unevaluated(
3288 Actions
, Sema::ExpressionEvaluationContext::Unevaluated
);
3290 Actions
.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3291 if (ControllingExpr
.isInvalid()) {
3292 SkipUntil(tok::r_paren
, StopAtSemi
);
3297 if (ExpectAndConsume(tok::comma
)) {
3298 SkipUntil(tok::r_paren
, StopAtSemi
);
3302 SourceLocation DefaultLoc
;
3303 SmallVector
<ParsedType
, 12> Types
;
3307 if (Tok
.is(tok::kw_default
)) {
3308 // C11 6.5.1.1p2 "A generic selection shall have no more than one default
3309 // generic association."
3310 if (!DefaultLoc
.isInvalid()) {
3311 Diag(Tok
, diag::err_duplicate_default_assoc
);
3312 Diag(DefaultLoc
, diag::note_previous_default_assoc
);
3313 SkipUntil(tok::r_paren
, StopAtSemi
);
3316 DefaultLoc
= ConsumeToken();
3319 ColonProtectionRAIIObject
X(*this);
3320 TypeResult TR
= ParseTypeName(nullptr, DeclaratorContext::Association
);
3321 if (TR
.isInvalid()) {
3322 SkipUntil(tok::r_paren
, StopAtSemi
);
3327 Types
.push_back(Ty
);
3329 if (ExpectAndConsume(tok::colon
)) {
3330 SkipUntil(tok::r_paren
, StopAtSemi
);
3334 // FIXME: These expressions should be parsed in a potentially potentially
3335 // evaluated context.
3337 Actions
.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
3338 if (ER
.isInvalid()) {
3339 SkipUntil(tok::r_paren
, StopAtSemi
);
3342 Exprs
.push_back(ER
.get());
3343 } while (TryConsumeToken(tok::comma
));
3346 if (T
.getCloseLocation().isInvalid())
3349 return Actions
.ActOnGenericSelectionExpr(KeyLoc
, DefaultLoc
,
3350 T
.getCloseLocation(),
3351 ControllingExpr
.get(),
3355 /// Parse A C++1z fold-expression after the opening paren and optional
3356 /// left-hand-side expression.
3359 /// fold-expression:
3360 /// ( cast-expression fold-operator ... )
3361 /// ( ... fold-operator cast-expression )
3362 /// ( cast-expression fold-operator ... fold-operator cast-expression )
3363 ExprResult
Parser::ParseFoldExpression(ExprResult LHS
,
3364 BalancedDelimiterTracker
&T
) {
3365 if (LHS
.isInvalid()) {
3370 tok::TokenKind Kind
= tok::unknown
;
3371 SourceLocation FirstOpLoc
;
3372 if (LHS
.isUsable()) {
3373 Kind
= Tok
.getKind();
3374 assert(isFoldOperator(Kind
) && "missing fold-operator");
3375 FirstOpLoc
= ConsumeToken();
3378 assert(Tok
.is(tok::ellipsis
) && "not a fold-expression");
3379 SourceLocation EllipsisLoc
= ConsumeToken();
3382 if (Tok
.isNot(tok::r_paren
)) {
3383 if (!isFoldOperator(Tok
.getKind()))
3384 return Diag(Tok
.getLocation(), diag::err_expected_fold_operator
);
3386 if (Kind
!= tok::unknown
&& Tok
.getKind() != Kind
)
3387 Diag(Tok
.getLocation(), diag::err_fold_operator_mismatch
)
3388 << SourceRange(FirstOpLoc
);
3389 Kind
= Tok
.getKind();
3392 RHS
= ParseExpression();
3393 if (RHS
.isInvalid()) {
3399 Diag(EllipsisLoc
, getLangOpts().CPlusPlus17
3400 ? diag::warn_cxx14_compat_fold_expression
3401 : diag::ext_fold_expression
);
3404 return Actions
.ActOnCXXFoldExpr(getCurScope(), T
.getOpenLocation(), LHS
.get(),
3405 Kind
, EllipsisLoc
, RHS
.get(),
3406 T
.getCloseLocation());
3409 /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
3412 /// argument-expression-list:
3413 /// assignment-expression
3414 /// argument-expression-list , assignment-expression
3416 /// [C++] expression-list:
3417 /// [C++] assignment-expression
3418 /// [C++] expression-list , assignment-expression
3420 /// [C++0x] expression-list:
3421 /// [C++0x] initializer-list
3423 /// [C++0x] initializer-list
3424 /// [C++0x] initializer-clause ...[opt]
3425 /// [C++0x] initializer-list , initializer-clause ...[opt]
3427 /// [C++0x] initializer-clause:
3428 /// [C++0x] assignment-expression
3429 /// [C++0x] braced-init-list
3431 bool Parser::ParseExpressionList(SmallVectorImpl
<Expr
*> &Exprs
,
3432 llvm::function_ref
<void()> ExpressionStarts
,
3433 bool FailImmediatelyOnInvalidExpr
,
3434 bool EarlyTypoCorrection
) {
3435 bool SawError
= false;
3437 if (ExpressionStarts
)
3441 if (getLangOpts().CPlusPlus11
&& Tok
.is(tok::l_brace
)) {
3442 Diag(Tok
, diag::warn_cxx98_compat_generalized_initializer_lists
);
3443 Expr
= ParseBraceInitializer();
3445 Expr
= ParseAssignmentExpression();
3447 if (EarlyTypoCorrection
)
3448 Expr
= Actions
.CorrectDelayedTyposInExpr(Expr
);
3450 if (Tok
.is(tok::ellipsis
))
3451 Expr
= Actions
.ActOnPackExpansion(Expr
.get(), ConsumeToken());
3452 else if (Tok
.is(tok::code_completion
)) {
3453 // There's nothing to suggest in here as we parsed a full expression.
3454 // Instead fail and propogate the error since caller might have something
3455 // the suggest, e.g. signature help in function call. Note that this is
3456 // performed before pushing the \p Expr, so that signature help can report
3457 // current argument correctly.
3462 if (Expr
.isInvalid()) {
3464 if (FailImmediatelyOnInvalidExpr
)
3466 SkipUntil(tok::comma
, tok::r_paren
, StopBeforeMatch
);
3468 Exprs
.push_back(Expr
.get());
3471 if (Tok
.isNot(tok::comma
))
3473 // Move to the next argument, remember where the comma was.
3476 checkPotentialAngleBracketDelimiter(Comma
);
3479 // Ensure typos get diagnosed when errors were encountered while parsing the
3481 for (auto &E
: Exprs
) {
3482 ExprResult Expr
= Actions
.CorrectDelayedTyposInExpr(E
);
3483 if (Expr
.isUsable()) E
= Expr
.get();
3489 /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
3490 /// used for misc language extensions.
3493 /// simple-expression-list:
3494 /// assignment-expression
3495 /// simple-expression-list , assignment-expression
3497 bool Parser::ParseSimpleExpressionList(SmallVectorImpl
<Expr
*> &Exprs
) {
3499 ExprResult Expr
= ParseAssignmentExpression();
3500 if (Expr
.isInvalid())
3503 Exprs
.push_back(Expr
.get());
3505 // We might be parsing the LHS of a fold-expression. If we reached the fold
3507 if (Tok
.isNot(tok::comma
) || NextToken().is(tok::ellipsis
))
3510 // Move to the next argument, remember where the comma was.
3513 checkPotentialAngleBracketDelimiter(Comma
);
3517 /// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
3520 /// [clang] block-id:
3521 /// [clang] specifier-qualifier-list block-declarator
3523 void Parser::ParseBlockId(SourceLocation CaretLoc
) {
3524 if (Tok
.is(tok::code_completion
)) {
3526 Actions
.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type
);
3530 // Parse the specifier-qualifier-list piece.
3531 DeclSpec
DS(AttrFactory
);
3532 ParseSpecifierQualifierList(DS
);
3534 // Parse the block-declarator.
3535 Declarator
DeclaratorInfo(DS
, ParsedAttributesView::none(),
3536 DeclaratorContext::BlockLiteral
);
3537 DeclaratorInfo
.setFunctionDefinitionKind(FunctionDefinitionKind::Definition
);
3538 ParseDeclarator(DeclaratorInfo
);
3540 MaybeParseGNUAttributes(DeclaratorInfo
);
3542 // Inform sema that we are starting a block.
3543 Actions
.ActOnBlockArguments(CaretLoc
, DeclaratorInfo
, getCurScope());
3546 /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
3547 /// like ^(int x){ return x+1; }
3551 /// [clang] '^' block-args[opt] compound-statement
3552 /// [clang] '^' block-id compound-statement
3553 /// [clang] block-args:
3554 /// [clang] '(' parameter-list ')'
3556 ExprResult
Parser::ParseBlockLiteralExpression() {
3557 assert(Tok
.is(tok::caret
) && "block literal starts with ^");
3558 SourceLocation CaretLoc
= ConsumeToken();
3560 PrettyStackTraceLoc
CrashInfo(PP
.getSourceManager(), CaretLoc
,
3561 "block literal parsing");
3563 // Enter a scope to hold everything within the block. This includes the
3564 // argument decls, decls within the compound expression, etc. This also
3565 // allows determining whether a variable reference inside the block is
3566 // within or outside of the block.
3567 ParseScope
BlockScope(this, Scope::BlockScope
| Scope::FnScope
|
3568 Scope::CompoundStmtScope
| Scope::DeclScope
);
3570 // Inform sema that we are starting a block.
3571 Actions
.ActOnBlockStart(CaretLoc
, getCurScope());
3573 // Parse the return type if present.
3574 DeclSpec
DS(AttrFactory
);
3575 Declarator
ParamInfo(DS
, ParsedAttributesView::none(),
3576 DeclaratorContext::BlockLiteral
);
3577 ParamInfo
.setFunctionDefinitionKind(FunctionDefinitionKind::Definition
);
3578 // FIXME: Since the return type isn't actually parsed, it can't be used to
3579 // fill ParamInfo with an initial valid range, so do it manually.
3580 ParamInfo
.SetSourceRange(SourceRange(Tok
.getLocation(), Tok
.getLocation()));
3582 // If this block has arguments, parse them. There is no ambiguity here with
3583 // the expression case, because the expression case requires a parameter list.
3584 if (Tok
.is(tok::l_paren
)) {
3585 ParseParenDeclarator(ParamInfo
);
3586 // Parse the pieces after the identifier as if we had "int(...)".
3587 // SetIdentifier sets the source range end, but in this case we're past
3589 SourceLocation Tmp
= ParamInfo
.getSourceRange().getEnd();
3590 ParamInfo
.SetIdentifier(nullptr, CaretLoc
);
3591 ParamInfo
.SetRangeEnd(Tmp
);
3592 if (ParamInfo
.isInvalidType()) {
3593 // If there was an error parsing the arguments, they may have
3594 // tried to use ^(x+y) which requires an argument list. Just
3595 // skip the whole block literal.
3596 Actions
.ActOnBlockError(CaretLoc
, getCurScope());
3600 MaybeParseGNUAttributes(ParamInfo
);
3602 // Inform sema that we are starting a block.
3603 Actions
.ActOnBlockArguments(CaretLoc
, ParamInfo
, getCurScope());
3604 } else if (!Tok
.is(tok::l_brace
)) {
3605 ParseBlockId(CaretLoc
);
3607 // Otherwise, pretend we saw (void).
3608 SourceLocation NoLoc
;
3609 ParamInfo
.AddTypeInfo(
3610 DeclaratorChunk::getFunction(/*HasProto=*/true,
3611 /*IsAmbiguous=*/false,
3612 /*RParenLoc=*/NoLoc
,
3613 /*ArgInfo=*/nullptr,
3615 /*EllipsisLoc=*/NoLoc
,
3616 /*RParenLoc=*/NoLoc
,
3617 /*RefQualifierIsLvalueRef=*/true,
3618 /*RefQualifierLoc=*/NoLoc
,
3619 /*MutableLoc=*/NoLoc
, EST_None
,
3620 /*ESpecRange=*/SourceRange(),
3621 /*Exceptions=*/nullptr,
3622 /*ExceptionRanges=*/nullptr,
3623 /*NumExceptions=*/0,
3624 /*NoexceptExpr=*/nullptr,
3625 /*ExceptionSpecTokens=*/nullptr,
3626 /*DeclsInPrototype=*/std::nullopt
,
3627 CaretLoc
, CaretLoc
, ParamInfo
),
3630 MaybeParseGNUAttributes(ParamInfo
);
3632 // Inform sema that we are starting a block.
3633 Actions
.ActOnBlockArguments(CaretLoc
, ParamInfo
, getCurScope());
3637 ExprResult
Result(true);
3638 if (!Tok
.is(tok::l_brace
)) {
3639 // Saw something like: ^expr
3640 Diag(Tok
, diag::err_expected_expression
);
3641 Actions
.ActOnBlockError(CaretLoc
, getCurScope());
3645 StmtResult
Stmt(ParseCompoundStatementBody());
3647 if (!Stmt
.isInvalid())
3648 Result
= Actions
.ActOnBlockStmtExpr(CaretLoc
, Stmt
.get(), getCurScope());
3650 Actions
.ActOnBlockError(CaretLoc
, getCurScope());
3654 /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
3658 ExprResult
Parser::ParseObjCBoolLiteral() {
3659 tok::TokenKind Kind
= Tok
.getKind();
3660 return Actions
.ActOnObjCBoolLiteral(ConsumeToken(), Kind
);
3663 /// Validate availability spec list, emitting diagnostics if necessary. Returns
3664 /// true if invalid.
3665 static bool CheckAvailabilitySpecList(Parser
&P
,
3666 ArrayRef
<AvailabilitySpec
> AvailSpecs
) {
3667 llvm::SmallSet
<StringRef
, 4> Platforms
;
3668 bool HasOtherPlatformSpec
= false;
3670 for (const auto &Spec
: AvailSpecs
) {
3671 if (Spec
.isOtherPlatformSpec()) {
3672 if (HasOtherPlatformSpec
) {
3673 P
.Diag(Spec
.getBeginLoc(), diag::err_availability_query_repeated_star
);
3677 HasOtherPlatformSpec
= true;
3681 bool Inserted
= Platforms
.insert(Spec
.getPlatform()).second
;
3683 // Rule out multiple version specs referring to the same platform.
3684 // For example, we emit an error for:
3685 // @available(macos 10.10, macos 10.11, *)
3686 StringRef Platform
= Spec
.getPlatform();
3687 P
.Diag(Spec
.getBeginLoc(), diag::err_availability_query_repeated_platform
)
3688 << Spec
.getEndLoc() << Platform
;
3693 if (!HasOtherPlatformSpec
) {
3694 SourceLocation InsertWildcardLoc
= AvailSpecs
.back().getEndLoc();
3695 P
.Diag(InsertWildcardLoc
, diag::err_availability_query_wildcard_required
)
3696 << FixItHint::CreateInsertion(InsertWildcardLoc
, ", *");
3703 /// Parse availability query specification.
3705 /// availability-spec:
3707 /// identifier version-tuple
3708 std::optional
<AvailabilitySpec
> Parser::ParseAvailabilitySpec() {
3709 if (Tok
.is(tok::star
)) {
3710 return AvailabilitySpec(ConsumeToken());
3712 // Parse the platform name.
3713 if (Tok
.is(tok::code_completion
)) {
3715 Actions
.CodeCompleteAvailabilityPlatformName();
3716 return std::nullopt
;
3718 if (Tok
.isNot(tok::identifier
)) {
3719 Diag(Tok
, diag::err_avail_query_expected_platform_name
);
3720 return std::nullopt
;
3723 IdentifierLoc
*PlatformIdentifier
= ParseIdentifierLoc();
3724 SourceRange VersionRange
;
3725 VersionTuple Version
= ParseVersionTuple(VersionRange
);
3727 if (Version
.empty())
3728 return std::nullopt
;
3730 StringRef GivenPlatform
= PlatformIdentifier
->Ident
->getName();
3731 StringRef Platform
=
3732 AvailabilityAttr::canonicalizePlatformName(GivenPlatform
);
3734 if (AvailabilityAttr::getPrettyPlatformName(Platform
).empty()) {
3735 Diag(PlatformIdentifier
->Loc
,
3736 diag::err_avail_query_unrecognized_platform_name
)
3738 return std::nullopt
;
3741 return AvailabilitySpec(Version
, Platform
, PlatformIdentifier
->Loc
,
3742 VersionRange
.getEnd());
3746 ExprResult
Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc
) {
3747 assert(Tok
.is(tok::kw___builtin_available
) ||
3748 Tok
.isObjCAtKeyword(tok::objc_available
));
3750 // Eat the available or __builtin_available.
3753 BalancedDelimiterTracker
Parens(*this, tok::l_paren
);
3754 if (Parens
.expectAndConsume())
3757 SmallVector
<AvailabilitySpec
, 4> AvailSpecs
;
3758 bool HasError
= false;
3760 std::optional
<AvailabilitySpec
> Spec
= ParseAvailabilitySpec();
3764 AvailSpecs
.push_back(*Spec
);
3766 if (!TryConsumeToken(tok::comma
))
3771 SkipUntil(tok::r_paren
, StopAtSemi
);
3775 CheckAvailabilitySpecList(*this, AvailSpecs
);
3777 if (Parens
.consumeClose())
3780 return Actions
.ActOnObjCAvailabilityCheckExpr(AvailSpecs
, BeginLoc
,
3781 Parens
.getCloseLocation());