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