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/Basic/PrettyStackTrace.h"
26 #include "clang/Parse/RAIIObjectsForParser.h"
27 #include "clang/Sema/DeclSpec.h"
28 #include "clang/Sema/ParsedTemplate.h"
29 #include "clang/Sema/Scope.h"
30 #include "clang/Sema/TypoCorrection.h"
31 #include "llvm/ADT/SmallVector.h"
32 using namespace clang;
34 /// Simple precedence-based parser for binary/ternary operators.
36 /// Note: we diverge from the C99 grammar when parsing the assignment-expression
37 /// production. C99 specifies that the LHS of an assignment operator should be
38 /// parsed as a unary-expression, but consistency dictates that it be a
39 /// conditional-expession. In practice, the important thing here is that the
40 /// LHS of an assignment has to be an l-value, which productions between
41 /// unary-expression and conditional-expression don't produce. Because we want
42 /// consistency, we parse the LHS as a conditional-expression, then check for
43 /// l-value-ness in semantic analysis stages.
46 /// pm-expression: [C++ 5.5]
48 /// pm-expression '.*' cast-expression
49 /// pm-expression '->*' cast-expression
51 /// multiplicative-expression: [C99 6.5.5]
52 /// Note: in C++, apply pm-expression instead of cast-expression
54 /// multiplicative-expression '*' cast-expression
55 /// multiplicative-expression '/' cast-expression
56 /// multiplicative-expression '%' cast-expression
58 /// additive-expression: [C99 6.5.6]
59 /// multiplicative-expression
60 /// additive-expression '+' multiplicative-expression
61 /// additive-expression '-' multiplicative-expression
63 /// shift-expression: [C99 6.5.7]
64 /// additive-expression
65 /// shift-expression '<<' additive-expression
66 /// shift-expression '>>' additive-expression
68 /// compare-expression: [C++20 expr.spaceship]
70 /// compare-expression '<=>' shift-expression
72 /// relational-expression: [C99 6.5.8]
73 /// compare-expression
74 /// relational-expression '<' compare-expression
75 /// relational-expression '>' compare-expression
76 /// relational-expression '<=' compare-expression
77 /// relational-expression '>=' compare-expression
79 /// equality-expression: [C99 6.5.9]
80 /// relational-expression
81 /// equality-expression '==' relational-expression
82 /// equality-expression '!=' relational-expression
84 /// AND-expression: [C99 6.5.10]
85 /// equality-expression
86 /// AND-expression '&' equality-expression
88 /// exclusive-OR-expression: [C99 6.5.11]
90 /// exclusive-OR-expression '^' AND-expression
92 /// inclusive-OR-expression: [C99 6.5.12]
93 /// exclusive-OR-expression
94 /// inclusive-OR-expression '|' exclusive-OR-expression
96 /// logical-AND-expression: [C99 6.5.13]
97 /// inclusive-OR-expression
98 /// logical-AND-expression '&&' inclusive-OR-expression
100 /// logical-OR-expression: [C99 6.5.14]
101 /// logical-AND-expression
102 /// logical-OR-expression '||' logical-AND-expression
104 /// conditional-expression: [C99 6.5.15]
105 /// logical-OR-expression
106 /// logical-OR-expression '?' expression ':' conditional-expression
107 /// [GNU] logical-OR-expression '?' ':' conditional-expression
108 /// [C++] the third operand is an assignment-expression
110 /// assignment-expression: [C99 6.5.16]
111 /// conditional-expression
112 /// unary-expression assignment-operator assignment-expression
113 /// [C++] throw-expression [C++ 15]
115 /// assignment-operator: one of
116 /// = *= /= %= += -= <<= >>= &= ^= |=
118 /// expression: [C99 6.5.17]
119 /// assignment-expression ...[opt]
120 /// expression ',' assignment-expression ...[opt]
122 ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
123 ExprResult LHS(ParseAssignmentExpression(isTypeCast));
124 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
127 /// This routine is called when the '@' is seen and consumed.
128 /// Current token is an Identifier and is not a 'try'. This
129 /// routine is necessary to disambiguate \@try-statement from,
130 /// for example, \@encode-expression.
133 Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
134 ExprResult LHS(ParseObjCAtExpression(AtLoc));
135 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
138 /// This routine is called when a leading '__extension__' is seen and
139 /// consumed. This is necessary because the token gets consumed in the
140 /// process of disambiguating between an expression and a declaration.
142 Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
143 ExprResult LHS(true);
145 // Silence extension warnings in the sub-expression
146 ExtensionRAIIObject O(Diags);
148 LHS = ParseCastExpression(false);
151 if (!LHS.isInvalid())
152 LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
155 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
158 /// Parse an expr that doesn't include (top-level) commas.
159 ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
160 if (Tok.is(tok::code_completion)) {
161 Actions.CodeCompleteExpression(getCurScope(),
162 PreferredType.get(Tok.getLocation()));
167 if (Tok.is(tok::kw_throw))
168 return ParseThrowExpression();
169 if (Tok.is(tok::kw_co_yield))
170 return ParseCoyieldExpression();
172 ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false,
173 /*isAddressOfOperand=*/false,
175 return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
178 /// Parse an assignment expression where part of an Objective-C message
179 /// send has already been parsed.
181 /// In this case \p LBracLoc indicates the location of the '[' of the message
182 /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating
183 /// the receiver of the message.
185 /// Since this handles full assignment-expression's, it handles postfix
186 /// expressions and other binary operators for these expressions as well.
188 Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
189 SourceLocation SuperLoc,
190 ParsedType ReceiverType,
191 Expr *ReceiverExpr) {
193 = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
194 ReceiverType, ReceiverExpr);
195 R = ParsePostfixExpressionSuffix(R);
196 return ParseRHSOfBinaryExpression(R, prec::Assignment);
200 Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) {
201 assert(Actions.ExprEvalContexts.back().Context ==
202 Sema::ExpressionEvaluationContext::ConstantEvaluated &&
203 "Call this function only if your ExpressionEvaluationContext is "
204 "already ConstantEvaluated");
205 ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
206 ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
207 return Actions.ActOnConstantExpression(Res);
210 ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
211 // C++03 [basic.def.odr]p2:
212 // An expression is potentially evaluated unless it appears where an
213 // integral constant expression is required (see 5.19) [...].
214 // C++98 and C++11 have no such rule, but this is only a defect in C++98.
215 EnterExpressionEvaluationContext ConstantEvaluated(
216 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
217 return ParseConstantExpressionInExprEvalContext(isTypeCast);
220 ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
221 EnterExpressionEvaluationContext ConstantEvaluated(
222 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
223 ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
224 ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
225 return Actions.ActOnCaseExpr(CaseLoc, Res);
228 /// Parse a constraint-expression.
231 /// constraint-expression: [Concepts TS temp.constr.decl p1]
232 /// logical-or-expression
234 ExprResult Parser::ParseConstraintExpression() {
235 // FIXME: this may erroneously consume a function-body as the braced
236 // initializer list of a compound literal
238 // FIXME: this may erroneously consume a parenthesized rvalue reference
239 // declarator as a parenthesized address-of-label expression
240 ExprResult LHS(ParseCastExpression(/*isUnaryExpression=*/false));
241 ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
246 bool Parser::isNotExpressionStart() {
247 tok::TokenKind K = Tok.getKind();
248 if (K == tok::l_brace || K == tok::r_brace ||
249 K == tok::kw_for || K == tok::kw_while ||
250 K == tok::kw_if || K == tok::kw_else ||
251 K == tok::kw_goto || K == tok::kw_try)
253 // If this is a decl-specifier, we can't be at the start of an expression.
254 return isKnownToBeDeclarationSpecifier();
257 bool Parser::isFoldOperator(prec::Level Level) const {
258 return Level > prec::Unknown && Level != prec::Conditional &&
259 Level != prec::Spaceship;
262 bool Parser::isFoldOperator(tok::TokenKind Kind) const {
263 return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true));
266 /// Parse a binary expression that starts with \p LHS and has a
267 /// precedence of at least \p MinPrec.
269 Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
270 prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
271 GreaterThanIsOperator,
272 getLangOpts().CPlusPlus11);
273 SourceLocation ColonLoc;
275 auto SavedType = PreferredType;
277 // Every iteration may rely on a preferred type for the whole expression.
278 PreferredType = SavedType;
279 // If this token has a lower precedence than we are allowed to parse (e.g.
280 // because we are called recursively, or because the token is not a binop),
282 if (NextTokPrec < MinPrec)
285 // Consume the operator, saving the operator token for error reporting.
289 if (OpToken.is(tok::caretcaret)) {
290 return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or));
293 // If we're potentially in a template-id, we may now be able to determine
294 // whether we're actually in one or not.
295 if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
296 tok::greatergreatergreater) &&
297 checkPotentialAngleBracketDelimiter(OpToken))
300 // Bail out when encountering a comma followed by a token which can't
301 // possibly be the start of an expression. For instance:
302 // int f() { return 1, }
303 // We can't do this before consuming the comma, because
304 // isNotExpressionStart() looks at the token stream.
305 if (OpToken.is(tok::comma) && isNotExpressionStart()) {
306 PP.EnterToken(Tok, /*IsReinject*/true);
311 // If the next token is an ellipsis, then this is a fold-expression. Leave
312 // it alone so we can handle it in the paren expression.
313 if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
314 // FIXME: We can't check this via lookahead before we consume the token
315 // because that tickles a lexer bug.
316 PP.EnterToken(Tok, /*IsReinject*/true);
321 // In Objective-C++, alternative operator tokens can be used as keyword args
322 // in message expressions. Unconsume the token so that it can reinterpreted
323 // as an identifier in ParseObjCMessageExpressionBody. i.e., we support:
324 // [foo meth:0 and:0];
326 if (getLangOpts().ObjC && getLangOpts().CPlusPlus &&
327 Tok.isOneOf(tok::colon, tok::r_square) &&
328 OpToken.getIdentifierInfo() != nullptr) {
329 PP.EnterToken(Tok, /*IsReinject*/true);
334 // Special case handling for the ternary operator.
335 ExprResult TernaryMiddle(true);
336 if (NextTokPrec == prec::Conditional) {
337 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
338 // Parse a braced-init-list here for error recovery purposes.
339 SourceLocation BraceLoc = Tok.getLocation();
340 TernaryMiddle = ParseBraceInitializer();
341 if (!TernaryMiddle.isInvalid()) {
342 Diag(BraceLoc, diag::err_init_list_bin_op)
343 << /*RHS*/ 1 << PP.getSpelling(OpToken)
344 << Actions.getExprRange(TernaryMiddle.get());
345 TernaryMiddle = ExprError();
347 } else if (Tok.isNot(tok::colon)) {
348 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
349 ColonProtectionRAIIObject X(*this);
351 // Handle this production specially:
352 // logical-OR-expression '?' expression ':' conditional-expression
353 // In particular, the RHS of the '?' is 'expression', not
354 // 'logical-OR-expression' as we might expect.
355 TernaryMiddle = ParseExpression();
357 // Special case handling of "X ? Y : Z" where Y is empty:
358 // logical-OR-expression '?' ':' conditional-expression [GNU]
359 TernaryMiddle = nullptr;
360 Diag(Tok, diag::ext_gnu_conditional_expr);
363 if (TernaryMiddle.isInvalid()) {
364 Actions.CorrectDelayedTyposInExpr(LHS);
366 TernaryMiddle = nullptr;
369 if (!TryConsumeToken(tok::colon, ColonLoc)) {
370 // Otherwise, we're missing a ':'. Assume that this was a typo that
371 // the user forgot. If we're not in a macro expansion, we can suggest
372 // a fixit hint. If there were two spaces before the current token,
373 // suggest inserting the colon in between them, otherwise insert ": ".
374 SourceLocation FILoc = Tok.getLocation();
375 const char *FIText = ": ";
376 const SourceManager &SM = PP.getSourceManager();
377 if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) {
378 assert(FILoc.isFileID());
379 bool IsInvalid = false;
380 const char *SourcePtr =
381 SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid);
382 if (!IsInvalid && *SourcePtr == ' ') {
384 SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid);
385 if (!IsInvalid && *SourcePtr == ' ') {
386 FILoc = FILoc.getLocWithOffset(-1);
392 Diag(Tok, diag::err_expected)
393 << tok::colon << FixItHint::CreateInsertion(FILoc, FIText);
394 Diag(OpToken, diag::note_matching) << tok::question;
395 ColonLoc = Tok.getLocation();
399 PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(),
401 // Parse another leaf here for the RHS of the operator.
402 // ParseCastExpression works here because all RHS expressions in C have it
403 // as a prefix, at least. However, in C++, an assignment-expression could
404 // be a throw-expression, which is not a valid cast-expression.
405 // Therefore we need some special-casing here.
406 // Also note that the third operand of the conditional operator is
407 // an assignment-expression in C++, and in C++11, we can have a
408 // braced-init-list on the RHS of an assignment. For better diagnostics,
409 // parse as if we were allowed braced-init-lists everywhere, and check that
410 // they only appear on the RHS of assignments later.
412 bool RHSIsInitList = false;
413 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
414 RHS = ParseBraceInitializer();
415 RHSIsInitList = true;
416 } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional)
417 RHS = ParseAssignmentExpression();
419 RHS = ParseCastExpression(false);
421 if (RHS.isInvalid()) {
422 // FIXME: Errors generated by the delayed typo correction should be
423 // printed before errors from parsing the RHS, not after.
424 Actions.CorrectDelayedTyposInExpr(LHS);
425 if (TernaryMiddle.isUsable())
426 TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
430 // Remember the precedence of this operator and get the precedence of the
431 // operator immediately to the right of the RHS.
432 prec::Level ThisPrec = NextTokPrec;
433 NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
434 getLangOpts().CPlusPlus11);
436 // Assignment and conditional expressions are right-associative.
437 bool isRightAssoc = ThisPrec == prec::Conditional ||
438 ThisPrec == prec::Assignment;
440 // Get the precedence of the operator to the right of the RHS. If it binds
441 // more tightly with RHS than we do, evaluate it completely first.
442 if (ThisPrec < NextTokPrec ||
443 (ThisPrec == NextTokPrec && isRightAssoc)) {
444 if (!RHS.isInvalid() && RHSIsInitList) {
445 Diag(Tok, diag::err_init_list_bin_op)
446 << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get());
449 // If this is left-associative, only parse things on the RHS that bind
450 // more tightly than the current operator. If it is left-associative, it
451 // is okay, to bind exactly as tightly. For example, compile A=B=C=D as
452 // A=(B=(C=D)), where each paren is a level of recursion here.
453 // The function takes ownership of the RHS.
454 RHS = ParseRHSOfBinaryExpression(RHS,
455 static_cast<prec::Level>(ThisPrec + !isRightAssoc));
456 RHSIsInitList = false;
458 if (RHS.isInvalid()) {
459 // FIXME: Errors generated by the delayed typo correction should be
460 // printed before errors from ParseRHSOfBinaryExpression, not after.
461 Actions.CorrectDelayedTyposInExpr(LHS);
462 if (TernaryMiddle.isUsable())
463 TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
467 NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
468 getLangOpts().CPlusPlus11);
471 if (!RHS.isInvalid() && RHSIsInitList) {
472 if (ThisPrec == prec::Assignment) {
473 Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
474 << Actions.getExprRange(RHS.get());
475 } else if (ColonLoc.isValid()) {
476 Diag(ColonLoc, diag::err_init_list_bin_op)
478 << Actions.getExprRange(RHS.get());
481 Diag(OpToken, diag::err_init_list_bin_op)
482 << /*RHS*/1 << PP.getSpelling(OpToken)
483 << Actions.getExprRange(RHS.get());
488 ExprResult OrigLHS = LHS;
489 if (!LHS.isInvalid()) {
490 // Combine the LHS and RHS into the LHS (e.g. build AST).
491 if (TernaryMiddle.isInvalid()) {
492 // If we're using '>>' as an operator within a template
493 // argument list (in C++98), suggest the addition of
494 // parentheses so that the code remains well-formed in C++0x.
495 if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater))
496 SuggestParentheses(OpToken.getLocation(),
497 diag::warn_cxx11_right_shift_in_template_arg,
498 SourceRange(Actions.getExprRange(LHS.get()).getBegin(),
499 Actions.getExprRange(RHS.get()).getEnd()));
501 LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
502 OpToken.getKind(), LHS.get(), RHS.get());
505 LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
506 LHS.get(), TernaryMiddle.get(),
509 // In this case, ActOnBinOp or ActOnConditionalOp performed the
510 // CorrectDelayedTyposInExpr check.
511 if (!getLangOpts().CPlusPlus)
515 // Ensure potential typos aren't left undiagnosed.
516 if (LHS.isInvalid()) {
517 Actions.CorrectDelayedTyposInExpr(OrigLHS);
518 Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
519 Actions.CorrectDelayedTyposInExpr(RHS);
524 /// Parse a cast-expression, or, if \p isUnaryExpression is true,
525 /// parse a unary-expression.
527 /// \p isAddressOfOperand exists because an id-expression that is the
528 /// operand of address-of gets special treatment due to member pointers.
530 ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
531 bool isAddressOfOperand,
532 TypeCastState isTypeCast,
533 bool isVectorLiteral) {
535 ExprResult Res = ParseCastExpression(isUnaryExpression,
541 Diag(Tok, diag::err_expected_expression);
546 class CastExpressionIdValidator final : public CorrectionCandidateCallback {
548 CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes)
549 : NextToken(Next), AllowNonTypes(AllowNonTypes) {
550 WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
553 bool ValidateCandidate(const TypoCorrection &candidate) override {
554 NamedDecl *ND = candidate.getCorrectionDecl();
556 return candidate.isKeyword();
558 if (isa<TypeDecl>(ND))
559 return WantTypeSpecifiers;
561 if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate))
564 if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period))
567 for (auto *C : candidate) {
568 NamedDecl *ND = C->getUnderlyingDecl();
569 if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND))
575 std::unique_ptr<CorrectionCandidateCallback> clone() override {
576 return llvm::make_unique<CastExpressionIdValidator>(*this);
585 /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
586 /// a unary-expression.
588 /// \p isAddressOfOperand exists because an id-expression that is the operand
589 /// of address-of gets special treatment due to member pointers. NotCastExpr
590 /// is set to true if the token is not the start of a cast-expression, and no
591 /// diagnostic is emitted in this case and no tokens are consumed.
594 /// cast-expression: [C99 6.5.4]
596 /// '(' type-name ')' cast-expression
598 /// unary-expression: [C99 6.5.3]
599 /// postfix-expression
600 /// '++' unary-expression
601 /// '--' unary-expression
602 /// [Coro] 'co_await' cast-expression
603 /// unary-operator cast-expression
604 /// 'sizeof' unary-expression
605 /// 'sizeof' '(' type-name ')'
606 /// [C++11] 'sizeof' '...' '(' identifier ')'
607 /// [GNU] '__alignof' unary-expression
608 /// [GNU] '__alignof' '(' type-name ')'
609 /// [C11] '_Alignof' '(' type-name ')'
610 /// [C++11] 'alignof' '(' type-id ')'
611 /// [GNU] '&&' identifier
612 /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7]
613 /// [C++] new-expression
614 /// [C++] delete-expression
616 /// unary-operator: one of
617 /// '&' '*' '+' '-' '~' '!'
618 /// [GNU] '__extension__' '__real' '__imag'
620 /// primary-expression: [C99 6.5.1]
622 /// [C++] id-expression
625 /// [C++] boolean-literal [C++ 2.13.5]
626 /// [C++11] 'nullptr' [C++11 2.14.7]
627 /// [C++11] user-defined-literal
628 /// '(' expression ')'
629 /// [C11] generic-selection
630 /// '__func__' [C99 6.4.2.2]
631 /// [GNU] '__FUNCTION__'
632 /// [MS] '__FUNCDNAME__'
633 /// [MS] 'L__FUNCTION__'
634 /// [MS] '__FUNCSIG__'
635 /// [MS] 'L__FUNCSIG__'
636 /// [GNU] '__PRETTY_FUNCTION__'
637 /// [GNU] '(' compound-statement ')'
638 /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
639 /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
640 /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
642 /// [GNU] '__builtin_FILE' '(' ')'
643 /// [GNU] '__builtin_FUNCTION' '(' ')'
644 /// [GNU] '__builtin_LINE' '(' ')'
645 /// [CLANG] '__builtin_COLUMN' '(' ')'
646 /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
648 /// [OBJC] '[' objc-message-expr ']'
649 /// [OBJC] '\@selector' '(' objc-selector-arg ')'
650 /// [OBJC] '\@protocol' '(' identifier ')'
651 /// [OBJC] '\@encode' '(' type-name ')'
652 /// [OBJC] objc-string-literal
653 /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
654 /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3]
655 /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
656 /// [C++11] typename-specifier braced-init-list [C++11 5.2.3]
657 /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
658 /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
659 /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
660 /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
661 /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1]
662 /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1]
663 /// [C++] 'this' [C++ 9.3.2]
664 /// [G++] unary-type-trait '(' type-id ')'
665 /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO]
666 /// [EMBT] array-type-trait '(' type-id ',' integer ')'
667 /// [clang] '^' block-literal
669 /// constant: [C99 6.4.4]
671 /// floating-constant
672 /// enumeration-constant -> identifier
673 /// character-constant
675 /// id-expression: [C++ 5.1]
679 /// unqualified-id: [C++ 5.1]
681 /// operator-function-id
682 /// conversion-function-id
686 /// new-expression: [C++ 5.3.4]
687 /// '::'[opt] 'new' new-placement[opt] new-type-id
688 /// new-initializer[opt]
689 /// '::'[opt] 'new' new-placement[opt] '(' type-id ')'
690 /// new-initializer[opt]
692 /// delete-expression: [C++ 5.3.5]
693 /// '::'[opt] 'delete' cast-expression
694 /// '::'[opt] 'delete' '[' ']' cast-expression
696 /// [GNU/Embarcadero] unary-type-trait:
697 /// '__is_arithmetic'
698 /// '__is_floating_point'
700 /// '__is_lvalue_expr'
701 /// '__is_rvalue_expr'
702 /// '__is_complete_type'
707 /// '__is_lvalue_reference'
708 /// '__is_rvalue_reference'
709 /// '__is_fundamental'
714 /// '__is_member_object_pointer'
715 /// '__is_member_function_pointer'
716 /// '__is_member_pointer'
720 /// '__is_standard_layout'
724 /// [GNU] unary-type-trait:
725 /// '__has_nothrow_assign'
726 /// '__has_nothrow_copy'
727 /// '__has_nothrow_constructor'
728 /// '__has_trivial_assign' [TODO]
729 /// '__has_trivial_copy' [TODO]
730 /// '__has_trivial_constructor'
731 /// '__has_trivial_destructor'
732 /// '__has_virtual_destructor'
733 /// '__is_abstract' [TODO]
735 /// '__is_empty' [TODO]
739 /// '__is_polymorphic'
740 /// '__is_sealed' [MS]
743 /// '__has_unique_object_representations'
745 /// [Clang] unary-type-trait:
747 /// '__trivially_copyable'
749 /// binary-type-trait:
750 /// [GNU] '__is_base_of'
751 /// [MS] '__is_convertible_to'
752 /// '__is_convertible'
755 /// [Embarcadero] array-type-trait:
759 /// [Embarcadero] expression-trait:
760 /// '__is_lvalue_expr'
761 /// '__is_rvalue_expr'
764 ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
765 bool isAddressOfOperand,
767 TypeCastState isTypeCast,
768 bool isVectorLiteral) {
770 tok::TokenKind SavedKind = Tok.getKind();
771 auto SavedType = PreferredType;
774 // This handles all of cast-expression, unary-expression, postfix-expression,
775 // and primary-expression. We handle them together like this for efficiency
776 // and to simplify handling of an expression starting with a '(' token: which
777 // may be one of a parenthesized expression, cast-expression, compound literal
778 // expression, or statement expression.
780 // If the parsed tokens consist of a primary-expression, the cases below
781 // break out of the switch; at the end we call ParsePostfixExpressionSuffix
782 // to handle the postfix expression suffixes. Cases that cannot be followed
783 // by postfix exprs should return without invoking
784 // ParsePostfixExpressionSuffix.
787 // If this expression is limited to being a unary-expression, the parent can
788 // not start a cast expression.
789 ParenParseOption ParenExprType =
790 (isUnaryExpression && !getLangOpts().CPlusPlus) ? CompoundLiteral
793 SourceLocation RParenLoc;
794 Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
795 isTypeCast == IsTypeCast, CastTy, RParenLoc);
800 switch (ParenExprType) {
801 case SimpleExpr: break; // Nothing else to do.
802 case CompoundStmt: break; // Nothing else to do.
803 case CompoundLiteral:
804 // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
805 // postfix-expression exist, parse them now.
808 // We have parsed the cast-expression and no postfix-expr pieces are
812 // We only parsed a fold-expression. There might be postfix-expr pieces
813 // afterwards; parse them now.
820 // primary-expression
821 case tok::numeric_constant:
822 // constant: integer-constant
823 // constant: floating-constant
825 Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope());
831 Res = ParseCXXBoolLiteral();
834 case tok::kw___objc_yes:
835 case tok::kw___objc_no:
836 return ParseObjCBoolLiteral();
838 case tok::kw_nullptr:
839 Diag(Tok, diag::warn_cxx98_compat_nullptr);
840 return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
842 case tok::annot_primary_expr:
843 assert(Res.get() == nullptr && "Stray primary-expression annotation?");
844 Res = getExprAnnotation(Tok);
845 ConsumeAnnotationToken();
846 if (!Res.isInvalid() && Tok.is(tok::less))
847 checkPotentialAngleBracket(Res);
850 case tok::kw___super:
851 case tok::kw_decltype:
852 // Annotate the token and tail recurse.
853 if (TryAnnotateTypeOrScopeToken())
855 assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super));
856 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
858 case tok::identifier: { // primary-expression: identifier
859 // unqualified-id: identifier
860 // constant: enumeration-constant
861 // Turn a potentially qualified name into a annot_typename or
862 // annot_cxxscope if it would be valid. This handles things like x::y, etc.
863 if (getLangOpts().CPlusPlus) {
864 // Avoid the unnecessary parse-time lookup in the common case
865 // where the syntax forbids a type.
866 const Token &Next = NextToken();
868 // If this identifier was reverted from a token ID, and the next token
869 // is a parenthesis, this is likely to be a use of a type trait. Check
871 if (Next.is(tok::l_paren) &&
872 Tok.is(tok::identifier) &&
873 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
874 IdentifierInfo *II = Tok.getIdentifierInfo();
875 // Build up the mapping of revertible type traits, for future use.
876 if (RevertibleTypeTraits.empty()) {
877 #define RTT_JOIN(X,Y) X##Y
878 #define REVERTIBLE_TYPE_TRAIT(Name) \
879 RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \
880 = RTT_JOIN(tok::kw_,Name)
882 REVERTIBLE_TYPE_TRAIT(__is_abstract);
883 REVERTIBLE_TYPE_TRAIT(__is_aggregate);
884 REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
885 REVERTIBLE_TYPE_TRAIT(__is_array);
886 REVERTIBLE_TYPE_TRAIT(__is_assignable);
887 REVERTIBLE_TYPE_TRAIT(__is_base_of);
888 REVERTIBLE_TYPE_TRAIT(__is_class);
889 REVERTIBLE_TYPE_TRAIT(__is_complete_type);
890 REVERTIBLE_TYPE_TRAIT(__is_compound);
891 REVERTIBLE_TYPE_TRAIT(__is_const);
892 REVERTIBLE_TYPE_TRAIT(__is_constructible);
893 REVERTIBLE_TYPE_TRAIT(__is_convertible);
894 REVERTIBLE_TYPE_TRAIT(__is_convertible_to);
895 REVERTIBLE_TYPE_TRAIT(__is_destructible);
896 REVERTIBLE_TYPE_TRAIT(__is_empty);
897 REVERTIBLE_TYPE_TRAIT(__is_enum);
898 REVERTIBLE_TYPE_TRAIT(__is_floating_point);
899 REVERTIBLE_TYPE_TRAIT(__is_final);
900 REVERTIBLE_TYPE_TRAIT(__is_function);
901 REVERTIBLE_TYPE_TRAIT(__is_fundamental);
902 REVERTIBLE_TYPE_TRAIT(__is_integral);
903 REVERTIBLE_TYPE_TRAIT(__is_interface_class);
904 REVERTIBLE_TYPE_TRAIT(__is_literal);
905 REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr);
906 REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference);
907 REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
908 REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer);
909 REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
910 REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
911 REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
912 REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
913 REVERTIBLE_TYPE_TRAIT(__is_object);
914 REVERTIBLE_TYPE_TRAIT(__is_pod);
915 REVERTIBLE_TYPE_TRAIT(__is_pointer);
916 REVERTIBLE_TYPE_TRAIT(__is_polymorphic);
917 REVERTIBLE_TYPE_TRAIT(__is_reference);
918 REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr);
919 REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
920 REVERTIBLE_TYPE_TRAIT(__is_same);
921 REVERTIBLE_TYPE_TRAIT(__is_scalar);
922 REVERTIBLE_TYPE_TRAIT(__is_sealed);
923 REVERTIBLE_TYPE_TRAIT(__is_signed);
924 REVERTIBLE_TYPE_TRAIT(__is_standard_layout);
925 REVERTIBLE_TYPE_TRAIT(__is_trivial);
926 REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
927 REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
928 REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
929 REVERTIBLE_TYPE_TRAIT(__is_union);
930 REVERTIBLE_TYPE_TRAIT(__is_unsigned);
931 REVERTIBLE_TYPE_TRAIT(__is_void);
932 REVERTIBLE_TYPE_TRAIT(__is_volatile);
933 #undef REVERTIBLE_TYPE_TRAIT
937 // If we find that this is in fact the name of a type trait,
938 // update the token kind in place and parse again to treat it as
939 // the appropriate kind of type trait.
940 llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known
941 = RevertibleTypeTraits.find(II);
942 if (Known != RevertibleTypeTraits.end()) {
943 Tok.setKind(Known->second);
944 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
945 NotCastExpr, isTypeCast);
949 if ((!ColonIsSacred && Next.is(tok::colon)) ||
950 Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren,
952 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
953 if (TryAnnotateTypeOrScopeToken())
955 if (!Tok.is(tok::identifier))
956 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
960 // Consume the identifier so that we can see if it is followed by a '(' or
962 IdentifierInfo &II = *Tok.getIdentifierInfo();
963 SourceLocation ILoc = ConsumeToken();
965 // Support 'Class.property' and 'super.property' notation.
966 if (getLangOpts().ObjC && Tok.is(tok::period) &&
967 (Actions.getTypeName(II, ILoc, getCurScope()) ||
968 // Allow the base to be 'super' if in an objc-method.
969 (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
972 if (Tok.is(tok::code_completion) && &II != Ident_super) {
973 Actions.CodeCompleteObjCClassPropertyRefExpr(
974 getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
978 // Allow either an identifier or the keyword 'class' (in C++).
979 if (Tok.isNot(tok::identifier) &&
980 !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) {
981 Diag(Tok, diag::err_expected_property_name);
984 IdentifierInfo &PropertyName = *Tok.getIdentifierInfo();
985 SourceLocation PropertyLoc = ConsumeToken();
987 Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName,
992 // In an Objective-C method, if we have "super" followed by an identifier,
993 // the token sequence is ill-formed. However, if there's a ':' or ']' after
994 // that identifier, this is probably a message send with a missing open
995 // bracket. Treat it as such.
996 if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression &&
997 getCurScope()->isInObjcMethodScope() &&
998 ((Tok.is(tok::identifier) &&
999 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) ||
1000 Tok.is(tok::code_completion))) {
1001 Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr,
1006 // If we have an Objective-C class name followed by an identifier
1007 // and either ':' or ']', this is an Objective-C class message
1008 // send that's missing the opening '['. Recovery
1009 // appropriately. Also take this path if we're performing code
1010 // completion after an Objective-C class name.
1011 if (getLangOpts().ObjC &&
1012 ((Tok.is(tok::identifier) && !InMessageExpression) ||
1013 Tok.is(tok::code_completion))) {
1014 const Token& Next = NextToken();
1015 if (Tok.is(tok::code_completion) ||
1016 Next.is(tok::colon) || Next.is(tok::r_square))
1017 if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
1018 if (Typ.get()->isObjCObjectOrInterfaceType()) {
1019 // Fake up a Declarator to use with ActOnTypeName.
1020 DeclSpec DS(AttrFactory);
1021 DS.SetRangeStart(ILoc);
1022 DS.SetRangeEnd(ILoc);
1023 const char *PrevSpec = nullptr;
1025 DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
1026 Actions.getASTContext().getPrintingPolicy());
1028 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
1029 TypeResult Ty = Actions.ActOnTypeName(getCurScope(),
1034 Res = ParseObjCMessageExpressionBody(SourceLocation(),
1041 // Make sure to pass down the right value for isAddressOfOperand.
1042 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
1043 isAddressOfOperand = false;
1045 // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
1046 // need to know whether or not this identifier is a function designator or
1049 CXXScopeSpec ScopeSpec;
1050 SourceLocation TemplateKWLoc;
1052 CastExpressionIdValidator Validator(
1054 /*AllowTypes=*/isTypeCast != NotTypeCast,
1055 /*AllowNonTypes=*/isTypeCast != IsTypeCast);
1056 Validator.IsAddressOfOperand = isAddressOfOperand;
1057 if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) {
1058 Validator.WantExpressionKeywords = false;
1059 Validator.WantRemainingKeywords = false;
1061 Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren);
1063 Name.setIdentifier(&II, ILoc);
1064 Res = Actions.ActOnIdExpression(
1065 getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
1066 isAddressOfOperand, &Validator,
1067 /*IsInlineAsmIdentifier=*/false,
1068 Tok.is(tok::r_paren) ? nullptr : &Replacement);
1069 if (!Res.isInvalid() && Res.isUnset()) {
1070 UnconsumeToken(Replacement);
1071 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1072 NotCastExpr, isTypeCast);
1074 if (!Res.isInvalid() && Tok.is(tok::less))
1075 checkPotentialAngleBracket(Res);
1078 case tok::char_constant: // constant: character-constant
1079 case tok::wide_char_constant:
1080 case tok::utf8_char_constant:
1081 case tok::utf16_char_constant:
1082 case tok::utf32_char_constant:
1083 Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope());
1086 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
1087 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
1088 case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS]
1089 case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS]
1090 case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
1091 case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS]
1092 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
1093 Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
1096 case tok::string_literal: // primary-expression: string-literal
1097 case tok::wide_string_literal:
1098 case tok::utf8_string_literal:
1099 case tok::utf16_string_literal:
1100 case tok::utf32_string_literal:
1101 Res = ParseStringLiteralExpression(true);
1103 case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1]
1104 Res = ParseGenericSelectionExpression();
1106 case tok::kw___builtin_available:
1107 return ParseAvailabilityCheckExpr(Tok.getLocation());
1108 case tok::kw___builtin_va_arg:
1109 case tok::kw___builtin_offsetof:
1110 case tok::kw___builtin_choose_expr:
1111 case tok::kw___builtin_astype: // primary-expression: [OCL] as_type()
1112 case tok::kw___builtin_convertvector:
1113 case tok::kw___builtin_COLUMN:
1114 case tok::kw___builtin_FILE:
1115 case tok::kw___builtin_FUNCTION:
1116 case tok::kw___builtin_LINE:
1117 return ParseBuiltinPrimaryExpression();
1118 case tok::kw___null:
1119 return Actions.ActOnGNUNullExpr(ConsumeToken());
1121 case tok::plusplus: // unary-expression: '++' unary-expression [C99]
1122 case tok::minusminus: { // unary-expression: '--' unary-expression [C99]
1123 // C++ [expr.unary] has:
1124 // unary-expression:
1125 // ++ cast-expression
1126 // -- cast-expression
1127 Token SavedTok = Tok;
1130 PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(),
1131 SavedTok.getLocation());
1132 // One special case is implicitly handled here: if the preceding tokens are
1133 // an ambiguous cast expression, such as "(T())++", then we recurse to
1134 // determine whether the '++' is prefix or postfix.
1135 Res = ParseCastExpression(!getLangOpts().CPlusPlus,
1136 /*isAddressOfOperand*/false, NotCastExpr,
1139 // If we return with NotCastExpr = true, we must not consume any tokens,
1140 // so put the token back where we found it.
1141 assert(Res.isInvalid());
1142 UnconsumeToken(SavedTok);
1145 if (!Res.isInvalid())
1146 Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(),
1147 SavedKind, Res.get());
1150 case tok::amp: { // unary-expression: '&' cast-expression
1151 // Special treatment because of member pointers
1152 SourceLocation SavedLoc = ConsumeToken();
1153 PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc);
1154 Res = ParseCastExpression(false, true);
1155 if (!Res.isInvalid())
1156 Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
1160 case tok::star: // unary-expression: '*' cast-expression
1161 case tok::plus: // unary-expression: '+' cast-expression
1162 case tok::minus: // unary-expression: '-' cast-expression
1163 case tok::tilde: // unary-expression: '~' cast-expression
1164 case tok::exclaim: // unary-expression: '!' cast-expression
1165 case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
1166 case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
1167 SourceLocation SavedLoc = ConsumeToken();
1168 PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc);
1169 Res = ParseCastExpression(false);
1170 if (!Res.isInvalid())
1171 Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
1175 case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression
1176 SourceLocation CoawaitLoc = ConsumeToken();
1177 Res = ParseCastExpression(false);
1178 if (!Res.isInvalid())
1179 Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get());
1183 case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
1184 // __extension__ silences extension warnings in the subexpression.
1185 ExtensionRAIIObject O(Diags); // Use RAII to do this.
1186 SourceLocation SavedLoc = ConsumeToken();
1187 Res = ParseCastExpression(false);
1188 if (!Res.isInvalid())
1189 Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
1192 case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')'
1193 if (!getLangOpts().C11)
1194 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
1196 case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')'
1197 case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
1198 // unary-expression: '__alignof' '(' type-name ')'
1199 case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
1200 // unary-expression: 'sizeof' '(' type-name ')'
1201 case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression
1202 // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')'
1203 case tok::kw___builtin_omp_required_simd_align:
1204 return ParseUnaryExprOrTypeTraitExpression();
1205 case tok::ampamp: { // unary-expression: '&&' identifier
1206 SourceLocation AmpAmpLoc = ConsumeToken();
1207 if (Tok.isNot(tok::identifier))
1208 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
1210 if (getCurScope()->getFnParent() == nullptr)
1211 return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
1213 Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
1214 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
1216 Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD);
1220 case tok::kw_const_cast:
1221 case tok::kw_dynamic_cast:
1222 case tok::kw_reinterpret_cast:
1223 case tok::kw_static_cast:
1224 Res = ParseCXXCasts();
1226 case tok::kw___builtin_bit_cast:
1227 Res = ParseBuiltinBitCast();
1229 case tok::kw_typeid:
1230 Res = ParseCXXTypeid();
1232 case tok::kw___uuidof:
1233 Res = ParseCXXUuidof();
1236 Res = ParseCXXThis();
1239 case tok::annot_typename:
1240 if (isStartOfObjCClassMessageMissingOpenBracket()) {
1241 ParsedType Type = getTypeAnnotation(Tok);
1243 // Fake up a Declarator to use with ActOnTypeName.
1244 DeclSpec DS(AttrFactory);
1245 DS.SetRangeStart(Tok.getLocation());
1246 DS.SetRangeEnd(Tok.getLastLoc());
1248 const char *PrevSpec = nullptr;
1250 DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(),
1251 PrevSpec, DiagID, Type,
1252 Actions.getASTContext().getPrintingPolicy());
1254 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
1255 TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
1259 ConsumeAnnotationToken();
1260 Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1266 case tok::annot_decltype:
1268 case tok::kw_wchar_t:
1269 case tok::kw_char8_t:
1270 case tok::kw_char16_t:
1271 case tok::kw_char32_t:
1276 case tok::kw___int64:
1277 case tok::kw___int128:
1278 case tok::kw_signed:
1279 case tok::kw_unsigned:
1282 case tok::kw_double:
1283 case tok::kw__Float16:
1284 case tok::kw___float128:
1286 case tok::kw_typename:
1287 case tok::kw_typeof:
1288 case tok::kw___vector:
1289 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1290 #include "clang/Basic/OpenCLImageTypes.def"
1292 if (!getLangOpts().CPlusPlus) {
1293 Diag(Tok, diag::err_expected_expression);
1297 if (SavedKind == tok::kw_typename) {
1298 // postfix-expression: typename-specifier '(' expression-list[opt] ')'
1299 // typename-specifier braced-init-list
1300 if (TryAnnotateTypeOrScopeToken())
1303 if (!Actions.isSimpleTypeSpecifier(Tok.getKind()))
1304 // We are trying to parse a simple-type-specifier but might not get such
1305 // a token after error recovery.
1309 // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
1310 // simple-type-specifier braced-init-list
1312 DeclSpec DS(AttrFactory);
1314 ParseCXXSimpleTypeSpecifier(DS);
1315 if (Tok.isNot(tok::l_paren) &&
1316 (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace)))
1317 return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
1318 << DS.getSourceRange());
1320 if (Tok.is(tok::l_brace))
1321 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1323 Res = ParseCXXTypeConstructExpression(DS);
1327 case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
1328 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1329 // (We can end up in this situation after tentative parsing.)
1330 if (TryAnnotateTypeOrScopeToken())
1332 if (!Tok.is(tok::annot_cxxscope))
1333 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1334 NotCastExpr, isTypeCast);
1336 Token Next = NextToken();
1337 if (Next.is(tok::annot_template_id)) {
1338 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
1339 if (TemplateId->Kind == TNK_Type_template) {
1340 // We have a qualified template-id that we know refers to a
1341 // type, translate it into a type and continue parsing as a
1344 ParseOptionalCXXScopeSpecifier(SS, nullptr,
1345 /*EnteringContext=*/false);
1346 AnnotateTemplateIdTokenAsType();
1347 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1348 NotCastExpr, isTypeCast);
1352 // Parse as an id-expression.
1353 Res = ParseCXXIdExpression(isAddressOfOperand);
1357 case tok::annot_template_id: { // [C++] template-id
1358 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1359 if (TemplateId->Kind == TNK_Type_template) {
1360 // We have a template-id that we know refers to a type,
1361 // translate it into a type and continue parsing as a cast
1363 AnnotateTemplateIdTokenAsType();
1364 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1365 NotCastExpr, isTypeCast);
1368 // Fall through to treat the template-id as an id-expression.
1372 case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
1373 Res = ParseCXXIdExpression(isAddressOfOperand);
1376 case tok::coloncolon: {
1377 // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken
1378 // annotates the token, tail recurse.
1379 if (TryAnnotateTypeOrScopeToken())
1381 if (!Tok.is(tok::coloncolon))
1382 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
1384 // ::new -> [C++] new-expression
1385 // ::delete -> [C++] delete-expression
1386 SourceLocation CCLoc = ConsumeToken();
1387 if (Tok.is(tok::kw_new))
1388 return ParseCXXNewExpression(true, CCLoc);
1389 if (Tok.is(tok::kw_delete))
1390 return ParseCXXDeleteExpression(true, CCLoc);
1392 // This is not a type name or scope specifier, it is an invalid expression.
1393 Diag(CCLoc, diag::err_expected_expression);
1397 case tok::kw_new: // [C++] new-expression
1398 return ParseCXXNewExpression(false, Tok.getLocation());
1400 case tok::kw_delete: // [C++] delete-expression
1401 return ParseCXXDeleteExpression(false, Tok.getLocation());
1403 case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')'
1404 Diag(Tok, diag::warn_cxx98_compat_noexcept_expr);
1405 SourceLocation KeyLoc = ConsumeToken();
1406 BalancedDelimiterTracker T(*this, tok::l_paren);
1408 if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept"))
1410 // C++11 [expr.unary.noexcept]p1:
1411 // The noexcept operator determines whether the evaluation of its operand,
1412 // which is an unevaluated operand, can throw an exception.
1413 EnterExpressionEvaluationContext Unevaluated(
1414 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1415 ExprResult Result = ParseExpression();
1419 if (!Result.isInvalid())
1420 Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(),
1421 Result.get(), T.getCloseLocation());
1425 #define TYPE_TRAIT(N,Spelling,K) \
1426 case tok::kw_##Spelling:
1427 #include "clang/Basic/TokenKinds.def"
1428 return ParseTypeTrait();
1430 case tok::kw___array_rank:
1431 case tok::kw___array_extent:
1432 return ParseArrayTypeTrait();
1434 case tok::kw___is_lvalue_expr:
1435 case tok::kw___is_rvalue_expr:
1436 return ParseExpressionTrait();
1439 SourceLocation AtLoc = ConsumeToken();
1440 return ParseObjCAtExpression(AtLoc);
1443 Res = ParseBlockLiteralExpression();
1445 case tok::code_completion: {
1446 Actions.CodeCompleteExpression(getCurScope(),
1447 PreferredType.get(Tok.getLocation()));
1452 if (getLangOpts().CPlusPlus11) {
1453 if (getLangOpts().ObjC) {
1454 // C++11 lambda expressions and Objective-C message sends both start with a
1455 // square bracket. There are three possibilities here:
1456 // we have a valid lambda expression, we have an invalid lambda
1457 // expression, or we have something that doesn't appear to be a lambda.
1458 // If we're in the last case, we fall back to ParseObjCMessageExpression.
1459 Res = TryParseLambdaExpression();
1460 if (!Res.isInvalid() && !Res.get())
1461 Res = ParseObjCMessageExpression();
1464 Res = ParseLambdaExpression();
1467 if (getLangOpts().ObjC) {
1468 Res = ParseObjCMessageExpression();
1477 // Check to see whether Res is a function designator only. If it is and we
1478 // are compiling for OpenCL, we need to return an error as this implies
1479 // that the address of the function is being taken, which is illegal in CL.
1481 // These can be followed by postfix-expr pieces.
1482 PreferredType = SavedType;
1483 Res = ParsePostfixExpressionSuffix(Res);
1484 if (getLangOpts().OpenCL)
1485 if (Expr *PostfixExpr = Res.get()) {
1486 QualType Ty = PostfixExpr->getType();
1487 if (!Ty.isNull() && Ty->isFunctionType()) {
1488 Diag(PostfixExpr->getExprLoc(),
1489 diag::err_opencl_taking_function_address_parser);
1497 /// Once the leading part of a postfix-expression is parsed, this
1498 /// method parses any suffixes that apply.
1501 /// postfix-expression: [C99 6.5.2]
1502 /// primary-expression
1503 /// postfix-expression '[' expression ']'
1504 /// postfix-expression '[' braced-init-list ']'
1505 /// postfix-expression '(' argument-expression-list[opt] ')'
1506 /// postfix-expression '.' identifier
1507 /// postfix-expression '->' identifier
1508 /// postfix-expression '++'
1509 /// postfix-expression '--'
1510 /// '(' type-name ')' '{' initializer-list '}'
1511 /// '(' type-name ')' '{' initializer-list ',' '}'
1513 /// argument-expression-list: [C99 6.5.2]
1514 /// argument-expression ...[opt]
1515 /// argument-expression-list ',' assignment-expression ...[opt]
1518 Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
1519 // Now that the primary-expression piece of the postfix-expression has been
1520 // parsed, see if there are any postfix-expression pieces here.
1522 auto SavedType = PreferredType;
1524 // Each iteration relies on preferred type for the whole expression.
1525 PreferredType = SavedType;
1526 switch (Tok.getKind()) {
1527 case tok::code_completion:
1528 if (InMessageExpression)
1531 Actions.CodeCompletePostfixExpression(
1532 getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
1536 case tok::identifier:
1537 // If we see identifier: after an expression, and we're not already in a
1538 // message send, then this is probably a message send with a missing
1539 // opening bracket '['.
1540 if (getLangOpts().ObjC && !InMessageExpression &&
1541 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
1542 LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1543 nullptr, LHS.get());
1546 // Fall through; this isn't a message send.
1549 default: // Not a postfix-expression suffix.
1551 case tok::l_square: { // postfix-expression: p-e '[' expression ']'
1552 // If we have a array postfix expression that starts on a new line and
1553 // Objective-C is enabled, it is highly likely that the user forgot a
1554 // semicolon after the base expression and that the array postfix-expr is
1555 // actually another message send. In this case, do some look-ahead to see
1556 // if the contents of the square brackets are obviously not a valid
1557 // expression and recover by pretending there is no suffix.
1558 if (getLangOpts().ObjC && Tok.isAtStartOfLine() &&
1559 isSimpleObjCMessageExpression())
1562 // Reject array indices starting with a lambda-expression. '[[' is
1563 // reserved for attributes.
1564 if (CheckProhibitedCXX11Attribute()) {
1565 (void)Actions.CorrectDelayedTyposInExpr(LHS);
1569 BalancedDelimiterTracker T(*this, tok::l_square);
1571 Loc = T.getOpenLocation();
1572 ExprResult Idx, Length;
1573 SourceLocation ColonLoc;
1574 PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get());
1575 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
1576 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1577 Idx = ParseBraceInitializer();
1578 } else if (getLangOpts().OpenMP) {
1579 ColonProtectionRAIIObject RAII(*this);
1580 // Parse [: or [ expr or [ expr :
1581 if (!Tok.is(tok::colon)) {
1583 Idx = ParseExpression();
1585 if (Tok.is(tok::colon)) {
1587 ColonLoc = ConsumeToken();
1588 if (Tok.isNot(tok::r_square))
1589 Length = ParseExpression();
1592 Idx = ParseExpression();
1594 SourceLocation RLoc = Tok.getLocation();
1596 LHS = Actions.CorrectDelayedTyposInExpr(LHS);
1597 Idx = Actions.CorrectDelayedTyposInExpr(Idx);
1598 Length = Actions.CorrectDelayedTyposInExpr(Length);
1599 if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() &&
1600 Tok.is(tok::r_square)) {
1601 if (ColonLoc.isValid()) {
1602 LHS = Actions.ActOnOMPArraySectionExpr(LHS.get(), Loc, Idx.get(),
1603 ColonLoc, Length.get(), RLoc);
1605 LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc,
1618 case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
1619 case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>'
1620 // '(' argument-expression-list[opt] ')'
1621 tok::TokenKind OpKind = Tok.getKind();
1622 InMessageExpressionRAIIObject InMessage(*this, false);
1624 Expr *ExecConfig = nullptr;
1626 BalancedDelimiterTracker PT(*this, tok::l_paren);
1628 if (OpKind == tok::lesslessless) {
1629 ExprVector ExecConfigExprs;
1630 CommaLocsTy ExecConfigCommaLocs;
1631 SourceLocation OpenLoc = ConsumeToken();
1633 if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) {
1634 (void)Actions.CorrectDelayedTyposInExpr(LHS);
1638 SourceLocation CloseLoc;
1639 if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) {
1640 } else if (LHS.isInvalid()) {
1641 SkipUntil(tok::greatergreatergreater, StopAtSemi);
1643 // There was an error closing the brackets
1644 Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
1645 Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
1646 SkipUntil(tok::greatergreatergreater, StopAtSemi);
1650 if (!LHS.isInvalid()) {
1651 if (ExpectAndConsume(tok::l_paren))
1654 Loc = PrevTokLocation;
1657 if (!LHS.isInvalid()) {
1658 ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(),
1662 if (ECResult.isInvalid())
1665 ExecConfig = ECResult.get();
1669 Loc = PT.getOpenLocation();
1672 ExprVector ArgExprs;
1673 CommaLocsTy CommaLocs;
1674 auto RunSignatureHelp = [&]() -> QualType {
1675 QualType PreferredType = Actions.ProduceCallSignatureHelp(
1676 getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
1677 CalledSignatureHelp = true;
1678 return PreferredType;
1680 if (OpKind == tok::l_paren || !LHS.isInvalid()) {
1681 if (Tok.isNot(tok::r_paren)) {
1682 if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
1683 PreferredType.enterFunctionArgument(Tok.getLocation(),
1686 (void)Actions.CorrectDelayedTyposInExpr(LHS);
1687 // If we got an error when parsing expression list, we don't call
1688 // the CodeCompleteCall handler inside the parser. So call it here
1689 // to make sure we get overload suggestions even when we are in the
1690 // middle of a parameter.
1691 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1694 } else if (LHS.isInvalid()) {
1695 for (auto &E : ArgExprs)
1696 Actions.CorrectDelayedTyposInExpr(E);
1702 if (LHS.isInvalid()) {
1703 SkipUntil(tok::r_paren, StopAtSemi);
1704 } else if (Tok.isNot(tok::r_paren)) {
1705 bool HadDelayedTypo = false;
1706 if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get())
1707 HadDelayedTypo = true;
1708 for (auto &E : ArgExprs)
1709 if (Actions.CorrectDelayedTyposInExpr(E).get() != E)
1710 HadDelayedTypo = true;
1711 // If there were delayed typos in the LHS or ArgExprs, call SkipUntil
1712 // instead of PT.consumeClose() to avoid emitting extra diagnostics for
1713 // the unmatched l_paren.
1715 SkipUntil(tok::r_paren, StopAtSemi);
1720 assert((ArgExprs.size() == 0 ||
1721 ArgExprs.size()-1 == CommaLocs.size())&&
1722 "Unexpected number of commas!");
1723 LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc,
1724 ArgExprs, Tok.getLocation(),
1733 // postfix-expression: p-e '->' template[opt] id-expression
1734 // postfix-expression: p-e '.' template[opt] id-expression
1735 tok::TokenKind OpKind = Tok.getKind();
1736 SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token.
1739 ParsedType ObjectType;
1740 bool MayBePseudoDestructor = false;
1741 Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr;
1743 PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS);
1745 if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
1746 Expr *Base = OrigLHS;
1747 const Type* BaseType = Base->getType().getTypePtrOrNull();
1748 if (BaseType && Tok.is(tok::l_paren) &&
1749 (BaseType->isFunctionType() ||
1750 BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) {
1751 Diag(OpLoc, diag::err_function_is_not_record)
1752 << OpKind << Base->getSourceRange()
1753 << FixItHint::CreateRemoval(OpLoc);
1754 return ParsePostfixExpressionSuffix(Base);
1757 LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base,
1758 OpLoc, OpKind, ObjectType,
1759 MayBePseudoDestructor);
1760 if (LHS.isInvalid())
1763 ParseOptionalCXXScopeSpecifier(SS, ObjectType,
1764 /*EnteringContext=*/false,
1765 &MayBePseudoDestructor);
1766 if (SS.isNotEmpty())
1767 ObjectType = nullptr;
1770 if (Tok.is(tok::code_completion)) {
1771 tok::TokenKind CorrectedOpKind =
1772 OpKind == tok::arrow ? tok::period : tok::arrow;
1773 ExprResult CorrectedLHS(/*Invalid=*/true);
1774 if (getLangOpts().CPlusPlus && OrigLHS) {
1775 const bool DiagsAreSuppressed = Diags.getSuppressAllDiagnostics();
1776 Diags.setSuppressAllDiagnostics(true);
1777 CorrectedLHS = Actions.ActOnStartCXXMemberReference(
1778 getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType,
1779 MayBePseudoDestructor);
1780 Diags.setSuppressAllDiagnostics(DiagsAreSuppressed);
1783 Expr *Base = LHS.get();
1784 Expr *CorrectedBase = CorrectedLHS.get();
1785 if (!CorrectedBase && !getLangOpts().CPlusPlus)
1786 CorrectedBase = Base;
1788 // Code completion for a member access expression.
1789 Actions.CodeCompleteMemberReferenceExpr(
1790 getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
1791 Base && ExprStatementTokLoc == Base->getBeginLoc(),
1792 PreferredType.get(Tok.getLocation()));
1798 if (MayBePseudoDestructor && !LHS.isInvalid()) {
1799 LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
1804 // Either the action has told us that this cannot be a
1805 // pseudo-destructor expression (based on the type of base
1806 // expression), or we didn't see a '~' in the right place. We
1807 // can still parse a destructor name here, but in that case it
1808 // names a real destructor.
1809 // Allow explicit constructor calls in Microsoft mode.
1810 // FIXME: Add support for explicit call of template constructor.
1811 SourceLocation TemplateKWLoc;
1813 if (getLangOpts().ObjC && OpKind == tok::period &&
1814 Tok.is(tok::kw_class)) {
1816 // After a '.' in a member access expression, treat the keyword
1817 // 'class' as if it were an identifier.
1819 // This hack allows property access to the 'class' method because it is
1820 // such a common method name. For other C++ keywords that are
1821 // Objective-C method names, one must use the message send syntax.
1822 IdentifierInfo *Id = Tok.getIdentifierInfo();
1823 SourceLocation Loc = ConsumeToken();
1824 Name.setIdentifier(Id, Loc);
1825 } else if (ParseUnqualifiedId(SS,
1826 /*EnteringContext=*/false,
1827 /*AllowDestructorName=*/true,
1828 /*AllowConstructorName=*/
1829 getLangOpts().MicrosoftExt &&
1831 /*AllowDeductionGuide=*/false,
1832 ObjectType, &TemplateKWLoc, Name)) {
1833 (void)Actions.CorrectDelayedTyposInExpr(LHS);
1837 if (!LHS.isInvalid())
1838 LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
1839 OpKind, SS, TemplateKWLoc, Name,
1840 CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
1842 if (!LHS.isInvalid() && Tok.is(tok::less))
1843 checkPotentialAngleBracket(LHS);
1846 case tok::plusplus: // postfix-expression: postfix-expression '++'
1847 case tok::minusminus: // postfix-expression: postfix-expression '--'
1848 if (!LHS.isInvalid()) {
1849 LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(),
1850 Tok.getKind(), LHS.get());
1858 /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/
1859 /// vec_step and we are at the start of an expression or a parenthesized
1860 /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the
1861 /// expression (isCastExpr == false) or the type (isCastExpr == true).
1864 /// unary-expression: [C99 6.5.3]
1865 /// 'sizeof' unary-expression
1866 /// 'sizeof' '(' type-name ')'
1867 /// [GNU] '__alignof' unary-expression
1868 /// [GNU] '__alignof' '(' type-name ')'
1869 /// [C11] '_Alignof' '(' type-name ')'
1870 /// [C++0x] 'alignof' '(' type-id ')'
1872 /// [GNU] typeof-specifier:
1873 /// typeof ( expressions )
1874 /// typeof ( type-name )
1875 /// [GNU/C++] typeof unary-expression
1877 /// [OpenCL 1.1 6.11.12] vec_step built-in function:
1878 /// vec_step ( expressions )
1879 /// vec_step ( type-name )
1882 Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
1885 SourceRange &CastRange) {
1887 assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof,
1888 tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step,
1889 tok::kw___builtin_omp_required_simd_align) &&
1890 "Not a typeof/sizeof/alignof/vec_step expression!");
1894 // If the operand doesn't start with an '(', it must be an expression.
1895 if (Tok.isNot(tok::l_paren)) {
1896 // If construct allows a form without parenthesis, user may forget to put
1897 // pathenthesis around type name.
1898 if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof,
1899 tok::kw__Alignof)) {
1900 if (isTypeIdUnambiguously()) {
1901 DeclSpec DS(AttrFactory);
1902 ParseSpecifierQualifierList(DS);
1903 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
1904 ParseDeclarator(DeclaratorInfo);
1906 SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation());
1907 SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation);
1908 Diag(LParenLoc, diag::err_expected_parentheses_around_typename)
1910 << FixItHint::CreateInsertion(LParenLoc, "(")
1911 << FixItHint::CreateInsertion(RParenLoc, ")");
1918 if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) {
1919 Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo()
1924 Operand = ParseCastExpression(true/*isUnaryExpression*/);
1926 // If it starts with a '(', we know that it is either a parenthesized
1927 // type-name, or it is a unary-expression that starts with a compound
1928 // literal, or starts with a primary-expression that is a parenthesized
1930 ParenParseOption ExprType = CastExpr;
1931 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
1933 Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
1934 false, CastTy, RParenLoc);
1935 CastRange = SourceRange(LParenLoc, RParenLoc);
1937 // If ParseParenExpression parsed a '(typename)' sequence only, then this is
1939 if (ExprType == CastExpr) {
1944 if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) {
1945 // GNU typeof in C requires the expression to be parenthesized. Not so for
1946 // sizeof/alignof or in C++. Therefore, the parenthesized expression is
1947 // the start of a unary-expression, but doesn't include any postfix
1948 // pieces. Parse these now if present.
1949 if (!Operand.isInvalid())
1950 Operand = ParsePostfixExpressionSuffix(Operand.get());
1954 // If we get here, the operand to the typeof/sizeof/alignof was an expression.
1960 /// Parse a sizeof or alignof expression.
1963 /// unary-expression: [C99 6.5.3]
1964 /// 'sizeof' unary-expression
1965 /// 'sizeof' '(' type-name ')'
1966 /// [C++11] 'sizeof' '...' '(' identifier ')'
1967 /// [GNU] '__alignof' unary-expression
1968 /// [GNU] '__alignof' '(' type-name ')'
1969 /// [C11] '_Alignof' '(' type-name ')'
1970 /// [C++11] 'alignof' '(' type-id ')'
1972 ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
1973 assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof,
1974 tok::kw__Alignof, tok::kw_vec_step,
1975 tok::kw___builtin_omp_required_simd_align) &&
1976 "Not a sizeof/alignof/vec_step expression!");
1980 // [C++11] 'sizeof' '...' '(' identifier ')'
1981 if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
1982 SourceLocation EllipsisLoc = ConsumeToken();
1983 SourceLocation LParenLoc, RParenLoc;
1984 IdentifierInfo *Name = nullptr;
1985 SourceLocation NameLoc;
1986 if (Tok.is(tok::l_paren)) {
1987 BalancedDelimiterTracker T(*this, tok::l_paren);
1989 LParenLoc = T.getOpenLocation();
1990 if (Tok.is(tok::identifier)) {
1991 Name = Tok.getIdentifierInfo();
1992 NameLoc = ConsumeToken();
1994 RParenLoc = T.getCloseLocation();
1995 if (RParenLoc.isInvalid())
1996 RParenLoc = PP.getLocForEndOfToken(NameLoc);
1998 Diag(Tok, diag::err_expected_parameter_pack);
1999 SkipUntil(tok::r_paren, StopAtSemi);
2001 } else if (Tok.is(tok::identifier)) {
2002 Name = Tok.getIdentifierInfo();
2003 NameLoc = ConsumeToken();
2004 LParenLoc = PP.getLocForEndOfToken(EllipsisLoc);
2005 RParenLoc = PP.getLocForEndOfToken(NameLoc);
2006 Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack)
2008 << FixItHint::CreateInsertion(LParenLoc, "(")
2009 << FixItHint::CreateInsertion(RParenLoc, ")");
2011 Diag(Tok, diag::err_sizeof_parameter_pack);
2017 EnterExpressionEvaluationContext Unevaluated(
2018 Actions, Sema::ExpressionEvaluationContext::Unevaluated,
2019 Sema::ReuseLambdaContextDecl);
2021 return Actions.ActOnSizeofParameterPackExpr(getCurScope(),
2022 OpTok.getLocation(),
2027 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2028 Diag(OpTok, diag::warn_cxx98_compat_alignof);
2030 EnterExpressionEvaluationContext Unevaluated(
2031 Actions, Sema::ExpressionEvaluationContext::Unevaluated,
2032 Sema::ReuseLambdaContextDecl);
2036 SourceRange CastRange;
2037 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok,
2042 UnaryExprOrTypeTrait ExprKind = UETT_SizeOf;
2043 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2044 ExprKind = UETT_AlignOf;
2045 else if (OpTok.is(tok::kw___alignof))
2046 ExprKind = UETT_PreferredAlignOf;
2047 else if (OpTok.is(tok::kw_vec_step))
2048 ExprKind = UETT_VecStep;
2049 else if (OpTok.is(tok::kw___builtin_omp_required_simd_align))
2050 ExprKind = UETT_OpenMPRequiredSimdAlign;
2053 return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
2056 CastTy.getAsOpaquePtr(),
2059 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2060 Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo();
2062 // If we get here, the operand to the sizeof/alignof was an expression.
2063 if (!Operand.isInvalid())
2064 Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
2072 /// ParseBuiltinPrimaryExpression
2075 /// primary-expression: [C99 6.5.1]
2076 /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
2077 /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
2078 /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
2080 /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
2081 /// [GNU] '__builtin_FILE' '(' ')'
2082 /// [GNU] '__builtin_FUNCTION' '(' ')'
2083 /// [GNU] '__builtin_LINE' '(' ')'
2084 /// [CLANG] '__builtin_COLUMN' '(' ')'
2085 /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')'
2087 /// [GNU] offsetof-member-designator:
2088 /// [GNU] identifier
2089 /// [GNU] offsetof-member-designator '.' identifier
2090 /// [GNU] offsetof-member-designator '[' expression ']'
2092 ExprResult Parser::ParseBuiltinPrimaryExpression() {
2094 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
2096 tok::TokenKind T = Tok.getKind();
2097 SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier.
2099 // All of these start with an open paren.
2100 if (Tok.isNot(tok::l_paren))
2101 return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII
2104 BalancedDelimiterTracker PT(*this, tok::l_paren);
2110 default: llvm_unreachable("Not a builtin primary expression!");
2111 case tok::kw___builtin_va_arg: {
2112 ExprResult Expr(ParseAssignmentExpression());
2114 if (ExpectAndConsume(tok::comma)) {
2115 SkipUntil(tok::r_paren, StopAtSemi);
2119 TypeResult Ty = ParseTypeName();
2121 if (Tok.isNot(tok::r_paren)) {
2122 Diag(Tok, diag::err_expected) << tok::r_paren;
2126 if (Expr.isInvalid() || Ty.isInvalid())
2129 Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen());
2132 case tok::kw___builtin_offsetof: {
2133 SourceLocation TypeLoc = Tok.getLocation();
2134 TypeResult Ty = ParseTypeName();
2135 if (Ty.isInvalid()) {
2136 SkipUntil(tok::r_paren, StopAtSemi);
2140 if (ExpectAndConsume(tok::comma)) {
2141 SkipUntil(tok::r_paren, StopAtSemi);
2145 // We must have at least one identifier here.
2146 if (Tok.isNot(tok::identifier)) {
2147 Diag(Tok, diag::err_expected) << tok::identifier;
2148 SkipUntil(tok::r_paren, StopAtSemi);
2152 // Keep track of the various subcomponents we see.
2153 SmallVector<Sema::OffsetOfComponent, 4> Comps;
2155 Comps.push_back(Sema::OffsetOfComponent());
2156 Comps.back().isBrackets = false;
2157 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2158 Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
2160 // FIXME: This loop leaks the index expressions on error.
2162 if (Tok.is(tok::period)) {
2163 // offsetof-member-designator: offsetof-member-designator '.' identifier
2164 Comps.push_back(Sema::OffsetOfComponent());
2165 Comps.back().isBrackets = false;
2166 Comps.back().LocStart = ConsumeToken();
2168 if (Tok.isNot(tok::identifier)) {
2169 Diag(Tok, diag::err_expected) << tok::identifier;
2170 SkipUntil(tok::r_paren, StopAtSemi);
2173 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2174 Comps.back().LocEnd = ConsumeToken();
2176 } else if (Tok.is(tok::l_square)) {
2177 if (CheckProhibitedCXX11Attribute())
2180 // offsetof-member-designator: offsetof-member-design '[' expression ']'
2181 Comps.push_back(Sema::OffsetOfComponent());
2182 Comps.back().isBrackets = true;
2183 BalancedDelimiterTracker ST(*this, tok::l_square);
2185 Comps.back().LocStart = ST.getOpenLocation();
2186 Res = ParseExpression();
2187 if (Res.isInvalid()) {
2188 SkipUntil(tok::r_paren, StopAtSemi);
2191 Comps.back().U.E = Res.get();
2194 Comps.back().LocEnd = ST.getCloseLocation();
2196 if (Tok.isNot(tok::r_paren)) {
2199 } else if (Ty.isInvalid()) {
2203 Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc,
2205 PT.getCloseLocation());
2212 case tok::kw___builtin_choose_expr: {
2213 ExprResult Cond(ParseAssignmentExpression());
2214 if (Cond.isInvalid()) {
2215 SkipUntil(tok::r_paren, StopAtSemi);
2218 if (ExpectAndConsume(tok::comma)) {
2219 SkipUntil(tok::r_paren, StopAtSemi);
2223 ExprResult Expr1(ParseAssignmentExpression());
2224 if (Expr1.isInvalid()) {
2225 SkipUntil(tok::r_paren, StopAtSemi);
2228 if (ExpectAndConsume(tok::comma)) {
2229 SkipUntil(tok::r_paren, StopAtSemi);
2233 ExprResult Expr2(ParseAssignmentExpression());
2234 if (Expr2.isInvalid()) {
2235 SkipUntil(tok::r_paren, StopAtSemi);
2238 if (Tok.isNot(tok::r_paren)) {
2239 Diag(Tok, diag::err_expected) << tok::r_paren;
2242 Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
2243 Expr2.get(), ConsumeParen());
2246 case tok::kw___builtin_astype: {
2247 // The first argument is an expression to be converted, followed by a comma.
2248 ExprResult Expr(ParseAssignmentExpression());
2249 if (Expr.isInvalid()) {
2250 SkipUntil(tok::r_paren, StopAtSemi);
2254 if (ExpectAndConsume(tok::comma)) {
2255 SkipUntil(tok::r_paren, StopAtSemi);
2259 // Second argument is the type to bitcast to.
2260 TypeResult DestTy = ParseTypeName();
2261 if (DestTy.isInvalid())
2264 // Attempt to consume the r-paren.
2265 if (Tok.isNot(tok::r_paren)) {
2266 Diag(Tok, diag::err_expected) << tok::r_paren;
2267 SkipUntil(tok::r_paren, StopAtSemi);
2271 Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc,
2275 case tok::kw___builtin_convertvector: {
2276 // The first argument is an expression to be converted, followed by a comma.
2277 ExprResult Expr(ParseAssignmentExpression());
2278 if (Expr.isInvalid()) {
2279 SkipUntil(tok::r_paren, StopAtSemi);
2283 if (ExpectAndConsume(tok::comma)) {
2284 SkipUntil(tok::r_paren, StopAtSemi);
2288 // Second argument is the type to bitcast to.
2289 TypeResult DestTy = ParseTypeName();
2290 if (DestTy.isInvalid())
2293 // Attempt to consume the r-paren.
2294 if (Tok.isNot(tok::r_paren)) {
2295 Diag(Tok, diag::err_expected) << tok::r_paren;
2296 SkipUntil(tok::r_paren, StopAtSemi);
2300 Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc,
2304 case tok::kw___builtin_COLUMN:
2305 case tok::kw___builtin_FILE:
2306 case tok::kw___builtin_FUNCTION:
2307 case tok::kw___builtin_LINE: {
2308 // Attempt to consume the r-paren.
2309 if (Tok.isNot(tok::r_paren)) {
2310 Diag(Tok, diag::err_expected) << tok::r_paren;
2311 SkipUntil(tok::r_paren, StopAtSemi);
2314 SourceLocExpr::IdentKind Kind = [&] {
2316 case tok::kw___builtin_FILE:
2317 return SourceLocExpr::File;
2318 case tok::kw___builtin_FUNCTION:
2319 return SourceLocExpr::Function;
2320 case tok::kw___builtin_LINE:
2321 return SourceLocExpr::Line;
2322 case tok::kw___builtin_COLUMN:
2323 return SourceLocExpr::Column;
2325 llvm_unreachable("invalid keyword");
2328 Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen());
2333 if (Res.isInvalid())
2336 // These can be followed by postfix-expr pieces because they are
2337 // primary-expressions.
2338 return ParsePostfixExpressionSuffix(Res.get());
2341 /// ParseParenExpression - This parses the unit that starts with a '(' token,
2342 /// based on what is allowed by ExprType. The actual thing parsed is returned
2343 /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
2344 /// not the parsed cast-expression.
2347 /// primary-expression: [C99 6.5.1]
2348 /// '(' expression ')'
2349 /// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
2350 /// postfix-expression: [C99 6.5.2]
2351 /// '(' type-name ')' '{' initializer-list '}'
2352 /// '(' type-name ')' '{' initializer-list ',' '}'
2353 /// cast-expression: [C99 6.5.4]
2354 /// '(' type-name ')' cast-expression
2355 /// [ARC] bridged-cast-expression
2356 /// [ARC] bridged-cast-expression:
2357 /// (__bridge type-name) cast-expression
2358 /// (__bridge_transfer type-name) cast-expression
2359 /// (__bridge_retained type-name) cast-expression
2360 /// fold-expression: [C++1z]
2361 /// '(' cast-expression fold-operator '...' ')'
2362 /// '(' '...' fold-operator cast-expression ')'
2363 /// '(' cast-expression fold-operator '...'
2364 /// fold-operator cast-expression ')'
2367 Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
2368 bool isTypeCast, ParsedType &CastTy,
2369 SourceLocation &RParenLoc) {
2370 assert(Tok.is(tok::l_paren) && "Not a paren expr!");
2371 ColonProtectionRAIIObject ColonProtection(*this, false);
2372 BalancedDelimiterTracker T(*this, tok::l_paren);
2373 if (T.consumeOpen())
2375 SourceLocation OpenLoc = T.getOpenLocation();
2377 PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
2379 ExprResult Result(true);
2380 bool isAmbiguousTypeId;
2383 if (Tok.is(tok::code_completion)) {
2384 Actions.CodeCompleteExpression(
2385 getCurScope(), PreferredType.get(Tok.getLocation()),
2386 /*IsParenthesized=*/ExprType >= CompoundLiteral);
2391 // Diagnose use of bridge casts in non-arc mode.
2392 bool BridgeCast = (getLangOpts().ObjC &&
2393 Tok.isOneOf(tok::kw___bridge,
2394 tok::kw___bridge_transfer,
2395 tok::kw___bridge_retained,
2396 tok::kw___bridge_retain));
2397 if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
2398 if (!TryConsumeToken(tok::kw___bridge)) {
2399 StringRef BridgeCastName = Tok.getName();
2400 SourceLocation BridgeKeywordLoc = ConsumeToken();
2401 if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
2402 Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
2404 << FixItHint::CreateReplacement(BridgeKeywordLoc, "");
2409 // None of these cases should fall through with an invalid Result
2410 // unless they've already reported an error.
2411 if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
2412 Diag(Tok, diag::ext_gnu_statement_expr);
2414 if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
2415 Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
2417 // Find the nearest non-record decl context. Variables declared in a
2418 // statement expression behave as if they were declared in the enclosing
2419 // function, block, or other code construct.
2420 DeclContext *CodeDC = Actions.CurContext;
2421 while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) {
2422 CodeDC = CodeDC->getParent();
2423 assert(CodeDC && !CodeDC->isFileContext() &&
2424 "statement expr not in code context");
2426 Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false);
2428 Actions.ActOnStartStmtExpr();
2430 StmtResult Stmt(ParseCompoundStatement(true));
2431 ExprType = CompoundStmt;
2433 // If the substmt parsed correctly, build the AST node.
2434 if (!Stmt.isInvalid()) {
2435 Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
2437 Actions.ActOnStmtExprError();
2440 } else if (ExprType >= CompoundLiteral && BridgeCast) {
2441 tok::TokenKind tokenKind = Tok.getKind();
2442 SourceLocation BridgeKeywordLoc = ConsumeToken();
2444 // Parse an Objective-C ARC ownership cast expression.
2445 ObjCBridgeCastKind Kind;
2446 if (tokenKind == tok::kw___bridge)
2448 else if (tokenKind == tok::kw___bridge_transfer)
2449 Kind = OBC_BridgeTransfer;
2450 else if (tokenKind == tok::kw___bridge_retained)
2451 Kind = OBC_BridgeRetained;
2453 // As a hopefully temporary workaround, allow __bridge_retain as
2454 // a synonym for __bridge_retained, but only in system headers.
2455 assert(tokenKind == tok::kw___bridge_retain);
2456 Kind = OBC_BridgeRetained;
2457 if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
2458 Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
2459 << FixItHint::CreateReplacement(BridgeKeywordLoc,
2460 "__bridge_retained");
2463 TypeResult Ty = ParseTypeName();
2465 ColonProtection.restore();
2466 RParenLoc = T.getCloseLocation();
2468 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get());
2469 ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
2471 if (Ty.isInvalid() || SubExpr.isInvalid())
2474 return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind,
2475 BridgeKeywordLoc, Ty.get(),
2476 RParenLoc, SubExpr.get());
2477 } else if (ExprType >= CompoundLiteral &&
2478 isTypeIdInParens(isAmbiguousTypeId)) {
2480 // Otherwise, this is a compound literal expression or cast expression.
2482 // In C++, if the type-id is ambiguous we disambiguate based on context.
2483 // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
2484 // in which case we should treat it as type-id.
2485 // if stopIfCastExpr is false, we need to determine the context past the
2486 // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
2487 if (isAmbiguousTypeId && !stopIfCastExpr) {
2488 ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
2490 RParenLoc = T.getCloseLocation();
2494 // Parse the type declarator.
2495 DeclSpec DS(AttrFactory);
2496 ParseSpecifierQualifierList(DS);
2497 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
2498 ParseDeclarator(DeclaratorInfo);
2500 // If our type is followed by an identifier and either ':' or ']', then
2501 // this is probably an Objective-C message send where the leading '[' is
2502 // missing. Recover as if that were the case.
2503 if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
2504 !InMessageExpression && getLangOpts().ObjC &&
2505 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
2508 InMessageExpressionRAIIObject InMessage(*this, false);
2509 Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
2511 Result = ParseObjCMessageExpressionBody(SourceLocation(),
2517 ColonProtection.restore();
2518 RParenLoc = T.getCloseLocation();
2519 if (Tok.is(tok::l_brace)) {
2520 ExprType = CompoundLiteral;
2523 InMessageExpressionRAIIObject InMessage(*this, false);
2524 Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
2526 return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
2529 if (Tok.is(tok::l_paren)) {
2530 // This could be OpenCL vector Literals
2531 if (getLangOpts().OpenCL)
2535 InMessageExpressionRAIIObject InMessage(*this, false);
2536 Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
2542 QualType QT = Ty.get().get().getCanonicalType();
2543 if (QT->isVectorType())
2545 // We parsed '(' vector-type-name ')' followed by '('
2547 // Parse the cast-expression that follows it next.
2548 // isVectorLiteral = true will make sure we don't parse any
2549 // Postfix expression yet
2550 Result = ParseCastExpression(/*isUnaryExpression=*/false,
2551 /*isAddressOfOperand=*/false,
2552 /*isTypeCast=*/IsTypeCast,
2553 /*isVectorLiteral=*/true);
2555 if (!Result.isInvalid()) {
2556 Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
2557 DeclaratorInfo, CastTy,
2558 RParenLoc, Result.get());
2561 // After we performed the cast we can check for postfix-expr pieces.
2562 if (!Result.isInvalid()) {
2563 Result = ParsePostfixExpressionSuffix(Result);
2571 if (ExprType == CastExpr) {
2572 // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
2574 if (DeclaratorInfo.isInvalidType())
2577 // Note that this doesn't parse the subsequent cast-expression, it just
2578 // returns the parsed type to the callee.
2579 if (stopIfCastExpr) {
2582 InMessageExpressionRAIIObject InMessage(*this, false);
2583 Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
2586 return ExprResult();
2589 // Reject the cast of super idiom in ObjC.
2590 if (Tok.is(tok::identifier) && getLangOpts().ObjC &&
2591 Tok.getIdentifierInfo() == Ident_super &&
2592 getCurScope()->isInObjcMethodScope() &&
2593 GetLookAheadToken(1).isNot(tok::period)) {
2594 Diag(Tok.getLocation(), diag::err_illegal_super_cast)
2595 << SourceRange(OpenLoc, RParenLoc);
2599 PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get());
2600 // Parse the cast-expression that follows it next.
2601 // TODO: For cast expression with CastTy.
2602 Result = ParseCastExpression(/*isUnaryExpression=*/false,
2603 /*isAddressOfOperand=*/false,
2604 /*isTypeCast=*/IsTypeCast);
2605 if (!Result.isInvalid()) {
2606 Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
2607 DeclaratorInfo, CastTy,
2608 RParenLoc, Result.get());
2613 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
2616 } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) &&
2617 isFoldOperator(NextToken().getKind())) {
2618 ExprType = FoldExpr;
2619 return ParseFoldExpression(ExprResult(), T);
2620 } else if (isTypeCast) {
2621 // Parse the expression-list.
2622 InMessageExpressionRAIIObject InMessage(*this, false);
2624 ExprVector ArgExprs;
2625 CommaLocsTy CommaLocs;
2627 if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) {
2628 // FIXME: If we ever support comma expressions as operands to
2629 // fold-expressions, we'll need to allow multiple ArgExprs here.
2630 if (ExprType >= FoldExpr && ArgExprs.size() == 1 &&
2631 isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
2632 ExprType = FoldExpr;
2633 return ParseFoldExpression(ArgExprs[0], T);
2636 ExprType = SimpleExpr;
2637 Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
2641 InMessageExpressionRAIIObject InMessage(*this, false);
2643 Result = ParseExpression(MaybeTypeCast);
2644 if (!getLangOpts().CPlusPlus && MaybeTypeCast && Result.isUsable()) {
2645 // Correct typos in non-C++ code earlier so that implicit-cast-like
2646 // expressions are parsed correctly.
2647 Result = Actions.CorrectDelayedTyposInExpr(Result);
2650 if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) &&
2651 NextToken().is(tok::ellipsis)) {
2652 ExprType = FoldExpr;
2653 return ParseFoldExpression(Result, T);
2655 ExprType = SimpleExpr;
2657 // Don't build a paren expression unless we actually match a ')'.
2658 if (!Result.isInvalid() && Tok.is(tok::r_paren))
2660 Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get());
2664 if (Result.isInvalid()) {
2665 SkipUntil(tok::r_paren, StopAtSemi);
2670 RParenLoc = T.getCloseLocation();
2674 /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
2675 /// and we are at the left brace.
2678 /// postfix-expression: [C99 6.5.2]
2679 /// '(' type-name ')' '{' initializer-list '}'
2680 /// '(' type-name ')' '{' initializer-list ',' '}'
2683 Parser::ParseCompoundLiteralExpression(ParsedType Ty,
2684 SourceLocation LParenLoc,
2685 SourceLocation RParenLoc) {
2686 assert(Tok.is(tok::l_brace) && "Not a compound literal!");
2687 if (!getLangOpts().C99) // Compound literals don't exist in C90.
2688 Diag(LParenLoc, diag::ext_c99_compound_literal);
2689 ExprResult Result = ParseInitializer();
2690 if (!Result.isInvalid() && Ty)
2691 return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
2695 /// ParseStringLiteralExpression - This handles the various token types that
2696 /// form string literals, and also handles string concatenation [C99 5.1.1.2,
2697 /// translation phase #6].
2700 /// primary-expression: [C99 6.5.1]
2703 ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) {
2704 assert(isTokenStringLiteral() && "Not a string literal!");
2706 // String concat. Note that keywords like __func__ and __FUNCTION__ are not
2707 // considered to be strings for concatenation purposes.
2708 SmallVector<Token, 4> StringToks;
2711 StringToks.push_back(Tok);
2712 ConsumeStringToken();
2713 } while (isTokenStringLiteral());
2715 // Pass the set of string tokens, ready for concatenation, to the actions.
2716 return Actions.ActOnStringLiteral(StringToks,
2717 AllowUserDefinedLiteral ? getCurScope()
2721 /// ParseGenericSelectionExpression - Parse a C11 generic-selection
2725 /// generic-selection:
2726 /// _Generic ( assignment-expression , generic-assoc-list )
2727 /// generic-assoc-list:
2728 /// generic-association
2729 /// generic-assoc-list , generic-association
2730 /// generic-association:
2731 /// type-name : assignment-expression
2732 /// default : assignment-expression
2734 ExprResult Parser::ParseGenericSelectionExpression() {
2735 assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
2736 SourceLocation KeyLoc = ConsumeToken();
2738 if (!getLangOpts().C11)
2739 Diag(KeyLoc, diag::ext_c11_generic_selection);
2741 BalancedDelimiterTracker T(*this, tok::l_paren);
2742 if (T.expectAndConsume())
2745 ExprResult ControllingExpr;
2747 // C11 6.5.1.1p3 "The controlling expression of a generic selection is
2749 EnterExpressionEvaluationContext Unevaluated(
2750 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
2752 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2753 if (ControllingExpr.isInvalid()) {
2754 SkipUntil(tok::r_paren, StopAtSemi);
2759 if (ExpectAndConsume(tok::comma)) {
2760 SkipUntil(tok::r_paren, StopAtSemi);
2764 SourceLocation DefaultLoc;
2769 if (Tok.is(tok::kw_default)) {
2770 // C11 6.5.1.1p2 "A generic selection shall have no more than one default
2771 // generic association."
2772 if (!DefaultLoc.isInvalid()) {
2773 Diag(Tok, diag::err_duplicate_default_assoc);
2774 Diag(DefaultLoc, diag::note_previous_default_assoc);
2775 SkipUntil(tok::r_paren, StopAtSemi);
2778 DefaultLoc = ConsumeToken();
2781 ColonProtectionRAIIObject X(*this);
2782 TypeResult TR = ParseTypeName();
2783 if (TR.isInvalid()) {
2784 SkipUntil(tok::r_paren, StopAtSemi);
2789 Types.push_back(Ty);
2791 if (ExpectAndConsume(tok::colon)) {
2792 SkipUntil(tok::r_paren, StopAtSemi);
2796 // FIXME: These expressions should be parsed in a potentially potentially
2797 // evaluated context.
2799 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
2800 if (ER.isInvalid()) {
2801 SkipUntil(tok::r_paren, StopAtSemi);
2804 Exprs.push_back(ER.get());
2805 } while (TryConsumeToken(tok::comma));
2808 if (T.getCloseLocation().isInvalid())
2811 return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc,
2812 T.getCloseLocation(),
2813 ControllingExpr.get(),
2817 /// Parse A C++1z fold-expression after the opening paren and optional
2818 /// left-hand-side expression.
2821 /// fold-expression:
2822 /// ( cast-expression fold-operator ... )
2823 /// ( ... fold-operator cast-expression )
2824 /// ( cast-expression fold-operator ... fold-operator cast-expression )
2825 ExprResult Parser::ParseFoldExpression(ExprResult LHS,
2826 BalancedDelimiterTracker &T) {
2827 if (LHS.isInvalid()) {
2832 tok::TokenKind Kind = tok::unknown;
2833 SourceLocation FirstOpLoc;
2834 if (LHS.isUsable()) {
2835 Kind = Tok.getKind();
2836 assert(isFoldOperator(Kind) && "missing fold-operator");
2837 FirstOpLoc = ConsumeToken();
2840 assert(Tok.is(tok::ellipsis) && "not a fold-expression");
2841 SourceLocation EllipsisLoc = ConsumeToken();
2844 if (Tok.isNot(tok::r_paren)) {
2845 if (!isFoldOperator(Tok.getKind()))
2846 return Diag(Tok.getLocation(), diag::err_expected_fold_operator);
2848 if (Kind != tok::unknown && Tok.getKind() != Kind)
2849 Diag(Tok.getLocation(), diag::err_fold_operator_mismatch)
2850 << SourceRange(FirstOpLoc);
2851 Kind = Tok.getKind();
2854 RHS = ParseExpression();
2855 if (RHS.isInvalid()) {
2861 Diag(EllipsisLoc, getLangOpts().CPlusPlus17
2862 ? diag::warn_cxx14_compat_fold_expression
2863 : diag::ext_fold_expression);
2866 return Actions.ActOnCXXFoldExpr(T.getOpenLocation(), LHS.get(), Kind,
2867 EllipsisLoc, RHS.get(), T.getCloseLocation());
2870 /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
2873 /// argument-expression-list:
2874 /// assignment-expression
2875 /// argument-expression-list , assignment-expression
2877 /// [C++] expression-list:
2878 /// [C++] assignment-expression
2879 /// [C++] expression-list , assignment-expression
2881 /// [C++0x] expression-list:
2882 /// [C++0x] initializer-list
2884 /// [C++0x] initializer-list
2885 /// [C++0x] initializer-clause ...[opt]
2886 /// [C++0x] initializer-list , initializer-clause ...[opt]
2888 /// [C++0x] initializer-clause:
2889 /// [C++0x] assignment-expression
2890 /// [C++0x] braced-init-list
2892 bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
2893 SmallVectorImpl<SourceLocation> &CommaLocs,
2894 llvm::function_ref<void()> ExpressionStarts) {
2895 bool SawError = false;
2897 if (ExpressionStarts)
2901 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
2902 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2903 Expr = ParseBraceInitializer();
2905 Expr = ParseAssignmentExpression();
2907 if (Tok.is(tok::ellipsis))
2908 Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
2909 if (Expr.isInvalid()) {
2910 SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
2913 Exprs.push_back(Expr.get());
2916 if (Tok.isNot(tok::comma))
2918 // Move to the next argument, remember where the comma was.
2920 CommaLocs.push_back(ConsumeToken());
2922 checkPotentialAngleBracketDelimiter(Comma);
2925 // Ensure typos get diagnosed when errors were encountered while parsing the
2927 for (auto &E : Exprs) {
2928 ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E);
2929 if (Expr.isUsable()) E = Expr.get();
2935 /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
2936 /// used for misc language extensions.
2939 /// simple-expression-list:
2940 /// assignment-expression
2941 /// simple-expression-list , assignment-expression
2944 Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
2945 SmallVectorImpl<SourceLocation> &CommaLocs) {
2947 ExprResult Expr = ParseAssignmentExpression();
2948 if (Expr.isInvalid())
2951 Exprs.push_back(Expr.get());
2953 if (Tok.isNot(tok::comma))
2956 // Move to the next argument, remember where the comma was.
2958 CommaLocs.push_back(ConsumeToken());
2960 checkPotentialAngleBracketDelimiter(Comma);
2964 /// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
2967 /// [clang] block-id:
2968 /// [clang] specifier-qualifier-list block-declarator
2970 void Parser::ParseBlockId(SourceLocation CaretLoc) {
2971 if (Tok.is(tok::code_completion)) {
2972 Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
2973 return cutOffParsing();
2976 // Parse the specifier-qualifier-list piece.
2977 DeclSpec DS(AttrFactory);
2978 ParseSpecifierQualifierList(DS);
2980 // Parse the block-declarator.
2981 Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteralContext);
2982 DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition);
2983 ParseDeclarator(DeclaratorInfo);
2985 MaybeParseGNUAttributes(DeclaratorInfo);
2987 // Inform sema that we are starting a block.
2988 Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
2991 /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
2992 /// like ^(int x){ return x+1; }
2996 /// [clang] '^' block-args[opt] compound-statement
2997 /// [clang] '^' block-id compound-statement
2998 /// [clang] block-args:
2999 /// [clang] '(' parameter-list ')'
3001 ExprResult Parser::ParseBlockLiteralExpression() {
3002 assert(Tok.is(tok::caret) && "block literal starts with ^");
3003 SourceLocation CaretLoc = ConsumeToken();
3005 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc,
3006 "block literal parsing");
3008 // Enter a scope to hold everything within the block. This includes the
3009 // argument decls, decls within the compound expression, etc. This also
3010 // allows determining whether a variable reference inside the block is
3011 // within or outside of the block.
3012 ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
3013 Scope::CompoundStmtScope | Scope::DeclScope);
3015 // Inform sema that we are starting a block.
3016 Actions.ActOnBlockStart(CaretLoc, getCurScope());
3018 // Parse the return type if present.
3019 DeclSpec DS(AttrFactory);
3020 Declarator ParamInfo(DS, DeclaratorContext::BlockLiteralContext);
3021 ParamInfo.setFunctionDefinitionKind(FDK_Definition);
3022 // FIXME: Since the return type isn't actually parsed, it can't be used to
3023 // fill ParamInfo with an initial valid range, so do it manually.
3024 ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
3026 // If this block has arguments, parse them. There is no ambiguity here with
3027 // the expression case, because the expression case requires a parameter list.
3028 if (Tok.is(tok::l_paren)) {
3029 ParseParenDeclarator(ParamInfo);
3030 // Parse the pieces after the identifier as if we had "int(...)".
3031 // SetIdentifier sets the source range end, but in this case we're past
3033 SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
3034 ParamInfo.SetIdentifier(nullptr, CaretLoc);
3035 ParamInfo.SetRangeEnd(Tmp);
3036 if (ParamInfo.isInvalidType()) {
3037 // If there was an error parsing the arguments, they may have
3038 // tried to use ^(x+y) which requires an argument list. Just
3039 // skip the whole block literal.
3040 Actions.ActOnBlockError(CaretLoc, getCurScope());
3044 MaybeParseGNUAttributes(ParamInfo);
3046 // Inform sema that we are starting a block.
3047 Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3048 } else if (!Tok.is(tok::l_brace)) {
3049 ParseBlockId(CaretLoc);
3051 // Otherwise, pretend we saw (void).
3052 SourceLocation NoLoc;
3053 ParamInfo.AddTypeInfo(
3054 DeclaratorChunk::getFunction(/*HasProto=*/true,
3055 /*IsAmbiguous=*/false,
3056 /*RParenLoc=*/NoLoc,
3057 /*ArgInfo=*/nullptr,
3059 /*EllipsisLoc=*/NoLoc,
3060 /*RParenLoc=*/NoLoc,
3061 /*RefQualifierIsLvalueRef=*/true,
3062 /*RefQualifierLoc=*/NoLoc,
3063 /*MutableLoc=*/NoLoc, EST_None,
3064 /*ESpecRange=*/SourceRange(),
3065 /*Exceptions=*/nullptr,
3066 /*ExceptionRanges=*/nullptr,
3067 /*NumExceptions=*/0,
3068 /*NoexceptExpr=*/nullptr,
3069 /*ExceptionSpecTokens=*/nullptr,
3070 /*DeclsInPrototype=*/None, CaretLoc,
3071 CaretLoc, ParamInfo),
3074 MaybeParseGNUAttributes(ParamInfo);
3076 // Inform sema that we are starting a block.
3077 Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3081 ExprResult Result(true);
3082 if (!Tok.is(tok::l_brace)) {
3083 // Saw something like: ^expr
3084 Diag(Tok, diag::err_expected_expression);
3085 Actions.ActOnBlockError(CaretLoc, getCurScope());
3089 StmtResult Stmt(ParseCompoundStatementBody());
3091 if (!Stmt.isInvalid())
3092 Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
3094 Actions.ActOnBlockError(CaretLoc, getCurScope());
3098 /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
3102 ExprResult Parser::ParseObjCBoolLiteral() {
3103 tok::TokenKind Kind = Tok.getKind();
3104 return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind);
3107 /// Validate availability spec list, emitting diagnostics if necessary. Returns
3108 /// true if invalid.
3109 static bool CheckAvailabilitySpecList(Parser &P,
3110 ArrayRef<AvailabilitySpec> AvailSpecs) {
3111 llvm::SmallSet<StringRef, 4> Platforms;
3112 bool HasOtherPlatformSpec = false;
3114 for (const auto &Spec : AvailSpecs) {
3115 if (Spec.isOtherPlatformSpec()) {
3116 if (HasOtherPlatformSpec) {
3117 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star);
3121 HasOtherPlatformSpec = true;
3125 bool Inserted = Platforms.insert(Spec.getPlatform()).second;
3127 // Rule out multiple version specs referring to the same platform.
3128 // For example, we emit an error for:
3129 // @available(macos 10.10, macos 10.11, *)
3130 StringRef Platform = Spec.getPlatform();
3131 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform)
3132 << Spec.getEndLoc() << Platform;
3137 if (!HasOtherPlatformSpec) {
3138 SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc();
3139 P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required)
3140 << FixItHint::CreateInsertion(InsertWildcardLoc, ", *");
3147 /// Parse availability query specification.
3149 /// availability-spec:
3151 /// identifier version-tuple
3152 Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
3153 if (Tok.is(tok::star)) {
3154 return AvailabilitySpec(ConsumeToken());
3156 // Parse the platform name.
3157 if (Tok.is(tok::code_completion)) {
3158 Actions.CodeCompleteAvailabilityPlatformName();
3162 if (Tok.isNot(tok::identifier)) {
3163 Diag(Tok, diag::err_avail_query_expected_platform_name);
3167 IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc();
3168 SourceRange VersionRange;
3169 VersionTuple Version = ParseVersionTuple(VersionRange);
3171 if (Version.empty())
3174 StringRef GivenPlatform = PlatformIdentifier->Ident->getName();
3175 StringRef Platform =
3176 AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
3178 if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) {
3179 Diag(PlatformIdentifier->Loc,
3180 diag::err_avail_query_unrecognized_platform_name)
3185 return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc,
3186 VersionRange.getEnd());
3190 ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) {
3191 assert(Tok.is(tok::kw___builtin_available) ||
3192 Tok.isObjCAtKeyword(tok::objc_available));
3194 // Eat the available or __builtin_available.
3197 BalancedDelimiterTracker Parens(*this, tok::l_paren);
3198 if (Parens.expectAndConsume())
3201 SmallVector<AvailabilitySpec, 4> AvailSpecs;
3202 bool HasError = false;
3204 Optional<AvailabilitySpec> Spec = ParseAvailabilitySpec();
3208 AvailSpecs.push_back(*Spec);
3210 if (!TryConsumeToken(tok::comma))
3215 SkipUntil(tok::r_paren, StopAtSemi);
3219 CheckAvailabilitySpecList(*this, AvailSpecs);
3221 if (Parens.consumeClose())
3224 return Actions.ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc,
3225 Parens.getCloseLocation());