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