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