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