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