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

source code of clang/lib/Parse/ParseExpr.cpp