clang 23.0.0git
ParseExpr.cpp
Go to the documentation of this file.
1//===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// Provides the Expression parsing implementation.
11///
12/// Expressions in C99 basically consist of a bunch of binary operators with
13/// unary operators and other random stuff at the leaves.
14///
15/// In the C99 grammar, these unary operators bind tightest and are represented
16/// as the 'cast-expression' production. Everything else is either a binary
17/// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are
18/// handled by ParseCastExpression, the higher level pieces are handled by
19/// ParseBinaryExpression.
20///
21//===----------------------------------------------------------------------===//
22
25#include "clang/AST/ExprCXX.h"
29#include "clang/Parse/Parser.h"
31#include "clang/Sema/DeclSpec.h"
34#include "clang/Sema/Scope.h"
35#include "clang/Sema/SemaCUDA.h"
37#include "clang/Sema/SemaObjC.h"
40#include "clang/Sema/SemaSYCL.h"
42#include "llvm/ADT/SmallVector.h"
43#include <optional>
44using namespace clang;
45
48 ExprResult LHS(ParseAssignmentExpression(CorrectionBehavior));
49 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
50}
51
53Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
54 ExprResult LHS(ParseObjCAtExpression(AtLoc));
55 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
56}
57
59Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
60 ExprResult LHS(true);
61 {
62 // Silence extension warnings in the sub-expression
63 ExtensionRAIIObject O(Diags);
64
65 LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
66 }
67
68 if (!LHS.isInvalid())
69 LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
70 LHS.get());
71
72 return ParseRHSOfBinaryExpression(LHS, prec::Comma);
73}
74
76 TypoCorrectionTypeBehavior CorrectionBehavior) {
77 if (Tok.is(tok::code_completion)) {
78 cutOffParsing();
79 Actions.CodeCompletion().CodeCompleteExpression(
80 getCurScope(), PreferredType.get(Tok.getLocation()));
81 return ExprError();
82 }
83
84 if (Tok.is(tok::kw_throw))
85 return ParseThrowExpression();
86 if (Tok.is(tok::kw_co_yield))
87 return ParseCoyieldExpression();
88
89 ExprResult LHS =
90 ParseCastExpression(CastParseKind::AnyCastExpr,
91 /*isAddressOfOperand=*/false, CorrectionBehavior);
92 return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
93}
94
96 if (Tok.is(tok::code_completion)) {
97 cutOffParsing();
98 Actions.CodeCompletion().CodeCompleteExpression(
99 getCurScope(), PreferredType.get(Tok.getLocation()));
100 return ExprError();
101 }
102
103 ExprResult LHS = ParseCastExpression(
105 /*isAddressOfOperand=*/false, TypoCorrectionTypeBehavior::AllowNonTypes);
106 return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
107}
108
110Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
111 SourceLocation SuperLoc,
112 ParsedType ReceiverType,
113 Expr *ReceiverExpr) {
114 ExprResult R
115 = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
116 ReceiverType, ReceiverExpr);
117 R = ParsePostfixExpressionSuffix(R);
118 return ParseRHSOfBinaryExpression(R, prec::Assignment);
119}
120
122 TypoCorrectionTypeBehavior CorrectionBehavior) {
123 assert(Actions.ExprEvalContexts.back().Context ==
125 "Call this function only if your ExpressionEvaluationContext is "
126 "already ConstantEvaluated");
127 ExprResult LHS(ParseCastExpression(CastParseKind::AnyCastExpr, false,
128 CorrectionBehavior));
129 ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
130 return Actions.ActOnConstantExpression(Res);
131}
132
134 // C++03 [basic.def.odr]p2:
135 // An expression is potentially evaluated unless it appears where an
136 // integral constant expression is required (see 5.19) [...].
137 // C++98 and C++11 have no such rule, but this is only a defect in C++98.
138 EnterExpressionEvaluationContext ConstantEvaluated(
142}
143
145 EnterExpressionEvaluationContext ConstantEvaluated(
147 // If we parse the bound of a VLA... we parse a non-constant
148 // constant-expression!
149 Actions.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
150 // For a VLA type inside an unevaluated operator like:
151 //
152 // sizeof(typeof(*(int (*)[N])array))
153 //
154 // N and array are supposed to be ODR-used.
155 // Initially when encountering `array`, it is deemed unevaluated and non-ODR
156 // used because that occurs before parsing the type cast. Therefore we use
157 // Sema::TransformToPotentiallyEvaluated() to rebuild the expression to ensure
158 // it's actually ODR-used.
159 //
160 // However, in other unevaluated contexts as in constraint substitution, it
161 // would end up rebuilding the type twice which is unnecessary. So we push up
162 // a flag to help distinguish these cases.
163 for (auto Iter = Actions.ExprEvalContexts.rbegin() + 1;
164 Iter != Actions.ExprEvalContexts.rend(); ++Iter) {
165 if (!Iter->isUnevaluated())
166 break;
167 Iter->InConditionallyConstantEvaluateContext = true;
168 }
171}
172
174 EnterExpressionEvaluationContext ConstantEvaluated(
176 Actions.currentEvaluationContext().IsCaseExpr = true;
177
178 ExprResult LHS(
179 ParseCastExpression(CastParseKind::AnyCastExpr, false,
181 ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
182 return Actions.ActOnCaseExpr(CaseLoc, Res);
183}
184
186 EnterExpressionEvaluationContext ConstantEvaluated(
188 ExprResult LHS(ParseCastExpression(CastParseKind::AnyCastExpr));
189 ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
190 if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) {
191 return ExprError();
192 }
193 return Res;
194}
195
197Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
198 EnterExpressionEvaluationContext ConstantEvaluated(
200 bool NotPrimaryExpression = false;
201 auto ParsePrimary = [&]() {
202 ExprResult E = ParseCastExpression(
204 /*isAddressOfOperand=*/false, TypoCorrectionTypeBehavior::AllowNonTypes,
205 /*isVectorLiteral=*/false, &NotPrimaryExpression);
206 if (E.isInvalid())
207 return ExprError();
208 auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) {
209 E = ParsePostfixExpressionSuffix(E);
210 // Use InclusiveOr, the precedence just after '&&' to not parse the
211 // next arguments to the logical and.
212 E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr);
213 if (!E.isInvalid())
214 Diag(E.get()->getExprLoc(),
215 Note
216 ? diag::note_unparenthesized_non_primary_expr_in_requires_clause
217 : diag::err_unparenthesized_non_primary_expr_in_requires_clause)
220 PP.getLocForEndOfToken(E.get()->getEndLoc()), ")")
221 << E.get()->getSourceRange();
222 return E;
223 };
224
225 if (NotPrimaryExpression ||
226 // Check if the following tokens must be a part of a non-primary
227 // expression
228 getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
229 /*CPlusPlus11=*/true) > prec::LogicalAnd ||
230 // Postfix operators other than '(' (which will be checked for in
231 // CheckConstraintExpression).
232 Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) ||
233 (Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) {
234 E = RecoverFromNonPrimary(E, /*Note=*/false);
235 if (E.isInvalid())
236 return ExprError();
237 NotPrimaryExpression = false;
238 }
239 bool PossibleNonPrimary;
240 bool IsConstraintExpr =
241 Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary,
242 IsTrailingRequiresClause);
243 if (!IsConstraintExpr || PossibleNonPrimary) {
244 // Atomic constraint might be an unparenthesized non-primary expression
245 // (such as a binary operator), in which case we might get here (e.g. in
246 // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore
247 // the rest of the addition expression). Try to parse the rest of it here.
248 if (PossibleNonPrimary)
249 E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr);
250 return ExprError();
251 }
252 return E;
253 };
254 ExprResult LHS = ParsePrimary();
255 if (LHS.isInvalid())
256 return ExprError();
257 while (Tok.is(tok::ampamp)) {
258 SourceLocation LogicalAndLoc = ConsumeToken();
259 ExprResult RHS = ParsePrimary();
260 if (RHS.isInvalid()) {
261 return ExprError();
262 }
263 ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc,
264 tok::ampamp, LHS.get(), RHS.get());
265 if (!Op.isUsable()) {
266 return ExprError();
267 }
268 LHS = Op;
269 }
270 return LHS;
271}
272
274Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) {
275 ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause));
276 if (!LHS.isUsable())
277 return ExprError();
278 while (Tok.is(tok::pipepipe)) {
279 SourceLocation LogicalOrLoc = ConsumeToken();
280 ExprResult RHS =
281 ParseConstraintLogicalAndExpression(IsTrailingRequiresClause);
282 if (!RHS.isUsable()) {
283 return ExprError();
284 }
285 ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc,
286 tok::pipepipe, LHS.get(), RHS.get());
287 if (!Op.isUsable()) {
288 return ExprError();
289 }
290 LHS = Op;
291 }
292 return LHS;
293}
294
295bool Parser::isNotExpressionStart() {
296 tok::TokenKind K = Tok.getKind();
297 if (K == tok::l_brace || K == tok::r_brace ||
298 K == tok::kw_for || K == tok::kw_while ||
299 K == tok::kw_if || K == tok::kw_else ||
300 K == tok::kw_goto || K == tok::kw_try)
301 return true;
302 // If this is a decl-specifier, we can't be at the start of an expression.
303 return isKnownToBeDeclarationSpecifier();
304}
305
306bool Parser::isFoldOperator(prec::Level Level) const {
307 return Level > prec::Unknown && Level != prec::Conditional &&
308 Level != prec::Spaceship;
309}
310
311bool Parser::isFoldOperator(tok::TokenKind Kind) const {
312 return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true));
313}
314
316Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
317 prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
318 GreaterThanIsOperator,
320 SourceLocation ColonLoc;
321
322 auto SavedType = PreferredType;
323 while (true) {
324 // Every iteration may rely on a preferred type for the whole expression.
325 PreferredType = SavedType;
326 // If this token has a lower precedence than we are allowed to parse (e.g.
327 // because we are called recursively, or because the token is not a binop),
328 // then we are done!
329 if (NextTokPrec < MinPrec)
330 return LHS;
331
332 // Consume the operator, saving the operator token for error reporting.
333 Token OpToken = Tok;
334 ConsumeToken();
335
336 // The reflection operator is not valid here (i.e., in the place of the
337 // operator token in a binary expression), so if reflection and blocks are
338 // enabled, we split caretcaret into two carets: the first being the binary
339 // operator and the second being the introducer for the block.
340 if (OpToken.is(tok::caretcaret)) {
341 assert(getLangOpts().Reflection);
342 if (getLangOpts().Blocks) {
343 OpToken.setKind(tok::caret);
344 Token Caret;
345 {
346 Caret.startToken();
347 Caret.setKind(tok::caret);
348 Caret.setLocation(OpToken.getLocation().getLocWithOffset(1));
349 Caret.setLength(1);
350 }
351 UnconsumeToken(OpToken);
352 PP.EnterToken(Caret, /*IsReinject=*/true);
353 return ParseRHSOfBinaryExpression(LHS, MinPrec);
354 }
355 }
356
357 // If we're potentially in a template-id, we may now be able to determine
358 // whether we're actually in one or not.
359 if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
360 tok::greatergreatergreater) &&
361 checkPotentialAngleBracketDelimiter(OpToken))
362 return ExprError();
363
364 // Bail out when encountering a comma followed by a token which can't
365 // possibly be the start of an expression. For instance:
366 // int f() { return 1, }
367 // We can't do this before consuming the comma, because
368 // isNotExpressionStart() looks at the token stream.
369 if (OpToken.is(tok::comma) && isNotExpressionStart()) {
370 PP.EnterToken(Tok, /*IsReinject*/true);
371 Tok = OpToken;
372 return LHS;
373 }
374
375 // If the next token is an ellipsis, then this is a fold-expression. Leave
376 // it alone so we can handle it in the paren expression.
377 if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
378 // FIXME: We can't check this via lookahead before we consume the token
379 // because that tickles a lexer bug.
380 PP.EnterToken(Tok, /*IsReinject*/true);
381 Tok = OpToken;
382 return LHS;
383 }
384
385 // In Objective-C++, alternative operator tokens can be used as keyword args
386 // in message expressions. Unconsume the token so that it can reinterpreted
387 // as an identifier in ParseObjCMessageExpressionBody. i.e., we support:
388 // [foo meth:0 and:0];
389 // [foo not_eq];
391 Tok.isOneOf(tok::colon, tok::r_square) &&
392 OpToken.getIdentifierInfo() != nullptr) {
393 PP.EnterToken(Tok, /*IsReinject*/true);
394 Tok = OpToken;
395 return LHS;
396 }
397
398 // Special case handling for the ternary operator.
399 ExprResult TernaryMiddle(true);
400 if (NextTokPrec == prec::Conditional) {
401 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
402 // Parse a braced-init-list here for error recovery purposes.
403 SourceLocation BraceLoc = Tok.getLocation();
404 TernaryMiddle = ParseBraceInitializer();
405 if (!TernaryMiddle.isInvalid()) {
406 Diag(BraceLoc, diag::err_init_list_bin_op)
407 << /*RHS*/ 1 << PP.getSpelling(OpToken)
408 << Actions.getExprRange(TernaryMiddle.get());
409 TernaryMiddle = ExprError();
410 }
411 } else if (Tok.isNot(tok::colon)) {
412 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
414
415 // Handle this production specially:
416 // logical-OR-expression '?' expression ':' conditional-expression
417 // In particular, the RHS of the '?' is 'expression', not
418 // 'logical-OR-expression' as we might expect.
419 TernaryMiddle = ParseExpression();
420 } else {
421 // Special case handling of "X ? Y : Z" where Y is empty:
422 // logical-OR-expression '?' ':' conditional-expression [GNU]
423 TernaryMiddle = nullptr;
424 Diag(Tok, diag::ext_gnu_conditional_expr);
425 }
426
427 if (TernaryMiddle.isInvalid()) {
428 LHS = ExprError();
429 TernaryMiddle = nullptr;
430 }
431
432 if (!TryConsumeToken(tok::colon, ColonLoc)) {
433 // Otherwise, we're missing a ':'. Assume that this was a typo that
434 // the user forgot. If we're not in a macro expansion, we can suggest
435 // a fixit hint. If there were two spaces before the current token,
436 // suggest inserting the colon in between them, otherwise insert ": ".
437 SourceLocation FILoc = Tok.getLocation();
438 const char *FIText = ": ";
439 const SourceManager &SM = PP.getSourceManager();
440 if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) {
441 assert(FILoc.isFileID());
442 bool IsInvalid = false;
443 const char *SourcePtr =
444 SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid);
445 if (!IsInvalid && *SourcePtr == ' ') {
446 SourcePtr =
447 SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid);
448 if (!IsInvalid && *SourcePtr == ' ') {
449 FILoc = FILoc.getLocWithOffset(-1);
450 FIText = ":";
451 }
452 }
453 }
454
455 Diag(Tok, diag::err_expected)
456 << tok::colon << FixItHint::CreateInsertion(FILoc, FIText);
457 Diag(OpToken, diag::note_matching) << tok::question;
458 ColonLoc = Tok.getLocation();
459 }
460 }
461
462 PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(),
463 OpToken.getKind());
464 // Parse another leaf here for the RHS of the operator.
465 // ParseCastExpression works here because all RHS expressions in C have it
466 // as a prefix, at least. However, in C++, an assignment-expression could
467 // be a throw-expression, which is not a valid cast-expression.
468 // Therefore we need some special-casing here.
469 // Also note that the third operand of the conditional operator is
470 // an assignment-expression in C++, and in C++11, we can have a
471 // braced-init-list on the RHS of an assignment. For better diagnostics,
472 // parse as if we were allowed braced-init-lists everywhere, and check that
473 // they only appear on the RHS of assignments later.
474 ExprResult RHS;
475 bool RHSIsInitList = false;
476 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
477 RHS = ParseBraceInitializer();
478 RHSIsInitList = true;
479 } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional)
481 else
482 RHS = ParseCastExpression(CastParseKind::AnyCastExpr);
483
484 if (RHS.isInvalid()) {
485 LHS = ExprError();
486 }
487
488 // Remember the precedence of this operator and get the precedence of the
489 // operator immediately to the right of the RHS.
490 prec::Level ThisPrec = NextTokPrec;
491 NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
493
494 // Assignment and conditional expressions are right-associative.
495 bool isRightAssoc = ThisPrec == prec::Conditional ||
496 ThisPrec == prec::Assignment;
497
498 // Get the precedence of the operator to the right of the RHS. If it binds
499 // more tightly with RHS than we do, evaluate it completely first.
500 if (ThisPrec < NextTokPrec ||
501 (ThisPrec == NextTokPrec && isRightAssoc)) {
502 if (!RHS.isInvalid() && RHSIsInitList) {
503 Diag(Tok, diag::err_init_list_bin_op)
504 << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get());
505 RHS = ExprError();
506 }
507 // If this is left-associative, only parse things on the RHS that bind
508 // more tightly than the current operator. If it is right-associative, it
509 // is okay, to bind exactly as tightly. For example, compile A=B=C=D as
510 // A=(B=(C=D)), where each paren is a level of recursion here.
511 // The function takes ownership of the RHS.
512 RHS = ParseRHSOfBinaryExpression(RHS,
513 static_cast<prec::Level>(ThisPrec + !isRightAssoc));
514 RHSIsInitList = false;
515
516 if (RHS.isInvalid()) {
517 LHS = ExprError();
518 }
519
520 NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
522 }
523
524 if (!RHS.isInvalid() && RHSIsInitList) {
525 if (ThisPrec == prec::Assignment) {
526 Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
527 << Actions.getExprRange(RHS.get());
528 } else if (ColonLoc.isValid()) {
529 Diag(ColonLoc, diag::err_init_list_bin_op)
530 << /*RHS*/1 << ":"
531 << Actions.getExprRange(RHS.get());
532 LHS = ExprError();
533 } else {
534 Diag(OpToken, diag::err_init_list_bin_op)
535 << /*RHS*/1 << PP.getSpelling(OpToken)
536 << Actions.getExprRange(RHS.get());
537 LHS = ExprError();
538 }
539 }
540
541 if (!LHS.isInvalid()) {
542 // Combine the LHS and RHS into the LHS (e.g. build AST).
543 if (TernaryMiddle.isInvalid()) {
544 // If we're using '>>' as an operator within a template
545 // argument list (in C++98), suggest the addition of
546 // parentheses so that the code remains well-formed in C++0x.
547 if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater))
548 SuggestParentheses(OpToken.getLocation(),
549 diag::warn_cxx11_right_shift_in_template_arg,
550 SourceRange(Actions.getExprRange(LHS.get()).getBegin(),
551 Actions.getExprRange(RHS.get()).getEnd()));
552
553 ExprResult BinOp =
554 Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
555 OpToken.getKind(), LHS.get(), RHS.get());
556 if (BinOp.isInvalid())
557 BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(),
558 RHS.get()->getEndLoc(),
559 {LHS.get(), RHS.get()});
560
561 LHS = BinOp;
562 } else {
563 ExprResult CondOp = Actions.ActOnConditionalOp(
564 OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(),
565 RHS.get());
566 if (CondOp.isInvalid()) {
567 std::vector<clang::Expr *> Args;
568 // TernaryMiddle can be null for the GNU conditional expr extension.
569 if (TernaryMiddle.get())
570 Args = {LHS.get(), TernaryMiddle.get(), RHS.get()};
571 else
572 Args = {LHS.get(), RHS.get()};
573 CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(),
574 RHS.get()->getEndLoc(), Args);
575 }
576
577 LHS = CondOp;
578 }
579 }
580 }
581}
582
584Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand,
585 TypoCorrectionTypeBehavior CorrectionBehavior,
586 bool isVectorLiteral, bool *NotPrimaryExpression) {
587 bool NotCastExpr;
588 ExprResult Res = ParseCastExpression(ParseKind, isAddressOfOperand,
589 NotCastExpr, CorrectionBehavior,
590 isVectorLiteral, NotPrimaryExpression);
591 if (NotCastExpr)
592 Diag(Tok, diag::err_expected_expression);
593 return Res;
594}
595
596namespace {
597class CastExpressionIdValidator final : public CorrectionCandidateCallback {
598public:
599 CastExpressionIdValidator(Token Next,
600 TypoCorrectionTypeBehavior CorrectionBehavior)
601 : NextToken(Next) {
602 WantTypeSpecifiers = WantFunctionLikeCasts =
603 (CorrectionBehavior != TypoCorrectionTypeBehavior::AllowNonTypes);
605 (CorrectionBehavior != TypoCorrectionTypeBehavior::AllowTypes);
606 }
607
608 bool ValidateCandidate(const TypoCorrection &candidate) override {
609 NamedDecl *ND = candidate.getCorrectionDecl();
610 if (!ND)
611 return candidate.isKeyword();
612
613 if (isa<TypeDecl>(ND))
614 return WantTypeSpecifiers;
615
617 return false;
618
619 if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period))
620 return true;
621
622 for (auto *C : candidate) {
623 NamedDecl *ND = C->getUnderlyingDecl();
624 if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND))
625 return true;
626 }
627 return false;
628 }
629
630 std::unique_ptr<CorrectionCandidateCallback> clone() override {
631 return std::make_unique<CastExpressionIdValidator>(*this);
632 }
633
634 private:
635 Token NextToken;
636 bool AllowNonTypes;
637};
638}
639
640bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
641 tok::TokenKind *Kind) {
642 if (RevertibleTypeTraits.empty()) {
643// Revertible type trait is a feature for backwards compatibility with older
644// standard libraries that declare their own structs with the same name as
645// the builtins listed below. New builtins should NOT be added to this list.
646#define RTT_JOIN(X, Y) X##Y
647#define REVERTIBLE_TYPE_TRAIT(Name) \
648 RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] = RTT_JOIN(tok::kw_, Name)
649
650 REVERTIBLE_TYPE_TRAIT(__is_abstract);
651 REVERTIBLE_TYPE_TRAIT(__is_aggregate);
652 REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
653 REVERTIBLE_TYPE_TRAIT(__is_array);
654 REVERTIBLE_TYPE_TRAIT(__is_assignable);
655 REVERTIBLE_TYPE_TRAIT(__is_base_of);
656 REVERTIBLE_TYPE_TRAIT(__is_bounded_array);
657 REVERTIBLE_TYPE_TRAIT(__is_class);
658 REVERTIBLE_TYPE_TRAIT(__is_complete_type);
659 REVERTIBLE_TYPE_TRAIT(__is_compound);
660 REVERTIBLE_TYPE_TRAIT(__is_const);
661 REVERTIBLE_TYPE_TRAIT(__is_constructible);
662 REVERTIBLE_TYPE_TRAIT(__is_convertible);
663 REVERTIBLE_TYPE_TRAIT(__is_convertible_to);
664 REVERTIBLE_TYPE_TRAIT(__is_destructible);
665 REVERTIBLE_TYPE_TRAIT(__is_empty);
666 REVERTIBLE_TYPE_TRAIT(__is_enum);
667 REVERTIBLE_TYPE_TRAIT(__is_floating_point);
668 REVERTIBLE_TYPE_TRAIT(__is_final);
669 REVERTIBLE_TYPE_TRAIT(__is_function);
670 REVERTIBLE_TYPE_TRAIT(__is_fundamental);
671 REVERTIBLE_TYPE_TRAIT(__is_integral);
672 REVERTIBLE_TYPE_TRAIT(__is_interface_class);
673 REVERTIBLE_TYPE_TRAIT(__is_literal);
674 REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr);
675 REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference);
676 REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
677 REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer);
678 REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
679 REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
680 REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
681 REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
682 REVERTIBLE_TYPE_TRAIT(__is_object);
683 REVERTIBLE_TYPE_TRAIT(__is_pod);
684 REVERTIBLE_TYPE_TRAIT(__is_pointer);
685 REVERTIBLE_TYPE_TRAIT(__is_polymorphic);
686 REVERTIBLE_TYPE_TRAIT(__is_reference);
687 REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr);
688 REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
689 REVERTIBLE_TYPE_TRAIT(__is_same);
690 REVERTIBLE_TYPE_TRAIT(__is_scalar);
691 REVERTIBLE_TYPE_TRAIT(__is_scoped_enum);
692 REVERTIBLE_TYPE_TRAIT(__is_sealed);
693 REVERTIBLE_TYPE_TRAIT(__is_signed);
694 REVERTIBLE_TYPE_TRAIT(__is_standard_layout);
695 REVERTIBLE_TYPE_TRAIT(__is_trivial);
696 REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
697 REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
698 REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
699 REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
700 REVERTIBLE_TYPE_TRAIT(__is_union);
701 REVERTIBLE_TYPE_TRAIT(__is_unsigned);
702 REVERTIBLE_TYPE_TRAIT(__is_void);
703 REVERTIBLE_TYPE_TRAIT(__is_volatile);
704 REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary);
705#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
706 REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
707#include "clang/Basic/TransformTypeTraits.def"
708#undef REVERTIBLE_TYPE_TRAIT
709#undef RTT_JOIN
710 }
711 llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known =
712 RevertibleTypeTraits.find(II);
713 if (Known != RevertibleTypeTraits.end()) {
714 if (Kind)
715 *Kind = Known->second;
716 return true;
717 }
718 return false;
719}
720
721ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() {
722 SourceLocation Loc = ConsumeToken();
723
724 BalancedDelimiterTracker T(*this, tok::l_paren);
725 if (T.expectAndConsume())
726 return ExprError();
727
729 if (Ty.isInvalid()) {
730 SkipUntil(tok::r_paren, StopAtSemi);
731 return ExprError();
732 }
733
734 SourceLocation EndLoc = Tok.getLocation();
735 T.consumeClose();
736 return Actions.ActOnUnaryExprOrTypeTraitExpr(
737 Loc, UETT_PtrAuthTypeDiscriminator,
738 /*isType=*/true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc));
739}
740
742Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand,
743 bool &NotCastExpr,
744 TypoCorrectionTypeBehavior CorrectionBehavior,
745 bool isVectorLiteral, bool *NotPrimaryExpression) {
746 ExprResult Res;
747 tok::TokenKind SavedKind = Tok.getKind();
748 auto SavedType = PreferredType;
749 NotCastExpr = false;
750
751 // Are postfix-expression suffix operators permitted after this
752 // cast-expression? If not, and we find some, we'll parse them anyway and
753 // diagnose them.
754 bool AllowSuffix = true;
755
756 // This handles all of cast-expression, unary-expression, postfix-expression,
757 // and primary-expression. We handle them together like this for efficiency
758 // and to simplify handling of an expression starting with a '(' token: which
759 // may be one of a parenthesized expression, cast-expression, compound literal
760 // expression, or statement expression.
761 //
762 // If the parsed tokens consist of a primary-expression, the cases below
763 // break out of the switch; at the end we call ParsePostfixExpressionSuffix
764 // to handle the postfix expression suffixes. Cases that cannot be followed
765 // by postfix exprs should set AllowSuffix to false.
766 switch (SavedKind) {
767 case tok::l_paren: {
768 // If this expression is limited to being a unary-expression, the paren can
769 // not start a cast expression.
770 ParenParseOption ParenExprType;
771 switch (ParseKind) {
773 assert(getLangOpts().CPlusPlus && "not possible to get here in C");
774 [[fallthrough]];
776 ParenExprType = ParenParseOption::CastExpr;
777 break;
779 ParenExprType = ParenParseOption::FoldExpr;
780 break;
781 }
782 ParsedType CastTy;
783 SourceLocation RParenLoc;
784 Res = ParseParenExpression(ParenExprType, /*StopIfCastExr=*/false,
785 ParenExprKind::Unknown, CorrectionBehavior,
786 CastTy, RParenLoc);
787
788 // FIXME: What should we do if a vector literal is followed by a
789 // postfix-expression suffix? Usually postfix operators are permitted on
790 // literals.
791 if (isVectorLiteral)
792 return Res;
793
794 switch (ParenExprType) {
796 break; // Nothing else to do.
798 break; // Nothing else to do.
800 // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
801 // postfix-expression exist, parse them now.
802 break;
804 // We have parsed the cast-expression and no postfix-expr pieces are
805 // following.
806 return Res;
808 // We only parsed a fold-expression. There might be postfix-expr pieces
809 // afterwards; parse them now.
810 break;
811 }
812
813 break;
814 }
815
816 // primary-expression
817 case tok::numeric_constant:
818 case tok::binary_data:
819 // constant: integer-constant
820 // constant: floating-constant
821
822 Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope());
823 ConsumeToken();
824 break;
825
826 case tok::kw_true:
827 case tok::kw_false:
828 Res = ParseCXXBoolLiteral();
829 break;
830
831 case tok::kw___objc_yes:
832 case tok::kw___objc_no:
833 Res = ParseObjCBoolLiteral();
834 break;
835
836 case tok::kw_nullptr:
838 Diag(Tok, diag::warn_cxx98_compat_nullptr);
839 else
840 Diag(Tok, getLangOpts().C23 ? diag::warn_c23_compat_keyword
841 : diag::ext_c_nullptr) << Tok.getName();
842
843 Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
844 break;
845
846 case tok::annot_primary_expr:
847 case tok::annot_overload_set:
848 Res = getExprAnnotation(Tok);
849 if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set)
850 Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get());
851 ConsumeAnnotationToken();
852 if (!Res.isInvalid() && Tok.is(tok::less))
853 checkPotentialAngleBracket(Res);
854 break;
855
856 case tok::annot_non_type:
857 case tok::annot_non_type_dependent:
858 case tok::annot_non_type_undeclared: {
859 CXXScopeSpec SS;
860 Token Replacement;
861 Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
862 assert(!Res.isUnset() &&
863 "should not perform typo correction on annotation token");
864 break;
865 }
866
867 case tok::annot_embed: {
868 injectEmbedTokens();
869 return ParseCastExpression(ParseKind, isAddressOfOperand,
870 CorrectionBehavior, isVectorLiteral,
871 NotPrimaryExpression);
872 }
873
874 case tok::kw___super:
875 case tok::kw_decltype:
876 // Annotate the token and tail recurse.
878 return ExprError();
879 assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super));
880 return ParseCastExpression(ParseKind, isAddressOfOperand,
881 CorrectionBehavior, isVectorLiteral,
882 NotPrimaryExpression);
883
884 case tok::identifier:
885 ParseIdentifier: { // primary-expression: identifier
886 // unqualified-id: identifier
887 // constant: enumeration-constant
888 // Turn a potentially qualified name into a annot_typename or
889 // annot_cxxscope if it would be valid. This handles things like x::y, etc.
890 if (getLangOpts().CPlusPlus) {
891 // Avoid the unnecessary parse-time lookup in the common case
892 // where the syntax forbids a type.
893 Token Next = NextToken();
894
895 if (Next.is(tok::ellipsis) && Tok.is(tok::identifier) &&
896 GetLookAheadToken(2).is(tok::l_square)) {
897 // Annotate the token and tail recurse.
898 // If the token is not annotated, then it might be an expression pack
899 // indexing
901 Tok.isOneOf(tok::annot_pack_indexing_type, tok::annot_cxxscope))
902 return ParseCastExpression(ParseKind, isAddressOfOperand,
903 CorrectionBehavior, isVectorLiteral,
904 NotPrimaryExpression);
905 }
906
907 // If this identifier was reverted from a token ID, and the next token
908 // is a parenthesis, this is likely to be a use of a type trait. Check
909 // those tokens.
910 else if (Next.is(tok::l_paren) && Tok.is(tok::identifier) &&
911 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
912 IdentifierInfo *II = Tok.getIdentifierInfo();
914 if (isRevertibleTypeTrait(II, &Kind)) {
915 Tok.setKind(Kind);
916 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
917 CorrectionBehavior, isVectorLiteral,
918 NotPrimaryExpression);
919 }
920 }
921
922 else if ((!ColonIsSacred && Next.is(tok::colon)) ||
923 Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren,
924 tok::l_brace)) {
925 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
926 if (TryAnnotateTypeOrScopeToken(isAddressOfOperand))
927 return ExprError();
928 if (!Tok.is(tok::identifier))
929 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
930 CorrectionBehavior, isVectorLiteral,
931 NotPrimaryExpression);
932 }
933 }
934
935 // Consume the identifier so that we can see if it is followed by a '(' or
936 // '.'.
937 IdentifierInfo &II = *Tok.getIdentifierInfo();
938 SourceLocation ILoc = ConsumeToken();
939
940 // Support 'Class.property' and 'super.property' notation.
941 if (getLangOpts().ObjC && Tok.is(tok::period) &&
942 (Actions.getTypeName(II, ILoc, getCurScope()) ||
943 // Allow the base to be 'super' if in an objc-method.
944 (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
945 ConsumeToken();
946
947 if (Tok.is(tok::code_completion) && &II != Ident_super) {
948 cutOffParsing();
949 Actions.CodeCompletion().CodeCompleteObjCClassPropertyRefExpr(
950 getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
951 return ExprError();
952 }
953 // Allow either an identifier or the keyword 'class' (in C++).
954 if (Tok.isNot(tok::identifier) &&
955 !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) {
956 Diag(Tok, diag::err_expected_property_name);
957 return ExprError();
958 }
959 IdentifierInfo &PropertyName = *Tok.getIdentifierInfo();
960 SourceLocation PropertyLoc = ConsumeToken();
961
962 Res = Actions.ObjC().ActOnClassPropertyRefExpr(II, PropertyName, ILoc,
963 PropertyLoc);
964 break;
965 }
966
967 // In an Objective-C method, if we have "super" followed by an identifier,
968 // the token sequence is ill-formed. However, if there's a ':' or ']' after
969 // that identifier, this is probably a message send with a missing open
970 // bracket. Treat it as such.
971 if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression &&
972 getCurScope()->isInObjcMethodScope() &&
973 ((Tok.is(tok::identifier) &&
974 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) ||
975 Tok.is(tok::code_completion))) {
976 Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr,
977 nullptr);
978 break;
979 }
980
981 // If we have an Objective-C class name followed by an identifier
982 // and either ':' or ']', this is an Objective-C class message
983 // send that's missing the opening '['. Recovery
984 // appropriately. Also take this path if we're performing code
985 // completion after an Objective-C class name.
986 if (getLangOpts().ObjC &&
987 ((Tok.is(tok::identifier) && !InMessageExpression) ||
988 Tok.is(tok::code_completion))) {
989 const Token& Next = NextToken();
990 if (Tok.is(tok::code_completion) ||
991 Next.is(tok::colon) || Next.is(tok::r_square))
992 if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
993 if (Typ.get()->isObjCObjectOrInterfaceType()) {
994 // Fake up a Declarator to use with ActOnTypeName.
995 DeclSpec DS(AttrFactory);
996 DS.SetRangeStart(ILoc);
997 DS.SetRangeEnd(ILoc);
998 const char *PrevSpec = nullptr;
999 unsigned DiagID;
1000 DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
1001 Actions.getASTContext().getPrintingPolicy());
1002
1003 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1005 TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo);
1006 if (Ty.isInvalid())
1007 break;
1008
1009 Res = ParseObjCMessageExpressionBody(SourceLocation(),
1010 SourceLocation(),
1011 Ty.get(), nullptr);
1012 break;
1013 }
1014 }
1015
1016 // Make sure to pass down the right value for isAddressOfOperand.
1017 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
1018 isAddressOfOperand = false;
1019
1020 // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
1021 // need to know whether or not this identifier is a function designator or
1022 // not.
1023 UnqualifiedId Name;
1024 CXXScopeSpec ScopeSpec;
1025 SourceLocation TemplateKWLoc;
1026 Token Replacement;
1027 CastExpressionIdValidator Validator(Tok, CorrectionBehavior);
1028 Validator.IsAddressOfOperand = isAddressOfOperand;
1029 if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) {
1030 Validator.WantExpressionKeywords = false;
1031 Validator.WantRemainingKeywords = false;
1032 } else {
1033 Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren);
1034 }
1035 Name.setIdentifier(&II, ILoc);
1036 Res = Actions.ActOnIdExpression(
1037 getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
1038 isAddressOfOperand, &Validator,
1039 /*IsInlineAsmIdentifier=*/false,
1040 Tok.is(tok::r_paren) ? nullptr : &Replacement);
1041 if (!Res.isInvalid() && Res.isUnset()) {
1042 UnconsumeToken(Replacement);
1043 return ParseCastExpression(
1044 ParseKind, isAddressOfOperand, NotCastExpr, CorrectionBehavior,
1045 /*isVectorLiteral=*/false, NotPrimaryExpression);
1046 }
1047 Res = tryParseCXXPackIndexingExpression(Res);
1048 if (!Res.isInvalid() && Tok.is(tok::less))
1049 checkPotentialAngleBracket(Res);
1050 break;
1051 }
1052 case tok::char_constant: // constant: character-constant
1053 case tok::wide_char_constant:
1054 case tok::utf8_char_constant:
1055 case tok::utf16_char_constant:
1056 case tok::utf32_char_constant:
1057 Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope());
1058 ConsumeToken();
1059 break;
1060 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
1061 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
1062 case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS]
1063 case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS]
1064 case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
1065 case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS]
1066 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
1067 // Function local predefined macros are represented by PredefinedExpr except
1068 // when Microsoft extensions are enabled and one of these macros is adjacent
1069 // to a string literal or another one of these macros.
1070 if (!(getLangOpts().MicrosoftExt &&
1073 Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
1074 ConsumeToken();
1075 break;
1076 }
1077 [[fallthrough]]; // treat MS function local macros as concatenable strings
1078 case tok::string_literal: // primary-expression: string-literal
1079 case tok::wide_string_literal:
1080 case tok::utf8_string_literal:
1081 case tok::utf16_string_literal:
1082 case tok::utf32_string_literal:
1083 Res = ParseStringLiteralExpression(true);
1084 break;
1085 case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1]
1086 Res = ParseGenericSelectionExpression();
1087 break;
1088 case tok::kw___builtin_available:
1089 Res = ParseAvailabilityCheckExpr(Tok.getLocation());
1090 break;
1091 case tok::kw___builtin_va_arg:
1092 case tok::kw___builtin_offsetof:
1093 case tok::kw___builtin_choose_expr:
1094 case tok::kw___builtin_astype: // primary-expression: [OCL] as_type()
1095 case tok::kw___builtin_convertvector:
1096 case tok::kw___builtin_COLUMN:
1097 case tok::kw___builtin_FILE:
1098 case tok::kw___builtin_FILE_NAME:
1099 case tok::kw___builtin_FUNCTION:
1100 case tok::kw___builtin_FUNCSIG:
1101 case tok::kw___builtin_LINE:
1102 case tok::kw___builtin_source_location:
1103 if (NotPrimaryExpression)
1104 *NotPrimaryExpression = true;
1105 // This parses the complete suffix; we can return early.
1106 return ParseBuiltinPrimaryExpression();
1107 case tok::kw___null:
1108 Res = Actions.ActOnGNUNullExpr(ConsumeToken());
1109 break;
1110
1111 case tok::plusplus: // unary-expression: '++' unary-expression [C99]
1112 case tok::minusminus: { // unary-expression: '--' unary-expression [C99]
1113 if (NotPrimaryExpression)
1114 *NotPrimaryExpression = true;
1115 // C++ [expr.unary] has:
1116 // unary-expression:
1117 // ++ cast-expression
1118 // -- cast-expression
1119 Token SavedTok = Tok;
1120 ConsumeToken();
1121
1122 PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(),
1123 SavedTok.getLocation());
1124 // One special case is implicitly handled here: if the preceding tokens are
1125 // an ambiguous cast expression, such as "(T())++", then we recurse to
1126 // determine whether the '++' is prefix or postfix.
1127 Res = ParseCastExpression(getLangOpts().CPlusPlus
1130 /*isAddressOfOperand*/ false, NotCastExpr,
1132 if (NotCastExpr) {
1133 // If we return with NotCastExpr = true, we must not consume any tokens,
1134 // so put the token back where we found it.
1135 assert(Res.isInvalid());
1136 UnconsumeToken(SavedTok);
1137 return ExprError();
1138 }
1139 if (!Res.isInvalid()) {
1140 Expr *Arg = Res.get();
1141 Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(),
1142 SavedKind, Arg);
1143 if (Res.isInvalid())
1144 Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(),
1145 Arg->getEndLoc(), Arg);
1146 }
1147 return Res;
1148 }
1149 case tok::amp: { // unary-expression: '&' cast-expression
1150 if (NotPrimaryExpression)
1151 *NotPrimaryExpression = true;
1152 // Special treatment because of member pointers
1153 SourceLocation SavedLoc = ConsumeToken();
1154 PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc);
1155
1156 Res = ParseCastExpression(CastParseKind::AnyCastExpr,
1157 /*isAddressOfOperand=*/true);
1158 if (!Res.isInvalid()) {
1159 Expr *Arg = Res.get();
1160 Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg);
1161 if (Res.isInvalid())
1162 Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(),
1163 Arg);
1164 }
1165 return Res;
1166 }
1167
1168 case tok::star: // unary-expression: '*' cast-expression
1169 case tok::plus: // unary-expression: '+' cast-expression
1170 case tok::minus: // unary-expression: '-' cast-expression
1171 case tok::tilde: // unary-expression: '~' cast-expression
1172 case tok::exclaim: // unary-expression: '!' cast-expression
1173 case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
1174 case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
1175 if (NotPrimaryExpression)
1176 *NotPrimaryExpression = true;
1177 SourceLocation SavedLoc = ConsumeToken();
1178 PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc);
1179 Res = ParseCastExpression(CastParseKind::AnyCastExpr);
1180 if (!Res.isInvalid()) {
1181 Expr *Arg = Res.get();
1182 Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg,
1183 isAddressOfOperand);
1184 if (Res.isInvalid())
1185 Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg);
1186 }
1187 return Res;
1188 }
1189
1190 case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression
1191 if (NotPrimaryExpression)
1192 *NotPrimaryExpression = true;
1193 SourceLocation CoawaitLoc = ConsumeToken();
1194 Res = ParseCastExpression(CastParseKind::AnyCastExpr);
1195 if (!Res.isInvalid())
1196 Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get());
1197 return Res;
1198 }
1199
1200 case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
1201 // __extension__ silences extension warnings in the subexpression.
1202 if (NotPrimaryExpression)
1203 *NotPrimaryExpression = true;
1204 ExtensionRAIIObject O(Diags); // Use RAII to do this.
1205 SourceLocation SavedLoc = ConsumeToken();
1206 Res = ParseCastExpression(CastParseKind::AnyCastExpr);
1207 if (!Res.isInvalid())
1208 Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
1209 return Res;
1210 }
1211 case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')'
1212 diagnoseUseOfC11Keyword(Tok);
1213 [[fallthrough]];
1214 case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')'
1215 case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
1216 // unary-expression: '__alignof' '(' type-name ')'
1217 case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
1218 // unary-expression: 'sizeof' '(' type-name ')'
1219 // unary-expression: '__datasizeof' unary-expression
1220 // unary-expression: '__datasizeof' '(' type-name ')'
1221 case tok::kw___datasizeof:
1222 case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression
1223 // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')'
1224 case tok::kw___builtin_omp_required_simd_align:
1225 case tok::kw___builtin_vectorelements:
1226 case tok::kw__Countof:
1227 if (NotPrimaryExpression)
1228 *NotPrimaryExpression = true;
1229 AllowSuffix = false;
1230 Res = ParseUnaryExprOrTypeTraitExpression();
1231 break;
1232 case tok::caretcaret: {
1233 if (!getLangOpts().Reflection) {
1234 NotCastExpr = true;
1235 return ExprError();
1236 }
1237
1238 if (NotPrimaryExpression)
1239 *NotPrimaryExpression = true;
1240 AllowSuffix = false;
1241 Res = ParseCXXReflectExpression();
1242 break;
1243 }
1244 case tok::ampamp: { // unary-expression: '&&' identifier
1245 if (NotPrimaryExpression)
1246 *NotPrimaryExpression = true;
1247 SourceLocation AmpAmpLoc = ConsumeToken();
1248 if (Tok.isNot(tok::identifier))
1249 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
1250
1251 if (getCurScope()->getFnParent() == nullptr)
1252 return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
1253
1254 Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
1255 LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
1256 Tok.getLocation());
1257 Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD);
1258 ConsumeToken();
1259 AllowSuffix = false;
1260 break;
1261 }
1262 case tok::kw_const_cast:
1263 case tok::kw_dynamic_cast:
1264 case tok::kw_reinterpret_cast:
1265 case tok::kw_static_cast:
1266 case tok::kw_addrspace_cast:
1267 if (NotPrimaryExpression)
1268 *NotPrimaryExpression = true;
1269 Res = ParseCXXCasts();
1270 break;
1271 case tok::kw___builtin_bit_cast:
1272 if (NotPrimaryExpression)
1273 *NotPrimaryExpression = true;
1274 Res = ParseBuiltinBitCast();
1275 break;
1276 case tok::kw_typeid:
1277 if (NotPrimaryExpression)
1278 *NotPrimaryExpression = true;
1279 Res = ParseCXXTypeid();
1280 break;
1281 case tok::kw___uuidof:
1282 if (NotPrimaryExpression)
1283 *NotPrimaryExpression = true;
1284 Res = ParseCXXUuidof();
1285 break;
1286 case tok::kw_this:
1287 Res = ParseCXXThis();
1288 break;
1289 case tok::kw___builtin_sycl_unique_stable_name:
1290 Res = ParseSYCLUniqueStableNameExpression();
1291 break;
1292
1293 case tok::annot_typename:
1294 if (isStartOfObjCClassMessageMissingOpenBracket()) {
1296
1297 // Fake up a Declarator to use with ActOnTypeName.
1298 DeclSpec DS(AttrFactory);
1299 DS.SetRangeStart(Tok.getLocation());
1300 DS.SetRangeEnd(Tok.getLastLoc());
1301
1302 const char *PrevSpec = nullptr;
1303 unsigned DiagID;
1304 DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(),
1305 PrevSpec, DiagID, Type,
1306 Actions.getASTContext().getPrintingPolicy());
1307
1308 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1310 TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo);
1311 if (Ty.isInvalid())
1312 break;
1313
1314 ConsumeAnnotationToken();
1315 Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
1316 Ty.get(), nullptr);
1317 break;
1318 }
1319 [[fallthrough]];
1320
1321 case tok::annot_decltype:
1322 case tok::annot_pack_indexing_type:
1323 case tok::kw_char:
1324 case tok::kw_wchar_t:
1325 case tok::kw_char8_t:
1326 case tok::kw_char16_t:
1327 case tok::kw_char32_t:
1328 case tok::kw_bool:
1329 case tok::kw_short:
1330 case tok::kw_int:
1331 case tok::kw_long:
1332 case tok::kw___int64:
1333 case tok::kw___int128:
1334 case tok::kw__ExtInt:
1335 case tok::kw__BitInt:
1336 case tok::kw_signed:
1337 case tok::kw_unsigned:
1338 case tok::kw_half:
1339 case tok::kw_float:
1340 case tok::kw_double:
1341 case tok::kw___bf16:
1342 case tok::kw__Float16:
1343 case tok::kw___float128:
1344 case tok::kw___ibm128:
1345 case tok::kw_void:
1346 case tok::kw_auto:
1347 case tok::kw_typename:
1348 case tok::kw_typeof:
1349 case tok::kw___vector:
1350 case tok::kw__Accum:
1351 case tok::kw__Fract:
1352 case tok::kw__Sat:
1353#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1354#include "clang/Basic/OpenCLImageTypes.def"
1355#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1356#include "clang/Basic/HLSLIntangibleTypes.def"
1357 {
1358 if (!getLangOpts().CPlusPlus) {
1359 Diag(Tok, diag::err_expected_expression);
1360 return ExprError();
1361 }
1362
1363 // Everything henceforth is a postfix-expression.
1364 if (NotPrimaryExpression)
1365 *NotPrimaryExpression = true;
1366
1367 if (SavedKind == tok::kw_typename) {
1368 // postfix-expression: typename-specifier '(' expression-list[opt] ')'
1369 // typename-specifier braced-init-list
1371 return ExprError();
1372
1373 if (!Tok.isSimpleTypeSpecifier(getLangOpts()))
1374 // We are trying to parse a simple-type-specifier but might not get such
1375 // a token after error recovery.
1376 return ExprError();
1377 }
1378
1379 // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
1380 // simple-type-specifier braced-init-list
1381 //
1382 DeclSpec DS(AttrFactory);
1383
1384 ParseCXXSimpleTypeSpecifier(DS);
1385 if (Tok.isNot(tok::l_paren) &&
1386 (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace)))
1387 return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
1388 << DS.getSourceRange());
1389
1390 if (Tok.is(tok::l_brace))
1391 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1392
1393 Res = ParseCXXTypeConstructExpression(DS);
1394 break;
1395 }
1396
1397 case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
1398 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
1399 // (We can end up in this situation after tentative parsing.)
1401 return ExprError();
1402 if (!Tok.is(tok::annot_cxxscope))
1403 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1404 CorrectionBehavior, isVectorLiteral,
1405 NotPrimaryExpression);
1406
1407 Token Next = NextToken();
1408 if (Next.is(tok::annot_template_id)) {
1409 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
1410 if (TemplateId->Kind == TNK_Type_template) {
1411 // We have a qualified template-id that we know refers to a
1412 // type, translate it into a type and continue parsing as a
1413 // cast expression.
1414 CXXScopeSpec SS;
1415 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1416 /*ObjectHasErrors=*/false,
1417 /*EnteringContext=*/false);
1418 AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes);
1419 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1420 CorrectionBehavior, isVectorLiteral,
1421 NotPrimaryExpression);
1422 }
1423 }
1424
1425 // Parse as an id-expression.
1426 Res = ParseCXXIdExpression(isAddressOfOperand);
1427 break;
1428 }
1429
1430 case tok::annot_template_id: { // [C++] template-id
1431 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1432 if (TemplateId->Kind == TNK_Type_template) {
1433 // We have a template-id that we know refers to a type,
1434 // translate it into a type and continue parsing as a cast
1435 // expression.
1436 CXXScopeSpec SS;
1437 AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes);
1438 return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr,
1439 CorrectionBehavior, isVectorLiteral,
1440 NotPrimaryExpression);
1441 }
1442
1443 // Fall through to treat the template-id as an id-expression.
1444 [[fallthrough]];
1445 }
1446
1447 case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
1448 Res = ParseCXXIdExpression(isAddressOfOperand);
1449 break;
1450
1451 case tok::coloncolon: {
1452 // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken
1453 // annotates the token, tail recurse.
1455 return ExprError();
1456 if (!Tok.is(tok::coloncolon))
1457 return ParseCastExpression(ParseKind, isAddressOfOperand,
1458 CorrectionBehavior, isVectorLiteral,
1459 NotPrimaryExpression);
1460
1461 // ::new -> [C++] new-expression
1462 // ::delete -> [C++] delete-expression
1463 SourceLocation CCLoc = ConsumeToken();
1464 if (Tok.is(tok::kw_new)) {
1465 if (NotPrimaryExpression)
1466 *NotPrimaryExpression = true;
1467 Res = ParseCXXNewExpression(true, CCLoc);
1468 AllowSuffix = false;
1469 break;
1470 }
1471 if (Tok.is(tok::kw_delete)) {
1472 if (NotPrimaryExpression)
1473 *NotPrimaryExpression = true;
1474 Res = ParseCXXDeleteExpression(true, CCLoc);
1475 AllowSuffix = false;
1476 break;
1477 }
1478
1479 // This is not a type name or scope specifier, it is an invalid expression.
1480 Diag(CCLoc, diag::err_expected_expression);
1481 return ExprError();
1482 }
1483
1484 case tok::kw_new: // [C++] new-expression
1485 if (NotPrimaryExpression)
1486 *NotPrimaryExpression = true;
1487 Res = ParseCXXNewExpression(false, Tok.getLocation());
1488 AllowSuffix = false;
1489 break;
1490
1491 case tok::kw_delete: // [C++] delete-expression
1492 if (NotPrimaryExpression)
1493 *NotPrimaryExpression = true;
1494 Res = ParseCXXDeleteExpression(false, Tok.getLocation());
1495 AllowSuffix = false;
1496 break;
1497
1498 case tok::kw_requires: // [C++2a] requires-expression
1499 Res = ParseRequiresExpression();
1500 AllowSuffix = false;
1501 break;
1502
1503 case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')'
1504 if (NotPrimaryExpression)
1505 *NotPrimaryExpression = true;
1506 Diag(Tok, diag::warn_cxx98_compat_noexcept_expr);
1507 SourceLocation KeyLoc = ConsumeToken();
1508 BalancedDelimiterTracker T(*this, tok::l_paren);
1509
1510 if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept"))
1511 return ExprError();
1512 // C++11 [expr.unary.noexcept]p1:
1513 // The noexcept operator determines whether the evaluation of its operand,
1514 // which is an unevaluated operand, can throw an exception.
1515 EnterExpressionEvaluationContext Unevaluated(
1517 Res = ParseExpression();
1518
1519 T.consumeClose();
1520
1521 if (!Res.isInvalid())
1522 Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(),
1523 T.getCloseLocation());
1524 AllowSuffix = false;
1525 break;
1526 }
1527
1528#define TYPE_TRAIT(N,Spelling,K) \
1529 case tok::kw_##Spelling:
1530#include "clang/Basic/TokenKinds.def"
1531 Res = ParseTypeTrait();
1532 break;
1533
1534 case tok::kw___array_rank:
1535 case tok::kw___array_extent:
1536 if (NotPrimaryExpression)
1537 *NotPrimaryExpression = true;
1538 Res = ParseArrayTypeTrait();
1539 break;
1540
1541 case tok::kw___builtin_ptrauth_type_discriminator:
1542 return ParseBuiltinPtrauthTypeDiscriminator();
1543
1544 case tok::kw___is_lvalue_expr:
1545 case tok::kw___is_rvalue_expr:
1546 if (NotPrimaryExpression)
1547 *NotPrimaryExpression = true;
1548 Res = ParseExpressionTrait();
1549 break;
1550
1551 case tok::at: {
1552 if (NotPrimaryExpression)
1553 *NotPrimaryExpression = true;
1554 SourceLocation AtLoc = ConsumeToken();
1555 return ParseObjCAtExpression(AtLoc);
1556 }
1557 case tok::caret:
1558 Res = ParseBlockLiteralExpression();
1559 break;
1560 case tok::code_completion: {
1561 cutOffParsing();
1562 Actions.CodeCompletion().CodeCompleteExpression(
1563 getCurScope(), PreferredType.get(Tok.getLocation()),
1564 /*IsParenthesized=*/false, /*IsAddressOfOperand=*/isAddressOfOperand);
1565 return ExprError();
1566 }
1567#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1568#include "clang/Basic/TransformTypeTraits.def"
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::warn_cxx98_compat_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 // We must have at least one identifier here.
2414 if (Tok.isNot(tok::identifier)) {
2415 Diag(Tok, diag::err_expected) << tok::identifier;
2416 SkipUntil(tok::r_paren, StopAtSemi);
2417 return ExprError();
2418 }
2419
2420 // Keep track of the various subcomponents we see.
2421 SmallVector<Sema::OffsetOfComponent, 4> Comps;
2422
2423 Comps.push_back(Sema::OffsetOfComponent());
2424 Comps.back().isBrackets = false;
2425 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2426 Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
2427
2428 // FIXME: This loop leaks the index expressions on error.
2429 while (true) {
2430 if (Tok.is(tok::period)) {
2431 // offsetof-member-designator: offsetof-member-designator '.' identifier
2432 Comps.push_back(Sema::OffsetOfComponent());
2433 Comps.back().isBrackets = false;
2434 Comps.back().LocStart = ConsumeToken();
2435
2436 if (Tok.isNot(tok::identifier)) {
2437 Diag(Tok, diag::err_expected) << tok::identifier;
2438 SkipUntil(tok::r_paren, StopAtSemi);
2439 return ExprError();
2440 }
2441 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
2442 Comps.back().LocEnd = ConsumeToken();
2443 } else if (Tok.is(tok::l_square)) {
2444 if (CheckProhibitedCXX11Attribute())
2445 return ExprError();
2446
2447 // offsetof-member-designator: offsetof-member-design '[' expression ']'
2448 Comps.push_back(Sema::OffsetOfComponent());
2449 Comps.back().isBrackets = true;
2450 BalancedDelimiterTracker ST(*this, tok::l_square);
2451 ST.consumeOpen();
2452 Comps.back().LocStart = ST.getOpenLocation();
2453 Res = ParseExpression();
2454 if (Res.isInvalid()) {
2455 SkipUntil(tok::r_paren, StopAtSemi);
2456 return Res;
2457 }
2458 Comps.back().U.E = Res.get();
2459
2460 ST.consumeClose();
2461 Comps.back().LocEnd = ST.getCloseLocation();
2462 } else {
2463 if (Tok.isNot(tok::r_paren)) {
2464 PT.consumeClose();
2465 Res = ExprError();
2466 } else if (Ty.isInvalid()) {
2467 Res = ExprError();
2468 } else {
2469 PT.consumeClose();
2470 Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc,
2471 Ty.get(), Comps,
2472 PT.getCloseLocation());
2473 }
2474 break;
2475 }
2476 }
2477 break;
2478 }
2479 case tok::kw___builtin_choose_expr: {
2481 if (Cond.isInvalid()) {
2482 SkipUntil(tok::r_paren, StopAtSemi);
2483 return Cond;
2484 }
2485 if (ExpectAndConsume(tok::comma)) {
2486 SkipUntil(tok::r_paren, StopAtSemi);
2487 return ExprError();
2488 }
2489
2491 if (Expr1.isInvalid()) {
2492 SkipUntil(tok::r_paren, StopAtSemi);
2493 return Expr1;
2494 }
2495 if (ExpectAndConsume(tok::comma)) {
2496 SkipUntil(tok::r_paren, StopAtSemi);
2497 return ExprError();
2498 }
2499
2501 if (Expr2.isInvalid()) {
2502 SkipUntil(tok::r_paren, StopAtSemi);
2503 return Expr2;
2504 }
2505 if (Tok.isNot(tok::r_paren)) {
2506 Diag(Tok, diag::err_expected) << tok::r_paren;
2507 return ExprError();
2508 }
2509 Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
2510 Expr2.get(), ConsumeParen());
2511 break;
2512 }
2513 case tok::kw___builtin_astype: {
2514 // The first argument is an expression to be converted, followed by a comma.
2516 if (Expr.isInvalid()) {
2517 SkipUntil(tok::r_paren, StopAtSemi);
2518 return ExprError();
2519 }
2520
2521 if (ExpectAndConsume(tok::comma)) {
2522 SkipUntil(tok::r_paren, StopAtSemi);
2523 return ExprError();
2524 }
2525
2526 // Second argument is the type to bitcast to.
2527 TypeResult DestTy = ParseTypeName();
2528 if (DestTy.isInvalid())
2529 return ExprError();
2530
2531 // Attempt to consume the r-paren.
2532 if (Tok.isNot(tok::r_paren)) {
2533 Diag(Tok, diag::err_expected) << tok::r_paren;
2534 SkipUntil(tok::r_paren, StopAtSemi);
2535 return ExprError();
2536 }
2537
2538 Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc,
2539 ConsumeParen());
2540 break;
2541 }
2542 case tok::kw___builtin_convertvector: {
2543 // The first argument is an expression to be converted, followed by a comma.
2545 if (Expr.isInvalid()) {
2546 SkipUntil(tok::r_paren, StopAtSemi);
2547 return ExprError();
2548 }
2549
2550 if (ExpectAndConsume(tok::comma)) {
2551 SkipUntil(tok::r_paren, StopAtSemi);
2552 return ExprError();
2553 }
2554
2555 // Second argument is the type to bitcast to.
2556 TypeResult DestTy = ParseTypeName();
2557 if (DestTy.isInvalid())
2558 return ExprError();
2559
2560 // Attempt to consume the r-paren.
2561 if (Tok.isNot(tok::r_paren)) {
2562 Diag(Tok, diag::err_expected) << tok::r_paren;
2563 SkipUntil(tok::r_paren, StopAtSemi);
2564 return ExprError();
2565 }
2566
2567 Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc,
2568 ConsumeParen());
2569 break;
2570 }
2571 case tok::kw___builtin_COLUMN:
2572 case tok::kw___builtin_FILE:
2573 case tok::kw___builtin_FILE_NAME:
2574 case tok::kw___builtin_FUNCTION:
2575 case tok::kw___builtin_FUNCSIG:
2576 case tok::kw___builtin_LINE:
2577 case tok::kw___builtin_source_location: {
2578 // Attempt to consume the r-paren.
2579 if (Tok.isNot(tok::r_paren)) {
2580 Diag(Tok, diag::err_expected) << tok::r_paren;
2581 SkipUntil(tok::r_paren, StopAtSemi);
2582 return ExprError();
2583 }
2584 SourceLocIdentKind Kind = [&] {
2585 switch (T) {
2586 case tok::kw___builtin_FILE:
2588 case tok::kw___builtin_FILE_NAME:
2590 case tok::kw___builtin_FUNCTION:
2592 case tok::kw___builtin_FUNCSIG:
2594 case tok::kw___builtin_LINE:
2596 case tok::kw___builtin_COLUMN:
2598 case tok::kw___builtin_source_location:
2600 default:
2601 llvm_unreachable("invalid keyword");
2602 }
2603 }();
2604 Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen());
2605 break;
2606 }
2607 }
2608
2609 if (Res.isInvalid())
2610 return ExprError();
2611
2612 // These can be followed by postfix-expr pieces because they are
2613 // primary-expressions.
2614 return ParsePostfixExpressionSuffix(Res.get());
2615}
2616
2617bool Parser::tryParseOpenMPArrayShapingCastPart() {
2618 assert(Tok.is(tok::l_square) && "Expected open bracket");
2619 bool ErrorFound = true;
2620 TentativeParsingAction TPA(*this);
2621 do {
2622 if (Tok.isNot(tok::l_square))
2623 break;
2624 // Consume '['
2625 ConsumeBracket();
2626 // Skip inner expression.
2627 while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end,
2629 ;
2630 if (Tok.isNot(tok::r_square))
2631 break;
2632 // Consume ']'
2633 ConsumeBracket();
2634 // Found ')' - done.
2635 if (Tok.is(tok::r_paren)) {
2636 ErrorFound = false;
2637 break;
2638 }
2639 } while (Tok.isNot(tok::annot_pragma_openmp_end));
2640 TPA.Revert();
2641 return !ErrorFound;
2642}
2643
2645Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
2646 ParenExprKind ParenBehavior,
2647 TypoCorrectionTypeBehavior CorrectionBehavior,
2648 ParsedType &CastTy, SourceLocation &RParenLoc) {
2649 assert(Tok.is(tok::l_paren) && "Not a paren expr!");
2650 ColonProtectionRAIIObject ColonProtection(*this, false);
2651 BalancedDelimiterTracker T(*this, tok::l_paren);
2652 if (T.consumeOpen())
2653 return ExprError();
2654 SourceLocation OpenLoc = T.getOpenLocation();
2655
2656 PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
2657
2658 ExprResult Result(true);
2659 bool isAmbiguousTypeId;
2660 CastTy = nullptr;
2661
2662 if (Tok.is(tok::code_completion)) {
2663 cutOffParsing();
2664 Actions.CodeCompletion().CodeCompleteExpression(
2665 getCurScope(), PreferredType.get(Tok.getLocation()),
2666 /*IsParenthesized=*/ExprType >= ParenParseOption::CompoundLiteral);
2667 return ExprError();
2668 }
2669
2670 // Diagnose use of bridge casts in non-arc mode.
2671 bool BridgeCast = (getLangOpts().ObjC &&
2672 Tok.isOneOf(tok::kw___bridge,
2673 tok::kw___bridge_transfer,
2674 tok::kw___bridge_retained,
2675 tok::kw___bridge_retain));
2676 if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
2677 if (!TryConsumeToken(tok::kw___bridge)) {
2678 StringRef BridgeCastName = Tok.getName();
2679 SourceLocation BridgeKeywordLoc = ConsumeToken();
2680 if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
2681 Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
2682 << BridgeCastName
2683 << FixItHint::CreateReplacement(BridgeKeywordLoc, "");
2684 }
2685 BridgeCast = false;
2686 }
2687
2688 // None of these cases should fall through with an invalid Result
2689 // unless they've already reported an error.
2690 if (ExprType >= ParenParseOption::CompoundStmt && Tok.is(tok::l_brace)) {
2691 Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro
2692 : diag::ext_gnu_statement_expr);
2693
2694 checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin);
2695
2696 if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
2697 Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
2698 } else {
2699 // Find the nearest non-record decl context. Variables declared in a
2700 // statement expression behave as if they were declared in the enclosing
2701 // function, block, or other code construct.
2702 DeclContext *CodeDC = Actions.CurContext;
2703 while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) {
2704 CodeDC = CodeDC->getParent();
2705 assert(CodeDC && !CodeDC->isFileContext() &&
2706 "statement expr not in code context");
2707 }
2708 Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false);
2709
2710 Actions.ActOnStartStmtExpr();
2711
2712 StmtResult Stmt(ParseCompoundStatement(true));
2714
2715 // If the substmt parsed correctly, build the AST node.
2716 if (!Stmt.isInvalid()) {
2717 Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(),
2718 Tok.getLocation());
2719 } else {
2720 Actions.ActOnStmtExprError();
2721 }
2722 }
2723 } else if (ExprType >= ParenParseOption::CompoundLiteral && BridgeCast) {
2724 tok::TokenKind tokenKind = Tok.getKind();
2725 SourceLocation BridgeKeywordLoc = ConsumeToken();
2726
2727 // Parse an Objective-C ARC ownership cast expression.
2729 if (tokenKind == tok::kw___bridge)
2730 Kind = OBC_Bridge;
2731 else if (tokenKind == tok::kw___bridge_transfer)
2733 else if (tokenKind == tok::kw___bridge_retained)
2735 else {
2736 // As a hopefully temporary workaround, allow __bridge_retain as
2737 // a synonym for __bridge_retained, but only in system headers.
2738 assert(tokenKind == tok::kw___bridge_retain);
2740 if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
2741 Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
2742 << FixItHint::CreateReplacement(BridgeKeywordLoc,
2743 "__bridge_retained");
2744 }
2745
2747 T.consumeClose();
2748 ColonProtection.restore();
2749 RParenLoc = T.getCloseLocation();
2750
2751 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get());
2752 ExprResult SubExpr = ParseCastExpression(CastParseKind::AnyCastExpr);
2753
2754 if (Ty.isInvalid() || SubExpr.isInvalid())
2755 return ExprError();
2756
2757 return Actions.ObjC().ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind,
2758 BridgeKeywordLoc, Ty.get(),
2759 RParenLoc, SubExpr.get());
2760 } else if (ExprType >= ParenParseOption::CompoundLiteral &&
2761 isTypeIdInParens(isAmbiguousTypeId)) {
2762
2763 // Otherwise, this is a compound literal expression or cast expression.
2764
2765 // In C++, if the type-id is ambiguous we disambiguate based on context.
2766 // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
2767 // in which case we should treat it as type-id.
2768 // if stopIfCastExpr is false, we need to determine the context past the
2769 // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
2770 if (isAmbiguousTypeId && !StopIfCastExpr) {
2771 ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
2772 ColonProtection);
2773 RParenLoc = T.getCloseLocation();
2774 return res;
2775 }
2776
2777 // Parse the type declarator.
2778 DeclSpec DS(AttrFactory);
2779 ParseSpecifierQualifierList(DS);
2780 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
2782 ParseDeclarator(DeclaratorInfo);
2783
2784 // If our type is followed by an identifier and either ':' or ']', then
2785 // this is probably an Objective-C message send where the leading '[' is
2786 // missing. Recover as if that were the case.
2787 if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
2788 !InMessageExpression && getLangOpts().ObjC &&
2789 (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
2790 TypeResult Ty;
2791 {
2792 InMessageExpressionRAIIObject InMessage(*this, false);
2793 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2794 }
2795 Result = ParseObjCMessageExpressionBody(SourceLocation(),
2796 SourceLocation(),
2797 Ty.get(), nullptr);
2798 } else {
2799 // Match the ')'.
2800 T.consumeClose();
2801 ColonProtection.restore();
2802 RParenLoc = T.getCloseLocation();
2803 if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_brace)) {
2805 TypeResult Ty;
2806 {
2807 InMessageExpressionRAIIObject InMessage(*this, false);
2808 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2809 }
2810 return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
2811 }
2812
2813 if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_paren)) {
2814 // This could be OpenCL vector Literals
2815 if (getLangOpts().OpenCL)
2816 {
2817 TypeResult Ty;
2818 {
2819 InMessageExpressionRAIIObject InMessage(*this, false);
2820 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2821 }
2822 if(Ty.isInvalid())
2823 {
2824 return ExprError();
2825 }
2826 QualType QT = Ty.get().get().getCanonicalType();
2827 if (QT->isVectorType())
2828 {
2829 // We parsed '(' vector-type-name ')' followed by '('
2830
2831 // Parse the cast-expression that follows it next.
2832 // isVectorLiteral = true will make sure we don't parse any
2833 // Postfix expression yet
2834 Result = ParseCastExpression(
2835 /*isUnaryExpression=*/CastParseKind::AnyCastExpr,
2836 /*isAddressOfOperand=*/false,
2838 /*isVectorLiteral=*/true);
2839
2840 if (!Result.isInvalid()) {
2841 Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
2842 DeclaratorInfo, CastTy,
2843 RParenLoc, Result.get());
2844 }
2845
2846 // After we performed the cast we can check for postfix-expr pieces.
2847 if (!Result.isInvalid()) {
2848 Result = ParsePostfixExpressionSuffix(Result);
2849 }
2850
2851 return Result;
2852 }
2853 }
2854 }
2855
2856 if (ExprType == ParenParseOption::CastExpr) {
2857 // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
2858
2859 if (DeclaratorInfo.isInvalidType())
2860 return ExprError();
2861
2862 // Note that this doesn't parse the subsequent cast-expression, it just
2863 // returns the parsed type to the callee.
2864 if (StopIfCastExpr) {
2865 TypeResult Ty;
2866 {
2867 InMessageExpressionRAIIObject InMessage(*this, false);
2868 Ty = Actions.ActOnTypeName(DeclaratorInfo);
2869 }
2870 CastTy = Ty.get();
2871 return ExprResult();
2872 }
2873
2874 // Reject the cast of super idiom in ObjC.
2875 if (Tok.is(tok::identifier) && getLangOpts().ObjC &&
2876 Tok.getIdentifierInfo() == Ident_super &&
2877 getCurScope()->isInObjcMethodScope() &&
2878 GetLookAheadToken(1).isNot(tok::period)) {
2879 Diag(Tok.getLocation(), diag::err_illegal_super_cast)
2880 << SourceRange(OpenLoc, RParenLoc);
2881 return ExprError();
2882 }
2883
2884 PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get());
2885 // Parse the cast-expression that follows it next.
2886 // TODO: For cast expression with CastTy.
2887 Result = ParseCastExpression(
2888 /*isUnaryExpression=*/CastParseKind::AnyCastExpr,
2889 /*isAddressOfOperand=*/false,
2891 if (!Result.isInvalid()) {
2892 Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
2893 DeclaratorInfo, CastTy,
2894 RParenLoc, Result.get());
2895 }
2896 return Result;
2897 }
2898
2899 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
2900 return ExprError();
2901 }
2902 } else if (ExprType >= ParenParseOption::FoldExpr && Tok.is(tok::ellipsis) &&
2903 isFoldOperator(NextToken().getKind())) {
2904 ExprType = ParenParseOption::FoldExpr;
2905 return ParseFoldExpression(ExprResult(), T);
2906 } else if (CorrectionBehavior == TypoCorrectionTypeBehavior::AllowTypes) {
2907 // FIXME: This should not be predicated on typo correction behavior.
2908 // Parse the expression-list.
2909 InMessageExpressionRAIIObject InMessage(*this, false);
2910 ExprVector ArgExprs;
2911
2912 if (!ParseSimpleExpressionList(ArgExprs)) {
2913 // FIXME: If we ever support comma expressions as operands to
2914 // fold-expressions, we'll need to allow multiple ArgExprs here.
2915 if (ExprType >= ParenParseOption::FoldExpr && ArgExprs.size() == 1 &&
2916 isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
2917 ExprType = ParenParseOption::FoldExpr;
2918 return ParseFoldExpression(ArgExprs[0], T);
2919 }
2920
2922 Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
2923 ArgExprs);
2924 }
2925 } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing &&
2926 ExprType == ParenParseOption::CastExpr && Tok.is(tok::l_square) &&
2927 tryParseOpenMPArrayShapingCastPart()) {
2928 bool ErrorFound = false;
2929 SmallVector<Expr *, 4> OMPDimensions;
2930 SmallVector<SourceRange, 4> OMPBracketsRanges;
2931 do {
2932 BalancedDelimiterTracker TS(*this, tok::l_square);
2933 TS.consumeOpen();
2934 ExprResult NumElements = ParseExpression();
2935 if (!NumElements.isUsable()) {
2936 ErrorFound = true;
2937 while (!SkipUntil(tok::r_square, tok::r_paren,
2939 ;
2940 }
2941 TS.consumeClose();
2942 OMPDimensions.push_back(NumElements.get());
2943 OMPBracketsRanges.push_back(TS.getRange());
2944 } while (Tok.isNot(tok::r_paren));
2945 // Match the ')'.
2946 T.consumeClose();
2947 RParenLoc = T.getCloseLocation();
2949 if (ErrorFound) {
2950 Result = ExprError();
2951 } else if (!Result.isInvalid()) {
2952 Result = Actions.OpenMP().ActOnOMPArrayShapingExpr(
2953 Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges);
2954 }
2955 return Result;
2956 } else {
2957 InMessageExpressionRAIIObject InMessage(*this, false);
2958
2960 if (ExprType >= ParenParseOption::FoldExpr &&
2961 isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
2962 ExprType = ParenParseOption::FoldExpr;
2963 return ParseFoldExpression(Result, T);
2964 }
2966
2967 // Don't build a paren expression unless we actually match a ')'.
2968 if (!Result.isInvalid() && Tok.is(tok::r_paren))
2969 Result =
2970 Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get());
2971 }
2972
2973 // Match the ')'.
2974 if (Result.isInvalid()) {
2975 SkipUntil(tok::r_paren, StopAtSemi);
2976 return ExprError();
2977 }
2978
2979 T.consumeClose();
2980 RParenLoc = T.getCloseLocation();
2981 return Result;
2982}
2983
2985Parser::ParseCompoundLiteralExpression(ParsedType Ty,
2986 SourceLocation LParenLoc,
2987 SourceLocation RParenLoc) {
2988 assert(Tok.is(tok::l_brace) && "Not a compound literal!");
2989 if (!getLangOpts().C99) // Compound literals don't exist in C90.
2990 Diag(LParenLoc, diag::ext_c99_compound_literal);
2991 PreferredType.enterTypeCast(Tok.getLocation(), Ty.get());
2992 ExprResult Result = ParseInitializer();
2993 if (!Result.isInvalid() && Ty)
2994 return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
2995 return Result;
2996}
2997
2999 return ParseStringLiteralExpression(AllowUserDefinedLiteral,
3000 /*Unevaluated=*/false);
3001}
3002
3004 return ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false,
3005 /*Unevaluated=*/true);
3006}
3007
3008ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
3009 bool Unevaluated) {
3011 "Not a string-literal-like token!");
3012
3013 // String concatenation.
3014 // Note: some keywords like __FUNCTION__ are not considered to be strings
3015 // for concatenation purposes, unless Microsoft extensions are enabled.
3016 SmallVector<Token, 4> StringToks;
3017
3018 do {
3019 StringToks.push_back(Tok);
3022
3023 if (Unevaluated) {
3024 assert(!AllowUserDefinedLiteral && "UDL are always evaluated");
3025 return Actions.ActOnUnevaluatedStringLiteral(StringToks);
3026 }
3027
3028 // Pass the set of string tokens, ready for concatenation, to the actions.
3029 return Actions.ActOnStringLiteral(StringToks,
3030 AllowUserDefinedLiteral ? getCurScope()
3031 : nullptr);
3032}
3033
3034ExprResult Parser::ParseGenericSelectionExpression() {
3035 assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
3036
3037 diagnoseUseOfC11Keyword(Tok);
3038
3039 SourceLocation KeyLoc = ConsumeToken();
3040 BalancedDelimiterTracker T(*this, tok::l_paren);
3041 if (T.expectAndConsume())
3042 return ExprError();
3043
3044 // We either have a controlling expression or we have a controlling type, and
3045 // we need to figure out which it is.
3046 TypeResult ControllingType;
3047 ExprResult ControllingExpr;
3048 if (isTypeIdForGenericSelection()) {
3049 ControllingType = ParseTypeName();
3050 if (ControllingType.isInvalid()) {
3051 SkipUntil(tok::r_paren, StopAtSemi);
3052 return ExprError();
3053 }
3054 const auto *LIT = cast<LocInfoType>(ControllingType.get().get());
3055 SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
3056 Diag(Loc, getLangOpts().C2y ? diag::warn_c2y_compat_generic_with_type_arg
3057 : diag::ext_c2y_generic_with_type_arg);
3058 } else {
3059 // C11 6.5.1.1p3 "The controlling expression of a generic selection is
3060 // not evaluated."
3061 EnterExpressionEvaluationContext Unevaluated(
3063 ControllingExpr = ParseAssignmentExpression();
3064 if (ControllingExpr.isInvalid()) {
3065 SkipUntil(tok::r_paren, StopAtSemi);
3066 return ExprError();
3067 }
3068 }
3069
3070 if (ExpectAndConsume(tok::comma)) {
3071 SkipUntil(tok::r_paren, StopAtSemi);
3072 return ExprError();
3073 }
3074
3075 SourceLocation DefaultLoc;
3076 SmallVector<ParsedType, 12> Types;
3077 ExprVector Exprs;
3078 do {
3079 ParsedType Ty;
3080 if (Tok.is(tok::kw_default)) {
3081 // C11 6.5.1.1p2 "A generic selection shall have no more than one default
3082 // generic association."
3083 if (!DefaultLoc.isInvalid()) {
3084 Diag(Tok, diag::err_duplicate_default_assoc);
3085 Diag(DefaultLoc, diag::note_previous_default_assoc);
3086 SkipUntil(tok::r_paren, StopAtSemi);
3087 return ExprError();
3088 }
3089 DefaultLoc = ConsumeToken();
3090 Ty = nullptr;
3091 } else {
3094 if (TR.isInvalid()) {
3095 SkipUntil(tok::r_paren, StopAtSemi);
3096 return ExprError();
3097 }
3098 Ty = TR.get();
3099 }
3100 Types.push_back(Ty);
3101
3102 if (ExpectAndConsume(tok::colon)) {
3103 SkipUntil(tok::r_paren, StopAtSemi);
3104 return ExprError();
3105 }
3106
3107 // FIXME: These expressions should be parsed in a potentially potentially
3108 // evaluated context.
3110 if (ER.isInvalid()) {
3111 SkipUntil(tok::r_paren, StopAtSemi);
3112 return ExprError();
3113 }
3114 Exprs.push_back(ER.get());
3115 } while (TryConsumeToken(tok::comma));
3116
3117 T.consumeClose();
3118 if (T.getCloseLocation().isInvalid())
3119 return ExprError();
3120
3121 void *ExprOrTy = ControllingExpr.isUsable()
3122 ? ControllingExpr.get()
3123 : ControllingType.get().getAsOpaquePtr();
3124
3125 return Actions.ActOnGenericSelectionExpr(
3126 KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(),
3127 ExprOrTy, Types, Exprs);
3128}
3129
3130ExprResult Parser::ParseFoldExpression(ExprResult LHS,
3132 if (LHS.isInvalid()) {
3133 T.skipToEnd();
3134 return true;
3135 }
3136
3137 tok::TokenKind Kind = tok::unknown;
3138 SourceLocation FirstOpLoc;
3139 if (LHS.isUsable()) {
3140 Kind = Tok.getKind();
3141 assert(isFoldOperator(Kind) && "missing fold-operator");
3142 FirstOpLoc = ConsumeToken();
3143 }
3144
3145 assert(Tok.is(tok::ellipsis) && "not a fold-expression");
3146 SourceLocation EllipsisLoc = ConsumeToken();
3147
3148 ExprResult RHS;
3149 if (Tok.isNot(tok::r_paren)) {
3150 if (!isFoldOperator(Tok.getKind()))
3151 return Diag(Tok.getLocation(), diag::err_expected_fold_operator);
3152
3153 if (Kind != tok::unknown && Tok.getKind() != Kind)
3154 Diag(Tok.getLocation(), diag::err_fold_operator_mismatch)
3155 << SourceRange(FirstOpLoc);
3156 Kind = Tok.getKind();
3157 ConsumeToken();
3158
3159 RHS = ParseExpression();
3160 if (RHS.isInvalid()) {
3161 T.skipToEnd();
3162 return true;
3163 }
3164 }
3165
3166 Diag(EllipsisLoc, getLangOpts().CPlusPlus17
3167 ? diag::warn_cxx14_compat_fold_expression
3168 : diag::ext_fold_expression);
3169
3170 T.consumeClose();
3171 return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(),
3172 Kind, EllipsisLoc, RHS.get(),
3173 T.getCloseLocation());
3174}
3175
3176void Parser::injectEmbedTokens() {
3177 EmbedAnnotationData *Data =
3178 reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue());
3179 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(
3180 Data->BinaryData.size() * 2 - 1),
3181 Data->BinaryData.size() * 2 - 1);
3182 unsigned I = 0;
3183 for (auto &Byte : Data->BinaryData) {
3184 Toks[I].startToken();
3185 Toks[I].setKind(tok::binary_data);
3186 Toks[I].setLocation(Tok.getLocation());
3187 Toks[I].setLength(1);
3188 Toks[I].setLiteralData(&Byte);
3189 if (I != ((Data->BinaryData.size() - 1) * 2)) {
3190 Toks[I + 1].startToken();
3191 Toks[I + 1].setKind(tok::comma);
3192 Toks[I + 1].setLocation(Tok.getLocation());
3193 }
3194 I += 2;
3195 }
3196 PP.EnterTokenStream(std::move(Toks), /*DisableMacroExpansion=*/true,
3197 /*IsReinject=*/true);
3198 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
3199}
3200
3201bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
3202 llvm::function_ref<void()> ExpressionStarts,
3203 bool FailImmediatelyOnInvalidExpr) {
3204 bool SawError = false;
3205 while (true) {
3206 if (ExpressionStarts)
3207 ExpressionStarts();
3208
3209 ExprResult Expr;
3210 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
3211 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3212 Expr = ParseBraceInitializer();
3213 } else
3215
3216 if (Tok.is(tok::ellipsis))
3217 Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
3218 else if (Tok.is(tok::code_completion)) {
3219 // There's nothing to suggest in here as we parsed a full expression.
3220 // Instead fail and propagate the error since caller might have something
3221 // the suggest, e.g. signature help in function call. Note that this is
3222 // performed before pushing the \p Expr, so that signature help can report
3223 // current argument correctly.
3224 SawError = true;
3225 cutOffParsing();
3226 break;
3227 }
3228 if (Expr.isInvalid()) {
3229 SawError = true;
3230 if (FailImmediatelyOnInvalidExpr)
3231 break;
3232 SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
3233 } else {
3234 Exprs.push_back(Expr.get());
3235 }
3236
3237 if (Tok.isNot(tok::comma))
3238 break;
3239 // Move to the next argument, remember where the comma was.
3240 Token Comma = Tok;
3241 ConsumeToken();
3242 checkPotentialAngleBracketDelimiter(Comma);
3243 }
3244 return SawError;
3245}
3246
3247bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) {
3248 while (true) {
3250 if (Expr.isInvalid())
3251 return true;
3252
3253 Exprs.push_back(Expr.get());
3254
3255 // We might be parsing the LHS of a fold-expression. If we reached the fold
3256 // operator, stop.
3257 if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis))
3258 return false;
3259
3260 // Move to the next argument, remember where the comma was.
3261 Token Comma = Tok;
3262 ConsumeToken();
3263 checkPotentialAngleBracketDelimiter(Comma);
3264 }
3265}
3266
3267void Parser::ParseBlockId(SourceLocation CaretLoc) {
3268 if (Tok.is(tok::code_completion)) {
3269 cutOffParsing();
3270 Actions.CodeCompletion().CodeCompleteOrdinaryName(
3272 return;
3273 }
3274
3275 // Parse the specifier-qualifier-list piece.
3276 DeclSpec DS(AttrFactory);
3277 ParseSpecifierQualifierList(DS);
3278
3279 // Parse the block-declarator.
3280 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
3282 DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
3283 ParseDeclarator(DeclaratorInfo);
3284
3285 MaybeParseGNUAttributes(DeclaratorInfo);
3286
3287 // Inform sema that we are starting a block.
3288 Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
3289}
3290
3291ExprResult Parser::ParseBlockLiteralExpression() {
3292 assert(Tok.is(tok::caret) && "block literal starts with ^");
3293 SourceLocation CaretLoc = ConsumeToken();
3294
3295 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc,
3296 "block literal parsing");
3297
3298 // Enter a scope to hold everything within the block. This includes the
3299 // argument decls, decls within the compound expression, etc. This also
3300 // allows determining whether a variable reference inside the block is
3301 // within or outside of the block.
3302 ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
3304
3305 // Inform sema that we are starting a block.
3306 Actions.ActOnBlockStart(CaretLoc, getCurScope());
3307
3308 // Parse the return type if present.
3309 DeclSpec DS(AttrFactory);
3310 Declarator ParamInfo(DS, ParsedAttributesView::none(),
3312 ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
3313 // FIXME: Since the return type isn't actually parsed, it can't be used to
3314 // fill ParamInfo with an initial valid range, so do it manually.
3315 ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
3316
3317 // If this block has arguments, parse them. There is no ambiguity here with
3318 // the expression case, because the expression case requires a parameter list.
3319 if (Tok.is(tok::l_paren)) {
3320 ParseParenDeclarator(ParamInfo);
3321 // Parse the pieces after the identifier as if we had "int(...)".
3322 // SetIdentifier sets the source range end, but in this case we're past
3323 // that location.
3324 SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
3325 ParamInfo.SetIdentifier(nullptr, CaretLoc);
3326 ParamInfo.SetRangeEnd(Tmp);
3327 if (ParamInfo.isInvalidType()) {
3328 // If there was an error parsing the arguments, they may have
3329 // tried to use ^(x+y) which requires an argument list. Just
3330 // skip the whole block literal.
3331 Actions.ActOnBlockError(CaretLoc, getCurScope());
3332 return ExprError();
3333 }
3334
3335 MaybeParseGNUAttributes(ParamInfo);
3336
3337 // Inform sema that we are starting a block.
3338 Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3339 } else if (!Tok.is(tok::l_brace)) {
3340 ParseBlockId(CaretLoc);
3341 } else {
3342 // Otherwise, pretend we saw (void).
3343 SourceLocation NoLoc;
3344 ParamInfo.AddTypeInfo(
3345 DeclaratorChunk::getFunction(/*HasProto=*/true,
3346 /*IsAmbiguous=*/false,
3347 /*RParenLoc=*/NoLoc,
3348 /*ArgInfo=*/nullptr,
3349 /*NumParams=*/0,
3350 /*EllipsisLoc=*/NoLoc,
3351 /*RParenLoc=*/NoLoc,
3352 /*RefQualifierIsLvalueRef=*/true,
3353 /*RefQualifierLoc=*/NoLoc,
3354 /*MutableLoc=*/NoLoc, EST_None,
3355 /*ESpecRange=*/SourceRange(),
3356 /*Exceptions=*/nullptr,
3357 /*ExceptionRanges=*/nullptr,
3358 /*NumExceptions=*/0,
3359 /*NoexceptExpr=*/nullptr,
3360 /*ExceptionSpecTokens=*/nullptr,
3361 /*DeclsInPrototype=*/{}, CaretLoc,
3362 CaretLoc, ParamInfo),
3363 CaretLoc);
3364
3365 MaybeParseGNUAttributes(ParamInfo);
3366
3367 // Inform sema that we are starting a block.
3368 Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
3369 }
3370
3371
3372 ExprResult Result(true);
3373 if (!Tok.is(tok::l_brace)) {
3374 // Saw something like: ^expr
3375 Diag(Tok, diag::err_expected_expression);
3376 Actions.ActOnBlockError(CaretLoc, getCurScope());
3377 return ExprError();
3378 }
3379 EnterExpressionEvaluationContextForFunction PotentiallyEvaluated(
3381 StmtResult Stmt(ParseCompoundStatementBody());
3382 BlockScope.Exit();
3383 if (!Stmt.isInvalid())
3384 Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
3385 else
3386 Actions.ActOnBlockError(CaretLoc, getCurScope());
3387 return Result;
3388}
3389
3390ExprResult Parser::ParseObjCBoolLiteral() {
3391 tok::TokenKind Kind = Tok.getKind();
3392 return Actions.ObjC().ActOnObjCBoolLiteral(ConsumeToken(), Kind);
3393}
3394
3395/// Validate availability spec list, emitting diagnostics if necessary. Returns
3396/// true if invalid.
3398 ArrayRef<AvailabilitySpec> AvailSpecs) {
3399 llvm::SmallSet<StringRef, 4> Platforms;
3400 bool HasOtherPlatformSpec = false;
3401 bool Valid = true;
3402 for (const auto &Spec : AvailSpecs) {
3403 if (Spec.isOtherPlatformSpec()) {
3404 if (HasOtherPlatformSpec) {
3405 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star);
3406 Valid = false;
3407 }
3408
3409 HasOtherPlatformSpec = true;
3410 continue;
3411 }
3412
3413 bool Inserted = Platforms.insert(Spec.getPlatform()).second;
3414 if (!Inserted) {
3415 // Rule out multiple version specs referring to the same platform.
3416 // For example, we emit an error for:
3417 // @available(macos 10.10, macos 10.11, *)
3418 StringRef Platform = Spec.getPlatform();
3419 P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform)
3420 << Spec.getEndLoc() << Platform;
3421 Valid = false;
3422 }
3423 }
3424
3425 if (!HasOtherPlatformSpec) {
3426 SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc();
3427 P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required)
3428 << FixItHint::CreateInsertion(InsertWildcardLoc, ", *");
3429 return true;
3430 }
3431
3432 return !Valid;
3433}
3434
3435std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
3436 if (Tok.is(tok::star)) {
3437 return AvailabilitySpec(ConsumeToken());
3438 } else {
3439 // Parse the platform name.
3440 if (Tok.is(tok::code_completion)) {
3441 cutOffParsing();
3442 Actions.CodeCompletion().CodeCompleteAvailabilityPlatformName();
3443 return std::nullopt;
3444 }
3445 if (Tok.isNot(tok::identifier)) {
3446 Diag(Tok, diag::err_avail_query_expected_platform_name);
3447 return std::nullopt;
3448 }
3449
3450 IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc();
3451 SourceRange VersionRange;
3452 VersionTuple Version = ParseVersionTuple(VersionRange);
3453
3454 if (Version.empty())
3455 return std::nullopt;
3456
3457 StringRef GivenPlatform =
3458 PlatformIdentifier->getIdentifierInfo()->getName();
3459 StringRef Platform =
3460 AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
3461
3462 if (AvailabilityAttr::getPrettyPlatformName(Platform).empty() ||
3463 (GivenPlatform.contains("xros") || GivenPlatform.contains("xrOS"))) {
3464 Diag(PlatformIdentifier->getLoc(),
3465 diag::err_avail_query_unrecognized_platform_name)
3466 << GivenPlatform;
3467 return std::nullopt;
3468 }
3469
3470 // Validate anyAppleOS version; reject versions older than 26.0.
3471 if (Platform == "anyappleos" &&
3473 Diag(VersionRange.getBegin(),
3474 diag::err_avail_query_anyappleos_min_version)
3475 << Version.getAsString();
3476 return std::nullopt;
3477 }
3478
3479 return AvailabilitySpec(Version, Platform, PlatformIdentifier->getLoc(),
3480 VersionRange.getEnd());
3481 }
3482}
3483
3484ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) {
3485 assert(Tok.is(tok::kw___builtin_available) ||
3486 Tok.isObjCAtKeyword(tok::objc_available));
3487
3488 // Eat the available or __builtin_available.
3489 ConsumeToken();
3490
3491 BalancedDelimiterTracker Parens(*this, tok::l_paren);
3492 if (Parens.expectAndConsume())
3493 return ExprError();
3494
3495 SmallVector<AvailabilitySpec, 4> AvailSpecs;
3496 bool HasError = false;
3497 while (true) {
3498 std::optional<AvailabilitySpec> Spec = ParseAvailabilitySpec();
3499 if (!Spec)
3500 HasError = true;
3501 else
3502 AvailSpecs.push_back(*Spec);
3503
3504 if (!TryConsumeToken(tok::comma))
3505 break;
3506 }
3507
3508 if (HasError) {
3509 SkipUntil(tok::r_paren, StopAtSemi);
3510 return ExprError();
3511 }
3512
3513 CheckAvailabilitySpecList(*this, AvailSpecs);
3514
3515 if (Parens.consumeClose())
3516 return ExprError();
3517
3518 return Actions.ObjC().ActOnObjCAvailabilityCheckExpr(
3519 AvailSpecs, BeginLoc, Parens.getCloseLocation());
3520}
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the clang::Expr interface and subclasses for C++ expressions.
bool isNot(T Kind) const
Token Tok
The Token.
FormatToken * Next
The next token in the unwrapped line.
bool is(tok::TokenKind Kind) const
#define X(type, name)
Definition Value.h:97
#define SM(sm)
static bool CheckAvailabilitySpecList(Parser &P, ArrayRef< AvailabilitySpec > AvailSpecs)
Validate availability spec list, emitting diagnostics if necessary.
#define REVERTIBLE_TYPE_TRAIT(Name)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenACC constructs and clauses.
This file declares semantic analysis for OpenMP constructs and clauses.
This file declares semantic analysis for SYCL constructs.
bool isUnset() const
Definition Ownership.h:168
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
bool isUsable() const
Definition Ownership.h:169
static bool validateAnyAppleOSVersion(const llvm::VersionTuple &Version)
Returns true if the anyAppleOS version is valid (empty or >= 26.0).
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getCloseLocation() const
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
Definition DeclSpec.h:181
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
bool isFileContext() const
Definition DeclBase.h:2180
bool isRecord() const
Definition DeclBase.h:2189
RAII object that enters a new expression evaluation context.
This represents one expression.
Definition Expr.h:112
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Definition Expr.h:246
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:277
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:140
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition Diagnostic.h:129
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition Diagnostic.h:103
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
SourceLocation getLoc() const
IdentifierInfo * getIdentifierInfo() const
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
Definition Lexer.cpp:1121
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:487
void * getAsOpaquePtr() const
Definition Ownership.h:91
PtrTy get() const
Definition Ownership.h:81
static const ParsedAttributesView & none()
Definition ParsedAttr.h:817
ParseScope - Introduces a new scope for parsing.
Definition Parser.h:408
Parser - This implements a parser for the C family of languages.
Definition Parser.h:172
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
Definition ParseDecl.cpp:44
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:1855
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Definition Parser.cpp:88
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Definition Parser.h:263
Sema & getActions() const
Definition Parser.h:208
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
Definition Parser.h:328
ExprResult ParseCaseExpression(SourceLocation CaseLoc)
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
Definition Parser.h:197
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
Definition Parser.h:291
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
Definition Parser.h:317
ExprResult ParseConstantExpression()
ExprResult ParseConditionalExpression()
Definition ParseExpr.cpp:95
bool TryConsumeToken(tok::TokenKind Expected)
Definition Parser.h:271
Scope * getCurScope() const
Definition Parser.h:212
ExprResult ParseArrayBoundExpression()
friend class InMessageExpressionRAIIObject
Definition Parser.h:5368
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:507
friend class OffsetOfStateRAIIObject
Definition Parser.h:3637
const LangOptions & getLangOpts() const
Definition Parser.h:205
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
Definition ParseExpr.cpp:47
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
Definition Parser.h:488
@ StopAtSemi
Stop skipping at semicolon.
Definition Parser.h:486
ExprResult ParseUnevaluatedStringLiteralExpression()
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Definition Parser.h:325
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
Definition ParseExpr.cpp:75
friend class BalancedDelimiterTracker
Definition Parser.h:200
ExprResult ParseConstraintExpression()
Parse a constraint-expression.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
QualType getCanonicalType() const
Definition TypeBase.h:8483
@ 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:7087
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
Definition Sema.h:6797
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
Definition Sema.h:6807
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
Definition Sema.h:6776
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Token - This structure provides full information about a lexed token.
Definition Token.h:36
IdentifierInfo * getIdentifierInfo() const
Definition Token.h:197
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition Token.h:142
const char * getName() const
Definition Token.h:184
void setLength(unsigned Len)
Definition Token.h:151
void setKind(tok::TokenKind K)
Definition Token.h:100
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition Token.h:104
tok::TokenKind getKind() const
Definition Token.h:99
bool isOneOf(Ts... Ks) const
Definition Token.h:105
void setLocation(SourceLocation L)
Definition Token.h:150
void startToken()
Reset all flags to cleared.
Definition Token.h:187
bool isSpecificPlaceholderType(unsigned K) const
Test for a specific placeholder type.
Definition TypeBase.h:9023
bool isFunctionType() const
Definition TypeBase.h:8664
bool isVectorType() const
Definition TypeBase.h:8807
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
Definition DeclSpec.h:1121
bool isValid() const
Determine whether this unqualified-id refers to a valid name.
Definition DeclSpec.h:1109
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclSpec.h:1246
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
@ TST_typename
Definition Specifiers.h:84
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus23
@ CPlusPlus
@ CPlusPlus11
@ CPlusPlus17
TypoCorrectionTypeBehavior
If a typo should be encountered, should typo correction suggest type names, non type names,...
Definition Parser.h:106
bool tokenIsLikeStringLiteral(const Token &Tok, const LangOptions &LO)
Return true if the token is a string literal, or a function local predefined macro,...
Expr * Cond
};
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition TypeTraits.h:51
ExprResult ExprEmpty()
Definition Ownership.h:272
@ Result
The result type of a method or function.
Definition TypeBase.h:905
ActionResult< ParsedType > TypeResult
Definition Ownership.h:251
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
ExprResult ExprError()
Definition Ownership.h:265
@ Type
The name was classified as a type.
Definition Sema.h:564
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
ParenExprKind
In a call to ParseParenExpression, are the initial parentheses part of an operator that requires the ...
Definition Parser.h:128
U cast(CodeGen::Address addr)
Definition Address.h:327
CastParseKind
Control what ParseCastExpression will parse.
Definition Parser.h:113
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition Ownership.h:230
SourceLocIdentKind
Definition Expr.h:5007
ParenParseOption
ParenParseOption - Control what ParseParenExpression will parse.
Definition Parser.h:116
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
@ Parens
New-expression has a C++98 paren-delimited initializer.
Definition ExprCXX.h:2246
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
Definition Ownership.h:250
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
Definition DeclSpec.cpp:132
TemplateNameKind Kind
The kind of template that Template refers to.