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_typeof_unqual:
1347 case tok::kw___vector:
1348 case tok::kw__Accum:
1349 case tok::kw__Fract:
1350 case tok::kw__Sat:
1351#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1352#include "clang/Basic/OpenCLImageTypes.def"
1353#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1354#include "clang/Basic/HLSLIntangibleTypes.def"
1355 {
1356 if (!getLangOpts().CPlusPlus) {
1357 Diag(Tok, diag::err_expected_expression);
1358 return ExprError();
1359 }
1360
1361 // Everything henceforth is a postfix-expression.
1362 if (NotPrimaryExpression)
1363 *NotPrimaryExpression = true;
1364
1365 if (SavedKind == tok::kw_typename) {
1366 // postfix-expression: typename-specifier '(' expression-list[opt] ')'
1367 // typename-specifier braced-init-list
1369 return ExprError();
1370
1371 if (!Tok.isSimpleTypeSpecifier(getLangOpts()))
1372 // We are trying to parse a simple-type-specifier but might not get such
1373 // a token after error recovery.
1374 return ExprError();
1375 }
1376
1377 // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
1378 // simple-type-specifier braced-init-list
1379 //
1380 DeclSpec DS(AttrFactory);
1381
1382 ParseCXXSimpleTypeSpecifier(DS);
1383 if (Tok.isNot(tok::l_paren) &&
1384 (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace)))
1385 return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
1386 << DS.getSourceRange());
1387
1388 if (Tok.is(tok::l_brace))
1389 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1390
1391 Res = ParseCXXTypeConstructExpression(DS);
1392 break;
1393 }
1394
1395 case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
1396 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1397 // (We can end up in this situation after tentative parsing.)
1399 return ExprError();
1400 if (!Tok.is(tok::annot_cxxscope))
1401 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1402 CorrectionBehavior, isVectorLiteral,
1403 NotPrimaryExpression);
1404
1405 Token Next = NextToken();
1406 if (Next.is(tok::annot_template_id)) {
1407 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
1408 if (TemplateId->Kind == TNK_Type_template) {
1409 // We have a qualified template-id that we know refers to a
1410 // type, translate it into a type and continue parsing as a
1411 // cast expression.
1412 CXXScopeSpec SS;
1413 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1414 /*ObjectHasErrors=*/false,
1415 /*EnteringContext=*/false);
1416 AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes);
1417 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1418 CorrectionBehavior, isVectorLiteral,
1419 NotPrimaryExpression);
1420 }
1421 }
1422
1423 // Parse as an id-expression.
1424 Res = ParseCXXIdExpression(isAddressOfOperand);
1425 break;
1426 }
1427
1428 case tok::annot_template_id: { // [C++] template-id
1429 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1430 if (TemplateId->Kind == TNK_Type_template) {
1431 // We have a template-id that we know refers to a type,
1432 // translate it into a type and continue parsing as a cast
1433 // expression.
1434 CXXScopeSpec SS;
1435 AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes);
1436 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1437 CorrectionBehavior, isVectorLiteral,
1438 NotPrimaryExpression);
1439 }
1440
1441 // Fall through to treat the template-id as an id-expression.
1442 [[fallthrough]];
1443 }
1444
1445 case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
1446 Res = ParseCXXIdExpression(isAddressOfOperand);
1447 break;
1448
1449 case tok::coloncolon: {
1450 // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken
1451 // annotates the token, tail recurse.
1453 return ExprError();
1454 if (!Tok.is(tok::coloncolon))
1455 return ParseCastExpression(ParseKind, isAddressOfOperand,
1456 CorrectionBehavior, isVectorLiteral,
1457 NotPrimaryExpression);
1458
1459 // ::new -> [C++] new-expression
1460 // ::delete -> [C++] delete-expression
1461 SourceLocation CCLoc = ConsumeToken();
1462 if (Tok.is(tok::kw_new)) {
1463 if (NotPrimaryExpression)
1464 *NotPrimaryExpression = true;
1465 Res = ParseCXXNewExpression(true, CCLoc);
1466 AllowSuffix = false;
1467 break;
1468 }
1469 if (Tok.is(tok::kw_delete)) {
1470 if (NotPrimaryExpression)
1471 *NotPrimaryExpression = true;
1472 Res = ParseCXXDeleteExpression(true, CCLoc);
1473 AllowSuffix = false;
1474 break;
1475 }
1476
1477 // This is not a type name or scope specifier, it is an invalid expression.
1478 Diag(CCLoc, diag::err_expected_expression);
1479 return ExprError();
1480 }
1481
1482 case tok::kw_new: // [C++] new-expression
1483 if (NotPrimaryExpression)
1484 *NotPrimaryExpression = true;
1485 Res = ParseCXXNewExpression(false, Tok.getLocation());
1486 AllowSuffix = false;
1487 break;
1488
1489 case tok::kw_delete: // [C++] delete-expression
1490 if (NotPrimaryExpression)
1491 *NotPrimaryExpression = true;
1492 Res = ParseCXXDeleteExpression(false, Tok.getLocation());
1493 AllowSuffix = false;
1494 break;
1495
1496 case tok::kw_requires: // [C++2a] requires-expression
1497 Res = ParseRequiresExpression();
1498 AllowSuffix = false;
1499 break;
1500
1501 case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')'
1502 if (NotPrimaryExpression)
1503 *NotPrimaryExpression = true;
1504 Diag(Tok, diag::warn_cxx98_compat_noexcept_expr);
1505 SourceLocation KeyLoc = ConsumeToken();
1506 BalancedDelimiterTracker T(*this, tok::l_paren);
1507
1508 if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept"))
1509 return ExprError();
1510 // C++11 [expr.unary.noexcept]p1:
1511 // The noexcept operator determines whether the evaluation of its operand,
1512 // which is an unevaluated operand, can throw an exception.
1513 EnterExpressionEvaluationContext Unevaluated(
1515 Res = ParseExpression();
1516
1517 T.consumeClose();
1518
1519 if (!Res.isInvalid())
1520 Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(),
1521 T.getCloseLocation());
1522 AllowSuffix = false;
1523 break;
1524 }
1525
1526#define TYPE_TRAIT(N,Spelling,K) \
1527 case tok::kw_##Spelling:
1528#include "clang/Basic/TokenKinds.def"
1529 Res = ParseTypeTrait();
1530 break;
1531
1532 case tok::kw___array_rank:
1533 case tok::kw___array_extent:
1534 if (NotPrimaryExpression)
1535 *NotPrimaryExpression = true;
1536 Res = ParseArrayTypeTrait();
1537 break;
1538
1539 case tok::kw___builtin_ptrauth_type_discriminator:
1540 return ParseBuiltinPtrauthTypeDiscriminator();
1541
1542 case tok::kw___is_lvalue_expr:
1543 case tok::kw___is_rvalue_expr:
1544 if (NotPrimaryExpression)
1545 *NotPrimaryExpression = true;
1546 Res = ParseExpressionTrait();
1547 break;
1548
1549 case tok::at: {
1550 if (NotPrimaryExpression)
1551 *NotPrimaryExpression = true;
1552 SourceLocation AtLoc = ConsumeToken();
1553 return ParseObjCAtExpression(AtLoc);
1554 }
1555 case tok::caret:
1556 Res = ParseBlockLiteralExpression();
1557 break;
1558 case tok::code_completion: {
1559 cutOffParsing();
1560 Actions.CodeCompletion().CodeCompleteExpression(
1561 getCurScope(), PreferredType.get(Tok.getLocation()),
1562 /*IsParenthesized=*/false, /*IsAddressOfOperand=*/isAddressOfOperand);
1563 return ExprError();
1564 }
1565#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1566#include "clang/Basic/TransformTypeTraits.def"
1567 // HACK: libstdc++ uses some of the transform-type-traits as alias
1568 // templates, so we need to work around this.
1569 if (!NextToken().is(tok::l_paren)) {
1570 Tok.setKind(tok::identifier);
1571 Diag(Tok, diag::ext_keyword_as_ident)
1572 << Tok.getIdentifierInfo()->getName() << 0;
1573 goto ParseIdentifier;
1574 }
1575 goto ExpectedExpression;
1576 case tok::l_square:
1577 if (getLangOpts().CPlusPlus) {
1578 if (getLangOpts().ObjC) {
1579 // C++11 lambda expressions and Objective-C message sends both start with a
1580 // square bracket. There are three possibilities here:
1581 // we have a valid lambda expression, we have an invalid lambda
1582 // expression, or we have something that doesn't appear to be a lambda.
1583 // If we're in the last case, we fall back to ParseObjCMessageExpression.
1584 Res = TryParseLambdaExpression();
1585 if (!Res.isInvalid() && !Res.get()) {
1586 // We assume Objective-C++ message expressions are not
1587 // primary-expressions.
1588 if (NotPrimaryExpression)
1589 *NotPrimaryExpression = true;
1590 Res = ParseObjCMessageExpression();
1591 }
1592 break;
1593 }
1594 Res = ParseLambdaExpression();
1595 break;
1596 }
1597 if (getLangOpts().ObjC) {
1598 Res = ParseObjCMessageExpression();
1599 break;
1600 }
1601 [[fallthrough]];
1602 default:
1603 ExpectedExpression:
1604 NotCastExpr = true;
1605 return ExprError();
1606 }
1607
1608 // Check to see whether Res is a function designator only. If it is and we
1609 // are compiling for OpenCL, we need to return an error as this implies
1610 // that the address of the function is being taken, which is illegal in CL.
1611
1612 if (ParseKind == CastParseKind::PrimaryExprOnly)
1613 // This is strictly a primary-expression - no postfix-expr pieces should be
1614 // parsed.
1615 return Res;
1616
1617 if (!AllowSuffix) {
1618 // FIXME: Don't parse a primary-expression suffix if we encountered a parse
1619 // error already.
1620 if (Res.isInvalid())
1621 return Res;
1622
1623 switch (Tok.getKind()) {
1624 case tok::l_square:
1625 case tok::l_paren:
1626 case tok::plusplus:
1627 case tok::minusminus:
1628 // "expected ';'" or similar is probably the right diagnostic here. Let
1629 // the caller decide what to do.
1630 if (Tok.isAtStartOfLine())
1631 return Res;
1632
1633 [[fallthrough]];
1634 case tok::period:
1635 case tok::arrow:
1636 break;
1637
1638 default:
1639 return Res;
1640 }
1641
1642 // This was a unary-expression for which a postfix-expression suffix is
1643 // not permitted by the grammar (eg, a sizeof expression or
1644 // new-expression or similar). Diagnose but parse the suffix anyway.
1645 Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens)
1646 << Tok.getKind() << Res.get()->getSourceRange()
1648 << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation),
1649 ")");
1650 }
1651
1652 // These can be followed by postfix-expr pieces.
1653 PreferredType = SavedType;
1654 Res = ParsePostfixExpressionSuffix(Res);
1655 if (getLangOpts().OpenCL &&
1656 !getActions().getOpenCLOptions().isAvailableOption(
1657 "__cl_clang_function_pointers", getLangOpts()))
1658 if (Expr *PostfixExpr = Res.get()) {
1659 QualType Ty = PostfixExpr->getType();
1660 if (!Ty.isNull() && Ty->isFunctionType()) {
1661 Diag(PostfixExpr->getExprLoc(),
1662 diag::err_opencl_taking_function_address_parser);
1663 return ExprError();
1664 }
1665 }
1666
1667 return Res;
1668}
1669
1671Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
1672 // Now that the primary-expression piece of the postfix-expression has been
1673 // parsed, see if there are any postfix-expression pieces here.
1674 SourceLocation Loc;
1675 auto SavedType = PreferredType;
1676 while (true) {
1677 // Each iteration relies on preferred type for the whole expression.
1678 PreferredType = SavedType;
1679 switch (Tok.getKind()) {
1680 case tok::code_completion:
1681 if (InMessageExpression)
1682 return LHS;
1683
1684 cutOffParsing();
1685 Actions.CodeCompletion().CodeCompletePostfixExpression(
1686 getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
1687 return ExprError();
1688
1689 case tok::identifier:
1690 // If we see identifier: after an expression, and we're not already in a
1691 // message send, then this is probably a message send with a missing
1692 // opening bracket '['.
1693 if (getLangOpts().ObjC && !InMessageExpression &&
1694 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
1695 LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1696 nullptr, LHS.get());
1697 break;
1698 }
1699 // Fall through; this isn't a message send.
1700 [[fallthrough]];
1701
1702 default: // Not a postfix-expression suffix.
1703 return LHS;
1704 case tok::l_square: { // postfix-expression: p-e '[' expression ']'
1705 // If we have a array postfix expression that starts on a new line and
1706 // Objective-C is enabled, it is highly likely that the user forgot a
1707 // semicolon after the base expression and that the array postfix-expr is
1708 // actually another message send. In this case, do some look-ahead to see
1709 // if the contents of the square brackets are obviously not a valid
1710 // expression and recover by pretending there is no suffix.
1711 if (getLangOpts().ObjC && Tok.isAtStartOfLine() &&
1712 isSimpleObjCMessageExpression())
1713 return LHS;
1714
1715 // Reject array indices starting with a lambda-expression. '[[' is
1716 // reserved for attributes.
1717 if (CheckProhibitedCXX11Attribute()) {
1718 return ExprError();
1719 }
1720 BalancedDelimiterTracker T(*this, tok::l_square);
1721 T.consumeOpen();
1722 Loc = T.getOpenLocation();
1723 ExprResult Length, Stride;
1724 SourceLocation ColonLocFirst, ColonLocSecond;
1725 ExprVector ArgExprs;
1726 bool HasError = false;
1727 PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get());
1728
1729 // We try to parse a list of indexes in all language mode first
1730 // and, in we find 0 or one index, we try to parse an OpenMP/OpenACC array
1731 // section. This allow us to support C++23 multi dimensional subscript and
1732 // OpenMP/OpenACC sections in the same language mode.
1733 if ((!getLangOpts().OpenMP && !AllowOpenACCArraySections) ||
1734 Tok.isNot(tok::colon)) {
1735 if (!getLangOpts().CPlusPlus23) {
1736 ExprResult Idx;
1737 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
1738 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1739 Idx = ParseBraceInitializer();
1740 } else {
1741 Idx = ParseExpression(); // May be a comma expression
1742 }
1743 if (Idx.isInvalid()) {
1744 HasError = true;
1745 } else {
1746 ArgExprs.push_back(Idx.get());
1747 }
1748 } else if (Tok.isNot(tok::r_square)) {
1749 if (ParseExpressionList(ArgExprs)) {
1750 HasError = true;
1751 }
1752 }
1753 }
1754
1755 // Handle OpenACC first, since 'AllowOpenACCArraySections' is only enabled
1756 // when actively parsing a 'var' in a 'var-list' during clause/'cache'
1757 // parsing, so it is the most specific, and best allows us to handle
1758 // OpenACC and OpenMP at the same time.
1759 if (ArgExprs.size() <= 1 && AllowOpenACCArraySections) {
1760 ColonProtectionRAIIObject RAII(*this);
1761 if (Tok.is(tok::colon)) {
1762 // Consume ':'
1763 ColonLocFirst = ConsumeToken();
1764 if (Tok.isNot(tok::r_square))
1765 Length = ParseExpression();
1766 }
1767 } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) {
1768 ColonProtectionRAIIObject RAII(*this);
1769 if (Tok.is(tok::colon)) {
1770 // Consume ':'
1771 ColonLocFirst = ConsumeToken();
1772 if (Tok.isNot(tok::r_square) &&
1773 (getLangOpts().OpenMP < 50 ||
1774 ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) {
1775 Length = ParseExpression();
1776 }
1777 }
1778 if (getLangOpts().OpenMP >= 50 &&
1779 (OMPClauseKind == llvm::omp::Clause::OMPC_to ||
1780 OMPClauseKind == llvm::omp::Clause::OMPC_from) &&
1781 Tok.is(tok::colon)) {
1782 // Consume ':'
1783 ColonLocSecond = ConsumeToken();
1784 if (Tok.isNot(tok::r_square)) {
1785 Stride = ParseExpression();
1786 }
1787 }
1788 }
1789
1790 SourceLocation RLoc = Tok.getLocation();
1791 if (!LHS.isInvalid() && !HasError && !Length.isInvalid() &&
1792 !Stride.isInvalid() && Tok.is(tok::r_square)) {
1793 if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) {
1794 // Like above, AllowOpenACCArraySections is 'more specific' and only
1795 // enabled when actively parsing a 'var' in a 'var-list' during
1796 // clause/'cache' construct parsing, so it is more specific. So we
1797 // should do it first, so that the correct node gets created.
1798 if (AllowOpenACCArraySections) {
1799 assert(!Stride.isUsable() && !ColonLocSecond.isValid() &&
1800 "Stride/second colon not allowed for OpenACC");
1801 LHS = Actions.OpenACC().ActOnArraySectionExpr(
1802 LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
1803 ColonLocFirst, Length.get(), RLoc);
1804 } else {
1805 LHS = Actions.OpenMP().ActOnOMPArraySectionExpr(
1806 LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
1807 ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(),
1808 RLoc);
1809 }
1810 } else {
1811 LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc,
1812 ArgExprs, RLoc);
1813 }
1814 } else {
1815 LHS = ExprError();
1816 }
1817
1818 // Match the ']'.
1819 T.consumeClose();
1820 break;
1821 }
1822
1823 case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
1824 case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>'
1825 // '(' argument-expression-list[opt] ')'
1826 tok::TokenKind OpKind = Tok.getKind();
1827 InMessageExpressionRAIIObject InMessage(*this, false);
1828
1829 Expr *ExecConfig = nullptr;
1830
1831 BalancedDelimiterTracker PT(*this, tok::l_paren);
1832
1833 if (OpKind == tok::lesslessless) {
1834 ExprVector ExecConfigExprs;
1835 SourceLocation OpenLoc = ConsumeToken();
1836
1837 if (ParseSimpleExpressionList(ExecConfigExprs)) {
1838 LHS = ExprError();
1839 }
1840
1841 SourceLocation CloseLoc;
1842 if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) {
1843 } else if (LHS.isInvalid()) {
1844 SkipUntil(tok::greatergreatergreater, StopAtSemi);
1845 } else {
1846 // There was an error closing the brackets
1847 Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
1848 Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
1849 SkipUntil(tok::greatergreatergreater, StopAtSemi);
1850 LHS = ExprError();
1851 }
1852
1853 if (!LHS.isInvalid()) {
1854 if (ExpectAndConsume(tok::l_paren))
1855 LHS = ExprError();
1856 else
1857 Loc = PrevTokLocation;
1858 }
1859
1860 if (!LHS.isInvalid()) {
1861 ExprResult ECResult = Actions.CUDA().ActOnExecConfigExpr(
1862 getCurScope(), OpenLoc, ExecConfigExprs, CloseLoc);
1863 if (ECResult.isInvalid())
1864 LHS = ExprError();
1865 else
1866 ExecConfig = ECResult.get();
1867 }
1868 } else {
1869 PT.consumeOpen();
1870 Loc = PT.getOpenLocation();
1871 }
1872
1873 ExprVector ArgExprs;
1874 auto RunSignatureHelp = [&]() -> QualType {
1875 QualType PreferredType =
1876 Actions.CodeCompletion().ProduceCallSignatureHelp(
1877 LHS.get(), ArgExprs, PT.getOpenLocation());
1878 CalledSignatureHelp = true;
1879 return PreferredType;
1880 };
1881 bool ExpressionListIsInvalid = false;
1882 if (OpKind == tok::l_paren || !LHS.isInvalid()) {
1883 if (Tok.isNot(tok::r_paren)) {
1884 if ((ExpressionListIsInvalid = ParseExpressionList(ArgExprs, [&] {
1885 PreferredType.enterFunctionArgument(Tok.getLocation(),
1886 RunSignatureHelp);
1887 }))) {
1888 // If we got an error when parsing expression list, we don't call
1889 // the CodeCompleteCall handler inside the parser. So call it here
1890 // to make sure we get overload suggestions even when we are in the
1891 // middle of a parameter.
1892 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1893 RunSignatureHelp();
1894 }
1895 }
1896 }
1897
1898 // Match the ')'.
1899 if (LHS.isInvalid()) {
1900 SkipUntil(tok::r_paren, StopAtSemi);
1901 } else if (ExpressionListIsInvalid) {
1902 Expr *Fn = LHS.get();
1903 ArgExprs.insert(ArgExprs.begin(), Fn);
1904 LHS = Actions.CreateRecoveryExpr(Fn->getBeginLoc(), Tok.getLocation(),
1905 ArgExprs);
1906 SkipUntil(tok::r_paren, StopAtSemi);
1907 } else if (Tok.isNot(tok::r_paren)) {
1908 bool HadErrors = false;
1909 if (LHS.get()->containsErrors())
1910 HadErrors = true;
1911 for (auto &E : ArgExprs)
1912 if (E->containsErrors())
1913 HadErrors = true;
1914 // If there were errors in the LHS or ArgExprs, call SkipUntil instead
1915 // of PT.consumeClose() to avoid emitting extra diagnostics for the
1916 // unmatched l_paren.
1917 if (HadErrors)
1918 SkipUntil(tok::r_paren, StopAtSemi);
1919 else
1920 PT.consumeClose();
1921 LHS = ExprError();
1922 } else {
1923 Expr *Fn = LHS.get();
1924 SourceLocation RParLoc = Tok.getLocation();
1925 LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc,
1926 ExecConfig);
1927 if (LHS.isInvalid()) {
1928 ArgExprs.insert(ArgExprs.begin(), Fn);
1929 LHS =
1930 Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs);
1931 }
1932 PT.consumeClose();
1933 }
1934
1935 break;
1936 }
1937 case tok::arrow:
1938 case tok::period: {
1939 // postfix-expression: p-e '->' template[opt] id-expression
1940 // postfix-expression: p-e '.' template[opt] id-expression
1941 tok::TokenKind OpKind = Tok.getKind();
1942 SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token.
1943
1944 CXXScopeSpec SS;
1945 ParsedType ObjectType;
1946 bool MayBePseudoDestructor = false;
1947 Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr;
1948
1949 PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS);
1950
1951 if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
1952 Expr *Base = OrigLHS;
1953 const Type* BaseType = Base->getType().getTypePtrOrNull();
1954 if (BaseType && Tok.is(tok::l_paren) &&
1955 (BaseType->isFunctionType() ||
1956 BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) {
1957 Diag(OpLoc, diag::err_function_is_not_record)
1958 << OpKind << Base->getSourceRange()
1959 << FixItHint::CreateRemoval(OpLoc);
1960 return ParsePostfixExpressionSuffix(Base);
1961 }
1962
1963 LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc,
1964 OpKind, ObjectType,
1965 MayBePseudoDestructor);
1966 if (LHS.isInvalid()) {
1967 // Clang will try to perform expression based completion as a
1968 // fallback, which is confusing in case of member references. So we
1969 // stop here without any completions.
1970 if (Tok.is(tok::code_completion)) {
1971 cutOffParsing();
1972 return ExprError();
1973 }
1974 break;
1975 }
1976 ParseOptionalCXXScopeSpecifier(
1977 SS, ObjectType, LHS.get() && LHS.get()->containsErrors(),
1978 /*EnteringContext=*/false, &MayBePseudoDestructor);
1979 if (SS.isNotEmpty())
1980 ObjectType = nullptr;
1981 }
1982
1983 if (Tok.is(tok::code_completion)) {
1984 tok::TokenKind CorrectedOpKind =
1985 OpKind == tok::arrow ? tok::period : tok::arrow;
1986 ExprResult CorrectedLHS(/*Invalid=*/true);
1987 if (getLangOpts().CPlusPlus && OrigLHS) {
1988 // FIXME: Creating a TentativeAnalysisScope from outside Sema is a
1989 // hack.
1990 Sema::TentativeAnalysisScope Trap(Actions);
1991 CorrectedLHS = Actions.ActOnStartCXXMemberReference(
1992 getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType,
1993 MayBePseudoDestructor);
1994 }
1995
1996 Expr *Base = LHS.get();
1997 Expr *CorrectedBase = CorrectedLHS.get();
1998 if (!CorrectedBase && !getLangOpts().CPlusPlus)
1999 CorrectedBase = Base;
2000
2001 // Code completion for a member access expression.
2002 cutOffParsing();
2003 Actions.CodeCompletion().CodeCompleteMemberReferenceExpr(
2004 getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
2005 Base && ExprStatementTokLoc == Base->getBeginLoc(),
2006 PreferredType.get(Tok.getLocation()));
2007
2008 return ExprError();
2009 }
2010
2011 if (MayBePseudoDestructor && !LHS.isInvalid()) {
2012 LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
2013 ObjectType);
2014 break;
2015 }
2016
2017 // Either the action has told us that this cannot be a
2018 // pseudo-destructor expression (based on the type of base
2019 // expression), or we didn't see a '~' in the right place. We
2020 // can still parse a destructor name here, but in that case it
2021 // names a real destructor.
2022 // Allow explicit constructor calls in Microsoft mode.
2023 // FIXME: Add support for explicit call of template constructor.
2024 SourceLocation TemplateKWLoc;
2025 UnqualifiedId Name;
2026 if (getLangOpts().ObjC && OpKind == tok::period &&
2027 Tok.is(tok::kw_class)) {
2028 // Objective-C++:
2029 // After a '.' in a member access expression, treat the keyword
2030 // 'class' as if it were an identifier.
2031 //
2032 // This hack allows property access to the 'class' method because it is
2033 // such a common method name. For other C++ keywords that are
2034 // Objective-C method names, one must use the message send syntax.
2035 IdentifierInfo *Id = Tok.getIdentifierInfo();
2036 SourceLocation Loc = ConsumeToken();
2037 Name.setIdentifier(Id, Loc);
2038 } else if (ParseUnqualifiedId(
2039 SS, ObjectType, LHS.get() && LHS.get()->containsErrors(),
2040 /*EnteringContext=*/false,
2041 /*AllowDestructorName=*/true,
2042 /*AllowConstructorName=*/
2043 getLangOpts().MicrosoftExt && SS.isNotEmpty(),
2044 /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) {
2045 LHS = ExprError();
2046 }
2047
2048 if (!LHS.isInvalid())
2049 LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
2050 OpKind, SS, TemplateKWLoc, Name,
2051 CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
2052 : nullptr);
2053 if (!LHS.isInvalid()) {
2054 if (Tok.is(tok::less))
2055 checkPotentialAngleBracket(LHS);
2056 } else if (OrigLHS && Name.isValid()) {
2057 // Preserve the LHS if the RHS is an invalid member.
2058 LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(),
2059 Name.getEndLoc(), {OrigLHS});
2060 }
2061 break;
2062 }
2063 case tok::plusplus: // postfix-expression: postfix-expression '++'
2064 case tok::minusminus: // postfix-expression: postfix-expression '--'
2065 if (!LHS.isInvalid()) {
2066 Expr *Arg = LHS.get();
2067 LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(),
2068 Tok.getKind(), Arg);
2069 if (LHS.isInvalid())
2070 LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(),
2071 Tok.getLocation(), Arg);
2072 }
2073 ConsumeToken();
2074 break;
2075 }
2076 }
2077}
2078
2080Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
2081 bool &isCastExpr,
2082 ParsedType &CastTy,
2083 SourceRange &CastRange) {
2084
2085 assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof,
2086 tok::kw___datasizeof, tok::kw___alignof, tok::kw_alignof,
2087 tok::kw__Alignof, tok::kw_vec_step,
2088 tok::kw___builtin_omp_required_simd_align,
2089 tok::kw___builtin_vectorelements, tok::kw__Countof) &&
2090 "Not a typeof/sizeof/alignof/vec_step expression!");
2091
2093
2094 // If the operand doesn't start with an '(', it must be an expression.
2095 if (Tok.isNot(tok::l_paren)) {
2096 // If construct allows a form without parenthesis, user may forget to put
2097 // pathenthesis around type name.
2098 if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2099 tok::kw_alignof, tok::kw__Alignof)) {
2100 if (isTypeIdUnambiguously()) {
2101 DeclSpec DS(AttrFactory);
2102 ParseSpecifierQualifierList(DS);
2103 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
2105 ParseDeclarator(DeclaratorInfo);
2106
2107 SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation());
2108 SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation);
2109 if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) {
2110 Diag(OpTok.getLocation(),
2111 diag::err_expected_parentheses_around_typename)
2112 << OpTok.getName();
2113 } else {
2114 Diag(LParenLoc, diag::err_expected_parentheses_around_typename)
2115 << OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(")
2116 << FixItHint::CreateInsertion(RParenLoc, ")");
2117 }
2118 isCastExpr = true;
2119 return ExprEmpty();
2120 }
2121 }
2122
2123 isCastExpr = false;
2124 if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
2126 Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo()
2127 << tok::l_paren;
2128 return ExprError();
2129 }
2130
2131 // If we're parsing a chain that consists of keywords that could be
2132 // followed by a non-parenthesized expression, BalancedDelimiterTracker
2133 // is not going to help when the nesting is too deep. In this corner case
2134 // we continue to parse with sufficient stack space to avoid crashing.
2135 if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2136 tok::kw_alignof, tok::kw__Alignof, tok::kw__Countof) &&
2137 Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2138 tok::kw_alignof, tok::kw__Alignof, tok::kw__Countof))
2139 Actions.runWithSufficientStackSpace(Tok.getLocation(), [&] {
2140 Operand = ParseCastExpression(CastParseKind::UnaryExprOnly);
2141 });
2142 else
2143 Operand = ParseCastExpression(CastParseKind::UnaryExprOnly);
2144 } else {
2145 // If it starts with a '(', we know that it is either a parenthesized
2146 // type-name, or it is a unary-expression that starts with a compound
2147 // literal, or starts with a primary-expression that is a parenthesized
2148 // expression. Most unary operators have an expression form without parens
2149 // as part of the grammar for the operator, and a type form with the parens
2150 // as part of the grammar for the operator. However, typeof and
2151 // typeof_unqual require parens for both forms. This means that we *know*
2152 // that the open and close parens cannot be part of a cast expression,
2153 // which means we definitely are not parsing a compound literal expression.
2154 // This disambiguates a case like enum E : typeof(int) { }; where we've
2155 // parsed typeof and need to handle the (int){} tokens properly despite
2156 // them looking like a compound literal, as in sizeof (int){}; where the
2157 // parens could be part of a parenthesized type name or for a cast
2158 // expression of some kind.
2159 bool ParenKnownToBeNonCast =
2160 OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual);
2162 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
2163
2164 Operand = ParseParenExpression(
2165 ExprType, /*StopIfCastExr=*/true,
2166 ParenKnownToBeNonCast ? ParenExprKind::PartOfOperator
2168 TypoCorrectionTypeBehavior::AllowBoth, CastTy, RParenLoc);
2169 CastRange = SourceRange(LParenLoc, RParenLoc);
2170
2171 // If ParseParenExpression parsed a '(typename)' sequence only, then this is
2172 // a type.
2173 if (ExprType == ParenParseOption::CastExpr) {
2174 isCastExpr = true;
2175 return ExprEmpty();
2176 }
2177
2178 if (getLangOpts().CPlusPlus ||
2179 !OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) {
2180 // GNU typeof in C requires the expression to be parenthesized. Not so for
2181 // sizeof/alignof or in C++. Therefore, the parenthesized expression is
2182 // the start of a unary-expression, but doesn't include any postfix
2183 // pieces. Parse these now if present.
2184 if (!Operand.isInvalid())
2185 Operand = ParsePostfixExpressionSuffix(Operand.get());
2186 }
2187 }
2188
2189 // If we get here, the operand to the typeof/sizeof/alignof was an expression.
2190 isCastExpr = false;
2191 return Operand;
2192}
2193
2194ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
2195 assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) &&
2196 "Not __builtin_sycl_unique_stable_name");
2197
2198 SourceLocation OpLoc = ConsumeToken();
2199 BalancedDelimiterTracker T(*this, tok::l_paren);
2200
2201 // __builtin_sycl_unique_stable_name expressions are always parenthesized.
2202 if (T.expectAndConsume(diag::err_expected_lparen_after,
2203 "__builtin_sycl_unique_stable_name"))
2204 return ExprError();
2205
2207
2208 if (Ty.isInvalid()) {
2209 T.skipToEnd();
2210 return ExprError();
2211 }
2212
2213 if (T.consumeClose())
2214 return ExprError();
2215
2216 return Actions.SYCL().ActOnUniqueStableNameExpr(
2217 OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get());
2218}
2219
2220ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
2221 assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
2222 tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step,
2223 tok::kw___builtin_omp_required_simd_align,
2224 tok::kw___builtin_vectorelements, tok::kw__Countof) &&
2225 "Not a sizeof/alignof/vec_step expression!");
2226 Token OpTok = Tok;
2227 ConsumeToken();
2228
2229 // [C++11] 'sizeof' '...' '(' identifier ')'
2230 if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
2231 SourceLocation EllipsisLoc = ConsumeToken();
2232 SourceLocation LParenLoc, RParenLoc;
2233 IdentifierInfo *Name = nullptr;
2234 SourceLocation NameLoc;
2235 if (Tok.is(tok::l_paren)) {
2236 BalancedDelimiterTracker T(*this, tok::l_paren);
2237 T.consumeOpen();
2238 LParenLoc = T.getOpenLocation();
2239 if (Tok.is(tok::identifier)) {
2240 Name = Tok.getIdentifierInfo();
2241 NameLoc = ConsumeToken();
2242 T.consumeClose();
2243 RParenLoc = T.getCloseLocation();
2244 if (RParenLoc.isInvalid())
2245 RParenLoc = PP.getLocForEndOfToken(NameLoc);
2246 } else {
2247 Diag(Tok, diag::err_expected_parameter_pack);
2248 SkipUntil(tok::r_paren, StopAtSemi);
2249 }
2250 } else if (Tok.is(tok::identifier)) {
2251 Name = Tok.getIdentifierInfo();
2252 NameLoc = ConsumeToken();
2253 LParenLoc = PP.getLocForEndOfToken(EllipsisLoc);
2254 RParenLoc = PP.getLocForEndOfToken(NameLoc);
2255 Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack)
2256 << Name
2257 << FixItHint::CreateInsertion(LParenLoc, "(")
2258 << FixItHint::CreateInsertion(RParenLoc, ")");
2259 } else {
2260 Diag(Tok, diag::err_sizeof_parameter_pack);
2261 }
2262
2263 if (!Name)
2264 return ExprError();
2265
2266 EnterExpressionEvaluationContext Unevaluated(
2269
2270 return Actions.ActOnSizeofParameterPackExpr(getCurScope(),
2271 OpTok.getLocation(),
2272 *Name, NameLoc,
2273 RParenLoc);
2274 }
2275
2276 if (getLangOpts().CPlusPlus &&
2277 OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2278 Diag(OpTok, diag::warn_cxx98_compat_alignof);
2279 else if (getLangOpts().C23 && OpTok.is(tok::kw_alignof))
2280 Diag(OpTok, diag::warn_c23_compat_keyword) << OpTok.getName();
2281 else if (getLangOpts().C2y && OpTok.is(tok::kw__Countof))
2282 Diag(OpTok, diag::warn_c2y_compat_keyword) << OpTok.getName();
2283
2284 EnterExpressionEvaluationContext Unevaluated(
2287
2288 bool isCastExpr;
2289 ParsedType CastTy;
2290 SourceRange CastRange;
2291 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok,
2292 isCastExpr,
2293 CastTy,
2294 CastRange);
2295
2296 UnaryExprOrTypeTrait ExprKind = UETT_SizeOf;
2297 switch (OpTok.getKind()) {
2298 case tok::kw_alignof:
2299 case tok::kw__Alignof:
2300 ExprKind = UETT_AlignOf;
2301 break;
2302 case tok::kw___alignof:
2303 ExprKind = UETT_PreferredAlignOf;
2304 break;
2305 case tok::kw_vec_step:
2306 ExprKind = UETT_VecStep;
2307 break;
2308 case tok::kw___builtin_omp_required_simd_align:
2309 ExprKind = UETT_OpenMPRequiredSimdAlign;
2310 break;
2311 case tok::kw___datasizeof:
2312 ExprKind = UETT_DataSizeOf;
2313 break;
2314 case tok::kw___builtin_vectorelements:
2315 ExprKind = UETT_VectorElements;
2316 break;
2317 case tok::kw__Countof:
2318 ExprKind = UETT_CountOf;
2319 assert(!getLangOpts().CPlusPlus && "_Countof in C++ mode?");
2320 if (!getLangOpts().C2y)
2321 Diag(OpTok, diag::ext_c2y_feature) << OpTok.getName();
2322 break;
2323 default:
2324 break;
2325 }
2326
2327 if (isCastExpr)
2328 return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
2329 ExprKind,
2330 /*IsType=*/true,
2331 CastTy.getAsOpaquePtr(),
2332 CastRange);
2333
2334 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
2335 Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo();
2336
2337 // If we get here, the operand to the sizeof/alignof was an expression.
2338 if (!Operand.isInvalid())
2339 Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
2340 ExprKind,
2341 /*IsType=*/false,
2342 Operand.get(),
2343 CastRange);
2344 return Operand;
2345}
2346
2347ExprResult Parser::ParseBuiltinPrimaryExpression() {
2348 ExprResult Res;
2349 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
2350
2351 tok::TokenKind T = Tok.getKind();
2352 SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier.
2353
2354 // All of these start with an open paren.
2355 if (Tok.isNot(tok::l_paren))
2356 return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII
2357 << tok::l_paren);
2358
2359 BalancedDelimiterTracker PT(*this, tok::l_paren);
2360 PT.consumeOpen();
2361
2362 // TODO: Build AST.
2363
2364 switch (T) {
2365 default: llvm_unreachable("Not a builtin primary expression!");
2366 case tok::kw___builtin_va_arg: {
2368
2369 if (ExpectAndConsume(tok::comma)) {
2370 SkipUntil(tok::r_paren, StopAtSemi);
2371 Expr = ExprError();
2372 }
2373
2375
2376 if (Tok.isNot(tok::r_paren)) {
2377 Diag(Tok, diag::err_expected) << tok::r_paren;
2378 Expr = ExprError();
2379 }
2380
2381 if (Expr.isInvalid() || Ty.isInvalid())
2382 Res = ExprError();
2383 else
2384 Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen());
2385 break;
2386 }
2387 case tok::kw___builtin_offsetof: {
2388 SourceLocation TypeLoc = Tok.getLocation();
2389 auto OOK = OffsetOfKind::Builtin;
2390 if (Tok.getLocation().isMacroID()) {
2391 StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
2392 Tok.getLocation(), PP.getSourceManager(), getLangOpts());
2393 if (MacroName == "offsetof")
2394 OOK = OffsetOfKind::Macro;
2395 }
2396 TypeResult Ty;
2397 {
2398 OffsetOfStateRAIIObject InOffsetof(*this, OOK);
2399 Ty = ParseTypeName();
2400 if (Ty.isInvalid()) {
2401 SkipUntil(tok::r_paren, StopAtSemi);
2402 return ExprError();
2403 }
2404 }
2405
2406 if (ExpectAndConsume(tok::comma)) {
2407 SkipUntil(tok::r_paren, StopAtSemi);
2408 return ExprError();
2409 }
2410
2411 auto TriggerCompletion = [&](const Designation &D) {
2412 cutOffParsing();
2413 Actions.CodeCompletion().CodeCompleteOffsetOfDesignator(
2414 Actions.GetTypeFromParser(Ty.get()), D);
2415 };
2416
2417 // We must have at least one identifier here.
2418 Designation D;
2419 if (Tok.is(tok::code_completion)) {
2420 TriggerCompletion(D);
2421 return ExprError();
2422 }
2423 if (Tok.isNot(tok::identifier)) {
2424 Diag(Tok, diag::err_expected) << tok::identifier;
2425 SkipUntil(tok::r_paren, StopAtSemi);
2426 return ExprError();
2427 }
2428
2429 // Keep track of the various subcomponents we see.
2430 // FIXME: Comps and D below carry the same designator chain in two
2431 // different shapes. ActOnBuiltinOffsetOf should be taught to accept a
2432 // Designation directly so this duplication can go away.
2433 SmallVector<Sema::OffsetOfComponent, 4> Comps;
2434
2435 Comps.push_back(Sema::OffsetOfComponent());
2436 Comps.back().isBrackets = false;
2437 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2438 Comps.back().LocStart = Comps.back().LocEnd = Tok.getLocation();
2440 Tok.getIdentifierInfo(), SourceLocation(), Tok.getLocation()));
2441 ConsumeToken();
2442
2443 // FIXME: This loop leaks the index expressions on error.
2444 while (true) {
2445 if (Tok.is(tok::period)) {
2446 // offsetof-member-designator: offsetof-member-designator '.' identifier
2447 Comps.push_back(Sema::OffsetOfComponent());
2448 Comps.back().isBrackets = false;
2449 Comps.back().LocStart = ConsumeToken();
2450
2451 if (Tok.is(tok::code_completion)) {
2452 TriggerCompletion(D);
2453 return ExprError();
2454 }
2455 if (Tok.isNot(tok::identifier)) {
2456 Diag(Tok, diag::err_expected) << tok::identifier;
2457 SkipUntil(tok::r_paren, StopAtSemi);
2458 return ExprError();
2459 }
2460 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2461 Comps.back().LocEnd = Tok.getLocation();
2463 Tok.getIdentifierInfo(), Comps.back().LocStart, Tok.getLocation()));
2464 ConsumeToken();
2465 } else if (Tok.is(tok::l_square)) {
2466 if (CheckProhibitedCXX11Attribute())
2467 return ExprError();
2468
2469 // offsetof-member-designator: offsetof-member-design '[' expression ']'
2470 Comps.push_back(Sema::OffsetOfComponent());
2471 Comps.back().isBrackets = true;
2472 BalancedDelimiterTracker ST(*this, tok::l_square);
2473 ST.consumeOpen();
2474 Comps.back().LocStart = ST.getOpenLocation();
2475 Res = ParseExpression();
2476 if (Res.isInvalid()) {
2477 SkipUntil(tok::r_paren, StopAtSemi);
2478 return Res;
2479 }
2480 Comps.back().U.E = Res.get();
2481
2482 ST.consumeClose();
2483 Comps.back().LocEnd = ST.getCloseLocation();
2484 Designator ArrayD =
2485 Designator::CreateArrayDesignator(Res.get(), Comps.back().LocStart);
2486 ArrayD.setRBracketLoc(Comps.back().LocEnd);
2487 D.AddDesignator(ArrayD);
2488 } else {
2489 // A code-completion token here (e.g. cursor right after `]`) is past
2490 // the point where a field can be applied without a leading `.`. Drop
2491 // it on the floor rather than leak into outer-scope completion or
2492 // emit field suggestions that wouldn't compose.
2493 if (Tok.is(tok::code_completion)) {
2494 cutOffParsing();
2495 return ExprError();
2496 }
2497 if (Tok.isNot(tok::r_paren)) {
2498 PT.consumeClose();
2499 Res = ExprError();
2500 } else if (Ty.isInvalid()) {
2501 Res = ExprError();
2502 } else {
2503 PT.consumeClose();
2504 Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc,
2505 Ty.get(), Comps,
2506 PT.getCloseLocation());
2507 }
2508 break;
2509 }
2510 }
2511 break;
2512 }
2513 case tok::kw___builtin_choose_expr: {
2515 if (Cond.isInvalid()) {
2516 SkipUntil(tok::r_paren, StopAtSemi);
2517 return Cond;
2518 }
2519 if (ExpectAndConsume(tok::comma)) {
2520 SkipUntil(tok::r_paren, StopAtSemi);
2521 return ExprError();
2522 }
2523
2525 if (Expr1.isInvalid()) {
2526 SkipUntil(tok::r_paren, StopAtSemi);
2527 return Expr1;
2528 }
2529 if (ExpectAndConsume(tok::comma)) {
2530 SkipUntil(tok::r_paren, StopAtSemi);
2531 return ExprError();
2532 }
2533
2535 if (Expr2.isInvalid()) {
2536 SkipUntil(tok::r_paren, StopAtSemi);
2537 return Expr2;
2538 }
2539 if (Tok.isNot(tok::r_paren)) {
2540 Diag(Tok, diag::err_expected) << tok::r_paren;
2541 return ExprError();
2542 }
2543 Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
2544 Expr2.get(), ConsumeParen());
2545 break;
2546 }
2547 case tok::kw___builtin_astype: {
2548 // The first argument is an expression to be converted, followed by a comma.
2550 if (Expr.isInvalid()) {
2551 SkipUntil(tok::r_paren, StopAtSemi);
2552 return ExprError();
2553 }
2554
2555 if (ExpectAndConsume(tok::comma)) {
2556 SkipUntil(tok::r_paren, StopAtSemi);
2557 return ExprError();
2558 }
2559
2560 // Second argument is the type to bitcast to.
2561 TypeResult DestTy = ParseTypeName();
2562 if (DestTy.isInvalid())
2563 return ExprError();
2564
2565 // Attempt to consume the r-paren.
2566 if (Tok.isNot(tok::r_paren)) {
2567 Diag(Tok, diag::err_expected) << tok::r_paren;
2568 SkipUntil(tok::r_paren, StopAtSemi);
2569 return ExprError();
2570 }
2571
2572 Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc,
2573 ConsumeParen());
2574 break;
2575 }
2576 case tok::kw___builtin_convertvector: {
2577 // The first argument is an expression to be converted, followed by a comma.
2579 if (Expr.isInvalid()) {
2580 SkipUntil(tok::r_paren, StopAtSemi);
2581 return ExprError();
2582 }
2583
2584 if (ExpectAndConsume(tok::comma)) {
2585 SkipUntil(tok::r_paren, StopAtSemi);
2586 return ExprError();
2587 }
2588
2589 // Second argument is the type to bitcast to.
2590 TypeResult DestTy = ParseTypeName();
2591 if (DestTy.isInvalid())
2592 return ExprError();
2593
2594 // Attempt to consume the r-paren.
2595 if (Tok.isNot(tok::r_paren)) {
2596 Diag(Tok, diag::err_expected) << tok::r_paren;
2597 SkipUntil(tok::r_paren, StopAtSemi);
2598 return ExprError();
2599 }
2600
2601 Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc,
2602 ConsumeParen());
2603 break;
2604 }
2605 case tok::kw___builtin_COLUMN:
2606 case tok::kw___builtin_FILE:
2607 case tok::kw___builtin_FILE_NAME:
2608 case tok::kw___builtin_FUNCTION:
2609 case tok::kw___builtin_FUNCSIG:
2610 case tok::kw___builtin_LINE:
2611 case tok::kw___builtin_source_location: {
2612 // Attempt to consume the r-paren.
2613 if (Tok.isNot(tok::r_paren)) {
2614 Diag(Tok, diag::err_expected) << tok::r_paren;
2615 SkipUntil(tok::r_paren, StopAtSemi);
2616 return ExprError();
2617 }
2618 SourceLocIdentKind Kind = [&] {
2619 switch (T) {
2620 case tok::kw___builtin_FILE:
2622 case tok::kw___builtin_FILE_NAME:
2624 case tok::kw___builtin_FUNCTION:
2626 case tok::kw___builtin_FUNCSIG:
2628 case tok::kw___builtin_LINE:
2630 case tok::kw___builtin_COLUMN:
2632 case tok::kw___builtin_source_location:
2634 default:
2635 llvm_unreachable("invalid keyword");
2636 }
2637 }();
2638 Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen());
2639 break;
2640 }
2641 }
2642
2643 if (Res.isInvalid())
2644 return ExprError();
2645
2646 // These can be followed by postfix-expr pieces because they are
2647 // primary-expressions.
2648 return ParsePostfixExpressionSuffix(Res.get());
2649}
2650
2651bool Parser::tryParseOpenMPArrayShapingCastPart() {
2652 assert(Tok.is(tok::l_square) && "Expected open bracket");
2653 bool ErrorFound = true;
2654 TentativeParsingAction TPA(*this);
2655 do {
2656 if (Tok.isNot(tok::l_square))
2657 break;
2658 // Consume '['
2659 ConsumeBracket();
2660 // Skip inner expression.
2661 while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end,
2663 ;
2664 if (Tok.isNot(tok::r_square))
2665 break;
2666 // Consume ']'
2667 ConsumeBracket();
2668 // Found ')' - done.
2669 if (Tok.is(tok::r_paren)) {
2670 ErrorFound = false;
2671 break;
2672 }
2673 } while (Tok.isNot(tok::annot_pragma_openmp_end));
2674 TPA.Revert();
2675 return !ErrorFound;
2676}
2677
2679Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
2680 ParenExprKind ParenBehavior,
2681 TypoCorrectionTypeBehavior CorrectionBehavior,
2682 ParsedType &CastTy, SourceLocation &RParenLoc) {
2683 assert(Tok.is(tok::l_paren) && "Not a paren expr!");
2684 ColonProtectionRAIIObject ColonProtection(*this, false);
2685 BalancedDelimiterTracker T(*this, tok::l_paren);
2686 if (T.consumeOpen())
2687 return ExprError();
2688 SourceLocation OpenLoc = T.getOpenLocation();
2689
2690 PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
2691
2692 ExprResult Result(true);
2693 bool isAmbiguousTypeId;
2694 CastTy = nullptr;
2695
2696 if (Tok.is(tok::code_completion)) {
2697 cutOffParsing();
2698 Actions.CodeCompletion().CodeCompleteExpression(
2699 getCurScope(), PreferredType.get(Tok.getLocation()),
2700 /*IsParenthesized=*/ExprType >= ParenParseOption::CompoundLiteral);
2701 return ExprError();
2702 }
2703
2704 // Diagnose use of bridge casts in non-arc mode.
2705 bool BridgeCast = (getLangOpts().ObjC &&
2706 Tok.isOneOf(tok::kw___bridge,
2707 tok::kw___bridge_transfer,
2708 tok::kw___bridge_retained,
2709 tok::kw___bridge_retain));
2710 if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
2711 if (!TryConsumeToken(tok::kw___bridge)) {
2712 StringRef BridgeCastName = Tok.getName();
2713 SourceLocation BridgeKeywordLoc = ConsumeToken();
2714 if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
2715 Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
2716 << BridgeCastName
2717 << FixItHint::CreateReplacement(BridgeKeywordLoc, "");
2718 }
2719 BridgeCast = false;
2720 }
2721
2722 // None of these cases should fall through with an invalid Result
2723 // unless they've already reported an error.
2724 if (ExprType >= ParenParseOption::CompoundStmt && Tok.is(tok::l_brace)) {
2725 Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro
2726 : diag::ext_gnu_statement_expr);
2727
2728 checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin);
2729
2730 if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
2731 Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
2732 } else {
2733 // Find the nearest non-record decl context. Variables declared in a
2734 // statement expression behave as if they were declared in the enclosing
2735 // function, block, or other code construct.
2736 DeclContext *CodeDC = Actions.CurContext;
2737 while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) {
2738 CodeDC = CodeDC->getParent();
2739 assert(CodeDC && !CodeDC->isFileContext() &&
2740 "statement expr not in code context");
2741 }
2742 Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false);
2743
2744 Actions.ActOnStartStmtExpr();
2745
2746 StmtResult Stmt(ParseCompoundStatement(true));
2748
2749 // If the substmt parsed correctly, build the AST node.
2750 if (!Stmt.isInvalid()) {
2751 Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(),
2752 Tok.getLocation());
2753 } else {
2754 Actions.ActOnStmtExprError();
2755 }
2756 }
2757 } else if (ExprType >= ParenParseOption::CompoundLiteral && BridgeCast) {
2758 tok::TokenKind tokenKind = Tok.getKind();
2759 SourceLocation BridgeKeywordLoc = ConsumeToken();
2760
2761 // Parse an Objective-C ARC ownership cast expression.
2763 if (tokenKind == tok::kw___bridge)
2764 Kind = OBC_Bridge;
2765 else if (tokenKind == tok::kw___bridge_transfer)
2767 else if (tokenKind == tok::kw___bridge_retained)
2769 else {
2770 // As a hopefully temporary workaround, allow __bridge_retain as
2771 // a synonym for __bridge_retained, but only in system headers.
2772 assert(tokenKind == tok::kw___bridge_retain);
2774 if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
2775 Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
2776 << FixItHint::CreateReplacement(BridgeKeywordLoc,
2777 "__bridge_retained");
2778 }
2779
2781 T.consumeClose();
2782 ColonProtection.restore();
2783 RParenLoc = T.getCloseLocation();
2784
2785 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get());
2786 ExprResult SubExpr = ParseCastExpression(CastParseKind::AnyCastExpr);
2787
2788 if (Ty.isInvalid() || SubExpr.isInvalid())
2789 return ExprError();
2790
2791 return Actions.ObjC().ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind,
2792 BridgeKeywordLoc, Ty.get(),
2793 RParenLoc, SubExpr.get());
2794 } else if (ExprType >= ParenParseOption::CompoundLiteral &&
2795 isTypeIdInParens(isAmbiguousTypeId)) {
2796
2797 // Otherwise, this is a compound literal expression or cast expression.
2798
2799 // In C++, if the type-id is ambiguous we disambiguate based on context.
2800 // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
2801 // in which case we should treat it as type-id.
2802 // if stopIfCastExpr is false, we need to determine the context past the
2803 // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
2804 if (isAmbiguousTypeId && !StopIfCastExpr) {
2805 ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
2806 ColonProtection);
2807 RParenLoc = T.getCloseLocation();
2808 return res;
2809 }
2810
2811 // Parse the type declarator.
2812 DeclSpec DS(AttrFactory);
2813 ParseSpecifierQualifierList(DS);
2814 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
2816 ParseDeclarator(DeclaratorInfo);
2817
2818 // If our type is followed by an identifier and either ':' or ']', then
2819 // this is probably an Objective-C message send where the leading '[' is
2820 // missing. Recover as if that were the case.
2821 if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
2822 !InMessageExpression && getLangOpts().ObjC &&
2823 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
2824 TypeResult Ty;
2825 {
2826 InMessageExpressionRAIIObject InMessage(*this, false);
2827 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2828 }
2829 Result = ParseObjCMessageExpressionBody(SourceLocation(),
2830 SourceLocation(),
2831 Ty.get(), nullptr);
2832 } else {
2833 // Match the ')'.
2834 T.consumeClose();
2835 ColonProtection.restore();
2836 RParenLoc = T.getCloseLocation();
2837 if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_brace)) {
2839 TypeResult Ty;
2840 {
2841 InMessageExpressionRAIIObject InMessage(*this, false);
2842 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2843 }
2844 return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
2845 }
2846
2847 if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_paren)) {
2848 // This could be OpenCL vector Literals
2849 if (getLangOpts().OpenCL)
2850 {
2851 TypeResult Ty;
2852 {
2853 InMessageExpressionRAIIObject InMessage(*this, false);
2854 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2855 }
2856 if(Ty.isInvalid())
2857 {
2858 return ExprError();
2859 }
2860 QualType QT = Ty.get().get().getCanonicalType();
2861 if (QT->isVectorType())
2862 {
2863 // We parsed '(' vector-type-name ')' followed by '('
2864
2865 // Parse the cast-expression that follows it next.
2866 // isVectorLiteral = true will make sure we don't parse any
2867 // Postfix expression yet
2868 Result = ParseCastExpression(
2869 /*isUnaryExpression=*/CastParseKind::AnyCastExpr,
2870 /*isAddressOfOperand=*/false,
2872 /*isVectorLiteral=*/true);
2873
2874 if (!Result.isInvalid()) {
2875 Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
2876 DeclaratorInfo, CastTy,
2877 RParenLoc, Result.get());
2878 }
2879
2880 // After we performed the cast we can check for postfix-expr pieces.
2881 if (!Result.isInvalid()) {
2882 Result = ParsePostfixExpressionSuffix(Result);
2883 }
2884
2885 return Result;
2886 }
2887 }
2888 }
2889
2890 if (ExprType == ParenParseOption::CastExpr) {
2891 // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
2892
2893 if (DeclaratorInfo.isInvalidType())
2894 return ExprError();
2895
2896 // Note that this doesn't parse the subsequent cast-expression, it just
2897 // returns the parsed type to the callee.
2898 if (StopIfCastExpr) {
2899 TypeResult Ty;
2900 {
2901 InMessageExpressionRAIIObject InMessage(*this, false);
2902 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2903 }
2904 CastTy = Ty.get();
2905 return ExprResult();
2906 }
2907
2908 // Reject the cast of super idiom in ObjC.
2909 if (Tok.is(tok::identifier) && getLangOpts().ObjC &&
2910 Tok.getIdentifierInfo() == Ident_super &&
2911 getCurScope()->isInObjcMethodScope() &&
2912 GetLookAheadToken(1).isNot(tok::period)) {
2913 Diag(Tok.getLocation(), diag::err_illegal_super_cast)
2914 << SourceRange(OpenLoc, RParenLoc);
2915 return ExprError();
2916 }
2917
2918 PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get());
2919 // Parse the cast-expression that follows it next.
2920 // TODO: For cast expression with CastTy.
2921 Result = ParseCastExpression(
2922 /*isUnaryExpression=*/CastParseKind::AnyCastExpr,
2923 /*isAddressOfOperand=*/false,
2925 if (!Result.isInvalid()) {
2926 Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
2927 DeclaratorInfo, CastTy,
2928 RParenLoc, Result.get());
2929 }
2930 return Result;
2931 }
2932
2933 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
2934 return ExprError();
2935 }
2936 } else if (ExprType >= ParenParseOption::FoldExpr && Tok.is(tok::ellipsis) &&
2937 isFoldOperator(NextToken().getKind())) {
2938 ExprType = ParenParseOption::FoldExpr;
2939 return ParseFoldExpression(ExprResult(), T);
2940 } else if (CorrectionBehavior == TypoCorrectionTypeBehavior::AllowTypes) {
2941 // FIXME: This should not be predicated on typo correction behavior.
2942 // Parse the expression-list.
2943 InMessageExpressionRAIIObject InMessage(*this, false);
2944 ExprVector ArgExprs;
2945
2946 if (!ParseSimpleExpressionList(ArgExprs)) {
2947 // FIXME: If we ever support comma expressions as operands to
2948 // fold-expressions, we'll need to allow multiple ArgExprs here.
2949 if (ExprType >= ParenParseOption::FoldExpr && ArgExprs.size() == 1 &&
2950 isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
2951 ExprType = ParenParseOption::FoldExpr;
2952 return ParseFoldExpression(ArgExprs[0], T);
2953 }
2954
2956 Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
2957 ArgExprs);
2958 }
2959 } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing &&
2960 ExprType == ParenParseOption::CastExpr && Tok.is(tok::l_square) &&
2961 tryParseOpenMPArrayShapingCastPart()) {
2962 bool ErrorFound = false;
2963 SmallVector<Expr *, 4> OMPDimensions;
2964 SmallVector<SourceRange, 4> OMPBracketsRanges;
2965 do {
2966 BalancedDelimiterTracker TS(*this, tok::l_square);
2967 TS.consumeOpen();
2968 ExprResult NumElements = ParseExpression();
2969 if (!NumElements.isUsable()) {
2970 ErrorFound = true;
2971 while (!SkipUntil(tok::r_square, tok::r_paren,
2973 ;
2974 }
2975 TS.consumeClose();
2976 OMPDimensions.push_back(NumElements.get());
2977 OMPBracketsRanges.push_back(TS.getRange());
2978 } while (Tok.isNot(tok::r_paren));
2979 // Match the ')'.
2980 T.consumeClose();
2981 RParenLoc = T.getCloseLocation();
2983 if (ErrorFound) {
2984 Result = ExprError();
2985 } else if (!Result.isInvalid()) {
2986 Result = Actions.OpenMP().ActOnOMPArrayShapingExpr(
2987 Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges);
2988 }
2989 return Result;
2990 } else {
2991 InMessageExpressionRAIIObject InMessage(*this, false);
2992
2994 if (ExprType >= ParenParseOption::FoldExpr &&
2995 isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
2996 ExprType = ParenParseOption::FoldExpr;
2997 return ParseFoldExpression(Result, T);
2998 }
3000
3001 // Don't build a paren expression unless we actually match a ')'.
3002 if (!Result.isInvalid() && Tok.is(tok::r_paren))
3003 Result =
3004 Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get());
3005 }
3006
3007 // Match the ')'.
3008 if (Result.isInvalid()) {
3009 SkipUntil(tok::r_paren, StopAtSemi);
3010 return ExprError();
3011 }
3012
3013 T.consumeClose();
3014 RParenLoc = T.getCloseLocation();
3015 return Result;
3016}
3017
3019Parser::ParseCompoundLiteralExpression(ParsedType Ty,
3020 SourceLocation LParenLoc,
3021 SourceLocation RParenLoc) {
3022 assert(Tok.is(tok::l_brace) && "Not a compound literal!");
3023 if (!getLangOpts().C99) // Compound literals don't exist in C90.
3024 Diag(LParenLoc, diag::ext_c99_compound_literal);
3025 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get());
3026 ExprResult Result = ParseInitializer();
3027 if (!Result.isInvalid() && Ty)
3028 return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
3029 return Result;
3030}
3031
3033 return ParseStringLiteralExpression(AllowUserDefinedLiteral,
3034 /*Unevaluated=*/false);
3035}
3036
3038 return ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false,
3039 /*Unevaluated=*/true);
3040}
3041
3042ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
3043 bool Unevaluated) {
3045 "Not a string-literal-like token!");
3046
3047 // String concatenation.
3048 // Note: some keywords like __FUNCTION__ are not considered to be strings
3049 // for concatenation purposes, unless Microsoft extensions are enabled.
3050 SmallVector<Token, 4> StringToks;
3051
3052 do {
3053 StringToks.push_back(Tok);
3056
3057 if (Unevaluated) {
3058 assert(!AllowUserDefinedLiteral && "UDL are always evaluated");
3059 return Actions.ActOnUnevaluatedStringLiteral(StringToks);
3060 }
3061
3062 // Pass the set of string tokens, ready for concatenation, to the actions.
3063 return Actions.ActOnStringLiteral(StringToks,
3064 AllowUserDefinedLiteral ? getCurScope()
3065 : nullptr);
3066}
3067
3068ExprResult Parser::ParseGenericSelectionExpression() {
3069 assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
3070
3071 diagnoseUseOfC11Keyword(Tok);
3072
3073 SourceLocation KeyLoc = ConsumeToken();
3074 BalancedDelimiterTracker T(*this, tok::l_paren);
3075 if (T.expectAndConsume())
3076 return ExprError();
3077
3078 // We either have a controlling expression or we have a controlling type, and
3079 // we need to figure out which it is.
3080 TypeResult ControllingType;
3081 ExprResult ControllingExpr;
3082 if (isTypeIdForGenericSelection()) {
3083 ControllingType = ParseTypeName();
3084 if (ControllingType.isInvalid()) {
3085 SkipUntil(tok::r_paren, StopAtSemi);
3086 return ExprError();
3087 }
3088 const auto *LIT = cast<LocInfoType>(ControllingType.get().get());
3089 SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
3090 Diag(Loc, getLangOpts().C2y ? diag::warn_c2y_compat_generic_with_type_arg
3091 : diag::ext_c2y_generic_with_type_arg);
3092 } else {
3093 // C11 6.5.1.1p3 "The controlling expression of a generic selection is
3094 // not evaluated."
3095 EnterExpressionEvaluationContext Unevaluated(
3097 ControllingExpr = ParseAssignmentExpression();
3098 if (ControllingExpr.isInvalid()) {
3099 SkipUntil(tok::r_paren, StopAtSemi);
3100 return ExprError();
3101 }
3102 }
3103
3104 if (ExpectAndConsume(tok::comma)) {
3105 SkipUntil(tok::r_paren, StopAtSemi);
3106 return ExprError();
3107 }
3108
3109 SourceLocation DefaultLoc;
3110 SmallVector<ParsedType, 12> Types;
3111 ExprVector Exprs;
3112 do {
3113 ParsedType Ty;
3114 if (Tok.is(tok::kw_default)) {
3115 // C11 6.5.1.1p2 "A generic selection shall have no more than one default
3116 // generic association."
3117 if (!DefaultLoc.isInvalid()) {
3118 Diag(Tok, diag::err_duplicate_default_assoc);
3119 Diag(DefaultLoc, diag::note_previous_default_assoc);
3120 SkipUntil(tok::r_paren, StopAtSemi);
3121 return ExprError();
3122 }
3123 DefaultLoc = ConsumeToken();
3124 Ty = nullptr;
3125 } else {
3128 if (TR.isInvalid()) {
3129 SkipUntil(tok::r_paren, StopAtSemi);
3130 return ExprError();
3131 }
3132 Ty = TR.get();
3133 }
3134 Types.push_back(Ty);
3135
3136 if (ExpectAndConsume(tok::colon)) {
3137 SkipUntil(tok::r_paren, StopAtSemi);
3138 return ExprError();
3139 }
3140
3141 // FIXME: These expressions should be parsed in a potentially potentially
3142 // evaluated context.
3144 if (ER.isInvalid()) {
3145 SkipUntil(tok::r_paren, StopAtSemi);
3146 return ExprError();
3147 }
3148 Exprs.push_back(ER.get());
3149 } while (TryConsumeToken(tok::comma));
3150
3151 T.consumeClose();
3152 if (T.getCloseLocation().isInvalid())
3153 return ExprError();
3154
3155 void *ExprOrTy = ControllingExpr.isUsable()
3156 ? ControllingExpr.get()
3157 : ControllingType.get().getAsOpaquePtr();
3158
3159 return Actions.ActOnGenericSelectionExpr(
3160 KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(),
3161 ExprOrTy, Types, Exprs);
3162}
3163
3164ExprResult Parser::ParseFoldExpression(ExprResult LHS,
3166 if (LHS.isInvalid()) {
3167 T.skipToEnd();
3168 return true;
3169 }
3170
3171 tok::TokenKind Kind = tok::unknown;
3172 SourceLocation FirstOpLoc;
3173 if (LHS.isUsable()) {
3174 Kind = Tok.getKind();
3175 assert(isFoldOperator(Kind) && "missing fold-operator");
3176 FirstOpLoc = ConsumeToken();
3177 }
3178
3179 assert(Tok.is(tok::ellipsis) && "not a fold-expression");
3180 SourceLocation EllipsisLoc = ConsumeToken();
3181
3182 ExprResult RHS;
3183 if (Tok.isNot(tok::r_paren)) {
3184 if (!isFoldOperator(Tok.getKind()))
3185 return Diag(Tok.getLocation(), diag::err_expected_fold_operator);
3186
3187 if (Kind != tok::unknown && Tok.getKind() != Kind)
3188 Diag(Tok.getLocation(), diag::err_fold_operator_mismatch)
3189 << SourceRange(FirstOpLoc);
3190 Kind = Tok.getKind();
3191 ConsumeToken();
3192
3193 RHS = ParseExpression();
3194 if (RHS.isInvalid()) {
3195 T.skipToEnd();
3196 return true;
3197 }
3198 }
3199
3200 Diag(EllipsisLoc, getLangOpts().CPlusPlus17
3201 ? diag::warn_cxx14_compat_fold_expression
3202 : diag::ext_fold_expression);
3203
3204 T.consumeClose();
3205 return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(),
3206 Kind, EllipsisLoc, RHS.get(),
3207 T.getCloseLocation());
3208}
3209
3210void Parser::injectEmbedTokens() {
3211 EmbedAnnotationData *Data =
3212 reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue());
3213 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(
3214 Data->BinaryData.size() * 2 - 1),
3215 Data->BinaryData.size() * 2 - 1);
3216 unsigned I = 0;
3217 for (auto &Byte : Data->BinaryData) {
3218 Toks[I].startToken();
3219 Toks[I].setKind(tok::binary_data);
3220 Toks[I].setLocation(Tok.getLocation());
3221 Toks[I].setLength(1);
3222 Toks[I].setLiteralData(&Byte);
3223 if (I != ((Data->BinaryData.size() - 1) * 2)) {
3224 Toks[I + 1].startToken();
3225 Toks[I + 1].setKind(tok::comma);
3226 Toks[I + 1].setLocation(Tok.getLocation());
3227 }
3228 I += 2;
3229 }
3230 PP.EnterTokenStream(std::move(Toks), /*DisableMacroExpansion=*/true,
3231 /*IsReinject=*/true);
3232 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
3233}
3234
3235bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
3236 llvm::function_ref<void()> ExpressionStarts,
3237 bool FailImmediatelyOnInvalidExpr) {
3238 bool SawError = false;
3239 while (true) {
3240 if (ExpressionStarts)
3241 ExpressionStarts();
3242
3243 ExprResult Expr;
3244 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
3245 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3246 Expr = ParseBraceInitializer();
3247 } else
3249
3250 if (Tok.is(tok::ellipsis))
3251 Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
3252 else if (Tok.is(tok::code_completion)) {
3253 // There's nothing to suggest in here as we parsed a full expression.
3254 // Instead fail and propagate the error since caller might have something
3255 // the suggest, e.g. signature help in function call. Note that this is
3256 // performed before pushing the \p Expr, so that signature help can report
3257 // current argument correctly.
3258 SawError = true;
3259 cutOffParsing();
3260 break;
3261 }
3262 if (Expr.isInvalid()) {
3263 SawError = true;
3264 if (FailImmediatelyOnInvalidExpr)
3265 break;
3266 SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
3267 } else {
3268 Exprs.push_back(Expr.get());
3269 }
3270
3271 if (Tok.isNot(tok::comma))
3272 break;
3273 // Move to the next argument, remember where the comma was.
3274 Token Comma = Tok;
3275 ConsumeToken();
3276 checkPotentialAngleBracketDelimiter(Comma);
3277 }
3278 return SawError;
3279}
3280
3281bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) {
3282 while (true) {
3284 if (Expr.isInvalid())
3285 return true;
3286
3287 Exprs.push_back(Expr.get());
3288
3289 // We might be parsing the LHS of a fold-expression. If we reached the fold
3290 // operator, stop.
3291 if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis))
3292 return false;
3293
3294 // Move to the next argument, remember where the comma was.
3295 Token Comma = Tok;
3296 ConsumeToken();
3297 checkPotentialAngleBracketDelimiter(Comma);
3298 }
3299}
3300
3301void Parser::ParseBlockId(SourceLocation CaretLoc) {
3302 if (Tok.is(tok::code_completion)) {
3303 cutOffParsing();
3304 Actions.CodeCompletion().CodeCompleteOrdinaryName(
3306 return;
3307 }
3308
3309 // Parse the specifier-qualifier-list piece.
3310 DeclSpec DS(AttrFactory);
3311 ParseSpecifierQualifierList(DS);
3312
3313 // Parse the block-declarator.
3314 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
3316 DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
3317 ParseDeclarator(DeclaratorInfo);
3318
3319 MaybeParseGNUAttributes(DeclaratorInfo);
3320
3321 // Inform sema that we are starting a block.
3322 Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
3323}
3324
3325ExprResult Parser::ParseBlockLiteralExpression() {
3326 assert(Tok.is(tok::caret) && "block literal starts with ^");
3327 SourceLocation CaretLoc = ConsumeToken();
3328
3329 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc,
3330 "block literal parsing");
3331
3332 // Enter a scope to hold everything within the block. This includes the
3333 // argument decls, decls within the compound expression, etc. This also
3334 // allows determining whether a variable reference inside the block is
3335 // within or outside of the block.
3336 ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
3338
3339 // Inform sema that we are starting a block.
3340 Actions.ActOnBlockStart(CaretLoc, getCurScope());
3341
3342 // Parse the return type if present.
3343 DeclSpec DS(AttrFactory);
3344 Declarator ParamInfo(DS, ParsedAttributesView::none(),
3346 ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
3347 // FIXME: Since the return type isn't actually parsed, it can't be used to
3348 // fill ParamInfo with an initial valid range, so do it manually.
3349 ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
3350
3351 // If this block has arguments, parse them. There is no ambiguity here with
3352 // the expression case, because the expression case requires a parameter list.
3353 if (Tok.is(tok::l_paren)) {
3354 ParseParenDeclarator(ParamInfo);
3355 // Parse the pieces after the identifier as if we had "int(...)".
3356 // SetIdentifier sets the source range end, but in this case we're past
3357 // that location.
3358 SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
3359 ParamInfo.SetIdentifier(nullptr, CaretLoc);
3360 ParamInfo.SetRangeEnd(Tmp);
3361 if (ParamInfo.isInvalidType()) {
3362 // If there was an error parsing the arguments, they may have
3363 // tried to use ^(x+y) which requires an argument list. Just
3364 // skip the whole block literal.
3365 Actions.ActOnBlockError(CaretLoc, getCurScope());
3366 return ExprError();
3367 }
3368
3369 MaybeParseGNUAttributes(ParamInfo);
3370
3371 // Inform sema that we are starting a block.
3372 Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3373 } else if (!Tok.is(tok::l_brace)) {
3374 ParseBlockId(CaretLoc);
3375 } else {
3376 // Otherwise, pretend we saw (void).
3377 SourceLocation NoLoc;
3378 ParamInfo.AddTypeInfo(
3379 DeclaratorChunk::getFunction(/*HasProto=*/true,
3380 /*IsAmbiguous=*/false,
3381 /*RParenLoc=*/NoLoc,
3382 /*ArgInfo=*/nullptr,
3383 /*NumParams=*/0,
3384 /*EllipsisLoc=*/NoLoc,
3385 /*RParenLoc=*/NoLoc,
3386 /*RefQualifierIsLvalueRef=*/true,
3387 /*RefQualifierLoc=*/NoLoc,
3388 /*MutableLoc=*/NoLoc, EST_None,
3389 /*ESpecRange=*/SourceRange(),
3390 /*Exceptions=*/nullptr,
3391 /*ExceptionRanges=*/nullptr,
3392 /*NumExceptions=*/0,
3393 /*NoexceptExpr=*/nullptr,
3394 /*ExceptionSpecTokens=*/nullptr,
3395 /*DeclsInPrototype=*/{}, CaretLoc,
3396 CaretLoc, ParamInfo),
3397 CaretLoc);
3398
3399 MaybeParseGNUAttributes(ParamInfo);
3400
3401 // Inform sema that we are starting a block.
3402 Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3403 }
3404
3405
3406 ExprResult Result(true);
3407 if (!Tok.is(tok::l_brace)) {
3408 // Saw something like: ^expr
3409 Diag(Tok, diag::err_expected_expression);
3410 Actions.ActOnBlockError(CaretLoc, getCurScope());
3411 return ExprError();
3412 }
3413 EnterExpressionEvaluationContextForFunction PotentiallyEvaluated(
3415 StmtResult Stmt(ParseCompoundStatementBody());
3416 BlockScope.Exit();
3417 if (!Stmt.isInvalid())
3418 Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
3419 else
3420 Actions.ActOnBlockError(CaretLoc, getCurScope());
3421 return Result;
3422}
3423
3424ExprResult Parser::ParseObjCBoolLiteral() {
3425 tok::TokenKind Kind = Tok.getKind();
3426 return Actions.ObjC().ActOnObjCBoolLiteral(ConsumeToken(), Kind);
3427}
3428
3429/// Validate availability spec list, emitting diagnostics if necessary. Returns
3430/// true if invalid.
3432 ArrayRef<AvailabilitySpec> AvailSpecs) {
3433 llvm::SmallSet<StringRef, 4> Platforms;
3434 bool HasOtherPlatformSpec = false;
3435 bool Valid = true;
3436 for (const auto &Spec : AvailSpecs) {
3437 if (Spec.isOtherPlatformSpec()) {
3438 if (HasOtherPlatformSpec) {
3439 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star);
3440 Valid = false;
3441 }
3442
3443 HasOtherPlatformSpec = true;
3444 continue;
3445 }
3446
3447 bool Inserted = Platforms.insert(Spec.getPlatform()).second;
3448 if (!Inserted) {
3449 // Rule out multiple version specs referring to the same platform.
3450 // For example, we emit an error for:
3451 // @available(macos 10.10, macos 10.11, *)
3452 StringRef Platform = Spec.getPlatform();
3453 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform)
3454 << Spec.getEndLoc() << Platform;
3455 Valid = false;
3456 }
3457 }
3458
3459 if (!HasOtherPlatformSpec) {
3460 SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc();
3461 P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required)
3462 << FixItHint::CreateInsertion(InsertWildcardLoc, ", *");
3463 return true;
3464 }
3465
3466 return !Valid;
3467}
3468
3469std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
3470 if (Tok.is(tok::star)) {
3471 return AvailabilitySpec(ConsumeToken());
3472 } else {
3473 // Parse the platform name.
3474 if (Tok.is(tok::code_completion)) {
3475 cutOffParsing();
3476 Actions.CodeCompletion().CodeCompleteAvailabilityPlatformName();
3477 return std::nullopt;
3478 }
3479 if (Tok.isNot(tok::identifier)) {
3480 Diag(Tok, diag::err_avail_query_expected_platform_name);
3481 return std::nullopt;
3482 }
3483
3484 IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc();
3485 SourceRange VersionRange;
3486 VersionTuple Version = ParseVersionTuple(VersionRange);
3487
3488 if (Version.empty())
3489 return std::nullopt;
3490
3491 StringRef GivenPlatform =
3492 PlatformIdentifier->getIdentifierInfo()->getName();
3493 StringRef Platform =
3494 AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
3495
3496 if (AvailabilityAttr::getPrettyPlatformName(Platform).empty() ||
3497 (GivenPlatform.contains("xros") || GivenPlatform.contains("xrOS"))) {
3498 Diag(PlatformIdentifier->getLoc(),
3499 diag::err_avail_query_unrecognized_platform_name)
3500 << GivenPlatform;
3501 return std::nullopt;
3502 }
3503
3504 // Validate anyAppleOS version; reject versions older than 26.0.
3505 if (Platform == "anyappleos" &&
3507 Diag(VersionRange.getBegin(),
3508 diag::err_avail_query_anyappleos_min_version)
3509 << Version.getAsString();
3510 return std::nullopt;
3511 }
3512
3513 return AvailabilitySpec(Version, Platform, PlatformIdentifier->getLoc(),
3514 VersionRange.getEnd());
3515 }
3516}
3517
3518ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) {
3519 assert(Tok.is(tok::kw___builtin_available) ||
3520 Tok.isObjCAtKeyword(tok::objc_available));
3521
3522 // Eat the available or __builtin_available.
3523 ConsumeToken();
3524
3525 BalancedDelimiterTracker Parens(*this, tok::l_paren);
3526 if (Parens.expectAndConsume())
3527 return ExprError();
3528
3529 SmallVector<AvailabilitySpec, 4> AvailSpecs;
3530 bool HasError = false;
3531 while (true) {
3532 std::optional<AvailabilitySpec> Spec = ParseAvailabilitySpec();
3533 if (!Spec)
3534 HasError = true;
3535 else
3536 AvailSpecs.push_back(*Spec);
3537
3538 if (!TryConsumeToken(tok::comma))
3539 break;
3540 }
3541
3542 if (HasError) {
3543 SkipUntil(tok::r_paren, StopAtSemi);
3544 return ExprError();
3545 }
3546
3547 CheckAvailabilitySpecList(*this, AvailSpecs);
3548
3549 if (Parens.consumeClose())
3550 return ExprError();
3551
3552 return Actions.ObjC().ActOnObjCAvailabilityCheckExpr(
3553 AvailSpecs, BeginLoc, Parens.getCloseLocation());
3554}
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:283
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:8499
@ 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:9039
bool isFunctionType() const
Definition TypeBase.h:8680
bool isVectorType() const
Definition TypeBase.h:8823
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:1127
bool isValid() const
Determine whether this unqualified-id refers to a valid name.
Definition DeclSpec.h:1115
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclSpec.h:1252
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:5010
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.