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