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