10b57cec5SDimitry Andric //===--- ParseExpr.cpp - Expression Parsing -------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Provides the Expression parsing implementation. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric /// Expressions in C99 basically consist of a bunch of binary operators with 130b57cec5SDimitry Andric /// unary operators and other random stuff at the leaves. 140b57cec5SDimitry Andric /// 150b57cec5SDimitry Andric /// In the C99 grammar, these unary operators bind tightest and are represented 160b57cec5SDimitry Andric /// as the 'cast-expression' production. Everything else is either a binary 170b57cec5SDimitry Andric /// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are 180b57cec5SDimitry Andric /// handled by ParseCastExpression, the higher level pieces are handled by 190b57cec5SDimitry Andric /// ParseBinaryExpression. 200b57cec5SDimitry Andric /// 210b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 24480093f4SDimitry Andric #include "clang/AST/ExprCXX.h" 250b57cec5SDimitry Andric #include "clang/Basic/PrettyStackTrace.h" 265f757f3fSDimitry Andric #include "clang/Lex/LiteralSupport.h" 2706c3fb27SDimitry Andric #include "clang/Parse/Parser.h" 280b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 290b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 3006c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h" 310b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 320b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 330fca6ea1SDimitry Andric #include "clang/Sema/SemaCUDA.h" 340fca6ea1SDimitry Andric #include "clang/Sema/SemaCodeCompletion.h" 350fca6ea1SDimitry Andric #include "clang/Sema/SemaObjC.h" 360fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenACC.h" 370fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenMP.h" 380fca6ea1SDimitry Andric #include "clang/Sema/SemaSYCL.h" 390b57cec5SDimitry Andric #include "clang/Sema/TypoCorrection.h" 400b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 41bdd1243dSDimitry Andric #include <optional> 420b57cec5SDimitry Andric using namespace clang; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric /// Simple precedence-based parser for binary/ternary operators. 450b57cec5SDimitry Andric /// 460b57cec5SDimitry Andric /// Note: we diverge from the C99 grammar when parsing the assignment-expression 470b57cec5SDimitry Andric /// production. C99 specifies that the LHS of an assignment operator should be 480b57cec5SDimitry Andric /// parsed as a unary-expression, but consistency dictates that it be a 490b57cec5SDimitry Andric /// conditional-expession. In practice, the important thing here is that the 500b57cec5SDimitry Andric /// LHS of an assignment has to be an l-value, which productions between 510b57cec5SDimitry Andric /// unary-expression and conditional-expression don't produce. Because we want 520b57cec5SDimitry Andric /// consistency, we parse the LHS as a conditional-expression, then check for 530b57cec5SDimitry Andric /// l-value-ness in semantic analysis stages. 540b57cec5SDimitry Andric /// 550b57cec5SDimitry Andric /// \verbatim 560b57cec5SDimitry Andric /// pm-expression: [C++ 5.5] 570b57cec5SDimitry Andric /// cast-expression 580b57cec5SDimitry Andric /// pm-expression '.*' cast-expression 590b57cec5SDimitry Andric /// pm-expression '->*' cast-expression 600b57cec5SDimitry Andric /// 610b57cec5SDimitry Andric /// multiplicative-expression: [C99 6.5.5] 620b57cec5SDimitry Andric /// Note: in C++, apply pm-expression instead of cast-expression 630b57cec5SDimitry Andric /// cast-expression 640b57cec5SDimitry Andric /// multiplicative-expression '*' cast-expression 650b57cec5SDimitry Andric /// multiplicative-expression '/' cast-expression 660b57cec5SDimitry Andric /// multiplicative-expression '%' cast-expression 670b57cec5SDimitry Andric /// 680b57cec5SDimitry Andric /// additive-expression: [C99 6.5.6] 690b57cec5SDimitry Andric /// multiplicative-expression 700b57cec5SDimitry Andric /// additive-expression '+' multiplicative-expression 710b57cec5SDimitry Andric /// additive-expression '-' multiplicative-expression 720b57cec5SDimitry Andric /// 730b57cec5SDimitry Andric /// shift-expression: [C99 6.5.7] 740b57cec5SDimitry Andric /// additive-expression 750b57cec5SDimitry Andric /// shift-expression '<<' additive-expression 760b57cec5SDimitry Andric /// shift-expression '>>' additive-expression 770b57cec5SDimitry Andric /// 780b57cec5SDimitry Andric /// compare-expression: [C++20 expr.spaceship] 790b57cec5SDimitry Andric /// shift-expression 800b57cec5SDimitry Andric /// compare-expression '<=>' shift-expression 810b57cec5SDimitry Andric /// 820b57cec5SDimitry Andric /// relational-expression: [C99 6.5.8] 830b57cec5SDimitry Andric /// compare-expression 840b57cec5SDimitry Andric /// relational-expression '<' compare-expression 850b57cec5SDimitry Andric /// relational-expression '>' compare-expression 860b57cec5SDimitry Andric /// relational-expression '<=' compare-expression 870b57cec5SDimitry Andric /// relational-expression '>=' compare-expression 880b57cec5SDimitry Andric /// 890b57cec5SDimitry Andric /// equality-expression: [C99 6.5.9] 900b57cec5SDimitry Andric /// relational-expression 910b57cec5SDimitry Andric /// equality-expression '==' relational-expression 920b57cec5SDimitry Andric /// equality-expression '!=' relational-expression 930b57cec5SDimitry Andric /// 940b57cec5SDimitry Andric /// AND-expression: [C99 6.5.10] 950b57cec5SDimitry Andric /// equality-expression 960b57cec5SDimitry Andric /// AND-expression '&' equality-expression 970b57cec5SDimitry Andric /// 980b57cec5SDimitry Andric /// exclusive-OR-expression: [C99 6.5.11] 990b57cec5SDimitry Andric /// AND-expression 1000b57cec5SDimitry Andric /// exclusive-OR-expression '^' AND-expression 1010b57cec5SDimitry Andric /// 1020b57cec5SDimitry Andric /// inclusive-OR-expression: [C99 6.5.12] 1030b57cec5SDimitry Andric /// exclusive-OR-expression 1040b57cec5SDimitry Andric /// inclusive-OR-expression '|' exclusive-OR-expression 1050b57cec5SDimitry Andric /// 1060b57cec5SDimitry Andric /// logical-AND-expression: [C99 6.5.13] 1070b57cec5SDimitry Andric /// inclusive-OR-expression 1080b57cec5SDimitry Andric /// logical-AND-expression '&&' inclusive-OR-expression 1090b57cec5SDimitry Andric /// 1100b57cec5SDimitry Andric /// logical-OR-expression: [C99 6.5.14] 1110b57cec5SDimitry Andric /// logical-AND-expression 1120b57cec5SDimitry Andric /// logical-OR-expression '||' logical-AND-expression 1130b57cec5SDimitry Andric /// 1140b57cec5SDimitry Andric /// conditional-expression: [C99 6.5.15] 1150b57cec5SDimitry Andric /// logical-OR-expression 1160b57cec5SDimitry Andric /// logical-OR-expression '?' expression ':' conditional-expression 1170b57cec5SDimitry Andric /// [GNU] logical-OR-expression '?' ':' conditional-expression 1180b57cec5SDimitry Andric /// [C++] the third operand is an assignment-expression 1190b57cec5SDimitry Andric /// 1200b57cec5SDimitry Andric /// assignment-expression: [C99 6.5.16] 1210b57cec5SDimitry Andric /// conditional-expression 1220b57cec5SDimitry Andric /// unary-expression assignment-operator assignment-expression 1230b57cec5SDimitry Andric /// [C++] throw-expression [C++ 15] 1240b57cec5SDimitry Andric /// 1250b57cec5SDimitry Andric /// assignment-operator: one of 1260b57cec5SDimitry Andric /// = *= /= %= += -= <<= >>= &= ^= |= 1270b57cec5SDimitry Andric /// 1280b57cec5SDimitry Andric /// expression: [C99 6.5.17] 1290b57cec5SDimitry Andric /// assignment-expression ...[opt] 1300b57cec5SDimitry Andric /// expression ',' assignment-expression ...[opt] 1310b57cec5SDimitry Andric /// \endverbatim 1320b57cec5SDimitry Andric ExprResult Parser::ParseExpression(TypeCastState isTypeCast) { 1330b57cec5SDimitry Andric ExprResult LHS(ParseAssignmentExpression(isTypeCast)); 1340b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric /// This routine is called when the '@' is seen and consumed. 1380b57cec5SDimitry Andric /// Current token is an Identifier and is not a 'try'. This 1390b57cec5SDimitry Andric /// routine is necessary to disambiguate \@try-statement from, 1400b57cec5SDimitry Andric /// for example, \@encode-expression. 1410b57cec5SDimitry Andric /// 1420b57cec5SDimitry Andric ExprResult 1430b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { 1440b57cec5SDimitry Andric ExprResult LHS(ParseObjCAtExpression(AtLoc)); 1450b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric /// This routine is called when a leading '__extension__' is seen and 1490b57cec5SDimitry Andric /// consumed. This is necessary because the token gets consumed in the 1500b57cec5SDimitry Andric /// process of disambiguating between an expression and a declaration. 1510b57cec5SDimitry Andric ExprResult 1520b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { 1530b57cec5SDimitry Andric ExprResult LHS(true); 1540b57cec5SDimitry Andric { 1550b57cec5SDimitry Andric // Silence extension warnings in the sub-expression 1560b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); 1570b57cec5SDimitry Andric 158480093f4SDimitry Andric LHS = ParseCastExpression(AnyCastExpr); 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric if (!LHS.isInvalid()) 1620b57cec5SDimitry Andric LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__, 1630b57cec5SDimitry Andric LHS.get()); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric /// Parse an expr that doesn't include (top-level) commas. 1690b57cec5SDimitry Andric ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { 1700b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 171fe6060f1SDimitry Andric cutOffParsing(); 1720fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteExpression( 1730fca6ea1SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation())); 1740b57cec5SDimitry Andric return ExprError(); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric if (Tok.is(tok::kw_throw)) 1780b57cec5SDimitry Andric return ParseThrowExpression(); 1790b57cec5SDimitry Andric if (Tok.is(tok::kw_co_yield)) 1800b57cec5SDimitry Andric return ParseCoyieldExpression(); 1810b57cec5SDimitry Andric 182480093f4SDimitry Andric ExprResult LHS = ParseCastExpression(AnyCastExpr, 1830b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 1840b57cec5SDimitry Andric isTypeCast); 1850b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Assignment); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880fca6ea1SDimitry Andric ExprResult Parser::ParseConditionalExpression() { 1890fca6ea1SDimitry Andric if (Tok.is(tok::code_completion)) { 1900fca6ea1SDimitry Andric cutOffParsing(); 1910fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteExpression( 1920fca6ea1SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation())); 1930fca6ea1SDimitry Andric return ExprError(); 1940fca6ea1SDimitry Andric } 1950fca6ea1SDimitry Andric 1960fca6ea1SDimitry Andric ExprResult LHS = ParseCastExpression( 1970fca6ea1SDimitry Andric AnyCastExpr, /*isAddressOfOperand=*/false, NotTypeCast); 1980fca6ea1SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Conditional); 1990fca6ea1SDimitry Andric } 2000fca6ea1SDimitry Andric 2010b57cec5SDimitry Andric /// Parse an assignment expression where part of an Objective-C message 2020b57cec5SDimitry Andric /// send has already been parsed. 2030b57cec5SDimitry Andric /// 2040b57cec5SDimitry Andric /// In this case \p LBracLoc indicates the location of the '[' of the message 2050b57cec5SDimitry Andric /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating 2060b57cec5SDimitry Andric /// the receiver of the message. 2070b57cec5SDimitry Andric /// 2080b57cec5SDimitry Andric /// Since this handles full assignment-expression's, it handles postfix 2090b57cec5SDimitry Andric /// expressions and other binary operators for these expressions as well. 2100b57cec5SDimitry Andric ExprResult 2110b57cec5SDimitry Andric Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, 2120b57cec5SDimitry Andric SourceLocation SuperLoc, 2130b57cec5SDimitry Andric ParsedType ReceiverType, 2140b57cec5SDimitry Andric Expr *ReceiverExpr) { 2150b57cec5SDimitry Andric ExprResult R 2160b57cec5SDimitry Andric = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, 2170b57cec5SDimitry Andric ReceiverType, ReceiverExpr); 2180b57cec5SDimitry Andric R = ParsePostfixExpressionSuffix(R); 2190b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(R, prec::Assignment); 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric ExprResult 2230b57cec5SDimitry Andric Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) { 2240b57cec5SDimitry Andric assert(Actions.ExprEvalContexts.back().Context == 2250b57cec5SDimitry Andric Sema::ExpressionEvaluationContext::ConstantEvaluated && 2260b57cec5SDimitry Andric "Call this function only if your ExpressionEvaluationContext is " 2270b57cec5SDimitry Andric "already ConstantEvaluated"); 228480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, isTypeCast)); 2290b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2300b57cec5SDimitry Andric return Actions.ActOnConstantExpression(Res); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 233bdd1243dSDimitry Andric ExprResult Parser::ParseConstantExpression() { 2340b57cec5SDimitry Andric // C++03 [basic.def.odr]p2: 2350b57cec5SDimitry Andric // An expression is potentially evaluated unless it appears where an 2360b57cec5SDimitry Andric // integral constant expression is required (see 5.19) [...]. 2370b57cec5SDimitry Andric // C++98 and C++11 have no such rule, but this is only a defect in C++98. 2380b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2390b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 240bdd1243dSDimitry Andric return ParseConstantExpressionInExprEvalContext(NotTypeCast); 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2435f757f3fSDimitry Andric ExprResult Parser::ParseArrayBoundExpression() { 2445f757f3fSDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2455f757f3fSDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 2465f757f3fSDimitry Andric // If we parse the bound of a VLA... we parse a non-constant 2475f757f3fSDimitry Andric // constant-expression! 2485f757f3fSDimitry Andric Actions.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true; 2495f757f3fSDimitry Andric return ParseConstantExpressionInExprEvalContext(NotTypeCast); 2505f757f3fSDimitry Andric } 2515f757f3fSDimitry Andric 2520b57cec5SDimitry Andric ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) { 2530b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2540b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 255480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); 2560b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2570b57cec5SDimitry Andric return Actions.ActOnCaseExpr(CaseLoc, Res); 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric /// Parse a constraint-expression. 2610b57cec5SDimitry Andric /// 2620b57cec5SDimitry Andric /// \verbatim 263a7dea167SDimitry Andric /// constraint-expression: C++2a[temp.constr.decl]p1 2640b57cec5SDimitry Andric /// logical-or-expression 2650b57cec5SDimitry Andric /// \endverbatim 2660b57cec5SDimitry Andric ExprResult Parser::ParseConstraintExpression() { 267a7dea167SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 26855e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 269480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr)); 2700b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); 271480093f4SDimitry Andric if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) { 272480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(Res); 273a7dea167SDimitry Andric return ExprError(); 274480093f4SDimitry Andric } 2750b57cec5SDimitry Andric return Res; 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 278480093f4SDimitry Andric /// \brief Parse a constraint-logical-and-expression. 279480093f4SDimitry Andric /// 280480093f4SDimitry Andric /// \verbatim 281480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 282480093f4SDimitry Andric /// constraint-logical-and-expression: 283480093f4SDimitry Andric /// primary-expression 284480093f4SDimitry Andric /// constraint-logical-and-expression '&&' primary-expression 285480093f4SDimitry Andric /// 286480093f4SDimitry Andric /// \endverbatim 287480093f4SDimitry Andric ExprResult 288480093f4SDimitry Andric Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { 289480093f4SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 29055e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 291480093f4SDimitry Andric bool NotPrimaryExpression = false; 292480093f4SDimitry Andric auto ParsePrimary = [&] () { 293480093f4SDimitry Andric ExprResult E = ParseCastExpression(PrimaryExprOnly, 294480093f4SDimitry Andric /*isAddressOfOperand=*/false, 295480093f4SDimitry Andric /*isTypeCast=*/NotTypeCast, 296480093f4SDimitry Andric /*isVectorLiteral=*/false, 297480093f4SDimitry Andric &NotPrimaryExpression); 298480093f4SDimitry Andric if (E.isInvalid()) 299480093f4SDimitry Andric return ExprError(); 300480093f4SDimitry Andric auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) { 301480093f4SDimitry Andric E = ParsePostfixExpressionSuffix(E); 302480093f4SDimitry Andric // Use InclusiveOr, the precedence just after '&&' to not parse the 303480093f4SDimitry Andric // next arguments to the logical and. 304480093f4SDimitry Andric E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr); 305480093f4SDimitry Andric if (!E.isInvalid()) 306480093f4SDimitry Andric Diag(E.get()->getExprLoc(), 307480093f4SDimitry Andric Note 308480093f4SDimitry Andric ? diag::note_unparenthesized_non_primary_expr_in_requires_clause 309480093f4SDimitry Andric : diag::err_unparenthesized_non_primary_expr_in_requires_clause) 310480093f4SDimitry Andric << FixItHint::CreateInsertion(E.get()->getBeginLoc(), "(") 311480093f4SDimitry Andric << FixItHint::CreateInsertion( 312480093f4SDimitry Andric PP.getLocForEndOfToken(E.get()->getEndLoc()), ")") 313480093f4SDimitry Andric << E.get()->getSourceRange(); 314480093f4SDimitry Andric return E; 315480093f4SDimitry Andric }; 316480093f4SDimitry Andric 317480093f4SDimitry Andric if (NotPrimaryExpression || 318480093f4SDimitry Andric // Check if the following tokens must be a part of a non-primary 319480093f4SDimitry Andric // expression 320480093f4SDimitry Andric getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 321480093f4SDimitry Andric /*CPlusPlus11=*/true) > prec::LogicalAnd || 322480093f4SDimitry Andric // Postfix operators other than '(' (which will be checked for in 323480093f4SDimitry Andric // CheckConstraintExpression). 324480093f4SDimitry Andric Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) || 325480093f4SDimitry Andric (Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) { 326480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/false); 327480093f4SDimitry Andric if (E.isInvalid()) 328480093f4SDimitry Andric return ExprError(); 329480093f4SDimitry Andric NotPrimaryExpression = false; 330480093f4SDimitry Andric } 331480093f4SDimitry Andric bool PossibleNonPrimary; 332480093f4SDimitry Andric bool IsConstraintExpr = 333480093f4SDimitry Andric Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary, 334480093f4SDimitry Andric IsTrailingRequiresClause); 335480093f4SDimitry Andric if (!IsConstraintExpr || PossibleNonPrimary) { 336480093f4SDimitry Andric // Atomic constraint might be an unparenthesized non-primary expression 337480093f4SDimitry Andric // (such as a binary operator), in which case we might get here (e.g. in 338480093f4SDimitry Andric // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore 339480093f4SDimitry Andric // the rest of the addition expression). Try to parse the rest of it here. 340480093f4SDimitry Andric if (PossibleNonPrimary) 341480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr); 342480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 343480093f4SDimitry Andric return ExprError(); 344480093f4SDimitry Andric } 345480093f4SDimitry Andric return E; 346480093f4SDimitry Andric }; 347480093f4SDimitry Andric ExprResult LHS = ParsePrimary(); 348480093f4SDimitry Andric if (LHS.isInvalid()) 349480093f4SDimitry Andric return ExprError(); 350480093f4SDimitry Andric while (Tok.is(tok::ampamp)) { 351480093f4SDimitry Andric SourceLocation LogicalAndLoc = ConsumeToken(); 352480093f4SDimitry Andric ExprResult RHS = ParsePrimary(); 353480093f4SDimitry Andric if (RHS.isInvalid()) { 354480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 355480093f4SDimitry Andric return ExprError(); 356480093f4SDimitry Andric } 357480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc, 358480093f4SDimitry Andric tok::ampamp, LHS.get(), RHS.get()); 359480093f4SDimitry Andric if (!Op.isUsable()) { 360480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 361480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 362480093f4SDimitry Andric return ExprError(); 363480093f4SDimitry Andric } 364480093f4SDimitry Andric LHS = Op; 365480093f4SDimitry Andric } 366480093f4SDimitry Andric return LHS; 367480093f4SDimitry Andric } 368480093f4SDimitry Andric 369480093f4SDimitry Andric /// \brief Parse a constraint-logical-or-expression. 370480093f4SDimitry Andric /// 371480093f4SDimitry Andric /// \verbatim 372480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 373480093f4SDimitry Andric /// constraint-logical-or-expression: 374480093f4SDimitry Andric /// constraint-logical-and-expression 375480093f4SDimitry Andric /// constraint-logical-or-expression '||' 376480093f4SDimitry Andric /// constraint-logical-and-expression 377480093f4SDimitry Andric /// 378480093f4SDimitry Andric /// \endverbatim 379480093f4SDimitry Andric ExprResult 380480093f4SDimitry Andric Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) { 381480093f4SDimitry Andric ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause)); 382480093f4SDimitry Andric if (!LHS.isUsable()) 383480093f4SDimitry Andric return ExprError(); 384480093f4SDimitry Andric while (Tok.is(tok::pipepipe)) { 385480093f4SDimitry Andric SourceLocation LogicalOrLoc = ConsumeToken(); 386480093f4SDimitry Andric ExprResult RHS = 387480093f4SDimitry Andric ParseConstraintLogicalAndExpression(IsTrailingRequiresClause); 388480093f4SDimitry Andric if (!RHS.isUsable()) { 389480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 390480093f4SDimitry Andric return ExprError(); 391480093f4SDimitry Andric } 392480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc, 393480093f4SDimitry Andric tok::pipepipe, LHS.get(), RHS.get()); 394480093f4SDimitry Andric if (!Op.isUsable()) { 395480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 396480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 397480093f4SDimitry Andric return ExprError(); 398480093f4SDimitry Andric } 399480093f4SDimitry Andric LHS = Op; 400480093f4SDimitry Andric } 401480093f4SDimitry Andric return LHS; 402480093f4SDimitry Andric } 403480093f4SDimitry Andric 4040b57cec5SDimitry Andric bool Parser::isNotExpressionStart() { 4050b57cec5SDimitry Andric tok::TokenKind K = Tok.getKind(); 4060b57cec5SDimitry Andric if (K == tok::l_brace || K == tok::r_brace || 4070b57cec5SDimitry Andric K == tok::kw_for || K == tok::kw_while || 4080b57cec5SDimitry Andric K == tok::kw_if || K == tok::kw_else || 4090b57cec5SDimitry Andric K == tok::kw_goto || K == tok::kw_try) 4100b57cec5SDimitry Andric return true; 4110b57cec5SDimitry Andric // If this is a decl-specifier, we can't be at the start of an expression. 4120b57cec5SDimitry Andric return isKnownToBeDeclarationSpecifier(); 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric bool Parser::isFoldOperator(prec::Level Level) const { 4160b57cec5SDimitry Andric return Level > prec::Unknown && Level != prec::Conditional && 4170b57cec5SDimitry Andric Level != prec::Spaceship; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric bool Parser::isFoldOperator(tok::TokenKind Kind) const { 4210b57cec5SDimitry Andric return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric /// Parse a binary expression that starts with \p LHS and has a 4250b57cec5SDimitry Andric /// precedence of at least \p MinPrec. 4260b57cec5SDimitry Andric ExprResult 4270b57cec5SDimitry Andric Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { 4280b57cec5SDimitry Andric prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(), 4290b57cec5SDimitry Andric GreaterThanIsOperator, 4300b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 4310b57cec5SDimitry Andric SourceLocation ColonLoc; 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric auto SavedType = PreferredType; 43404eeddc0SDimitry Andric while (true) { 4350b57cec5SDimitry Andric // Every iteration may rely on a preferred type for the whole expression. 4360b57cec5SDimitry Andric PreferredType = SavedType; 4370b57cec5SDimitry Andric // If this token has a lower precedence than we are allowed to parse (e.g. 4380b57cec5SDimitry Andric // because we are called recursively, or because the token is not a binop), 4390b57cec5SDimitry Andric // then we are done! 4400b57cec5SDimitry Andric if (NextTokPrec < MinPrec) 4410b57cec5SDimitry Andric return LHS; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // Consume the operator, saving the operator token for error reporting. 4440b57cec5SDimitry Andric Token OpToken = Tok; 4450b57cec5SDimitry Andric ConsumeToken(); 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric if (OpToken.is(tok::caretcaret)) { 4480b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or)); 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric // If we're potentially in a template-id, we may now be able to determine 4520b57cec5SDimitry Andric // whether we're actually in one or not. 4530b57cec5SDimitry Andric if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater, 4540b57cec5SDimitry Andric tok::greatergreatergreater) && 4550b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(OpToken)) 4560b57cec5SDimitry Andric return ExprError(); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric // Bail out when encountering a comma followed by a token which can't 4590b57cec5SDimitry Andric // possibly be the start of an expression. For instance: 4600b57cec5SDimitry Andric // int f() { return 1, } 4610b57cec5SDimitry Andric // We can't do this before consuming the comma, because 4620b57cec5SDimitry Andric // isNotExpressionStart() looks at the token stream. 4630b57cec5SDimitry Andric if (OpToken.is(tok::comma) && isNotExpressionStart()) { 4640b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4650b57cec5SDimitry Andric Tok = OpToken; 4660b57cec5SDimitry Andric return LHS; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric // If the next token is an ellipsis, then this is a fold-expression. Leave 4700b57cec5SDimitry Andric // it alone so we can handle it in the paren expression. 4710b57cec5SDimitry Andric if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) { 4720b57cec5SDimitry Andric // FIXME: We can't check this via lookahead before we consume the token 4730b57cec5SDimitry Andric // because that tickles a lexer bug. 4740b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4750b57cec5SDimitry Andric Tok = OpToken; 4760b57cec5SDimitry Andric return LHS; 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric // In Objective-C++, alternative operator tokens can be used as keyword args 4800b57cec5SDimitry Andric // in message expressions. Unconsume the token so that it can reinterpreted 4810b57cec5SDimitry Andric // as an identifier in ParseObjCMessageExpressionBody. i.e., we support: 4820b57cec5SDimitry Andric // [foo meth:0 and:0]; 4830b57cec5SDimitry Andric // [foo not_eq]; 4840b57cec5SDimitry Andric if (getLangOpts().ObjC && getLangOpts().CPlusPlus && 4850b57cec5SDimitry Andric Tok.isOneOf(tok::colon, tok::r_square) && 4860b57cec5SDimitry Andric OpToken.getIdentifierInfo() != nullptr) { 4870b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4880b57cec5SDimitry Andric Tok = OpToken; 4890b57cec5SDimitry Andric return LHS; 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric // Special case handling for the ternary operator. 4930b57cec5SDimitry Andric ExprResult TernaryMiddle(true); 4940b57cec5SDimitry Andric if (NextTokPrec == prec::Conditional) { 4950b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 4960b57cec5SDimitry Andric // Parse a braced-init-list here for error recovery purposes. 4970b57cec5SDimitry Andric SourceLocation BraceLoc = Tok.getLocation(); 4980b57cec5SDimitry Andric TernaryMiddle = ParseBraceInitializer(); 4990b57cec5SDimitry Andric if (!TernaryMiddle.isInvalid()) { 5000b57cec5SDimitry Andric Diag(BraceLoc, diag::err_init_list_bin_op) 5010b57cec5SDimitry Andric << /*RHS*/ 1 << PP.getSpelling(OpToken) 5020b57cec5SDimitry Andric << Actions.getExprRange(TernaryMiddle.get()); 5030b57cec5SDimitry Andric TernaryMiddle = ExprError(); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric } else if (Tok.isNot(tok::colon)) { 5060b57cec5SDimitry Andric // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 5070b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric // Handle this production specially: 5100b57cec5SDimitry Andric // logical-OR-expression '?' expression ':' conditional-expression 5110b57cec5SDimitry Andric // In particular, the RHS of the '?' is 'expression', not 5120b57cec5SDimitry Andric // 'logical-OR-expression' as we might expect. 5130b57cec5SDimitry Andric TernaryMiddle = ParseExpression(); 5140b57cec5SDimitry Andric } else { 5150b57cec5SDimitry Andric // Special case handling of "X ? Y : Z" where Y is empty: 5160b57cec5SDimitry Andric // logical-OR-expression '?' ':' conditional-expression [GNU] 5170b57cec5SDimitry Andric TernaryMiddle = nullptr; 5180b57cec5SDimitry Andric Diag(Tok, diag::ext_gnu_conditional_expr); 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 5220b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5230b57cec5SDimitry Andric LHS = ExprError(); 5240b57cec5SDimitry Andric TernaryMiddle = nullptr; 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric if (!TryConsumeToken(tok::colon, ColonLoc)) { 5280b57cec5SDimitry Andric // Otherwise, we're missing a ':'. Assume that this was a typo that 5290b57cec5SDimitry Andric // the user forgot. If we're not in a macro expansion, we can suggest 5300b57cec5SDimitry Andric // a fixit hint. If there were two spaces before the current token, 5310b57cec5SDimitry Andric // suggest inserting the colon in between them, otherwise insert ": ". 5320b57cec5SDimitry Andric SourceLocation FILoc = Tok.getLocation(); 5330b57cec5SDimitry Andric const char *FIText = ": "; 5340b57cec5SDimitry Andric const SourceManager &SM = PP.getSourceManager(); 5350b57cec5SDimitry Andric if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) { 5360b57cec5SDimitry Andric assert(FILoc.isFileID()); 5370b57cec5SDimitry Andric bool IsInvalid = false; 5380b57cec5SDimitry Andric const char *SourcePtr = 5390b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid); 5400b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5410b57cec5SDimitry Andric SourcePtr = 5420b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid); 5430b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5440b57cec5SDimitry Andric FILoc = FILoc.getLocWithOffset(-1); 5450b57cec5SDimitry Andric FIText = ":"; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric Diag(Tok, diag::err_expected) 5510b57cec5SDimitry Andric << tok::colon << FixItHint::CreateInsertion(FILoc, FIText); 5520b57cec5SDimitry Andric Diag(OpToken, diag::note_matching) << tok::question; 5530b57cec5SDimitry Andric ColonLoc = Tok.getLocation(); 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(), 5580b57cec5SDimitry Andric OpToken.getKind()); 5590b57cec5SDimitry Andric // Parse another leaf here for the RHS of the operator. 5600b57cec5SDimitry Andric // ParseCastExpression works here because all RHS expressions in C have it 5610b57cec5SDimitry Andric // as a prefix, at least. However, in C++, an assignment-expression could 5620b57cec5SDimitry Andric // be a throw-expression, which is not a valid cast-expression. 5630b57cec5SDimitry Andric // Therefore we need some special-casing here. 5640b57cec5SDimitry Andric // Also note that the third operand of the conditional operator is 5650b57cec5SDimitry Andric // an assignment-expression in C++, and in C++11, we can have a 5660b57cec5SDimitry Andric // braced-init-list on the RHS of an assignment. For better diagnostics, 5670b57cec5SDimitry Andric // parse as if we were allowed braced-init-lists everywhere, and check that 5680b57cec5SDimitry Andric // they only appear on the RHS of assignments later. 5690b57cec5SDimitry Andric ExprResult RHS; 5700b57cec5SDimitry Andric bool RHSIsInitList = false; 5710b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5720b57cec5SDimitry Andric RHS = ParseBraceInitializer(); 5730b57cec5SDimitry Andric RHSIsInitList = true; 5740b57cec5SDimitry Andric } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional) 5750b57cec5SDimitry Andric RHS = ParseAssignmentExpression(); 5760b57cec5SDimitry Andric else 577480093f4SDimitry Andric RHS = ParseCastExpression(AnyCastExpr); 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric if (RHS.isInvalid()) { 5800b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5810b57cec5SDimitry Andric // printed before errors from parsing the RHS, not after. 5820b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5830b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 5840b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 5850b57cec5SDimitry Andric LHS = ExprError(); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric // Remember the precedence of this operator and get the precedence of the 5890b57cec5SDimitry Andric // operator immediately to the right of the RHS. 5900b57cec5SDimitry Andric prec::Level ThisPrec = NextTokPrec; 5910b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 5920b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // Assignment and conditional expressions are right-associative. 5950b57cec5SDimitry Andric bool isRightAssoc = ThisPrec == prec::Conditional || 5960b57cec5SDimitry Andric ThisPrec == prec::Assignment; 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric // Get the precedence of the operator to the right of the RHS. If it binds 5990b57cec5SDimitry Andric // more tightly with RHS than we do, evaluate it completely first. 6000b57cec5SDimitry Andric if (ThisPrec < NextTokPrec || 6010b57cec5SDimitry Andric (ThisPrec == NextTokPrec && isRightAssoc)) { 6020b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 6030b57cec5SDimitry Andric Diag(Tok, diag::err_init_list_bin_op) 6040b57cec5SDimitry Andric << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get()); 6050b57cec5SDimitry Andric RHS = ExprError(); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric // If this is left-associative, only parse things on the RHS that bind 6080b57cec5SDimitry Andric // more tightly than the current operator. If it is left-associative, it 6090b57cec5SDimitry Andric // is okay, to bind exactly as tightly. For example, compile A=B=C=D as 6100b57cec5SDimitry Andric // A=(B=(C=D)), where each paren is a level of recursion here. 6110b57cec5SDimitry Andric // The function takes ownership of the RHS. 6120b57cec5SDimitry Andric RHS = ParseRHSOfBinaryExpression(RHS, 6130b57cec5SDimitry Andric static_cast<prec::Level>(ThisPrec + !isRightAssoc)); 6140b57cec5SDimitry Andric RHSIsInitList = false; 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric if (RHS.isInvalid()) { 6170b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 6180b57cec5SDimitry Andric // printed before errors from ParseRHSOfBinaryExpression, not after. 6190b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 6200b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 6210b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6220b57cec5SDimitry Andric LHS = ExprError(); 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 6260b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 6300b57cec5SDimitry Andric if (ThisPrec == prec::Assignment) { 6310b57cec5SDimitry Andric Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists) 6320b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6330b57cec5SDimitry Andric } else if (ColonLoc.isValid()) { 6340b57cec5SDimitry Andric Diag(ColonLoc, diag::err_init_list_bin_op) 6350b57cec5SDimitry Andric << /*RHS*/1 << ":" 6360b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6370b57cec5SDimitry Andric LHS = ExprError(); 6380b57cec5SDimitry Andric } else { 6390b57cec5SDimitry Andric Diag(OpToken, diag::err_init_list_bin_op) 6400b57cec5SDimitry Andric << /*RHS*/1 << PP.getSpelling(OpToken) 6410b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6420b57cec5SDimitry Andric LHS = ExprError(); 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric ExprResult OrigLHS = LHS; 6470b57cec5SDimitry Andric if (!LHS.isInvalid()) { 6480b57cec5SDimitry Andric // Combine the LHS and RHS into the LHS (e.g. build AST). 6490b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 6500b57cec5SDimitry Andric // If we're using '>>' as an operator within a template 6510b57cec5SDimitry Andric // argument list (in C++98), suggest the addition of 6520b57cec5SDimitry Andric // parentheses so that the code remains well-formed in C++0x. 6530b57cec5SDimitry Andric if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) 6540b57cec5SDimitry Andric SuggestParentheses(OpToken.getLocation(), 6550b57cec5SDimitry Andric diag::warn_cxx11_right_shift_in_template_arg, 6560b57cec5SDimitry Andric SourceRange(Actions.getExprRange(LHS.get()).getBegin(), 6570b57cec5SDimitry Andric Actions.getExprRange(RHS.get()).getEnd())); 6580b57cec5SDimitry Andric 6595ffd83dbSDimitry Andric ExprResult BinOp = 6605ffd83dbSDimitry Andric Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), 6610b57cec5SDimitry Andric OpToken.getKind(), LHS.get(), RHS.get()); 6625ffd83dbSDimitry Andric if (BinOp.isInvalid()) 6635ffd83dbSDimitry Andric BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6645ffd83dbSDimitry Andric RHS.get()->getEndLoc(), 6655ffd83dbSDimitry Andric {LHS.get(), RHS.get()}); 6660b57cec5SDimitry Andric 6675ffd83dbSDimitry Andric LHS = BinOp; 6680b57cec5SDimitry Andric } else { 6695ffd83dbSDimitry Andric ExprResult CondOp = Actions.ActOnConditionalOp( 6705ffd83dbSDimitry Andric OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), 6710b57cec5SDimitry Andric RHS.get()); 6725ffd83dbSDimitry Andric if (CondOp.isInvalid()) { 6735ffd83dbSDimitry Andric std::vector<clang::Expr *> Args; 6745ffd83dbSDimitry Andric // TernaryMiddle can be null for the GNU conditional expr extension. 6755ffd83dbSDimitry Andric if (TernaryMiddle.get()) 6765ffd83dbSDimitry Andric Args = {LHS.get(), TernaryMiddle.get(), RHS.get()}; 6775ffd83dbSDimitry Andric else 6785ffd83dbSDimitry Andric Args = {LHS.get(), RHS.get()}; 6795ffd83dbSDimitry Andric CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6805ffd83dbSDimitry Andric RHS.get()->getEndLoc(), Args); 6815ffd83dbSDimitry Andric } 6825ffd83dbSDimitry Andric 6835ffd83dbSDimitry Andric LHS = CondOp; 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric // In this case, ActOnBinOp or ActOnConditionalOp performed the 6860b57cec5SDimitry Andric // CorrectDelayedTyposInExpr check. 6870b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 6880b57cec5SDimitry Andric continue; 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric // Ensure potential typos aren't left undiagnosed. 6920b57cec5SDimitry Andric if (LHS.isInvalid()) { 6930b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(OrigLHS); 6940b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6950b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 6960b57cec5SDimitry Andric } 6970b57cec5SDimitry Andric } 6980b57cec5SDimitry Andric } 6990b57cec5SDimitry Andric 700480093f4SDimitry Andric /// Parse a cast-expression, unary-expression or primary-expression, based 701480093f4SDimitry Andric /// on \p ExprType. 7020b57cec5SDimitry Andric /// 7030b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the 7040b57cec5SDimitry Andric /// operand of address-of gets special treatment due to member pointers. 7050b57cec5SDimitry Andric /// 706480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 7070b57cec5SDimitry Andric bool isAddressOfOperand, 7080b57cec5SDimitry Andric TypeCastState isTypeCast, 709480093f4SDimitry Andric bool isVectorLiteral, 710480093f4SDimitry Andric bool *NotPrimaryExpression) { 7110b57cec5SDimitry Andric bool NotCastExpr; 712480093f4SDimitry Andric ExprResult Res = ParseCastExpression(ParseKind, 7130b57cec5SDimitry Andric isAddressOfOperand, 7140b57cec5SDimitry Andric NotCastExpr, 7150b57cec5SDimitry Andric isTypeCast, 716480093f4SDimitry Andric isVectorLiteral, 717480093f4SDimitry Andric NotPrimaryExpression); 7180b57cec5SDimitry Andric if (NotCastExpr) 7190b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 7200b57cec5SDimitry Andric return Res; 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric namespace { 7240b57cec5SDimitry Andric class CastExpressionIdValidator final : public CorrectionCandidateCallback { 7250b57cec5SDimitry Andric public: 7260b57cec5SDimitry Andric CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes) 7270b57cec5SDimitry Andric : NextToken(Next), AllowNonTypes(AllowNonTypes) { 7280b57cec5SDimitry Andric WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes; 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric bool ValidateCandidate(const TypoCorrection &candidate) override { 7320b57cec5SDimitry Andric NamedDecl *ND = candidate.getCorrectionDecl(); 7330b57cec5SDimitry Andric if (!ND) 7340b57cec5SDimitry Andric return candidate.isKeyword(); 7350b57cec5SDimitry Andric 7360b57cec5SDimitry Andric if (isa<TypeDecl>(ND)) 7370b57cec5SDimitry Andric return WantTypeSpecifiers; 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate)) 7400b57cec5SDimitry Andric return false; 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period)) 7430b57cec5SDimitry Andric return true; 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric for (auto *C : candidate) { 7460b57cec5SDimitry Andric NamedDecl *ND = C->getUnderlyingDecl(); 7470b57cec5SDimitry Andric if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND)) 7480b57cec5SDimitry Andric return true; 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric return false; 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric std::unique_ptr<CorrectionCandidateCallback> clone() override { 754a7dea167SDimitry Andric return std::make_unique<CastExpressionIdValidator>(*this); 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric private: 7580b57cec5SDimitry Andric Token NextToken; 7590b57cec5SDimitry Andric bool AllowNonTypes; 7600b57cec5SDimitry Andric }; 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630fca6ea1SDimitry Andric bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II, 7640fca6ea1SDimitry Andric tok::TokenKind *Kind) { 7650fca6ea1SDimitry Andric if (RevertibleTypeTraits.empty()) { 766*36b606aeSDimitry Andric // Revertible type trait is a feature for backwards compatibility with older 767*36b606aeSDimitry Andric // standard libraries that declare their own structs with the same name as 768*36b606aeSDimitry Andric // the builtins listed below. New builtins should NOT be added to this list. 7690fca6ea1SDimitry Andric #define RTT_JOIN(X, Y) X##Y 7700fca6ea1SDimitry Andric #define REVERTIBLE_TYPE_TRAIT(Name) \ 7710fca6ea1SDimitry Andric RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] = RTT_JOIN(tok::kw_, Name) 7720fca6ea1SDimitry Andric 7730fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_abstract); 7740fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_aggregate); 7750fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_arithmetic); 7760fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_array); 7770fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_assignable); 7780fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_base_of); 7790fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_bounded_array); 7800fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_class); 7810fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_complete_type); 7820fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_compound); 7830fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_const); 7840fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_constructible); 7850fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible); 7860fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible_to); 7870fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_destructible); 7880fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_empty); 7890fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_enum); 7900fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_floating_point); 7910fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_final); 7920fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_function); 7930fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_fundamental); 7940fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_integral); 7950fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_interface_class); 7960fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_literal); 7970fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); 7980fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); 7990fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); 8000fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); 8010fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_pointer); 8020fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); 8030fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); 8040fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); 8050fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nullptr); 8060fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_object); 8070fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pod); 8080fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pointer); 8090fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_polymorphic); 8100fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_reference); 8110fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_referenceable); 8120fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); 8130fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); 8140fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_same); 8150fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scalar); 8160fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); 8170fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_sealed); 8180fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_signed); 8190fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_standard_layout); 8200fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivial); 8210fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); 8220fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); 8230fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); 8240fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); 8250fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_union); 8260fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unsigned); 8270fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_void); 8280fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_volatile); 8290fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary); 8300fca6ea1SDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ 8310fca6ea1SDimitry Andric REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait)); 8320fca6ea1SDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 8330fca6ea1SDimitry Andric #undef REVERTIBLE_TYPE_TRAIT 8340fca6ea1SDimitry Andric #undef RTT_JOIN 8350fca6ea1SDimitry Andric } 8360fca6ea1SDimitry Andric llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known = 8370fca6ea1SDimitry Andric RevertibleTypeTraits.find(II); 8380fca6ea1SDimitry Andric if (Known != RevertibleTypeTraits.end()) { 8390fca6ea1SDimitry Andric if (Kind) 8400fca6ea1SDimitry Andric *Kind = Known->second; 8410fca6ea1SDimitry Andric return true; 8420fca6ea1SDimitry Andric } 8430fca6ea1SDimitry Andric return false; 8440fca6ea1SDimitry Andric } 8450fca6ea1SDimitry Andric 846*36b606aeSDimitry Andric ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() { 847*36b606aeSDimitry Andric SourceLocation Loc = ConsumeToken(); 848*36b606aeSDimitry Andric 849*36b606aeSDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 850*36b606aeSDimitry Andric if (T.expectAndConsume()) 851*36b606aeSDimitry Andric return ExprError(); 852*36b606aeSDimitry Andric 853*36b606aeSDimitry Andric TypeResult Ty = ParseTypeName(); 854*36b606aeSDimitry Andric if (Ty.isInvalid()) { 855*36b606aeSDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 856*36b606aeSDimitry Andric return ExprError(); 857*36b606aeSDimitry Andric } 858*36b606aeSDimitry Andric 859*36b606aeSDimitry Andric SourceLocation EndLoc = Tok.getLocation(); 860*36b606aeSDimitry Andric T.consumeClose(); 861*36b606aeSDimitry Andric return Actions.ActOnUnaryExprOrTypeTraitExpr( 862*36b606aeSDimitry Andric Loc, UETT_PtrAuthTypeDiscriminator, 863*36b606aeSDimitry Andric /*isType=*/true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc)); 864*36b606aeSDimitry Andric } 865*36b606aeSDimitry Andric 8660b57cec5SDimitry Andric /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse 8670b57cec5SDimitry Andric /// a unary-expression. 8680b57cec5SDimitry Andric /// 8690b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the operand 8700b57cec5SDimitry Andric /// of address-of gets special treatment due to member pointers. NotCastExpr 8710b57cec5SDimitry Andric /// is set to true if the token is not the start of a cast-expression, and no 8720b57cec5SDimitry Andric /// diagnostic is emitted in this case and no tokens are consumed. 8730b57cec5SDimitry Andric /// 8740b57cec5SDimitry Andric /// \verbatim 8750b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 8760b57cec5SDimitry Andric /// unary-expression 8770b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 8780b57cec5SDimitry Andric /// 8790b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 8800b57cec5SDimitry Andric /// postfix-expression 8810b57cec5SDimitry Andric /// '++' unary-expression 8820b57cec5SDimitry Andric /// '--' unary-expression 8830b57cec5SDimitry Andric /// [Coro] 'co_await' cast-expression 8840b57cec5SDimitry Andric /// unary-operator cast-expression 8850b57cec5SDimitry Andric /// 'sizeof' unary-expression 8860b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 8870b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 8880b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 8890b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 8900b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 8910b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 8920b57cec5SDimitry Andric /// [GNU] '&&' identifier 8930b57cec5SDimitry Andric /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7] 8940b57cec5SDimitry Andric /// [C++] new-expression 8950b57cec5SDimitry Andric /// [C++] delete-expression 8960b57cec5SDimitry Andric /// 8970b57cec5SDimitry Andric /// unary-operator: one of 8980b57cec5SDimitry Andric /// '&' '*' '+' '-' '~' '!' 8990b57cec5SDimitry Andric /// [GNU] '__extension__' '__real' '__imag' 9000b57cec5SDimitry Andric /// 9010b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 9020b57cec5SDimitry Andric /// [C99] identifier 9030b57cec5SDimitry Andric /// [C++] id-expression 9040b57cec5SDimitry Andric /// constant 9050b57cec5SDimitry Andric /// string-literal 9060b57cec5SDimitry Andric /// [C++] boolean-literal [C++ 2.13.5] 9070b57cec5SDimitry Andric /// [C++11] 'nullptr' [C++11 2.14.7] 9080b57cec5SDimitry Andric /// [C++11] user-defined-literal 9090b57cec5SDimitry Andric /// '(' expression ')' 9100b57cec5SDimitry Andric /// [C11] generic-selection 91155e4f9d5SDimitry Andric /// [C++2a] requires-expression 9120b57cec5SDimitry Andric /// '__func__' [C99 6.4.2.2] 9130b57cec5SDimitry Andric /// [GNU] '__FUNCTION__' 9140b57cec5SDimitry Andric /// [MS] '__FUNCDNAME__' 9150b57cec5SDimitry Andric /// [MS] 'L__FUNCTION__' 9160b57cec5SDimitry Andric /// [MS] '__FUNCSIG__' 9170b57cec5SDimitry Andric /// [MS] 'L__FUNCSIG__' 9180b57cec5SDimitry Andric /// [GNU] '__PRETTY_FUNCTION__' 9190b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' 9200b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 9210b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 9220b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 9230b57cec5SDimitry Andric /// assign-expr ')' 9240b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 92506c3fb27SDimitry Andric /// [CLANG] '__builtin_FILE_NAME' '(' ')' 9260b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 92706c3fb27SDimitry Andric /// [MS] '__builtin_FUNCSIG' '(' ')' 9280b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 9290b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 93081ad6265SDimitry Andric /// [GNU] '__builtin_source_location' '(' ')' 9310b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 9320b57cec5SDimitry Andric /// [GNU] '__null' 9330b57cec5SDimitry Andric /// [OBJC] '[' objc-message-expr ']' 9340b57cec5SDimitry Andric /// [OBJC] '\@selector' '(' objc-selector-arg ')' 9350b57cec5SDimitry Andric /// [OBJC] '\@protocol' '(' identifier ')' 9360b57cec5SDimitry Andric /// [OBJC] '\@encode' '(' type-name ')' 9370b57cec5SDimitry Andric /// [OBJC] objc-string-literal 9380b57cec5SDimitry Andric /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 9390b57cec5SDimitry Andric /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] 9400b57cec5SDimitry Andric /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 9410b57cec5SDimitry Andric /// [C++11] typename-specifier braced-init-list [C++11 5.2.3] 9420b57cec5SDimitry Andric /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 9430b57cec5SDimitry Andric /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 9440b57cec5SDimitry Andric /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 9450b57cec5SDimitry Andric /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 9460b57cec5SDimitry Andric /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 9470b57cec5SDimitry Andric /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 9480b57cec5SDimitry Andric /// [C++] 'this' [C++ 9.3.2] 9490b57cec5SDimitry Andric /// [G++] unary-type-trait '(' type-id ')' 9500b57cec5SDimitry Andric /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 9510b57cec5SDimitry Andric /// [EMBT] array-type-trait '(' type-id ',' integer ')' 9520b57cec5SDimitry Andric /// [clang] '^' block-literal 9530b57cec5SDimitry Andric /// 9540b57cec5SDimitry Andric /// constant: [C99 6.4.4] 9550b57cec5SDimitry Andric /// integer-constant 9560b57cec5SDimitry Andric /// floating-constant 9570b57cec5SDimitry Andric /// enumeration-constant -> identifier 9580b57cec5SDimitry Andric /// character-constant 9590b57cec5SDimitry Andric /// 9600b57cec5SDimitry Andric /// id-expression: [C++ 5.1] 9610b57cec5SDimitry Andric /// unqualified-id 9620b57cec5SDimitry Andric /// qualified-id 9630b57cec5SDimitry Andric /// 9640b57cec5SDimitry Andric /// unqualified-id: [C++ 5.1] 9650b57cec5SDimitry Andric /// identifier 9660b57cec5SDimitry Andric /// operator-function-id 9670b57cec5SDimitry Andric /// conversion-function-id 9680b57cec5SDimitry Andric /// '~' class-name 9690b57cec5SDimitry Andric /// template-id 9700b57cec5SDimitry Andric /// 9710b57cec5SDimitry Andric /// new-expression: [C++ 5.3.4] 9720b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 9730b57cec5SDimitry Andric /// new-initializer[opt] 9740b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 9750b57cec5SDimitry Andric /// new-initializer[opt] 9760b57cec5SDimitry Andric /// 9770b57cec5SDimitry Andric /// delete-expression: [C++ 5.3.5] 9780b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 9790b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 9800b57cec5SDimitry Andric /// 9810b57cec5SDimitry Andric /// [GNU/Embarcadero] unary-type-trait: 9820b57cec5SDimitry Andric /// '__is_arithmetic' 9830b57cec5SDimitry Andric /// '__is_floating_point' 9840b57cec5SDimitry Andric /// '__is_integral' 9850b57cec5SDimitry Andric /// '__is_lvalue_expr' 9860b57cec5SDimitry Andric /// '__is_rvalue_expr' 9870b57cec5SDimitry Andric /// '__is_complete_type' 9880b57cec5SDimitry Andric /// '__is_void' 9890b57cec5SDimitry Andric /// '__is_array' 9900b57cec5SDimitry Andric /// '__is_function' 9910b57cec5SDimitry Andric /// '__is_reference' 9920b57cec5SDimitry Andric /// '__is_lvalue_reference' 9930b57cec5SDimitry Andric /// '__is_rvalue_reference' 9940b57cec5SDimitry Andric /// '__is_fundamental' 9950b57cec5SDimitry Andric /// '__is_object' 9960b57cec5SDimitry Andric /// '__is_scalar' 9970b57cec5SDimitry Andric /// '__is_compound' 9980b57cec5SDimitry Andric /// '__is_pointer' 9990b57cec5SDimitry Andric /// '__is_member_object_pointer' 10000b57cec5SDimitry Andric /// '__is_member_function_pointer' 10010b57cec5SDimitry Andric /// '__is_member_pointer' 10020b57cec5SDimitry Andric /// '__is_const' 10030b57cec5SDimitry Andric /// '__is_volatile' 10040b57cec5SDimitry Andric /// '__is_trivial' 10050b57cec5SDimitry Andric /// '__is_standard_layout' 10060b57cec5SDimitry Andric /// '__is_signed' 10070b57cec5SDimitry Andric /// '__is_unsigned' 10080b57cec5SDimitry Andric /// 10090b57cec5SDimitry Andric /// [GNU] unary-type-trait: 10100b57cec5SDimitry Andric /// '__has_nothrow_assign' 10110b57cec5SDimitry Andric /// '__has_nothrow_copy' 10120b57cec5SDimitry Andric /// '__has_nothrow_constructor' 10130b57cec5SDimitry Andric /// '__has_trivial_assign' [TODO] 10140b57cec5SDimitry Andric /// '__has_trivial_copy' [TODO] 10150b57cec5SDimitry Andric /// '__has_trivial_constructor' 10160b57cec5SDimitry Andric /// '__has_trivial_destructor' 10170b57cec5SDimitry Andric /// '__has_virtual_destructor' 10180b57cec5SDimitry Andric /// '__is_abstract' [TODO] 10190b57cec5SDimitry Andric /// '__is_class' 10200b57cec5SDimitry Andric /// '__is_empty' [TODO] 10210b57cec5SDimitry Andric /// '__is_enum' 10220b57cec5SDimitry Andric /// '__is_final' 10230b57cec5SDimitry Andric /// '__is_pod' 10240b57cec5SDimitry Andric /// '__is_polymorphic' 10250b57cec5SDimitry Andric /// '__is_sealed' [MS] 10260b57cec5SDimitry Andric /// '__is_trivial' 10270b57cec5SDimitry Andric /// '__is_union' 10280b57cec5SDimitry Andric /// '__has_unique_object_representations' 10290b57cec5SDimitry Andric /// 10300b57cec5SDimitry Andric /// [Clang] unary-type-trait: 10310b57cec5SDimitry Andric /// '__is_aggregate' 10320b57cec5SDimitry Andric /// '__trivially_copyable' 10330b57cec5SDimitry Andric /// 10340b57cec5SDimitry Andric /// binary-type-trait: 10350b57cec5SDimitry Andric /// [GNU] '__is_base_of' 10360b57cec5SDimitry Andric /// [MS] '__is_convertible_to' 10370b57cec5SDimitry Andric /// '__is_convertible' 10380b57cec5SDimitry Andric /// '__is_same' 10390b57cec5SDimitry Andric /// 10400b57cec5SDimitry Andric /// [Embarcadero] array-type-trait: 10410b57cec5SDimitry Andric /// '__array_rank' 10420b57cec5SDimitry Andric /// '__array_extent' 10430b57cec5SDimitry Andric /// 10440b57cec5SDimitry Andric /// [Embarcadero] expression-trait: 10450b57cec5SDimitry Andric /// '__is_lvalue_expr' 10460b57cec5SDimitry Andric /// '__is_rvalue_expr' 10470b57cec5SDimitry Andric /// \endverbatim 10480b57cec5SDimitry Andric /// 1049480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 10500b57cec5SDimitry Andric bool isAddressOfOperand, 10510b57cec5SDimitry Andric bool &NotCastExpr, 10520b57cec5SDimitry Andric TypeCastState isTypeCast, 1053480093f4SDimitry Andric bool isVectorLiteral, 1054480093f4SDimitry Andric bool *NotPrimaryExpression) { 10550b57cec5SDimitry Andric ExprResult Res; 10560b57cec5SDimitry Andric tok::TokenKind SavedKind = Tok.getKind(); 10570b57cec5SDimitry Andric auto SavedType = PreferredType; 10580b57cec5SDimitry Andric NotCastExpr = false; 10590b57cec5SDimitry Andric 10605ffd83dbSDimitry Andric // Are postfix-expression suffix operators permitted after this 10615ffd83dbSDimitry Andric // cast-expression? If not, and we find some, we'll parse them anyway and 10625ffd83dbSDimitry Andric // diagnose them. 10635ffd83dbSDimitry Andric bool AllowSuffix = true; 10645ffd83dbSDimitry Andric 10650b57cec5SDimitry Andric // This handles all of cast-expression, unary-expression, postfix-expression, 10660b57cec5SDimitry Andric // and primary-expression. We handle them together like this for efficiency 10670b57cec5SDimitry Andric // and to simplify handling of an expression starting with a '(' token: which 10680b57cec5SDimitry Andric // may be one of a parenthesized expression, cast-expression, compound literal 10690b57cec5SDimitry Andric // expression, or statement expression. 10700b57cec5SDimitry Andric // 10710b57cec5SDimitry Andric // If the parsed tokens consist of a primary-expression, the cases below 10720b57cec5SDimitry Andric // break out of the switch; at the end we call ParsePostfixExpressionSuffix 10730b57cec5SDimitry Andric // to handle the postfix expression suffixes. Cases that cannot be followed 10745ffd83dbSDimitry Andric // by postfix exprs should set AllowSuffix to false. 10750b57cec5SDimitry Andric switch (SavedKind) { 10760b57cec5SDimitry Andric case tok::l_paren: { 1077480093f4SDimitry Andric // If this expression is limited to being a unary-expression, the paren can 10780b57cec5SDimitry Andric // not start a cast expression. 1079480093f4SDimitry Andric ParenParseOption ParenExprType; 1080480093f4SDimitry Andric switch (ParseKind) { 1081480093f4SDimitry Andric case CastParseKind::UnaryExprOnly: 1082bdd1243dSDimitry Andric assert(getLangOpts().CPlusPlus && "not possible to get here in C"); 1083bdd1243dSDimitry Andric [[fallthrough]]; 1084480093f4SDimitry Andric case CastParseKind::AnyCastExpr: 1085480093f4SDimitry Andric ParenExprType = ParenParseOption::CastExpr; 1086480093f4SDimitry Andric break; 1087480093f4SDimitry Andric case CastParseKind::PrimaryExprOnly: 1088480093f4SDimitry Andric ParenExprType = FoldExpr; 1089480093f4SDimitry Andric break; 1090480093f4SDimitry Andric } 10910b57cec5SDimitry Andric ParsedType CastTy; 10920b57cec5SDimitry Andric SourceLocation RParenLoc; 10930b57cec5SDimitry Andric Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 10940b57cec5SDimitry Andric isTypeCast == IsTypeCast, CastTy, RParenLoc); 10950b57cec5SDimitry Andric 10965ffd83dbSDimitry Andric // FIXME: What should we do if a vector literal is followed by a 10975ffd83dbSDimitry Andric // postfix-expression suffix? Usually postfix operators are permitted on 10985ffd83dbSDimitry Andric // literals. 10990b57cec5SDimitry Andric if (isVectorLiteral) 11000b57cec5SDimitry Andric return Res; 11010b57cec5SDimitry Andric 11020b57cec5SDimitry Andric switch (ParenExprType) { 11030b57cec5SDimitry Andric case SimpleExpr: break; // Nothing else to do. 11040b57cec5SDimitry Andric case CompoundStmt: break; // Nothing else to do. 11050b57cec5SDimitry Andric case CompoundLiteral: 11060b57cec5SDimitry Andric // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 11070b57cec5SDimitry Andric // postfix-expression exist, parse them now. 11080b57cec5SDimitry Andric break; 11090b57cec5SDimitry Andric case CastExpr: 11100b57cec5SDimitry Andric // We have parsed the cast-expression and no postfix-expr pieces are 11110b57cec5SDimitry Andric // following. 11120b57cec5SDimitry Andric return Res; 11130b57cec5SDimitry Andric case FoldExpr: 11140b57cec5SDimitry Andric // We only parsed a fold-expression. There might be postfix-expr pieces 11150b57cec5SDimitry Andric // afterwards; parse them now. 11160b57cec5SDimitry Andric break; 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric break; 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric // primary-expression 11230b57cec5SDimitry Andric case tok::numeric_constant: 11240fca6ea1SDimitry Andric case tok::binary_data: 11250b57cec5SDimitry Andric // constant: integer-constant 11260b57cec5SDimitry Andric // constant: floating-constant 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope()); 11290b57cec5SDimitry Andric ConsumeToken(); 11300b57cec5SDimitry Andric break; 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric case tok::kw_true: 11330b57cec5SDimitry Andric case tok::kw_false: 11340b57cec5SDimitry Andric Res = ParseCXXBoolLiteral(); 11350b57cec5SDimitry Andric break; 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric case tok::kw___objc_yes: 11380b57cec5SDimitry Andric case tok::kw___objc_no: 11395ffd83dbSDimitry Andric Res = ParseObjCBoolLiteral(); 11405ffd83dbSDimitry Andric break; 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric case tok::kw_nullptr: 1143bdd1243dSDimitry Andric if (getLangOpts().CPlusPlus) 11440b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_nullptr); 1145bdd1243dSDimitry Andric else 11465f757f3fSDimitry Andric Diag(Tok, getLangOpts().C23 ? diag::warn_c23_compat_keyword 114706c3fb27SDimitry Andric : diag::ext_c_nullptr) << Tok.getName(); 1148bdd1243dSDimitry Andric 11495ffd83dbSDimitry Andric Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 11505ffd83dbSDimitry Andric break; 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric case tok::annot_primary_expr: 1153e8d8bef9SDimitry Andric case tok::annot_overload_set: 11540b57cec5SDimitry Andric Res = getExprAnnotation(Tok); 1155e8d8bef9SDimitry Andric if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set) 1156e8d8bef9SDimitry Andric Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get()); 11570b57cec5SDimitry Andric ConsumeAnnotationToken(); 11580b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 11590b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 11600b57cec5SDimitry Andric break; 11610b57cec5SDimitry Andric 1162a7dea167SDimitry Andric case tok::annot_non_type: 1163a7dea167SDimitry Andric case tok::annot_non_type_dependent: 1164a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 1165a7dea167SDimitry Andric CXXScopeSpec SS; 1166a7dea167SDimitry Andric Token Replacement; 1167a7dea167SDimitry Andric Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 1168a7dea167SDimitry Andric assert(!Res.isUnset() && 1169a7dea167SDimitry Andric "should not perform typo correction on annotation token"); 1170a7dea167SDimitry Andric break; 1171a7dea167SDimitry Andric } 1172a7dea167SDimitry Andric 11730fca6ea1SDimitry Andric case tok::annot_embed: { 11740fca6ea1SDimitry Andric injectEmbedTokens(); 11750fca6ea1SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 11760fca6ea1SDimitry Andric isVectorLiteral, NotPrimaryExpression); 11770fca6ea1SDimitry Andric } 11780fca6ea1SDimitry Andric 11790b57cec5SDimitry Andric case tok::kw___super: 11800b57cec5SDimitry Andric case tok::kw_decltype: 11810b57cec5SDimitry Andric // Annotate the token and tail recurse. 11820b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 11830b57cec5SDimitry Andric return ExprError(); 11840b57cec5SDimitry Andric assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); 1185480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1186480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 11870b57cec5SDimitry Andric 1188bdd1243dSDimitry Andric case tok::identifier: 1189bdd1243dSDimitry Andric ParseIdentifier: { // primary-expression: identifier 11900b57cec5SDimitry Andric // unqualified-id: identifier 11910b57cec5SDimitry Andric // constant: enumeration-constant 11920b57cec5SDimitry Andric // Turn a potentially qualified name into a annot_typename or 11930b57cec5SDimitry Andric // annot_cxxscope if it would be valid. This handles things like x::y, etc. 11940b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) { 11950b57cec5SDimitry Andric // Avoid the unnecessary parse-time lookup in the common case 11960b57cec5SDimitry Andric // where the syntax forbids a type. 11970fca6ea1SDimitry Andric Token Next = NextToken(); 11980fca6ea1SDimitry Andric 11990fca6ea1SDimitry Andric if (Next.is(tok::ellipsis) && Tok.is(tok::identifier) && 12000fca6ea1SDimitry Andric GetLookAheadToken(2).is(tok::l_square)) { 12010fca6ea1SDimitry Andric // Annotate the token and tail recurse. 12020fca6ea1SDimitry Andric // If the token is not annotated, then it might be an expression pack 12030fca6ea1SDimitry Andric // indexing 12040fca6ea1SDimitry Andric if (!TryAnnotateTypeOrScopeToken() && 12050fca6ea1SDimitry Andric Tok.is(tok::annot_pack_indexing_type)) 12060fca6ea1SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 12070fca6ea1SDimitry Andric isVectorLiteral, NotPrimaryExpression); 12080fca6ea1SDimitry Andric } 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric // If this identifier was reverted from a token ID, and the next token 12110b57cec5SDimitry Andric // is a parenthesis, this is likely to be a use of a type trait. Check 12120b57cec5SDimitry Andric // those tokens. 12130fca6ea1SDimitry Andric else if (Next.is(tok::l_paren) && Tok.is(tok::identifier) && 12140b57cec5SDimitry Andric Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { 12150b57cec5SDimitry Andric IdentifierInfo *II = Tok.getIdentifierInfo(); 12160fca6ea1SDimitry Andric tok::TokenKind Kind; 12170fca6ea1SDimitry Andric if (isRevertibleTypeTrait(II, &Kind)) { 12180fca6ea1SDimitry Andric Tok.setKind(Kind); 1219480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1220480093f4SDimitry Andric NotCastExpr, isTypeCast, 1221480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 12220b57cec5SDimitry Andric } 12230b57cec5SDimitry Andric } 12240b57cec5SDimitry Andric 12250fca6ea1SDimitry Andric else if ((!ColonIsSacred && Next.is(tok::colon)) || 12260b57cec5SDimitry Andric Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren, 12270b57cec5SDimitry Andric tok::l_brace)) { 12280b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 12290b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 12300b57cec5SDimitry Andric return ExprError(); 12310b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) 1232480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1233480093f4SDimitry Andric NotCastExpr, isTypeCast, 1234480093f4SDimitry Andric isVectorLiteral, 1235480093f4SDimitry Andric NotPrimaryExpression); 12360b57cec5SDimitry Andric } 12370b57cec5SDimitry Andric } 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric // Consume the identifier so that we can see if it is followed by a '(' or 12400b57cec5SDimitry Andric // '.'. 12410b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 12420b57cec5SDimitry Andric SourceLocation ILoc = ConsumeToken(); 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric // Support 'Class.property' and 'super.property' notation. 12450b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.is(tok::period) && 12460b57cec5SDimitry Andric (Actions.getTypeName(II, ILoc, getCurScope()) || 12470b57cec5SDimitry Andric // Allow the base to be 'super' if in an objc-method. 12480b57cec5SDimitry Andric (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { 12490b57cec5SDimitry Andric ConsumeToken(); 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && &II != Ident_super) { 1252fe6060f1SDimitry Andric cutOffParsing(); 12530fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteObjCClassPropertyRefExpr( 12540b57cec5SDimitry Andric getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); 12550b57cec5SDimitry Andric return ExprError(); 12560b57cec5SDimitry Andric } 12570b57cec5SDimitry Andric // Allow either an identifier or the keyword 'class' (in C++). 12580b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) && 12590b57cec5SDimitry Andric !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { 12600b57cec5SDimitry Andric Diag(Tok, diag::err_expected_property_name); 12610b57cec5SDimitry Andric return ExprError(); 12620b57cec5SDimitry Andric } 12630b57cec5SDimitry Andric IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 12640b57cec5SDimitry Andric SourceLocation PropertyLoc = ConsumeToken(); 12650b57cec5SDimitry Andric 12660fca6ea1SDimitry Andric Res = Actions.ObjC().ActOnClassPropertyRefExpr(II, PropertyName, ILoc, 12670fca6ea1SDimitry Andric PropertyLoc); 12680b57cec5SDimitry Andric break; 12690b57cec5SDimitry Andric } 12700b57cec5SDimitry Andric 12710b57cec5SDimitry Andric // In an Objective-C method, if we have "super" followed by an identifier, 12720b57cec5SDimitry Andric // the token sequence is ill-formed. However, if there's a ':' or ']' after 12730b57cec5SDimitry Andric // that identifier, this is probably a message send with a missing open 12740b57cec5SDimitry Andric // bracket. Treat it as such. 12750b57cec5SDimitry Andric if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression && 12760b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 12770b57cec5SDimitry Andric ((Tok.is(tok::identifier) && 12780b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || 12790b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12800b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr, 12810b57cec5SDimitry Andric nullptr); 12820b57cec5SDimitry Andric break; 12830b57cec5SDimitry Andric } 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric // If we have an Objective-C class name followed by an identifier 12860b57cec5SDimitry Andric // and either ':' or ']', this is an Objective-C class message 12870b57cec5SDimitry Andric // send that's missing the opening '['. Recovery 12880b57cec5SDimitry Andric // appropriately. Also take this path if we're performing code 12890b57cec5SDimitry Andric // completion after an Objective-C class name. 12900b57cec5SDimitry Andric if (getLangOpts().ObjC && 12910b57cec5SDimitry Andric ((Tok.is(tok::identifier) && !InMessageExpression) || 12920b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12930b57cec5SDimitry Andric const Token& Next = NextToken(); 12940b57cec5SDimitry Andric if (Tok.is(tok::code_completion) || 12950b57cec5SDimitry Andric Next.is(tok::colon) || Next.is(tok::r_square)) 12960b57cec5SDimitry Andric if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) 12970b57cec5SDimitry Andric if (Typ.get()->isObjCObjectOrInterfaceType()) { 12980b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 12990b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 13000b57cec5SDimitry Andric DS.SetRangeStart(ILoc); 13010b57cec5SDimitry Andric DS.SetRangeEnd(ILoc); 13020b57cec5SDimitry Andric const char *PrevSpec = nullptr; 13030b57cec5SDimitry Andric unsigned DiagID; 13040b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, 13050b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 13060b57cec5SDimitry Andric 130781ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 130881ad6265SDimitry Andric DeclaratorContext::TypeName); 13097a6dacacSDimitry Andric TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo); 13100b57cec5SDimitry Andric if (Ty.isInvalid()) 13110b57cec5SDimitry Andric break; 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), 13140b57cec5SDimitry Andric SourceLocation(), 13150b57cec5SDimitry Andric Ty.get(), nullptr); 13160b57cec5SDimitry Andric break; 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric } 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric // Make sure to pass down the right value for isAddressOfOperand. 13210b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 13220b57cec5SDimitry Andric isAddressOfOperand = false; 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 13250b57cec5SDimitry Andric // need to know whether or not this identifier is a function designator or 13260b57cec5SDimitry Andric // not. 13270b57cec5SDimitry Andric UnqualifiedId Name; 13280b57cec5SDimitry Andric CXXScopeSpec ScopeSpec; 13290b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 13300b57cec5SDimitry Andric Token Replacement; 13310b57cec5SDimitry Andric CastExpressionIdValidator Validator( 13320b57cec5SDimitry Andric /*Next=*/Tok, 13330b57cec5SDimitry Andric /*AllowTypes=*/isTypeCast != NotTypeCast, 13340b57cec5SDimitry Andric /*AllowNonTypes=*/isTypeCast != IsTypeCast); 13350b57cec5SDimitry Andric Validator.IsAddressOfOperand = isAddressOfOperand; 13360b57cec5SDimitry Andric if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) { 13370b57cec5SDimitry Andric Validator.WantExpressionKeywords = false; 13380b57cec5SDimitry Andric Validator.WantRemainingKeywords = false; 13390b57cec5SDimitry Andric } else { 13400b57cec5SDimitry Andric Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren); 13410b57cec5SDimitry Andric } 13420b57cec5SDimitry Andric Name.setIdentifier(&II, ILoc); 13430b57cec5SDimitry Andric Res = Actions.ActOnIdExpression( 13440b57cec5SDimitry Andric getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), 13450b57cec5SDimitry Andric isAddressOfOperand, &Validator, 13460b57cec5SDimitry Andric /*IsInlineAsmIdentifier=*/false, 13470b57cec5SDimitry Andric Tok.is(tok::r_paren) ? nullptr : &Replacement); 13480b57cec5SDimitry Andric if (!Res.isInvalid() && Res.isUnset()) { 13490b57cec5SDimitry Andric UnconsumeToken(Replacement); 1350480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1351480093f4SDimitry Andric NotCastExpr, isTypeCast, 1352480093f4SDimitry Andric /*isVectorLiteral=*/false, 1353480093f4SDimitry Andric NotPrimaryExpression); 13540b57cec5SDimitry Andric } 13550fca6ea1SDimitry Andric Res = tryParseCXXPackIndexingExpression(Res); 13560b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 13570b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 13580b57cec5SDimitry Andric break; 13590b57cec5SDimitry Andric } 13600b57cec5SDimitry Andric case tok::char_constant: // constant: character-constant 13610b57cec5SDimitry Andric case tok::wide_char_constant: 13620b57cec5SDimitry Andric case tok::utf8_char_constant: 13630b57cec5SDimitry Andric case tok::utf16_char_constant: 13640b57cec5SDimitry Andric case tok::utf32_char_constant: 13650b57cec5SDimitry Andric Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope()); 13660b57cec5SDimitry Andric ConsumeToken(); 13670b57cec5SDimitry Andric break; 13680b57cec5SDimitry Andric case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 13690b57cec5SDimitry Andric case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 13700b57cec5SDimitry Andric case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] 13710b57cec5SDimitry Andric case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS] 13720b57cec5SDimitry Andric case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] 13730b57cec5SDimitry Andric case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] 13740b57cec5SDimitry Andric case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 13755f757f3fSDimitry Andric // Function local predefined macros are represented by PredefinedExpr except 13765f757f3fSDimitry Andric // when Microsoft extensions are enabled and one of these macros is adjacent 13775f757f3fSDimitry Andric // to a string literal or another one of these macros. 13785f757f3fSDimitry Andric if (!(getLangOpts().MicrosoftExt && 13795f757f3fSDimitry Andric tokenIsLikeStringLiteral(Tok, getLangOpts()) && 13805f757f3fSDimitry Andric tokenIsLikeStringLiteral(NextToken(), getLangOpts()))) { 13810b57cec5SDimitry Andric Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 13820b57cec5SDimitry Andric ConsumeToken(); 13830b57cec5SDimitry Andric break; 13845f757f3fSDimitry Andric } 13855f757f3fSDimitry Andric [[fallthrough]]; // treat MS function local macros as concatenable strings 13860b57cec5SDimitry Andric case tok::string_literal: // primary-expression: string-literal 13870b57cec5SDimitry Andric case tok::wide_string_literal: 13880b57cec5SDimitry Andric case tok::utf8_string_literal: 13890b57cec5SDimitry Andric case tok::utf16_string_literal: 13900b57cec5SDimitry Andric case tok::utf32_string_literal: 13910b57cec5SDimitry Andric Res = ParseStringLiteralExpression(true); 13920b57cec5SDimitry Andric break; 13930b57cec5SDimitry Andric case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1] 13940b57cec5SDimitry Andric Res = ParseGenericSelectionExpression(); 13950b57cec5SDimitry Andric break; 13960b57cec5SDimitry Andric case tok::kw___builtin_available: 13975ffd83dbSDimitry Andric Res = ParseAvailabilityCheckExpr(Tok.getLocation()); 13985ffd83dbSDimitry Andric break; 13990b57cec5SDimitry Andric case tok::kw___builtin_va_arg: 14000b57cec5SDimitry Andric case tok::kw___builtin_offsetof: 14010b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: 14020b57cec5SDimitry Andric case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() 14030b57cec5SDimitry Andric case tok::kw___builtin_convertvector: 14040b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 14050b57cec5SDimitry Andric case tok::kw___builtin_FILE: 140606c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 14070b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 140806c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 14090b57cec5SDimitry Andric case tok::kw___builtin_LINE: 141081ad6265SDimitry Andric case tok::kw___builtin_source_location: 1411480093f4SDimitry Andric if (NotPrimaryExpression) 1412480093f4SDimitry Andric *NotPrimaryExpression = true; 14135ffd83dbSDimitry Andric // This parses the complete suffix; we can return early. 14140b57cec5SDimitry Andric return ParseBuiltinPrimaryExpression(); 14150b57cec5SDimitry Andric case tok::kw___null: 14165ffd83dbSDimitry Andric Res = Actions.ActOnGNUNullExpr(ConsumeToken()); 14175ffd83dbSDimitry Andric break; 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric case tok::plusplus: // unary-expression: '++' unary-expression [C99] 14200b57cec5SDimitry Andric case tok::minusminus: { // unary-expression: '--' unary-expression [C99] 1421480093f4SDimitry Andric if (NotPrimaryExpression) 1422480093f4SDimitry Andric *NotPrimaryExpression = true; 14230b57cec5SDimitry Andric // C++ [expr.unary] has: 14240b57cec5SDimitry Andric // unary-expression: 14250b57cec5SDimitry Andric // ++ cast-expression 14260b57cec5SDimitry Andric // -- cast-expression 14270b57cec5SDimitry Andric Token SavedTok = Tok; 14280b57cec5SDimitry Andric ConsumeToken(); 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(), 14310b57cec5SDimitry Andric SavedTok.getLocation()); 14320b57cec5SDimitry Andric // One special case is implicitly handled here: if the preceding tokens are 14330b57cec5SDimitry Andric // an ambiguous cast expression, such as "(T())++", then we recurse to 14340b57cec5SDimitry Andric // determine whether the '++' is prefix or postfix. 1435480093f4SDimitry Andric Res = ParseCastExpression(getLangOpts().CPlusPlus ? 1436480093f4SDimitry Andric UnaryExprOnly : AnyCastExpr, 14370b57cec5SDimitry Andric /*isAddressOfOperand*/false, NotCastExpr, 14380b57cec5SDimitry Andric NotTypeCast); 14390b57cec5SDimitry Andric if (NotCastExpr) { 14400b57cec5SDimitry Andric // If we return with NotCastExpr = true, we must not consume any tokens, 14410b57cec5SDimitry Andric // so put the token back where we found it. 14420b57cec5SDimitry Andric assert(Res.isInvalid()); 14430b57cec5SDimitry Andric UnconsumeToken(SavedTok); 14440b57cec5SDimitry Andric return ExprError(); 14450b57cec5SDimitry Andric } 14465ffd83dbSDimitry Andric if (!Res.isInvalid()) { 14475ffd83dbSDimitry Andric Expr *Arg = Res.get(); 14480b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(), 14495ffd83dbSDimitry Andric SavedKind, Arg); 14505ffd83dbSDimitry Andric if (Res.isInvalid()) 14515ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(), 14525ffd83dbSDimitry Andric Arg->getEndLoc(), Arg); 14535ffd83dbSDimitry Andric } 14540b57cec5SDimitry Andric return Res; 14550b57cec5SDimitry Andric } 14560b57cec5SDimitry Andric case tok::amp: { // unary-expression: '&' cast-expression 1457480093f4SDimitry Andric if (NotPrimaryExpression) 1458480093f4SDimitry Andric *NotPrimaryExpression = true; 14590b57cec5SDimitry Andric // Special treatment because of member pointers 14600b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 14610b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); 1462bdd1243dSDimitry Andric 1463bdd1243dSDimitry Andric Res = ParseCastExpression(AnyCastExpr, /*isAddressOfOperand=*/true); 14645ffd83dbSDimitry Andric if (!Res.isInvalid()) { 14655ffd83dbSDimitry Andric Expr *Arg = Res.get(); 14665ffd83dbSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); 14675ffd83dbSDimitry Andric if (Res.isInvalid()) 14685ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(), 14695ffd83dbSDimitry Andric Arg); 14705ffd83dbSDimitry Andric } 14710b57cec5SDimitry Andric return Res; 14720b57cec5SDimitry Andric } 14730b57cec5SDimitry Andric 14740b57cec5SDimitry Andric case tok::star: // unary-expression: '*' cast-expression 14750b57cec5SDimitry Andric case tok::plus: // unary-expression: '+' cast-expression 14760b57cec5SDimitry Andric case tok::minus: // unary-expression: '-' cast-expression 14770b57cec5SDimitry Andric case tok::tilde: // unary-expression: '~' cast-expression 14780b57cec5SDimitry Andric case tok::exclaim: // unary-expression: '!' cast-expression 14790b57cec5SDimitry Andric case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 14800b57cec5SDimitry Andric case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 1481480093f4SDimitry Andric if (NotPrimaryExpression) 1482480093f4SDimitry Andric *NotPrimaryExpression = true; 14830b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 14840b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); 1485480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14865ffd83dbSDimitry Andric if (!Res.isInvalid()) { 14875ffd83dbSDimitry Andric Expr *Arg = Res.get(); 1488bdd1243dSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg, 1489bdd1243dSDimitry Andric isAddressOfOperand); 14905ffd83dbSDimitry Andric if (Res.isInvalid()) 14915ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg); 14925ffd83dbSDimitry Andric } 14930b57cec5SDimitry Andric return Res; 14940b57cec5SDimitry Andric } 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression 1497480093f4SDimitry Andric if (NotPrimaryExpression) 1498480093f4SDimitry Andric *NotPrimaryExpression = true; 14990b57cec5SDimitry Andric SourceLocation CoawaitLoc = ConsumeToken(); 1500480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 15010b57cec5SDimitry Andric if (!Res.isInvalid()) 15020b57cec5SDimitry Andric Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get()); 15030b57cec5SDimitry Andric return Res; 15040b57cec5SDimitry Andric } 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 15070b57cec5SDimitry Andric // __extension__ silences extension warnings in the subexpression. 1508480093f4SDimitry Andric if (NotPrimaryExpression) 1509480093f4SDimitry Andric *NotPrimaryExpression = true; 15100b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); // Use RAII to do this. 15110b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 1512480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 15130b57cec5SDimitry Andric if (!Res.isInvalid()) 15140b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 15150b57cec5SDimitry Andric return Res; 15160b57cec5SDimitry Andric } 15170b57cec5SDimitry Andric case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' 15180fca6ea1SDimitry Andric diagnoseUseOfC11Keyword(Tok); 1519bdd1243dSDimitry Andric [[fallthrough]]; 15200b57cec5SDimitry Andric case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' 15210b57cec5SDimitry Andric case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 15220b57cec5SDimitry Andric // unary-expression: '__alignof' '(' type-name ')' 15230b57cec5SDimitry Andric case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 15240b57cec5SDimitry Andric // unary-expression: 'sizeof' '(' type-name ')' 15255f757f3fSDimitry Andric // unary-expression: '__datasizeof' unary-expression 15265f757f3fSDimitry Andric // unary-expression: '__datasizeof' '(' type-name ')' 15275f757f3fSDimitry Andric case tok::kw___datasizeof: 15280b57cec5SDimitry Andric case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression 15290b57cec5SDimitry Andric // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' 15300b57cec5SDimitry Andric case tok::kw___builtin_omp_required_simd_align: 15315f757f3fSDimitry Andric case tok::kw___builtin_vectorelements: 1532480093f4SDimitry Andric if (NotPrimaryExpression) 1533480093f4SDimitry Andric *NotPrimaryExpression = true; 15345ffd83dbSDimitry Andric AllowSuffix = false; 15355ffd83dbSDimitry Andric Res = ParseUnaryExprOrTypeTraitExpression(); 15365ffd83dbSDimitry Andric break; 15370b57cec5SDimitry Andric case tok::ampamp: { // unary-expression: '&&' identifier 1538480093f4SDimitry Andric if (NotPrimaryExpression) 1539480093f4SDimitry Andric *NotPrimaryExpression = true; 15400b57cec5SDimitry Andric SourceLocation AmpAmpLoc = ConsumeToken(); 15410b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 15420b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric if (getCurScope()->getFnParent() == nullptr) 15450b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 15480b57cec5SDimitry Andric LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 15490b57cec5SDimitry Andric Tok.getLocation()); 15500b57cec5SDimitry Andric Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); 15510b57cec5SDimitry Andric ConsumeToken(); 15525ffd83dbSDimitry Andric AllowSuffix = false; 15535ffd83dbSDimitry Andric break; 15540b57cec5SDimitry Andric } 15550b57cec5SDimitry Andric case tok::kw_const_cast: 15560b57cec5SDimitry Andric case tok::kw_dynamic_cast: 15570b57cec5SDimitry Andric case tok::kw_reinterpret_cast: 15580b57cec5SDimitry Andric case tok::kw_static_cast: 15595ffd83dbSDimitry Andric case tok::kw_addrspace_cast: 1560480093f4SDimitry Andric if (NotPrimaryExpression) 1561480093f4SDimitry Andric *NotPrimaryExpression = true; 15620b57cec5SDimitry Andric Res = ParseCXXCasts(); 15630b57cec5SDimitry Andric break; 15640b57cec5SDimitry Andric case tok::kw___builtin_bit_cast: 1565480093f4SDimitry Andric if (NotPrimaryExpression) 1566480093f4SDimitry Andric *NotPrimaryExpression = true; 15670b57cec5SDimitry Andric Res = ParseBuiltinBitCast(); 15680b57cec5SDimitry Andric break; 15690b57cec5SDimitry Andric case tok::kw_typeid: 1570480093f4SDimitry Andric if (NotPrimaryExpression) 1571480093f4SDimitry Andric *NotPrimaryExpression = true; 15720b57cec5SDimitry Andric Res = ParseCXXTypeid(); 15730b57cec5SDimitry Andric break; 15740b57cec5SDimitry Andric case tok::kw___uuidof: 1575480093f4SDimitry Andric if (NotPrimaryExpression) 1576480093f4SDimitry Andric *NotPrimaryExpression = true; 15770b57cec5SDimitry Andric Res = ParseCXXUuidof(); 15780b57cec5SDimitry Andric break; 15790b57cec5SDimitry Andric case tok::kw_this: 15800b57cec5SDimitry Andric Res = ParseCXXThis(); 15810b57cec5SDimitry Andric break; 1582fe6060f1SDimitry Andric case tok::kw___builtin_sycl_unique_stable_name: 1583fe6060f1SDimitry Andric Res = ParseSYCLUniqueStableNameExpression(); 1584fe6060f1SDimitry Andric break; 1585e8d8bef9SDimitry Andric 15860b57cec5SDimitry Andric case tok::annot_typename: 15870b57cec5SDimitry Andric if (isStartOfObjCClassMessageMissingOpenBracket()) { 15885ffd83dbSDimitry Andric TypeResult Type = getTypeAnnotation(Tok); 15890b57cec5SDimitry Andric 15900b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 15910b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 15920b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 15930b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getLastLoc()); 15940b57cec5SDimitry Andric 15950b57cec5SDimitry Andric const char *PrevSpec = nullptr; 15960b57cec5SDimitry Andric unsigned DiagID; 15970b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(), 15980b57cec5SDimitry Andric PrevSpec, DiagID, Type, 15990b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 16000b57cec5SDimitry Andric 160181ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 160281ad6265SDimitry Andric DeclaratorContext::TypeName); 16037a6dacacSDimitry Andric TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo); 16040b57cec5SDimitry Andric if (Ty.isInvalid()) 16050b57cec5SDimitry Andric break; 16060b57cec5SDimitry Andric 16070b57cec5SDimitry Andric ConsumeAnnotationToken(); 16080b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 16090b57cec5SDimitry Andric Ty.get(), nullptr); 16100b57cec5SDimitry Andric break; 16110b57cec5SDimitry Andric } 1612bdd1243dSDimitry Andric [[fallthrough]]; 16130b57cec5SDimitry Andric 16140b57cec5SDimitry Andric case tok::annot_decltype: 16150fca6ea1SDimitry Andric case tok::annot_pack_indexing_type: 16160b57cec5SDimitry Andric case tok::kw_char: 16170b57cec5SDimitry Andric case tok::kw_wchar_t: 16180b57cec5SDimitry Andric case tok::kw_char8_t: 16190b57cec5SDimitry Andric case tok::kw_char16_t: 16200b57cec5SDimitry Andric case tok::kw_char32_t: 16210b57cec5SDimitry Andric case tok::kw_bool: 16220b57cec5SDimitry Andric case tok::kw_short: 16230b57cec5SDimitry Andric case tok::kw_int: 16240b57cec5SDimitry Andric case tok::kw_long: 16250b57cec5SDimitry Andric case tok::kw___int64: 16260b57cec5SDimitry Andric case tok::kw___int128: 16275ffd83dbSDimitry Andric case tok::kw__ExtInt: 16280eae32dcSDimitry Andric case tok::kw__BitInt: 16290b57cec5SDimitry Andric case tok::kw_signed: 16300b57cec5SDimitry Andric case tok::kw_unsigned: 16310b57cec5SDimitry Andric case tok::kw_half: 16320b57cec5SDimitry Andric case tok::kw_float: 16330b57cec5SDimitry Andric case tok::kw_double: 16345ffd83dbSDimitry Andric case tok::kw___bf16: 16350b57cec5SDimitry Andric case tok::kw__Float16: 16360b57cec5SDimitry Andric case tok::kw___float128: 1637349cc55cSDimitry Andric case tok::kw___ibm128: 16380b57cec5SDimitry Andric case tok::kw_void: 163981ad6265SDimitry Andric case tok::kw_auto: 16400b57cec5SDimitry Andric case tok::kw_typename: 16410b57cec5SDimitry Andric case tok::kw_typeof: 16420b57cec5SDimitry Andric case tok::kw___vector: 16435f757f3fSDimitry Andric case tok::kw__Accum: 16445f757f3fSDimitry Andric case tok::kw__Fract: 16455f757f3fSDimitry Andric case tok::kw__Sat: 16460b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 16470b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 16480b57cec5SDimitry Andric { 16490b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 16500b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 16510b57cec5SDimitry Andric return ExprError(); 16520b57cec5SDimitry Andric } 16530b57cec5SDimitry Andric 1654480093f4SDimitry Andric // Everything henceforth is a postfix-expression. 1655480093f4SDimitry Andric if (NotPrimaryExpression) 1656480093f4SDimitry Andric *NotPrimaryExpression = true; 1657480093f4SDimitry Andric 16580b57cec5SDimitry Andric if (SavedKind == tok::kw_typename) { 16590b57cec5SDimitry Andric // postfix-expression: typename-specifier '(' expression-list[opt] ')' 16600b57cec5SDimitry Andric // typename-specifier braced-init-list 16610b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16620b57cec5SDimitry Andric return ExprError(); 16630b57cec5SDimitry Andric 16640fca6ea1SDimitry Andric if (!Tok.isSimpleTypeSpecifier(getLangOpts())) 16650b57cec5SDimitry Andric // We are trying to parse a simple-type-specifier but might not get such 16660b57cec5SDimitry Andric // a token after error recovery. 16670b57cec5SDimitry Andric return ExprError(); 16680b57cec5SDimitry Andric } 16690b57cec5SDimitry Andric 16700b57cec5SDimitry Andric // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 16710b57cec5SDimitry Andric // simple-type-specifier braced-init-list 16720b57cec5SDimitry Andric // 16730b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 16740b57cec5SDimitry Andric 16750b57cec5SDimitry Andric ParseCXXSimpleTypeSpecifier(DS); 16760b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren) && 16770b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) 16780b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 16790b57cec5SDimitry Andric << DS.getSourceRange()); 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) 16820b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric Res = ParseCXXTypeConstructExpression(DS); 16850b57cec5SDimitry Andric break; 16860b57cec5SDimitry Andric } 16870b57cec5SDimitry Andric 16880b57cec5SDimitry Andric case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 16890b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 16900b57cec5SDimitry Andric // (We can end up in this situation after tentative parsing.) 16910b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16920b57cec5SDimitry Andric return ExprError(); 16930b57cec5SDimitry Andric if (!Tok.is(tok::annot_cxxscope)) 1694480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1695480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1696480093f4SDimitry Andric NotPrimaryExpression); 16970b57cec5SDimitry Andric 16980b57cec5SDimitry Andric Token Next = NextToken(); 16990b57cec5SDimitry Andric if (Next.is(tok::annot_template_id)) { 17000b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 17010b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 17020b57cec5SDimitry Andric // We have a qualified template-id that we know refers to a 17030b57cec5SDimitry Andric // type, translate it into a type and continue parsing as a 17040b57cec5SDimitry Andric // cast expression. 17050b57cec5SDimitry Andric CXXScopeSpec SS; 17065ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 170704eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 17080b57cec5SDimitry Andric /*EnteringContext=*/false); 1709bdd1243dSDimitry Andric AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); 1710480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1711480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1712480093f4SDimitry Andric NotPrimaryExpression); 17130b57cec5SDimitry Andric } 17140b57cec5SDimitry Andric } 17150b57cec5SDimitry Andric 17160b57cec5SDimitry Andric // Parse as an id-expression. 17170b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 17180b57cec5SDimitry Andric break; 17190b57cec5SDimitry Andric } 17200b57cec5SDimitry Andric 17210b57cec5SDimitry Andric case tok::annot_template_id: { // [C++] template-id 17220b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 17230b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 17240b57cec5SDimitry Andric // We have a template-id that we know refers to a type, 17250b57cec5SDimitry Andric // translate it into a type and continue parsing as a cast 17260b57cec5SDimitry Andric // expression. 172755e4f9d5SDimitry Andric CXXScopeSpec SS; 1728bdd1243dSDimitry Andric AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); 1729480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1730480093f4SDimitry Andric NotCastExpr, isTypeCast, isVectorLiteral, 1731480093f4SDimitry Andric NotPrimaryExpression); 17320b57cec5SDimitry Andric } 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andric // Fall through to treat the template-id as an id-expression. 1735bdd1243dSDimitry Andric [[fallthrough]]; 17360b57cec5SDimitry Andric } 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 17390b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 17400b57cec5SDimitry Andric break; 17410b57cec5SDimitry Andric 17420b57cec5SDimitry Andric case tok::coloncolon: { 17430b57cec5SDimitry Andric // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 17440b57cec5SDimitry Andric // annotates the token, tail recurse. 17450b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 17460b57cec5SDimitry Andric return ExprError(); 17470b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) 1748480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1749480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 17500b57cec5SDimitry Andric 17510b57cec5SDimitry Andric // ::new -> [C++] new-expression 17520b57cec5SDimitry Andric // ::delete -> [C++] delete-expression 17530b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 1754480093f4SDimitry Andric if (Tok.is(tok::kw_new)) { 1755480093f4SDimitry Andric if (NotPrimaryExpression) 1756480093f4SDimitry Andric *NotPrimaryExpression = true; 17575ffd83dbSDimitry Andric Res = ParseCXXNewExpression(true, CCLoc); 17585ffd83dbSDimitry Andric AllowSuffix = false; 17595ffd83dbSDimitry Andric break; 1760480093f4SDimitry Andric } 1761480093f4SDimitry Andric if (Tok.is(tok::kw_delete)) { 1762480093f4SDimitry Andric if (NotPrimaryExpression) 1763480093f4SDimitry Andric *NotPrimaryExpression = true; 17645ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(true, CCLoc); 17655ffd83dbSDimitry Andric AllowSuffix = false; 17665ffd83dbSDimitry Andric break; 1767480093f4SDimitry Andric } 17680b57cec5SDimitry Andric 17690b57cec5SDimitry Andric // This is not a type name or scope specifier, it is an invalid expression. 17700b57cec5SDimitry Andric Diag(CCLoc, diag::err_expected_expression); 17710b57cec5SDimitry Andric return ExprError(); 17720b57cec5SDimitry Andric } 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric case tok::kw_new: // [C++] new-expression 1775480093f4SDimitry Andric if (NotPrimaryExpression) 1776480093f4SDimitry Andric *NotPrimaryExpression = true; 17775ffd83dbSDimitry Andric Res = ParseCXXNewExpression(false, Tok.getLocation()); 17785ffd83dbSDimitry Andric AllowSuffix = false; 17795ffd83dbSDimitry Andric break; 17800b57cec5SDimitry Andric 17810b57cec5SDimitry Andric case tok::kw_delete: // [C++] delete-expression 1782480093f4SDimitry Andric if (NotPrimaryExpression) 1783480093f4SDimitry Andric *NotPrimaryExpression = true; 17845ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(false, Tok.getLocation()); 17855ffd83dbSDimitry Andric AllowSuffix = false; 17865ffd83dbSDimitry Andric break; 17870b57cec5SDimitry Andric 178855e4f9d5SDimitry Andric case tok::kw_requires: // [C++2a] requires-expression 17895ffd83dbSDimitry Andric Res = ParseRequiresExpression(); 17905ffd83dbSDimitry Andric AllowSuffix = false; 17915ffd83dbSDimitry Andric break; 179255e4f9d5SDimitry Andric 17930b57cec5SDimitry Andric case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' 1794480093f4SDimitry Andric if (NotPrimaryExpression) 1795480093f4SDimitry Andric *NotPrimaryExpression = true; 17960b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_noexcept_expr); 17970b57cec5SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 17980b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 17990b57cec5SDimitry Andric 18000b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept")) 18010b57cec5SDimitry Andric return ExprError(); 18020b57cec5SDimitry Andric // C++11 [expr.unary.noexcept]p1: 18030b57cec5SDimitry Andric // The noexcept operator determines whether the evaluation of its operand, 18040b57cec5SDimitry Andric // which is an unevaluated operand, can throw an exception. 18050b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 18060b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 18075ffd83dbSDimitry Andric Res = ParseExpression(); 18080b57cec5SDimitry Andric 18090b57cec5SDimitry Andric T.consumeClose(); 18100b57cec5SDimitry Andric 18115ffd83dbSDimitry Andric if (!Res.isInvalid()) 18125ffd83dbSDimitry Andric Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(), 18135ffd83dbSDimitry Andric T.getCloseLocation()); 18145ffd83dbSDimitry Andric AllowSuffix = false; 18155ffd83dbSDimitry Andric break; 18160b57cec5SDimitry Andric } 18170b57cec5SDimitry Andric 18180b57cec5SDimitry Andric #define TYPE_TRAIT(N,Spelling,K) \ 18190b57cec5SDimitry Andric case tok::kw_##Spelling: 18200b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 18215ffd83dbSDimitry Andric Res = ParseTypeTrait(); 18225ffd83dbSDimitry Andric break; 18230b57cec5SDimitry Andric 18240b57cec5SDimitry Andric case tok::kw___array_rank: 18250b57cec5SDimitry Andric case tok::kw___array_extent: 1826480093f4SDimitry Andric if (NotPrimaryExpression) 1827480093f4SDimitry Andric *NotPrimaryExpression = true; 18285ffd83dbSDimitry Andric Res = ParseArrayTypeTrait(); 18295ffd83dbSDimitry Andric break; 18300b57cec5SDimitry Andric 1831*36b606aeSDimitry Andric case tok::kw___builtin_ptrauth_type_discriminator: 1832*36b606aeSDimitry Andric return ParseBuiltinPtrauthTypeDiscriminator(); 1833*36b606aeSDimitry Andric 18340b57cec5SDimitry Andric case tok::kw___is_lvalue_expr: 18350b57cec5SDimitry Andric case tok::kw___is_rvalue_expr: 1836480093f4SDimitry Andric if (NotPrimaryExpression) 1837480093f4SDimitry Andric *NotPrimaryExpression = true; 18385ffd83dbSDimitry Andric Res = ParseExpressionTrait(); 18395ffd83dbSDimitry Andric break; 18400b57cec5SDimitry Andric 18410b57cec5SDimitry Andric case tok::at: { 1842480093f4SDimitry Andric if (NotPrimaryExpression) 1843480093f4SDimitry Andric *NotPrimaryExpression = true; 18440b57cec5SDimitry Andric SourceLocation AtLoc = ConsumeToken(); 18450b57cec5SDimitry Andric return ParseObjCAtExpression(AtLoc); 18460b57cec5SDimitry Andric } 18470b57cec5SDimitry Andric case tok::caret: 18480b57cec5SDimitry Andric Res = ParseBlockLiteralExpression(); 18490b57cec5SDimitry Andric break; 18500b57cec5SDimitry Andric case tok::code_completion: { 1851fe6060f1SDimitry Andric cutOffParsing(); 18520fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteExpression( 18530fca6ea1SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation())); 18540b57cec5SDimitry Andric return ExprError(); 18550b57cec5SDimitry Andric } 1856bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: 1857bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 1858bdd1243dSDimitry Andric // HACK: libstdc++ uses some of the transform-type-traits as alias 1859bdd1243dSDimitry Andric // templates, so we need to work around this. 1860bdd1243dSDimitry Andric if (!NextToken().is(tok::l_paren)) { 1861bdd1243dSDimitry Andric Tok.setKind(tok::identifier); 1862bdd1243dSDimitry Andric Diag(Tok, diag::ext_keyword_as_ident) 1863bdd1243dSDimitry Andric << Tok.getIdentifierInfo()->getName() << 0; 1864bdd1243dSDimitry Andric goto ParseIdentifier; 1865bdd1243dSDimitry Andric } 1866bdd1243dSDimitry Andric goto ExpectedExpression; 18670b57cec5SDimitry Andric case tok::l_square: 18680fca6ea1SDimitry Andric if (getLangOpts().CPlusPlus) { 18690b57cec5SDimitry Andric if (getLangOpts().ObjC) { 18700b57cec5SDimitry Andric // C++11 lambda expressions and Objective-C message sends both start with a 18710b57cec5SDimitry Andric // square bracket. There are three possibilities here: 18720b57cec5SDimitry Andric // we have a valid lambda expression, we have an invalid lambda 18730b57cec5SDimitry Andric // expression, or we have something that doesn't appear to be a lambda. 18740b57cec5SDimitry Andric // If we're in the last case, we fall back to ParseObjCMessageExpression. 18750b57cec5SDimitry Andric Res = TryParseLambdaExpression(); 1876480093f4SDimitry Andric if (!Res.isInvalid() && !Res.get()) { 1877480093f4SDimitry Andric // We assume Objective-C++ message expressions are not 1878480093f4SDimitry Andric // primary-expressions. 1879480093f4SDimitry Andric if (NotPrimaryExpression) 1880480093f4SDimitry Andric *NotPrimaryExpression = true; 18810b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 1882480093f4SDimitry Andric } 18830b57cec5SDimitry Andric break; 18840b57cec5SDimitry Andric } 18850b57cec5SDimitry Andric Res = ParseLambdaExpression(); 18860b57cec5SDimitry Andric break; 18870b57cec5SDimitry Andric } 18880b57cec5SDimitry Andric if (getLangOpts().ObjC) { 18890b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 18900b57cec5SDimitry Andric break; 18910b57cec5SDimitry Andric } 1892bdd1243dSDimitry Andric [[fallthrough]]; 18930b57cec5SDimitry Andric default: 1894bdd1243dSDimitry Andric ExpectedExpression: 18950b57cec5SDimitry Andric NotCastExpr = true; 18960b57cec5SDimitry Andric return ExprError(); 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric 18990b57cec5SDimitry Andric // Check to see whether Res is a function designator only. If it is and we 19000b57cec5SDimitry Andric // are compiling for OpenCL, we need to return an error as this implies 19010b57cec5SDimitry Andric // that the address of the function is being taken, which is illegal in CL. 19020b57cec5SDimitry Andric 1903480093f4SDimitry Andric if (ParseKind == PrimaryExprOnly) 1904480093f4SDimitry Andric // This is strictly a primary-expression - no postfix-expr pieces should be 1905480093f4SDimitry Andric // parsed. 1906480093f4SDimitry Andric return Res; 1907480093f4SDimitry Andric 19085ffd83dbSDimitry Andric if (!AllowSuffix) { 19095ffd83dbSDimitry Andric // FIXME: Don't parse a primary-expression suffix if we encountered a parse 19105ffd83dbSDimitry Andric // error already. 19115ffd83dbSDimitry Andric if (Res.isInvalid()) 19125ffd83dbSDimitry Andric return Res; 19135ffd83dbSDimitry Andric 19145ffd83dbSDimitry Andric switch (Tok.getKind()) { 19155ffd83dbSDimitry Andric case tok::l_square: 19165ffd83dbSDimitry Andric case tok::l_paren: 19175ffd83dbSDimitry Andric case tok::plusplus: 19185ffd83dbSDimitry Andric case tok::minusminus: 19195ffd83dbSDimitry Andric // "expected ';'" or similar is probably the right diagnostic here. Let 19205ffd83dbSDimitry Andric // the caller decide what to do. 19215ffd83dbSDimitry Andric if (Tok.isAtStartOfLine()) 19225ffd83dbSDimitry Andric return Res; 19235ffd83dbSDimitry Andric 1924bdd1243dSDimitry Andric [[fallthrough]]; 19255ffd83dbSDimitry Andric case tok::period: 19265ffd83dbSDimitry Andric case tok::arrow: 19275ffd83dbSDimitry Andric break; 19285ffd83dbSDimitry Andric 19295ffd83dbSDimitry Andric default: 19305ffd83dbSDimitry Andric return Res; 19315ffd83dbSDimitry Andric } 19325ffd83dbSDimitry Andric 19335ffd83dbSDimitry Andric // This was a unary-expression for which a postfix-expression suffix is 19345ffd83dbSDimitry Andric // not permitted by the grammar (eg, a sizeof expression or 19355ffd83dbSDimitry Andric // new-expression or similar). Diagnose but parse the suffix anyway. 19365ffd83dbSDimitry Andric Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens) 19375ffd83dbSDimitry Andric << Tok.getKind() << Res.get()->getSourceRange() 19385ffd83dbSDimitry Andric << FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(") 19395ffd83dbSDimitry Andric << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation), 19405ffd83dbSDimitry Andric ")"); 19415ffd83dbSDimitry Andric } 19425ffd83dbSDimitry Andric 19430b57cec5SDimitry Andric // These can be followed by postfix-expr pieces. 19440b57cec5SDimitry Andric PreferredType = SavedType; 19450b57cec5SDimitry Andric Res = ParsePostfixExpressionSuffix(Res); 1946fe6060f1SDimitry Andric if (getLangOpts().OpenCL && 1947fe6060f1SDimitry Andric !getActions().getOpenCLOptions().isAvailableOption( 1948fe6060f1SDimitry Andric "__cl_clang_function_pointers", getLangOpts())) 19490b57cec5SDimitry Andric if (Expr *PostfixExpr = Res.get()) { 19500b57cec5SDimitry Andric QualType Ty = PostfixExpr->getType(); 19510b57cec5SDimitry Andric if (!Ty.isNull() && Ty->isFunctionType()) { 19520b57cec5SDimitry Andric Diag(PostfixExpr->getExprLoc(), 19530b57cec5SDimitry Andric diag::err_opencl_taking_function_address_parser); 19540b57cec5SDimitry Andric return ExprError(); 19550b57cec5SDimitry Andric } 19560b57cec5SDimitry Andric } 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric return Res; 19590b57cec5SDimitry Andric } 19600b57cec5SDimitry Andric 19610b57cec5SDimitry Andric /// Once the leading part of a postfix-expression is parsed, this 19620b57cec5SDimitry Andric /// method parses any suffixes that apply. 19630b57cec5SDimitry Andric /// 19640b57cec5SDimitry Andric /// \verbatim 19650b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 19660b57cec5SDimitry Andric /// primary-expression 19670b57cec5SDimitry Andric /// postfix-expression '[' expression ']' 19680b57cec5SDimitry Andric /// postfix-expression '[' braced-init-list ']' 196906c3fb27SDimitry Andric /// postfix-expression '[' expression-list [opt] ']' [C++23 12.4.5] 19700b57cec5SDimitry Andric /// postfix-expression '(' argument-expression-list[opt] ')' 19710b57cec5SDimitry Andric /// postfix-expression '.' identifier 19720b57cec5SDimitry Andric /// postfix-expression '->' identifier 19730b57cec5SDimitry Andric /// postfix-expression '++' 19740b57cec5SDimitry Andric /// postfix-expression '--' 19750b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 19760b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 19770b57cec5SDimitry Andric /// 19780b57cec5SDimitry Andric /// argument-expression-list: [C99 6.5.2] 19790b57cec5SDimitry Andric /// argument-expression ...[opt] 19800b57cec5SDimitry Andric /// argument-expression-list ',' assignment-expression ...[opt] 19810b57cec5SDimitry Andric /// \endverbatim 19820b57cec5SDimitry Andric ExprResult 19830b57cec5SDimitry Andric Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { 19840b57cec5SDimitry Andric // Now that the primary-expression piece of the postfix-expression has been 19850b57cec5SDimitry Andric // parsed, see if there are any postfix-expression pieces here. 19860b57cec5SDimitry Andric SourceLocation Loc; 19870b57cec5SDimitry Andric auto SavedType = PreferredType; 198804eeddc0SDimitry Andric while (true) { 19890b57cec5SDimitry Andric // Each iteration relies on preferred type for the whole expression. 19900b57cec5SDimitry Andric PreferredType = SavedType; 19910b57cec5SDimitry Andric switch (Tok.getKind()) { 19920b57cec5SDimitry Andric case tok::code_completion: 19930b57cec5SDimitry Andric if (InMessageExpression) 19940b57cec5SDimitry Andric return LHS; 19950b57cec5SDimitry Andric 1996fe6060f1SDimitry Andric cutOffParsing(); 19970fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompletePostfixExpression( 19980b57cec5SDimitry Andric getCurScope(), LHS, PreferredType.get(Tok.getLocation())); 19990b57cec5SDimitry Andric return ExprError(); 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andric case tok::identifier: 20020b57cec5SDimitry Andric // If we see identifier: after an expression, and we're not already in a 20030b57cec5SDimitry Andric // message send, then this is probably a message send with a missing 20040b57cec5SDimitry Andric // opening bracket '['. 20050b57cec5SDimitry Andric if (getLangOpts().ObjC && !InMessageExpression && 20060b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 20070b57cec5SDimitry Andric LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 20080b57cec5SDimitry Andric nullptr, LHS.get()); 20090b57cec5SDimitry Andric break; 20100b57cec5SDimitry Andric } 20110b57cec5SDimitry Andric // Fall through; this isn't a message send. 2012bdd1243dSDimitry Andric [[fallthrough]]; 20130b57cec5SDimitry Andric 20140b57cec5SDimitry Andric default: // Not a postfix-expression suffix. 20150b57cec5SDimitry Andric return LHS; 20160b57cec5SDimitry Andric case tok::l_square: { // postfix-expression: p-e '[' expression ']' 20170b57cec5SDimitry Andric // If we have a array postfix expression that starts on a new line and 20180b57cec5SDimitry Andric // Objective-C is enabled, it is highly likely that the user forgot a 20190b57cec5SDimitry Andric // semicolon after the base expression and that the array postfix-expr is 20200b57cec5SDimitry Andric // actually another message send. In this case, do some look-ahead to see 20210b57cec5SDimitry Andric // if the contents of the square brackets are obviously not a valid 20220b57cec5SDimitry Andric // expression and recover by pretending there is no suffix. 20230b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.isAtStartOfLine() && 20240b57cec5SDimitry Andric isSimpleObjCMessageExpression()) 20250b57cec5SDimitry Andric return LHS; 20260b57cec5SDimitry Andric 20270b57cec5SDimitry Andric // Reject array indices starting with a lambda-expression. '[[' is 20280b57cec5SDimitry Andric // reserved for attributes. 20290b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) { 20300b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 20310b57cec5SDimitry Andric return ExprError(); 20320b57cec5SDimitry Andric } 20330b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 20340b57cec5SDimitry Andric T.consumeOpen(); 20350b57cec5SDimitry Andric Loc = T.getOpenLocation(); 203681ad6265SDimitry Andric ExprResult Length, Stride; 20375ffd83dbSDimitry Andric SourceLocation ColonLocFirst, ColonLocSecond; 203881ad6265SDimitry Andric ExprVector ArgExprs; 203981ad6265SDimitry Andric bool HasError = false; 20400b57cec5SDimitry Andric PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); 204181ad6265SDimitry Andric 204281ad6265SDimitry Andric // We try to parse a list of indexes in all language mode first 2043297eecfbSDimitry Andric // and, in we find 0 or one index, we try to parse an OpenMP/OpenACC array 204406c3fb27SDimitry Andric // section. This allow us to support C++23 multi dimensional subscript and 2045297eecfbSDimitry Andric // OpenMP/OpenACC sections in the same language mode. 2046297eecfbSDimitry Andric if ((!getLangOpts().OpenMP && !AllowOpenACCArraySections) || 2047297eecfbSDimitry Andric Tok.isNot(tok::colon)) { 204806c3fb27SDimitry Andric if (!getLangOpts().CPlusPlus23) { 204981ad6265SDimitry Andric ExprResult Idx; 20500b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 20510b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 20520b57cec5SDimitry Andric Idx = ParseBraceInitializer(); 205381ad6265SDimitry Andric } else { 205481ad6265SDimitry Andric Idx = ParseExpression(); // May be a comma expression 20550b57cec5SDimitry Andric } 205681ad6265SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 205781ad6265SDimitry Andric Idx = Actions.CorrectDelayedTyposInExpr(Idx); 205881ad6265SDimitry Andric if (Idx.isInvalid()) { 205981ad6265SDimitry Andric HasError = true; 206081ad6265SDimitry Andric } else { 206181ad6265SDimitry Andric ArgExprs.push_back(Idx.get()); 206281ad6265SDimitry Andric } 206381ad6265SDimitry Andric } else if (Tok.isNot(tok::r_square)) { 2064bdd1243dSDimitry Andric if (ParseExpressionList(ArgExprs)) { 206581ad6265SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 206681ad6265SDimitry Andric HasError = true; 206781ad6265SDimitry Andric } 206881ad6265SDimitry Andric } 206981ad6265SDimitry Andric } 207081ad6265SDimitry Andric 2071297eecfbSDimitry Andric // Handle OpenACC first, since 'AllowOpenACCArraySections' is only enabled 2072297eecfbSDimitry Andric // when actively parsing a 'var' in a 'var-list' during clause/'cache' 2073297eecfbSDimitry Andric // parsing, so it is the most specific, and best allows us to handle 2074297eecfbSDimitry Andric // OpenACC and OpenMP at the same time. 2075297eecfbSDimitry Andric if (ArgExprs.size() <= 1 && AllowOpenACCArraySections) { 2076297eecfbSDimitry Andric ColonProtectionRAIIObject RAII(*this); 2077297eecfbSDimitry Andric if (Tok.is(tok::colon)) { 2078297eecfbSDimitry Andric // Consume ':' 2079297eecfbSDimitry Andric ColonLocFirst = ConsumeToken(); 20800fca6ea1SDimitry Andric if (Tok.isNot(tok::r_square)) 2081297eecfbSDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); 2082297eecfbSDimitry Andric } 2083297eecfbSDimitry Andric } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { 208481ad6265SDimitry Andric ColonProtectionRAIIObject RAII(*this); 20850b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 20860b57cec5SDimitry Andric // Consume ':' 20875ffd83dbSDimitry Andric ColonLocFirst = ConsumeToken(); 20885ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square) && 20895ffd83dbSDimitry Andric (getLangOpts().OpenMP < 50 || 209081ad6265SDimitry Andric ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) { 20910b57cec5SDimitry Andric Length = ParseExpression(); 209281ad6265SDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(Length); 209381ad6265SDimitry Andric } 20940b57cec5SDimitry Andric } 20955ffd83dbSDimitry Andric if (getLangOpts().OpenMP >= 50 && 20965ffd83dbSDimitry Andric (OMPClauseKind == llvm::omp::Clause::OMPC_to || 20975ffd83dbSDimitry Andric OMPClauseKind == llvm::omp::Clause::OMPC_from) && 20985ffd83dbSDimitry Andric Tok.is(tok::colon)) { 20995ffd83dbSDimitry Andric // Consume ':' 21005ffd83dbSDimitry Andric ColonLocSecond = ConsumeToken(); 21015ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) { 21025ffd83dbSDimitry Andric Stride = ParseExpression(); 21035ffd83dbSDimitry Andric } 21045ffd83dbSDimitry Andric } 210581ad6265SDimitry Andric } 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric SourceLocation RLoc = Tok.getLocation(); 21080b57cec5SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 210981ad6265SDimitry Andric 211081ad6265SDimitry Andric if (!LHS.isInvalid() && !HasError && !Length.isInvalid() && 21115ffd83dbSDimitry Andric !Stride.isInvalid() && Tok.is(tok::r_square)) { 21125ffd83dbSDimitry Andric if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { 21130fca6ea1SDimitry Andric // Like above, AllowOpenACCArraySections is 'more specific' and only 21140fca6ea1SDimitry Andric // enabled when actively parsing a 'var' in a 'var-list' during 21150fca6ea1SDimitry Andric // clause/'cache' construct parsing, so it is more specific. So we 21160fca6ea1SDimitry Andric // should do it first, so that the correct node gets created. 21170fca6ea1SDimitry Andric if (AllowOpenACCArraySections) { 21180fca6ea1SDimitry Andric assert(!Stride.isUsable() && !ColonLocSecond.isValid() && 21190fca6ea1SDimitry Andric "Stride/second colon not allowed for OpenACC"); 21200fca6ea1SDimitry Andric LHS = Actions.OpenACC().ActOnArraySectionExpr( 212181ad6265SDimitry Andric LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], 21220fca6ea1SDimitry Andric ColonLocFirst, Length.get(), RLoc); 21230fca6ea1SDimitry Andric } else { 21240fca6ea1SDimitry Andric LHS = Actions.OpenMP().ActOnOMPArraySectionExpr( 21250fca6ea1SDimitry Andric LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], 21260fca6ea1SDimitry Andric ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), 21270fca6ea1SDimitry Andric RLoc); 21280fca6ea1SDimitry Andric } 21290b57cec5SDimitry Andric } else { 21300b57cec5SDimitry Andric LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, 213181ad6265SDimitry Andric ArgExprs, RLoc); 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric } else { 21340b57cec5SDimitry Andric LHS = ExprError(); 21350b57cec5SDimitry Andric } 21360b57cec5SDimitry Andric 21370b57cec5SDimitry Andric // Match the ']'. 21380b57cec5SDimitry Andric T.consumeClose(); 21390b57cec5SDimitry Andric break; 21400b57cec5SDimitry Andric } 21410b57cec5SDimitry Andric 21420b57cec5SDimitry Andric case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' 21430b57cec5SDimitry Andric case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>' 21440b57cec5SDimitry Andric // '(' argument-expression-list[opt] ')' 21450b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 21460b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 21470b57cec5SDimitry Andric 21480b57cec5SDimitry Andric Expr *ExecConfig = nullptr; 21490b57cec5SDimitry Andric 21500b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 21510b57cec5SDimitry Andric 21520b57cec5SDimitry Andric if (OpKind == tok::lesslessless) { 21530b57cec5SDimitry Andric ExprVector ExecConfigExprs; 21540b57cec5SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 21550b57cec5SDimitry Andric 2156bdd1243dSDimitry Andric if (ParseSimpleExpressionList(ExecConfigExprs)) { 21570b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 21580b57cec5SDimitry Andric LHS = ExprError(); 21590b57cec5SDimitry Andric } 21600b57cec5SDimitry Andric 21610b57cec5SDimitry Andric SourceLocation CloseLoc; 21620b57cec5SDimitry Andric if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) { 21630b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 21640b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 21650b57cec5SDimitry Andric } else { 21660b57cec5SDimitry Andric // There was an error closing the brackets 21670b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::greatergreatergreater; 21680b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::lesslessless; 21690b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 21700b57cec5SDimitry Andric LHS = ExprError(); 21710b57cec5SDimitry Andric } 21720b57cec5SDimitry Andric 21730b57cec5SDimitry Andric if (!LHS.isInvalid()) { 21740b57cec5SDimitry Andric if (ExpectAndConsume(tok::l_paren)) 21750b57cec5SDimitry Andric LHS = ExprError(); 21760b57cec5SDimitry Andric else 21770b57cec5SDimitry Andric Loc = PrevTokLocation; 21780b57cec5SDimitry Andric } 21790b57cec5SDimitry Andric 21800b57cec5SDimitry Andric if (!LHS.isInvalid()) { 21810fca6ea1SDimitry Andric ExprResult ECResult = Actions.CUDA().ActOnExecConfigExpr( 21820fca6ea1SDimitry Andric getCurScope(), OpenLoc, ExecConfigExprs, CloseLoc); 21830b57cec5SDimitry Andric if (ECResult.isInvalid()) 21840b57cec5SDimitry Andric LHS = ExprError(); 21850b57cec5SDimitry Andric else 21860b57cec5SDimitry Andric ExecConfig = ECResult.get(); 21870b57cec5SDimitry Andric } 21880b57cec5SDimitry Andric } else { 21890b57cec5SDimitry Andric PT.consumeOpen(); 21900b57cec5SDimitry Andric Loc = PT.getOpenLocation(); 21910b57cec5SDimitry Andric } 21920b57cec5SDimitry Andric 21930b57cec5SDimitry Andric ExprVector ArgExprs; 21940b57cec5SDimitry Andric auto RunSignatureHelp = [&]() -> QualType { 21950fca6ea1SDimitry Andric QualType PreferredType = 21960fca6ea1SDimitry Andric Actions.CodeCompletion().ProduceCallSignatureHelp( 219704eeddc0SDimitry Andric LHS.get(), ArgExprs, PT.getOpenLocation()); 21980b57cec5SDimitry Andric CalledSignatureHelp = true; 21990b57cec5SDimitry Andric return PreferredType; 22000b57cec5SDimitry Andric }; 22010b57cec5SDimitry Andric if (OpKind == tok::l_paren || !LHS.isInvalid()) { 22020b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 2203bdd1243dSDimitry Andric if (ParseExpressionList(ArgExprs, [&] { 22040b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 22050b57cec5SDimitry Andric RunSignatureHelp); 22060b57cec5SDimitry Andric })) { 22070b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 22080b57cec5SDimitry Andric // If we got an error when parsing expression list, we don't call 22090b57cec5SDimitry Andric // the CodeCompleteCall handler inside the parser. So call it here 22100b57cec5SDimitry Andric // to make sure we get overload suggestions even when we are in the 22110b57cec5SDimitry Andric // middle of a parameter. 22120b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 22130b57cec5SDimitry Andric RunSignatureHelp(); 22140b57cec5SDimitry Andric LHS = ExprError(); 22150b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 22160b57cec5SDimitry Andric for (auto &E : ArgExprs) 22170b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 22180b57cec5SDimitry Andric } 22190b57cec5SDimitry Andric } 22200b57cec5SDimitry Andric } 22210b57cec5SDimitry Andric 22220b57cec5SDimitry Andric // Match the ')'. 22230b57cec5SDimitry Andric if (LHS.isInvalid()) { 22240b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 22250b57cec5SDimitry Andric } else if (Tok.isNot(tok::r_paren)) { 22260b57cec5SDimitry Andric bool HadDelayedTypo = false; 22270b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get()) 22280b57cec5SDimitry Andric HadDelayedTypo = true; 22290b57cec5SDimitry Andric for (auto &E : ArgExprs) 22300b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(E).get() != E) 22310b57cec5SDimitry Andric HadDelayedTypo = true; 22320b57cec5SDimitry Andric // If there were delayed typos in the LHS or ArgExprs, call SkipUntil 22330b57cec5SDimitry Andric // instead of PT.consumeClose() to avoid emitting extra diagnostics for 22340b57cec5SDimitry Andric // the unmatched l_paren. 22350b57cec5SDimitry Andric if (HadDelayedTypo) 22360b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 22370b57cec5SDimitry Andric else 22380b57cec5SDimitry Andric PT.consumeClose(); 22390b57cec5SDimitry Andric LHS = ExprError(); 22400b57cec5SDimitry Andric } else { 22415ffd83dbSDimitry Andric Expr *Fn = LHS.get(); 22425ffd83dbSDimitry Andric SourceLocation RParLoc = Tok.getLocation(); 22435ffd83dbSDimitry Andric LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc, 22440b57cec5SDimitry Andric ExecConfig); 22455ffd83dbSDimitry Andric if (LHS.isInvalid()) { 22465ffd83dbSDimitry Andric ArgExprs.insert(ArgExprs.begin(), Fn); 22475ffd83dbSDimitry Andric LHS = 22485ffd83dbSDimitry Andric Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs); 22495ffd83dbSDimitry Andric } 22500b57cec5SDimitry Andric PT.consumeClose(); 22510b57cec5SDimitry Andric } 22520b57cec5SDimitry Andric 22530b57cec5SDimitry Andric break; 22540b57cec5SDimitry Andric } 22550b57cec5SDimitry Andric case tok::arrow: 22560b57cec5SDimitry Andric case tok::period: { 22570b57cec5SDimitry Andric // postfix-expression: p-e '->' template[opt] id-expression 22580b57cec5SDimitry Andric // postfix-expression: p-e '.' template[opt] id-expression 22590b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 22600b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 22610b57cec5SDimitry Andric 22620b57cec5SDimitry Andric CXXScopeSpec SS; 22630b57cec5SDimitry Andric ParsedType ObjectType; 22640b57cec5SDimitry Andric bool MayBePseudoDestructor = false; 22650b57cec5SDimitry Andric Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; 22660b57cec5SDimitry Andric 22670b57cec5SDimitry Andric PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS); 22680b57cec5SDimitry Andric 22690b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { 22700b57cec5SDimitry Andric Expr *Base = OrigLHS; 22710b57cec5SDimitry Andric const Type* BaseType = Base->getType().getTypePtrOrNull(); 22720b57cec5SDimitry Andric if (BaseType && Tok.is(tok::l_paren) && 22730b57cec5SDimitry Andric (BaseType->isFunctionType() || 22740b57cec5SDimitry Andric BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { 22750b57cec5SDimitry Andric Diag(OpLoc, diag::err_function_is_not_record) 22760b57cec5SDimitry Andric << OpKind << Base->getSourceRange() 22770b57cec5SDimitry Andric << FixItHint::CreateRemoval(OpLoc); 22780b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Base); 22790b57cec5SDimitry Andric } 22800b57cec5SDimitry Andric 22815ffd83dbSDimitry Andric LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, 22825ffd83dbSDimitry Andric OpKind, ObjectType, 22830b57cec5SDimitry Andric MayBePseudoDestructor); 22845ffd83dbSDimitry Andric if (LHS.isInvalid()) { 22855ffd83dbSDimitry Andric // Clang will try to perform expression based completion as a 22865ffd83dbSDimitry Andric // fallback, which is confusing in case of member references. So we 22875ffd83dbSDimitry Andric // stop here without any completions. 22885ffd83dbSDimitry Andric if (Tok.is(tok::code_completion)) { 22895ffd83dbSDimitry Andric cutOffParsing(); 22905ffd83dbSDimitry Andric return ExprError(); 22915ffd83dbSDimitry Andric } 22920b57cec5SDimitry Andric break; 22935ffd83dbSDimitry Andric } 22945ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier( 22955ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 22965ffd83dbSDimitry Andric /*EnteringContext=*/false, &MayBePseudoDestructor); 22970b57cec5SDimitry Andric if (SS.isNotEmpty()) 22980b57cec5SDimitry Andric ObjectType = nullptr; 22990b57cec5SDimitry Andric } 23000b57cec5SDimitry Andric 23010b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 23020b57cec5SDimitry Andric tok::TokenKind CorrectedOpKind = 23030b57cec5SDimitry Andric OpKind == tok::arrow ? tok::period : tok::arrow; 23040b57cec5SDimitry Andric ExprResult CorrectedLHS(/*Invalid=*/true); 23050b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && OrigLHS) { 2306a7dea167SDimitry Andric // FIXME: Creating a TentativeAnalysisScope from outside Sema is a 2307a7dea167SDimitry Andric // hack. 2308a7dea167SDimitry Andric Sema::TentativeAnalysisScope Trap(Actions); 23090b57cec5SDimitry Andric CorrectedLHS = Actions.ActOnStartCXXMemberReference( 23100b57cec5SDimitry Andric getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType, 23110b57cec5SDimitry Andric MayBePseudoDestructor); 23120b57cec5SDimitry Andric } 23130b57cec5SDimitry Andric 23140b57cec5SDimitry Andric Expr *Base = LHS.get(); 23150b57cec5SDimitry Andric Expr *CorrectedBase = CorrectedLHS.get(); 23160b57cec5SDimitry Andric if (!CorrectedBase && !getLangOpts().CPlusPlus) 23170b57cec5SDimitry Andric CorrectedBase = Base; 23180b57cec5SDimitry Andric 23190b57cec5SDimitry Andric // Code completion for a member access expression. 2320fe6060f1SDimitry Andric cutOffParsing(); 23210fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteMemberReferenceExpr( 23220b57cec5SDimitry Andric getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, 23230b57cec5SDimitry Andric Base && ExprStatementTokLoc == Base->getBeginLoc(), 23240b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 23250b57cec5SDimitry Andric 23260b57cec5SDimitry Andric return ExprError(); 23270b57cec5SDimitry Andric } 23280b57cec5SDimitry Andric 23290b57cec5SDimitry Andric if (MayBePseudoDestructor && !LHS.isInvalid()) { 23300b57cec5SDimitry Andric LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 23310b57cec5SDimitry Andric ObjectType); 23320b57cec5SDimitry Andric break; 23330b57cec5SDimitry Andric } 23340b57cec5SDimitry Andric 23350b57cec5SDimitry Andric // Either the action has told us that this cannot be a 23360b57cec5SDimitry Andric // pseudo-destructor expression (based on the type of base 23370b57cec5SDimitry Andric // expression), or we didn't see a '~' in the right place. We 23380b57cec5SDimitry Andric // can still parse a destructor name here, but in that case it 23390b57cec5SDimitry Andric // names a real destructor. 23400b57cec5SDimitry Andric // Allow explicit constructor calls in Microsoft mode. 23410b57cec5SDimitry Andric // FIXME: Add support for explicit call of template constructor. 23420b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 23430b57cec5SDimitry Andric UnqualifiedId Name; 23440b57cec5SDimitry Andric if (getLangOpts().ObjC && OpKind == tok::period && 23450b57cec5SDimitry Andric Tok.is(tok::kw_class)) { 23460b57cec5SDimitry Andric // Objective-C++: 23470b57cec5SDimitry Andric // After a '.' in a member access expression, treat the keyword 23480b57cec5SDimitry Andric // 'class' as if it were an identifier. 23490b57cec5SDimitry Andric // 23500b57cec5SDimitry Andric // This hack allows property access to the 'class' method because it is 23510b57cec5SDimitry Andric // such a common method name. For other C++ keywords that are 23520b57cec5SDimitry Andric // Objective-C method names, one must use the message send syntax. 23530b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 23540b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 23550b57cec5SDimitry Andric Name.setIdentifier(Id, Loc); 23565ffd83dbSDimitry Andric } else if (ParseUnqualifiedId( 23575ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 23580b57cec5SDimitry Andric /*EnteringContext=*/false, 23590b57cec5SDimitry Andric /*AllowDestructorName=*/true, 23600b57cec5SDimitry Andric /*AllowConstructorName=*/ 23615ffd83dbSDimitry Andric getLangOpts().MicrosoftExt && SS.isNotEmpty(), 23625ffd83dbSDimitry Andric /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) { 23630b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 23640b57cec5SDimitry Andric LHS = ExprError(); 23650b57cec5SDimitry Andric } 23660b57cec5SDimitry Andric 23670b57cec5SDimitry Andric if (!LHS.isInvalid()) 23680b57cec5SDimitry Andric LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 23690b57cec5SDimitry Andric OpKind, SS, TemplateKWLoc, Name, 23700b57cec5SDimitry Andric CurParsedObjCImpl ? CurParsedObjCImpl->Dcl 23710b57cec5SDimitry Andric : nullptr); 23725ffd83dbSDimitry Andric if (!LHS.isInvalid()) { 23735ffd83dbSDimitry Andric if (Tok.is(tok::less)) 23740b57cec5SDimitry Andric checkPotentialAngleBracket(LHS); 23755ffd83dbSDimitry Andric } else if (OrigLHS && Name.isValid()) { 23765ffd83dbSDimitry Andric // Preserve the LHS if the RHS is an invalid member. 23775ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), 23785ffd83dbSDimitry Andric Name.getEndLoc(), {OrigLHS}); 23795ffd83dbSDimitry Andric } 23800b57cec5SDimitry Andric break; 23810b57cec5SDimitry Andric } 23820b57cec5SDimitry Andric case tok::plusplus: // postfix-expression: postfix-expression '++' 23830b57cec5SDimitry Andric case tok::minusminus: // postfix-expression: postfix-expression '--' 23840b57cec5SDimitry Andric if (!LHS.isInvalid()) { 23855ffd83dbSDimitry Andric Expr *Arg = LHS.get(); 23860b57cec5SDimitry Andric LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), 23875ffd83dbSDimitry Andric Tok.getKind(), Arg); 23885ffd83dbSDimitry Andric if (LHS.isInvalid()) 23895ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(), 23905ffd83dbSDimitry Andric Tok.getLocation(), Arg); 23910b57cec5SDimitry Andric } 23920b57cec5SDimitry Andric ConsumeToken(); 23930b57cec5SDimitry Andric break; 23940b57cec5SDimitry Andric } 23950b57cec5SDimitry Andric } 23960b57cec5SDimitry Andric } 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/ 23990b57cec5SDimitry Andric /// vec_step and we are at the start of an expression or a parenthesized 24000b57cec5SDimitry Andric /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the 24010b57cec5SDimitry Andric /// expression (isCastExpr == false) or the type (isCastExpr == true). 24020b57cec5SDimitry Andric /// 24030b57cec5SDimitry Andric /// \verbatim 24040b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 24050b57cec5SDimitry Andric /// 'sizeof' unary-expression 24060b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 24075f757f3fSDimitry Andric /// [Clang] '__datasizeof' unary-expression 24085f757f3fSDimitry Andric /// [Clang] '__datasizeof' '(' type-name ')' 24090b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 24100b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 24110b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 24120b57cec5SDimitry Andric /// [C++0x] 'alignof' '(' type-id ')' 24130b57cec5SDimitry Andric /// 24140b57cec5SDimitry Andric /// [GNU] typeof-specifier: 24150b57cec5SDimitry Andric /// typeof ( expressions ) 24160b57cec5SDimitry Andric /// typeof ( type-name ) 24170b57cec5SDimitry Andric /// [GNU/C++] typeof unary-expression 24185f757f3fSDimitry Andric /// [C23] typeof-specifier: 2419bdd1243dSDimitry Andric /// typeof '(' typeof-specifier-argument ')' 2420bdd1243dSDimitry Andric /// typeof_unqual '(' typeof-specifier-argument ')' 2421bdd1243dSDimitry Andric /// 2422bdd1243dSDimitry Andric /// typeof-specifier-argument: 2423bdd1243dSDimitry Andric /// expression 2424bdd1243dSDimitry Andric /// type-name 24250b57cec5SDimitry Andric /// 24260b57cec5SDimitry Andric /// [OpenCL 1.1 6.11.12] vec_step built-in function: 24270b57cec5SDimitry Andric /// vec_step ( expressions ) 24280b57cec5SDimitry Andric /// vec_step ( type-name ) 24290b57cec5SDimitry Andric /// \endverbatim 24300b57cec5SDimitry Andric ExprResult 24310b57cec5SDimitry Andric Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, 24320b57cec5SDimitry Andric bool &isCastExpr, 24330b57cec5SDimitry Andric ParsedType &CastTy, 24340b57cec5SDimitry Andric SourceRange &CastRange) { 24350b57cec5SDimitry Andric 2436bdd1243dSDimitry Andric assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof, 24375f757f3fSDimitry Andric tok::kw___datasizeof, tok::kw___alignof, tok::kw_alignof, 24385f757f3fSDimitry Andric tok::kw__Alignof, tok::kw_vec_step, 24395f757f3fSDimitry Andric tok::kw___builtin_omp_required_simd_align, 24405f757f3fSDimitry Andric tok::kw___builtin_vectorelements) && 24410b57cec5SDimitry Andric "Not a typeof/sizeof/alignof/vec_step expression!"); 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric ExprResult Operand; 24440b57cec5SDimitry Andric 24450b57cec5SDimitry Andric // If the operand doesn't start with an '(', it must be an expression. 24460b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) { 24470b57cec5SDimitry Andric // If construct allows a form without parenthesis, user may forget to put 24480b57cec5SDimitry Andric // pathenthesis around type name. 24495f757f3fSDimitry Andric if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, 24505f757f3fSDimitry Andric tok::kw_alignof, tok::kw__Alignof)) { 24510b57cec5SDimitry Andric if (isTypeIdUnambiguously()) { 24520b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 24530b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 245481ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 245581ad6265SDimitry Andric DeclaratorContext::TypeName); 24560b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 24570b57cec5SDimitry Andric 24580b57cec5SDimitry Andric SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); 24590b57cec5SDimitry Andric SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); 2460e8d8bef9SDimitry Andric if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) { 2461e8d8bef9SDimitry Andric Diag(OpTok.getLocation(), 2462e8d8bef9SDimitry Andric diag::err_expected_parentheses_around_typename) 2463e8d8bef9SDimitry Andric << OpTok.getName(); 2464e8d8bef9SDimitry Andric } else { 24650b57cec5SDimitry Andric Diag(LParenLoc, diag::err_expected_parentheses_around_typename) 2466e8d8bef9SDimitry Andric << OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(") 24670b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 2468e8d8bef9SDimitry Andric } 24690b57cec5SDimitry Andric isCastExpr = true; 24700b57cec5SDimitry Andric return ExprEmpty(); 24710b57cec5SDimitry Andric } 24720b57cec5SDimitry Andric } 24730b57cec5SDimitry Andric 24740b57cec5SDimitry Andric isCastExpr = false; 2475bdd1243dSDimitry Andric if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) && 2476bdd1243dSDimitry Andric !getLangOpts().CPlusPlus) { 24770b57cec5SDimitry Andric Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo() 24780b57cec5SDimitry Andric << tok::l_paren; 24790b57cec5SDimitry Andric return ExprError(); 24800b57cec5SDimitry Andric } 24810b57cec5SDimitry Andric 2482480093f4SDimitry Andric Operand = ParseCastExpression(UnaryExprOnly); 24830b57cec5SDimitry Andric } else { 24840b57cec5SDimitry Andric // If it starts with a '(', we know that it is either a parenthesized 24850b57cec5SDimitry Andric // type-name, or it is a unary-expression that starts with a compound 24860b57cec5SDimitry Andric // literal, or starts with a primary-expression that is a parenthesized 24870b57cec5SDimitry Andric // expression. 24880b57cec5SDimitry Andric ParenParseOption ExprType = CastExpr; 24890b57cec5SDimitry Andric SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 24900b57cec5SDimitry Andric 24910b57cec5SDimitry Andric Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 24920b57cec5SDimitry Andric false, CastTy, RParenLoc); 24930b57cec5SDimitry Andric CastRange = SourceRange(LParenLoc, RParenLoc); 24940b57cec5SDimitry Andric 24950b57cec5SDimitry Andric // If ParseParenExpression parsed a '(typename)' sequence only, then this is 24960b57cec5SDimitry Andric // a type. 24970b57cec5SDimitry Andric if (ExprType == CastExpr) { 24980b57cec5SDimitry Andric isCastExpr = true; 24990b57cec5SDimitry Andric return ExprEmpty(); 25000b57cec5SDimitry Andric } 25010b57cec5SDimitry Andric 2502bdd1243dSDimitry Andric if (getLangOpts().CPlusPlus || 2503bdd1243dSDimitry Andric !OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) { 25040b57cec5SDimitry Andric // GNU typeof in C requires the expression to be parenthesized. Not so for 25050b57cec5SDimitry Andric // sizeof/alignof or in C++. Therefore, the parenthesized expression is 25060b57cec5SDimitry Andric // the start of a unary-expression, but doesn't include any postfix 25070b57cec5SDimitry Andric // pieces. Parse these now if present. 25080b57cec5SDimitry Andric if (!Operand.isInvalid()) 25090b57cec5SDimitry Andric Operand = ParsePostfixExpressionSuffix(Operand.get()); 25100b57cec5SDimitry Andric } 25110b57cec5SDimitry Andric } 25120b57cec5SDimitry Andric 25130b57cec5SDimitry Andric // If we get here, the operand to the typeof/sizeof/alignof was an expression. 25140b57cec5SDimitry Andric isCastExpr = false; 25150b57cec5SDimitry Andric return Operand; 25160b57cec5SDimitry Andric } 25170b57cec5SDimitry Andric 2518fe6060f1SDimitry Andric /// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as 2519fe6060f1SDimitry Andric /// a parameter. 2520fe6060f1SDimitry Andric ExprResult Parser::ParseSYCLUniqueStableNameExpression() { 2521fe6060f1SDimitry Andric assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) && 2522349cc55cSDimitry Andric "Not __builtin_sycl_unique_stable_name"); 2523fe6060f1SDimitry Andric 2524fe6060f1SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 2525fe6060f1SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 2526fe6060f1SDimitry Andric 2527fe6060f1SDimitry Andric // __builtin_sycl_unique_stable_name expressions are always parenthesized. 2528fe6060f1SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, 2529fe6060f1SDimitry Andric "__builtin_sycl_unique_stable_name")) 2530fe6060f1SDimitry Andric return ExprError(); 2531fe6060f1SDimitry Andric 2532fe6060f1SDimitry Andric TypeResult Ty = ParseTypeName(); 2533fe6060f1SDimitry Andric 2534fe6060f1SDimitry Andric if (Ty.isInvalid()) { 2535fe6060f1SDimitry Andric T.skipToEnd(); 2536fe6060f1SDimitry Andric return ExprError(); 2537fe6060f1SDimitry Andric } 2538fe6060f1SDimitry Andric 2539fe6060f1SDimitry Andric if (T.consumeClose()) 2540fe6060f1SDimitry Andric return ExprError(); 2541fe6060f1SDimitry Andric 25420fca6ea1SDimitry Andric return Actions.SYCL().ActOnUniqueStableNameExpr( 25430fca6ea1SDimitry Andric OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get()); 2544fe6060f1SDimitry Andric } 25450b57cec5SDimitry Andric 25460b57cec5SDimitry Andric /// Parse a sizeof or alignof expression. 25470b57cec5SDimitry Andric /// 25480b57cec5SDimitry Andric /// \verbatim 25490b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 25500b57cec5SDimitry Andric /// 'sizeof' unary-expression 25510b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 25520b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 25535f757f3fSDimitry Andric /// [Clang] '__datasizeof' unary-expression 25545f757f3fSDimitry Andric /// [Clang] '__datasizeof' '(' type-name ')' 25550b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 25560b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 25570b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 25580b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 25590b57cec5SDimitry Andric /// \endverbatim 25600b57cec5SDimitry Andric ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { 25615f757f3fSDimitry Andric assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, 25625f757f3fSDimitry Andric tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, 25635f757f3fSDimitry Andric tok::kw___builtin_omp_required_simd_align, 25645f757f3fSDimitry Andric tok::kw___builtin_vectorelements) && 25650b57cec5SDimitry Andric "Not a sizeof/alignof/vec_step expression!"); 25660b57cec5SDimitry Andric Token OpTok = Tok; 25670b57cec5SDimitry Andric ConsumeToken(); 25680b57cec5SDimitry Andric 25690b57cec5SDimitry Andric // [C++11] 'sizeof' '...' '(' identifier ')' 25700b57cec5SDimitry Andric if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { 25710b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 25720b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 25730b57cec5SDimitry Andric IdentifierInfo *Name = nullptr; 25740b57cec5SDimitry Andric SourceLocation NameLoc; 25750b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 25760b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 25770b57cec5SDimitry Andric T.consumeOpen(); 25780b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 25790b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 25800b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 25810b57cec5SDimitry Andric NameLoc = ConsumeToken(); 25820b57cec5SDimitry Andric T.consumeClose(); 25830b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 25840b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 25850b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 25860b57cec5SDimitry Andric } else { 25870b57cec5SDimitry Andric Diag(Tok, diag::err_expected_parameter_pack); 25880b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25890b57cec5SDimitry Andric } 25900b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 25910b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 25920b57cec5SDimitry Andric NameLoc = ConsumeToken(); 25930b57cec5SDimitry Andric LParenLoc = PP.getLocForEndOfToken(EllipsisLoc); 25940b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 25950b57cec5SDimitry Andric Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack) 25960b57cec5SDimitry Andric << Name 25970b57cec5SDimitry Andric << FixItHint::CreateInsertion(LParenLoc, "(") 25980b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 25990b57cec5SDimitry Andric } else { 26000b57cec5SDimitry Andric Diag(Tok, diag::err_sizeof_parameter_pack); 26010b57cec5SDimitry Andric } 26020b57cec5SDimitry Andric 26030b57cec5SDimitry Andric if (!Name) 26040b57cec5SDimitry Andric return ExprError(); 26050b57cec5SDimitry Andric 26060b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 26070b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 26080b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 26090b57cec5SDimitry Andric 26100b57cec5SDimitry Andric return Actions.ActOnSizeofParameterPackExpr(getCurScope(), 26110b57cec5SDimitry Andric OpTok.getLocation(), 26120b57cec5SDimitry Andric *Name, NameLoc, 26130b57cec5SDimitry Andric RParenLoc); 26140b57cec5SDimitry Andric } 26150b57cec5SDimitry Andric 261606c3fb27SDimitry Andric if (getLangOpts().CPlusPlus && 261706c3fb27SDimitry Andric OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 26180b57cec5SDimitry Andric Diag(OpTok, diag::warn_cxx98_compat_alignof); 26195f757f3fSDimitry Andric else if (getLangOpts().C23 && OpTok.is(tok::kw_alignof)) 26205f757f3fSDimitry Andric Diag(OpTok, diag::warn_c23_compat_keyword) << OpTok.getName(); 26210b57cec5SDimitry Andric 26220b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 26230b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 26240b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 26250b57cec5SDimitry Andric 26260b57cec5SDimitry Andric bool isCastExpr; 26270b57cec5SDimitry Andric ParsedType CastTy; 26280b57cec5SDimitry Andric SourceRange CastRange; 26290b57cec5SDimitry Andric ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, 26300b57cec5SDimitry Andric isCastExpr, 26310b57cec5SDimitry Andric CastTy, 26320b57cec5SDimitry Andric CastRange); 26330b57cec5SDimitry Andric 26340b57cec5SDimitry Andric UnaryExprOrTypeTrait ExprKind = UETT_SizeOf; 26355f757f3fSDimitry Andric switch (OpTok.getKind()) { 26365f757f3fSDimitry Andric case tok::kw_alignof: 26375f757f3fSDimitry Andric case tok::kw__Alignof: 26380b57cec5SDimitry Andric ExprKind = UETT_AlignOf; 26395f757f3fSDimitry Andric break; 26405f757f3fSDimitry Andric case tok::kw___alignof: 26410b57cec5SDimitry Andric ExprKind = UETT_PreferredAlignOf; 26425f757f3fSDimitry Andric break; 26435f757f3fSDimitry Andric case tok::kw_vec_step: 26440b57cec5SDimitry Andric ExprKind = UETT_VecStep; 26455f757f3fSDimitry Andric break; 26465f757f3fSDimitry Andric case tok::kw___builtin_omp_required_simd_align: 26470b57cec5SDimitry Andric ExprKind = UETT_OpenMPRequiredSimdAlign; 26485f757f3fSDimitry Andric break; 26495f757f3fSDimitry Andric case tok::kw___datasizeof: 26505f757f3fSDimitry Andric ExprKind = UETT_DataSizeOf; 26515f757f3fSDimitry Andric break; 26525f757f3fSDimitry Andric case tok::kw___builtin_vectorelements: 26535f757f3fSDimitry Andric ExprKind = UETT_VectorElements; 26545f757f3fSDimitry Andric break; 26555f757f3fSDimitry Andric default: 26565f757f3fSDimitry Andric break; 26575f757f3fSDimitry Andric } 26580b57cec5SDimitry Andric 26590b57cec5SDimitry Andric if (isCastExpr) 26600b57cec5SDimitry Andric return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 26610b57cec5SDimitry Andric ExprKind, 26620b57cec5SDimitry Andric /*IsType=*/true, 26630b57cec5SDimitry Andric CastTy.getAsOpaquePtr(), 26640b57cec5SDimitry Andric CastRange); 26650b57cec5SDimitry Andric 26660b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 26670b57cec5SDimitry Andric Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); 26680b57cec5SDimitry Andric 26690b57cec5SDimitry Andric // If we get here, the operand to the sizeof/alignof was an expression. 26700b57cec5SDimitry Andric if (!Operand.isInvalid()) 26710b57cec5SDimitry Andric Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 26720b57cec5SDimitry Andric ExprKind, 26730b57cec5SDimitry Andric /*IsType=*/false, 26740b57cec5SDimitry Andric Operand.get(), 26750b57cec5SDimitry Andric CastRange); 26760b57cec5SDimitry Andric return Operand; 26770b57cec5SDimitry Andric } 26780b57cec5SDimitry Andric 26790b57cec5SDimitry Andric /// ParseBuiltinPrimaryExpression 26800b57cec5SDimitry Andric /// 26810b57cec5SDimitry Andric /// \verbatim 26820b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 26830b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 26840b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 26850b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 26860b57cec5SDimitry Andric /// assign-expr ')' 26870b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 26880b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 268906c3fb27SDimitry Andric /// [CLANG] '__builtin_FILE_NAME' '(' ')' 26900b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 269106c3fb27SDimitry Andric /// [MS] '__builtin_FUNCSIG' '(' ')' 26920b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 26930b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 269481ad6265SDimitry Andric /// [GNU] '__builtin_source_location' '(' ')' 26950b57cec5SDimitry Andric /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' 26960b57cec5SDimitry Andric /// 26970b57cec5SDimitry Andric /// [GNU] offsetof-member-designator: 26980b57cec5SDimitry Andric /// [GNU] identifier 26990b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '.' identifier 27000b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '[' expression ']' 27010b57cec5SDimitry Andric /// \endverbatim 27020b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinPrimaryExpression() { 27030b57cec5SDimitry Andric ExprResult Res; 27040b57cec5SDimitry Andric const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 27050b57cec5SDimitry Andric 27060b57cec5SDimitry Andric tok::TokenKind T = Tok.getKind(); 27070b57cec5SDimitry Andric SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 27080b57cec5SDimitry Andric 27090b57cec5SDimitry Andric // All of these start with an open paren. 27100b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) 27110b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII 27120b57cec5SDimitry Andric << tok::l_paren); 27130b57cec5SDimitry Andric 27140b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 27150b57cec5SDimitry Andric PT.consumeOpen(); 27160b57cec5SDimitry Andric 27170b57cec5SDimitry Andric // TODO: Build AST. 27180b57cec5SDimitry Andric 27190b57cec5SDimitry Andric switch (T) { 27200b57cec5SDimitry Andric default: llvm_unreachable("Not a builtin primary expression!"); 27210b57cec5SDimitry Andric case tok::kw___builtin_va_arg: { 27220b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 27230b57cec5SDimitry Andric 27240b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27250b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27260b57cec5SDimitry Andric Expr = ExprError(); 27270b57cec5SDimitry Andric } 27280b57cec5SDimitry Andric 27290b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 27300b57cec5SDimitry Andric 27310b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27320b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27330b57cec5SDimitry Andric Expr = ExprError(); 27340b57cec5SDimitry Andric } 27350b57cec5SDimitry Andric 27360b57cec5SDimitry Andric if (Expr.isInvalid() || Ty.isInvalid()) 27370b57cec5SDimitry Andric Res = ExprError(); 27380b57cec5SDimitry Andric else 27390b57cec5SDimitry Andric Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen()); 27400b57cec5SDimitry Andric break; 27410b57cec5SDimitry Andric } 27420b57cec5SDimitry Andric case tok::kw___builtin_offsetof: { 27430b57cec5SDimitry Andric SourceLocation TypeLoc = Tok.getLocation(); 2744bdd1243dSDimitry Andric auto OOK = Sema::OffsetOfKind::OOK_Builtin; 2745bdd1243dSDimitry Andric if (Tok.getLocation().isMacroID()) { 2746bdd1243dSDimitry Andric StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics( 2747bdd1243dSDimitry Andric Tok.getLocation(), PP.getSourceManager(), getLangOpts()); 2748bdd1243dSDimitry Andric if (MacroName == "offsetof") 2749bdd1243dSDimitry Andric OOK = Sema::OffsetOfKind::OOK_Macro; 2750bdd1243dSDimitry Andric } 2751bdd1243dSDimitry Andric TypeResult Ty; 2752bdd1243dSDimitry Andric { 2753bdd1243dSDimitry Andric OffsetOfStateRAIIObject InOffsetof(*this, OOK); 2754bdd1243dSDimitry Andric Ty = ParseTypeName(); 27550b57cec5SDimitry Andric if (Ty.isInvalid()) { 27560b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27570b57cec5SDimitry Andric return ExprError(); 27580b57cec5SDimitry Andric } 2759bdd1243dSDimitry Andric } 27600b57cec5SDimitry Andric 27610b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27620b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27630b57cec5SDimitry Andric return ExprError(); 27640b57cec5SDimitry Andric } 27650b57cec5SDimitry Andric 27660b57cec5SDimitry Andric // We must have at least one identifier here. 27670b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 27680b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 27690b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27700b57cec5SDimitry Andric return ExprError(); 27710b57cec5SDimitry Andric } 27720b57cec5SDimitry Andric 27730b57cec5SDimitry Andric // Keep track of the various subcomponents we see. 27740b57cec5SDimitry Andric SmallVector<Sema::OffsetOfComponent, 4> Comps; 27750b57cec5SDimitry Andric 27760b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 27770b57cec5SDimitry Andric Comps.back().isBrackets = false; 27780b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 27790b57cec5SDimitry Andric Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 27800b57cec5SDimitry Andric 27810b57cec5SDimitry Andric // FIXME: This loop leaks the index expressions on error. 278204eeddc0SDimitry Andric while (true) { 27830b57cec5SDimitry Andric if (Tok.is(tok::period)) { 27840b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-designator '.' identifier 27850b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 27860b57cec5SDimitry Andric Comps.back().isBrackets = false; 27870b57cec5SDimitry Andric Comps.back().LocStart = ConsumeToken(); 27880b57cec5SDimitry Andric 27890b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 27900b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 27910b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27920b57cec5SDimitry Andric return ExprError(); 27930b57cec5SDimitry Andric } 27940b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 27950b57cec5SDimitry Andric Comps.back().LocEnd = ConsumeToken(); 27960b57cec5SDimitry Andric } else if (Tok.is(tok::l_square)) { 27970b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 27980b57cec5SDimitry Andric return ExprError(); 27990b57cec5SDimitry Andric 28000b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-design '[' expression ']' 28010b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 28020b57cec5SDimitry Andric Comps.back().isBrackets = true; 28030b57cec5SDimitry Andric BalancedDelimiterTracker ST(*this, tok::l_square); 28040b57cec5SDimitry Andric ST.consumeOpen(); 28050b57cec5SDimitry Andric Comps.back().LocStart = ST.getOpenLocation(); 28060b57cec5SDimitry Andric Res = ParseExpression(); 28070b57cec5SDimitry Andric if (Res.isInvalid()) { 28080b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28090b57cec5SDimitry Andric return Res; 28100b57cec5SDimitry Andric } 28110b57cec5SDimitry Andric Comps.back().U.E = Res.get(); 28120b57cec5SDimitry Andric 28130b57cec5SDimitry Andric ST.consumeClose(); 28140b57cec5SDimitry Andric Comps.back().LocEnd = ST.getCloseLocation(); 28150b57cec5SDimitry Andric } else { 28160b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 28170b57cec5SDimitry Andric PT.consumeClose(); 28180b57cec5SDimitry Andric Res = ExprError(); 28190b57cec5SDimitry Andric } else if (Ty.isInvalid()) { 28200b57cec5SDimitry Andric Res = ExprError(); 28210b57cec5SDimitry Andric } else { 28220b57cec5SDimitry Andric PT.consumeClose(); 28230b57cec5SDimitry Andric Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc, 28240b57cec5SDimitry Andric Ty.get(), Comps, 28250b57cec5SDimitry Andric PT.getCloseLocation()); 28260b57cec5SDimitry Andric } 28270b57cec5SDimitry Andric break; 28280b57cec5SDimitry Andric } 28290b57cec5SDimitry Andric } 28300b57cec5SDimitry Andric break; 28310b57cec5SDimitry Andric } 28320b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: { 28330b57cec5SDimitry Andric ExprResult Cond(ParseAssignmentExpression()); 28340b57cec5SDimitry Andric if (Cond.isInvalid()) { 28350b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28360b57cec5SDimitry Andric return Cond; 28370b57cec5SDimitry Andric } 28380b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 28390b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28400b57cec5SDimitry Andric return ExprError(); 28410b57cec5SDimitry Andric } 28420b57cec5SDimitry Andric 28430b57cec5SDimitry Andric ExprResult Expr1(ParseAssignmentExpression()); 28440b57cec5SDimitry Andric if (Expr1.isInvalid()) { 28450b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28460b57cec5SDimitry Andric return Expr1; 28470b57cec5SDimitry Andric } 28480b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 28490b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28500b57cec5SDimitry Andric return ExprError(); 28510b57cec5SDimitry Andric } 28520b57cec5SDimitry Andric 28530b57cec5SDimitry Andric ExprResult Expr2(ParseAssignmentExpression()); 28540b57cec5SDimitry Andric if (Expr2.isInvalid()) { 28550b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28560b57cec5SDimitry Andric return Expr2; 28570b57cec5SDimitry Andric } 28580b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 28590b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 28600b57cec5SDimitry Andric return ExprError(); 28610b57cec5SDimitry Andric } 28620b57cec5SDimitry Andric Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(), 28630b57cec5SDimitry Andric Expr2.get(), ConsumeParen()); 28640b57cec5SDimitry Andric break; 28650b57cec5SDimitry Andric } 28660b57cec5SDimitry Andric case tok::kw___builtin_astype: { 28670b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 28680b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 28690b57cec5SDimitry Andric if (Expr.isInvalid()) { 28700b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28710b57cec5SDimitry Andric return ExprError(); 28720b57cec5SDimitry Andric } 28730b57cec5SDimitry Andric 28740b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 28750b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28760b57cec5SDimitry Andric return ExprError(); 28770b57cec5SDimitry Andric } 28780b57cec5SDimitry Andric 28790b57cec5SDimitry Andric // Second argument is the type to bitcast to. 28800b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 28810b57cec5SDimitry Andric if (DestTy.isInvalid()) 28820b57cec5SDimitry Andric return ExprError(); 28830b57cec5SDimitry Andric 28840b57cec5SDimitry Andric // Attempt to consume the r-paren. 28850b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 28860b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 28870b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28880b57cec5SDimitry Andric return ExprError(); 28890b57cec5SDimitry Andric } 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 28920b57cec5SDimitry Andric ConsumeParen()); 28930b57cec5SDimitry Andric break; 28940b57cec5SDimitry Andric } 28950b57cec5SDimitry Andric case tok::kw___builtin_convertvector: { 28960b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 28970b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 28980b57cec5SDimitry Andric if (Expr.isInvalid()) { 28990b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29000b57cec5SDimitry Andric return ExprError(); 29010b57cec5SDimitry Andric } 29020b57cec5SDimitry Andric 29030b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 29040b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29050b57cec5SDimitry Andric return ExprError(); 29060b57cec5SDimitry Andric } 29070b57cec5SDimitry Andric 29080b57cec5SDimitry Andric // Second argument is the type to bitcast to. 29090b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 29100b57cec5SDimitry Andric if (DestTy.isInvalid()) 29110b57cec5SDimitry Andric return ExprError(); 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andric // Attempt to consume the r-paren. 29140b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 29150b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 29160b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29170b57cec5SDimitry Andric return ExprError(); 29180b57cec5SDimitry Andric } 29190b57cec5SDimitry Andric 29200b57cec5SDimitry Andric Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 29210b57cec5SDimitry Andric ConsumeParen()); 29220b57cec5SDimitry Andric break; 29230b57cec5SDimitry Andric } 29240b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 29250b57cec5SDimitry Andric case tok::kw___builtin_FILE: 292606c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 29270b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 292806c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 292981ad6265SDimitry Andric case tok::kw___builtin_LINE: 293081ad6265SDimitry Andric case tok::kw___builtin_source_location: { 29310b57cec5SDimitry Andric // Attempt to consume the r-paren. 29320b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 29330b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 29340b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29350b57cec5SDimitry Andric return ExprError(); 29360b57cec5SDimitry Andric } 29375f757f3fSDimitry Andric SourceLocIdentKind Kind = [&] { 29380b57cec5SDimitry Andric switch (T) { 29390b57cec5SDimitry Andric case tok::kw___builtin_FILE: 29405f757f3fSDimitry Andric return SourceLocIdentKind::File; 294106c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 29425f757f3fSDimitry Andric return SourceLocIdentKind::FileName; 29430b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 29445f757f3fSDimitry Andric return SourceLocIdentKind::Function; 294506c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 29465f757f3fSDimitry Andric return SourceLocIdentKind::FuncSig; 29470b57cec5SDimitry Andric case tok::kw___builtin_LINE: 29485f757f3fSDimitry Andric return SourceLocIdentKind::Line; 29490b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 29505f757f3fSDimitry Andric return SourceLocIdentKind::Column; 295181ad6265SDimitry Andric case tok::kw___builtin_source_location: 29525f757f3fSDimitry Andric return SourceLocIdentKind::SourceLocStruct; 29530b57cec5SDimitry Andric default: 29540b57cec5SDimitry Andric llvm_unreachable("invalid keyword"); 29550b57cec5SDimitry Andric } 29560b57cec5SDimitry Andric }(); 29570b57cec5SDimitry Andric Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen()); 29580b57cec5SDimitry Andric break; 29590b57cec5SDimitry Andric } 29600b57cec5SDimitry Andric } 29610b57cec5SDimitry Andric 29620b57cec5SDimitry Andric if (Res.isInvalid()) 29630b57cec5SDimitry Andric return ExprError(); 29640b57cec5SDimitry Andric 29650b57cec5SDimitry Andric // These can be followed by postfix-expr pieces because they are 29660b57cec5SDimitry Andric // primary-expressions. 29670b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Res.get()); 29680b57cec5SDimitry Andric } 29690b57cec5SDimitry Andric 29705ffd83dbSDimitry Andric bool Parser::tryParseOpenMPArrayShapingCastPart() { 29715ffd83dbSDimitry Andric assert(Tok.is(tok::l_square) && "Expected open bracket"); 29725ffd83dbSDimitry Andric bool ErrorFound = true; 29735ffd83dbSDimitry Andric TentativeParsingAction TPA(*this); 29745ffd83dbSDimitry Andric do { 29755ffd83dbSDimitry Andric if (Tok.isNot(tok::l_square)) 29765ffd83dbSDimitry Andric break; 29775ffd83dbSDimitry Andric // Consume '[' 29785ffd83dbSDimitry Andric ConsumeBracket(); 29795ffd83dbSDimitry Andric // Skip inner expression. 29805ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end, 29815ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 29825ffd83dbSDimitry Andric ; 29835ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) 29845ffd83dbSDimitry Andric break; 29855ffd83dbSDimitry Andric // Consume ']' 29865ffd83dbSDimitry Andric ConsumeBracket(); 29875ffd83dbSDimitry Andric // Found ')' - done. 29885ffd83dbSDimitry Andric if (Tok.is(tok::r_paren)) { 29895ffd83dbSDimitry Andric ErrorFound = false; 29905ffd83dbSDimitry Andric break; 29915ffd83dbSDimitry Andric } 29925ffd83dbSDimitry Andric } while (Tok.isNot(tok::annot_pragma_openmp_end)); 29935ffd83dbSDimitry Andric TPA.Revert(); 29945ffd83dbSDimitry Andric return !ErrorFound; 29955ffd83dbSDimitry Andric } 29965ffd83dbSDimitry Andric 29970b57cec5SDimitry Andric /// ParseParenExpression - This parses the unit that starts with a '(' token, 29980b57cec5SDimitry Andric /// based on what is allowed by ExprType. The actual thing parsed is returned 29990b57cec5SDimitry Andric /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 30000b57cec5SDimitry Andric /// not the parsed cast-expression. 30010b57cec5SDimitry Andric /// 30020b57cec5SDimitry Andric /// \verbatim 30030b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 30040b57cec5SDimitry Andric /// '(' expression ')' 30050b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 30060b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 30070b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 30080b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 30090b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 30100b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 30110b57cec5SDimitry Andric /// [ARC] bridged-cast-expression 30120b57cec5SDimitry Andric /// [ARC] bridged-cast-expression: 30130b57cec5SDimitry Andric /// (__bridge type-name) cast-expression 30140b57cec5SDimitry Andric /// (__bridge_transfer type-name) cast-expression 30150b57cec5SDimitry Andric /// (__bridge_retained type-name) cast-expression 30160b57cec5SDimitry Andric /// fold-expression: [C++1z] 30170b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' ')' 30180b57cec5SDimitry Andric /// '(' '...' fold-operator cast-expression ')' 30190b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' 30200b57cec5SDimitry Andric /// fold-operator cast-expression ')' 30215ffd83dbSDimitry Andric /// [OPENMP] Array shaping operation 30225ffd83dbSDimitry Andric /// '(' '[' expression ']' { '[' expression ']' } cast-expression 30230b57cec5SDimitry Andric /// \endverbatim 30240b57cec5SDimitry Andric ExprResult 30250b57cec5SDimitry Andric Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 30260b57cec5SDimitry Andric bool isTypeCast, ParsedType &CastTy, 30270b57cec5SDimitry Andric SourceLocation &RParenLoc) { 30280b57cec5SDimitry Andric assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 30290b57cec5SDimitry Andric ColonProtectionRAIIObject ColonProtection(*this, false); 30300b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 30310b57cec5SDimitry Andric if (T.consumeOpen()) 30320b57cec5SDimitry Andric return ExprError(); 30330b57cec5SDimitry Andric SourceLocation OpenLoc = T.getOpenLocation(); 30340b57cec5SDimitry Andric 30350b57cec5SDimitry Andric PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc); 30360b57cec5SDimitry Andric 30370b57cec5SDimitry Andric ExprResult Result(true); 30380b57cec5SDimitry Andric bool isAmbiguousTypeId; 30390b57cec5SDimitry Andric CastTy = nullptr; 30400b57cec5SDimitry Andric 30410b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 3042fe6060f1SDimitry Andric cutOffParsing(); 30430fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteExpression( 30440b57cec5SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation()), 30450b57cec5SDimitry Andric /*IsParenthesized=*/ExprType >= CompoundLiteral); 30460b57cec5SDimitry Andric return ExprError(); 30470b57cec5SDimitry Andric } 30480b57cec5SDimitry Andric 30490b57cec5SDimitry Andric // Diagnose use of bridge casts in non-arc mode. 30500b57cec5SDimitry Andric bool BridgeCast = (getLangOpts().ObjC && 30510b57cec5SDimitry Andric Tok.isOneOf(tok::kw___bridge, 30520b57cec5SDimitry Andric tok::kw___bridge_transfer, 30530b57cec5SDimitry Andric tok::kw___bridge_retained, 30540b57cec5SDimitry Andric tok::kw___bridge_retain)); 30550b57cec5SDimitry Andric if (BridgeCast && !getLangOpts().ObjCAutoRefCount) { 30560b57cec5SDimitry Andric if (!TryConsumeToken(tok::kw___bridge)) { 30570b57cec5SDimitry Andric StringRef BridgeCastName = Tok.getName(); 30580b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 30590b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 30600b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc) 30610b57cec5SDimitry Andric << BridgeCastName 30620b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, ""); 30630b57cec5SDimitry Andric } 30640b57cec5SDimitry Andric BridgeCast = false; 30650b57cec5SDimitry Andric } 30660b57cec5SDimitry Andric 30670b57cec5SDimitry Andric // None of these cases should fall through with an invalid Result 30680b57cec5SDimitry Andric // unless they've already reported an error. 30690b57cec5SDimitry Andric if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 307081ad6265SDimitry Andric Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro 307181ad6265SDimitry Andric : diag::ext_gnu_statement_expr); 30720b57cec5SDimitry Andric 3073e8d8bef9SDimitry Andric checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin); 3074e8d8bef9SDimitry Andric 30750b57cec5SDimitry Andric if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) { 30760b57cec5SDimitry Andric Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope)); 30770b57cec5SDimitry Andric } else { 30780b57cec5SDimitry Andric // Find the nearest non-record decl context. Variables declared in a 30790b57cec5SDimitry Andric // statement expression behave as if they were declared in the enclosing 30800b57cec5SDimitry Andric // function, block, or other code construct. 30810b57cec5SDimitry Andric DeclContext *CodeDC = Actions.CurContext; 30820b57cec5SDimitry Andric while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) { 30830b57cec5SDimitry Andric CodeDC = CodeDC->getParent(); 30840b57cec5SDimitry Andric assert(CodeDC && !CodeDC->isFileContext() && 30850b57cec5SDimitry Andric "statement expr not in code context"); 30860b57cec5SDimitry Andric } 30870b57cec5SDimitry Andric Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false); 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric Actions.ActOnStartStmtExpr(); 30900b57cec5SDimitry Andric 30910b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatement(true)); 30920b57cec5SDimitry Andric ExprType = CompoundStmt; 30930b57cec5SDimitry Andric 30940b57cec5SDimitry Andric // If the substmt parsed correctly, build the AST node. 30950b57cec5SDimitry Andric if (!Stmt.isInvalid()) { 30968c27c554SDimitry Andric Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(), 30978c27c554SDimitry Andric Tok.getLocation()); 30980b57cec5SDimitry Andric } else { 30990b57cec5SDimitry Andric Actions.ActOnStmtExprError(); 31000b57cec5SDimitry Andric } 31010b57cec5SDimitry Andric } 31020b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && BridgeCast) { 31030b57cec5SDimitry Andric tok::TokenKind tokenKind = Tok.getKind(); 31040b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 31050b57cec5SDimitry Andric 31060b57cec5SDimitry Andric // Parse an Objective-C ARC ownership cast expression. 31070b57cec5SDimitry Andric ObjCBridgeCastKind Kind; 31080b57cec5SDimitry Andric if (tokenKind == tok::kw___bridge) 31090b57cec5SDimitry Andric Kind = OBC_Bridge; 31100b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_transfer) 31110b57cec5SDimitry Andric Kind = OBC_BridgeTransfer; 31120b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_retained) 31130b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 31140b57cec5SDimitry Andric else { 31150b57cec5SDimitry Andric // As a hopefully temporary workaround, allow __bridge_retain as 31160b57cec5SDimitry Andric // a synonym for __bridge_retained, but only in system headers. 31170b57cec5SDimitry Andric assert(tokenKind == tok::kw___bridge_retain); 31180b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 31190b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 31200b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain) 31210b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, 31220b57cec5SDimitry Andric "__bridge_retained"); 31230b57cec5SDimitry Andric } 31240b57cec5SDimitry Andric 31250b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 31260b57cec5SDimitry Andric T.consumeClose(); 31270b57cec5SDimitry Andric ColonProtection.restore(); 31280b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 31290b57cec5SDimitry Andric 31300b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); 3131480093f4SDimitry Andric ExprResult SubExpr = ParseCastExpression(AnyCastExpr); 31320b57cec5SDimitry Andric 31330b57cec5SDimitry Andric if (Ty.isInvalid() || SubExpr.isInvalid()) 31340b57cec5SDimitry Andric return ExprError(); 31350b57cec5SDimitry Andric 31360fca6ea1SDimitry Andric return Actions.ObjC().ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, 31370b57cec5SDimitry Andric BridgeKeywordLoc, Ty.get(), 31380b57cec5SDimitry Andric RParenLoc, SubExpr.get()); 31390b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && 31400b57cec5SDimitry Andric isTypeIdInParens(isAmbiguousTypeId)) { 31410b57cec5SDimitry Andric 31420b57cec5SDimitry Andric // Otherwise, this is a compound literal expression or cast expression. 31430b57cec5SDimitry Andric 31440b57cec5SDimitry Andric // In C++, if the type-id is ambiguous we disambiguate based on context. 31450b57cec5SDimitry Andric // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 31460b57cec5SDimitry Andric // in which case we should treat it as type-id. 31470b57cec5SDimitry Andric // if stopIfCastExpr is false, we need to determine the context past the 31480b57cec5SDimitry Andric // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 31490b57cec5SDimitry Andric if (isAmbiguousTypeId && !stopIfCastExpr) { 31500b57cec5SDimitry Andric ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T, 31510b57cec5SDimitry Andric ColonProtection); 31520b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 31530b57cec5SDimitry Andric return res; 31540b57cec5SDimitry Andric } 31550b57cec5SDimitry Andric 31560b57cec5SDimitry Andric // Parse the type declarator. 31570b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 31580b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 315981ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 316081ad6265SDimitry Andric DeclaratorContext::TypeName); 31610b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 31620b57cec5SDimitry Andric 31630b57cec5SDimitry Andric // If our type is followed by an identifier and either ':' or ']', then 31640b57cec5SDimitry Andric // this is probably an Objective-C message send where the leading '[' is 31650b57cec5SDimitry Andric // missing. Recover as if that were the case. 31660b57cec5SDimitry Andric if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && 31670b57cec5SDimitry Andric !InMessageExpression && getLangOpts().ObjC && 31680b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 31690b57cec5SDimitry Andric TypeResult Ty; 31700b57cec5SDimitry Andric { 31710b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31727a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 31730b57cec5SDimitry Andric } 31740b57cec5SDimitry Andric Result = ParseObjCMessageExpressionBody(SourceLocation(), 31750b57cec5SDimitry Andric SourceLocation(), 31760b57cec5SDimitry Andric Ty.get(), nullptr); 31770b57cec5SDimitry Andric } else { 31780b57cec5SDimitry Andric // Match the ')'. 31790b57cec5SDimitry Andric T.consumeClose(); 31800b57cec5SDimitry Andric ColonProtection.restore(); 31810b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 31820b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 31830b57cec5SDimitry Andric ExprType = CompoundLiteral; 31840b57cec5SDimitry Andric TypeResult Ty; 31850b57cec5SDimitry Andric { 31860b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31877a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 31880b57cec5SDimitry Andric } 31890b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 31900b57cec5SDimitry Andric } 31910b57cec5SDimitry Andric 31920b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 31930b57cec5SDimitry Andric // This could be OpenCL vector Literals 31940b57cec5SDimitry Andric if (getLangOpts().OpenCL) 31950b57cec5SDimitry Andric { 31960b57cec5SDimitry Andric TypeResult Ty; 31970b57cec5SDimitry Andric { 31980b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31997a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 32000b57cec5SDimitry Andric } 32010b57cec5SDimitry Andric if(Ty.isInvalid()) 32020b57cec5SDimitry Andric { 32030b57cec5SDimitry Andric return ExprError(); 32040b57cec5SDimitry Andric } 32050b57cec5SDimitry Andric QualType QT = Ty.get().get().getCanonicalType(); 32060b57cec5SDimitry Andric if (QT->isVectorType()) 32070b57cec5SDimitry Andric { 32080b57cec5SDimitry Andric // We parsed '(' vector-type-name ')' followed by '(' 32090b57cec5SDimitry Andric 32100b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 32110b57cec5SDimitry Andric // isVectorLiteral = true will make sure we don't parse any 32120b57cec5SDimitry Andric // Postfix expression yet 3213480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 32140b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 32150b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast, 32160b57cec5SDimitry Andric /*isVectorLiteral=*/true); 32170b57cec5SDimitry Andric 32180b57cec5SDimitry Andric if (!Result.isInvalid()) { 32190b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 32200b57cec5SDimitry Andric DeclaratorInfo, CastTy, 32210b57cec5SDimitry Andric RParenLoc, Result.get()); 32220b57cec5SDimitry Andric } 32230b57cec5SDimitry Andric 32240b57cec5SDimitry Andric // After we performed the cast we can check for postfix-expr pieces. 32250b57cec5SDimitry Andric if (!Result.isInvalid()) { 32260b57cec5SDimitry Andric Result = ParsePostfixExpressionSuffix(Result); 32270b57cec5SDimitry Andric } 32280b57cec5SDimitry Andric 32290b57cec5SDimitry Andric return Result; 32300b57cec5SDimitry Andric } 32310b57cec5SDimitry Andric } 32320b57cec5SDimitry Andric } 32330b57cec5SDimitry Andric 32340b57cec5SDimitry Andric if (ExprType == CastExpr) { 32350b57cec5SDimitry Andric // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 32360b57cec5SDimitry Andric 32370b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 32380b57cec5SDimitry Andric return ExprError(); 32390b57cec5SDimitry Andric 32400b57cec5SDimitry Andric // Note that this doesn't parse the subsequent cast-expression, it just 32410b57cec5SDimitry Andric // returns the parsed type to the callee. 32420b57cec5SDimitry Andric if (stopIfCastExpr) { 32430b57cec5SDimitry Andric TypeResult Ty; 32440b57cec5SDimitry Andric { 32450b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 32467a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 32470b57cec5SDimitry Andric } 32480b57cec5SDimitry Andric CastTy = Ty.get(); 32490b57cec5SDimitry Andric return ExprResult(); 32500b57cec5SDimitry Andric } 32510b57cec5SDimitry Andric 32520b57cec5SDimitry Andric // Reject the cast of super idiom in ObjC. 32530b57cec5SDimitry Andric if (Tok.is(tok::identifier) && getLangOpts().ObjC && 32540b57cec5SDimitry Andric Tok.getIdentifierInfo() == Ident_super && 32550b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 32560b57cec5SDimitry Andric GetLookAheadToken(1).isNot(tok::period)) { 32570b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_illegal_super_cast) 32580b57cec5SDimitry Andric << SourceRange(OpenLoc, RParenLoc); 32590b57cec5SDimitry Andric return ExprError(); 32600b57cec5SDimitry Andric } 32610b57cec5SDimitry Andric 32620b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get()); 32630b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 32640b57cec5SDimitry Andric // TODO: For cast expression with CastTy. 3265480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 32660b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 32670b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast); 32680b57cec5SDimitry Andric if (!Result.isInvalid()) { 32690b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 32700b57cec5SDimitry Andric DeclaratorInfo, CastTy, 32710b57cec5SDimitry Andric RParenLoc, Result.get()); 32720b57cec5SDimitry Andric } 32730b57cec5SDimitry Andric return Result; 32740b57cec5SDimitry Andric } 32750b57cec5SDimitry Andric 32760b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 32770b57cec5SDimitry Andric return ExprError(); 32780b57cec5SDimitry Andric } 32790b57cec5SDimitry Andric } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && 32800b57cec5SDimitry Andric isFoldOperator(NextToken().getKind())) { 32810b57cec5SDimitry Andric ExprType = FoldExpr; 32820b57cec5SDimitry Andric return ParseFoldExpression(ExprResult(), T); 32830b57cec5SDimitry Andric } else if (isTypeCast) { 32840b57cec5SDimitry Andric // Parse the expression-list. 32850b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 32860b57cec5SDimitry Andric ExprVector ArgExprs; 32870b57cec5SDimitry Andric 3288bdd1243dSDimitry Andric if (!ParseSimpleExpressionList(ArgExprs)) { 32890b57cec5SDimitry Andric // FIXME: If we ever support comma expressions as operands to 32900b57cec5SDimitry Andric // fold-expressions, we'll need to allow multiple ArgExprs here. 32910b57cec5SDimitry Andric if (ExprType >= FoldExpr && ArgExprs.size() == 1 && 32920b57cec5SDimitry Andric isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { 32930b57cec5SDimitry Andric ExprType = FoldExpr; 32940b57cec5SDimitry Andric return ParseFoldExpression(ArgExprs[0], T); 32950b57cec5SDimitry Andric } 32960b57cec5SDimitry Andric 32970b57cec5SDimitry Andric ExprType = SimpleExpr; 32980b57cec5SDimitry Andric Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), 32990b57cec5SDimitry Andric ArgExprs); 33000b57cec5SDimitry Andric } 33015ffd83dbSDimitry Andric } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing && 33025ffd83dbSDimitry Andric ExprType == CastExpr && Tok.is(tok::l_square) && 33035ffd83dbSDimitry Andric tryParseOpenMPArrayShapingCastPart()) { 33045ffd83dbSDimitry Andric bool ErrorFound = false; 33055ffd83dbSDimitry Andric SmallVector<Expr *, 4> OMPDimensions; 33065ffd83dbSDimitry Andric SmallVector<SourceRange, 4> OMPBracketsRanges; 33075ffd83dbSDimitry Andric do { 33085ffd83dbSDimitry Andric BalancedDelimiterTracker TS(*this, tok::l_square); 33095ffd83dbSDimitry Andric TS.consumeOpen(); 33105ffd83dbSDimitry Andric ExprResult NumElements = 33115ffd83dbSDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 33125ffd83dbSDimitry Andric if (!NumElements.isUsable()) { 33135ffd83dbSDimitry Andric ErrorFound = true; 33145ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::r_paren, 33155ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 33165ffd83dbSDimitry Andric ; 33175ffd83dbSDimitry Andric } 33185ffd83dbSDimitry Andric TS.consumeClose(); 33195ffd83dbSDimitry Andric OMPDimensions.push_back(NumElements.get()); 33205ffd83dbSDimitry Andric OMPBracketsRanges.push_back(TS.getRange()); 33215ffd83dbSDimitry Andric } while (Tok.isNot(tok::r_paren)); 33225ffd83dbSDimitry Andric // Match the ')'. 33235ffd83dbSDimitry Andric T.consumeClose(); 33245ffd83dbSDimitry Andric RParenLoc = T.getCloseLocation(); 33255ffd83dbSDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 33265ffd83dbSDimitry Andric if (ErrorFound) { 33275ffd83dbSDimitry Andric Result = ExprError(); 33285ffd83dbSDimitry Andric } else if (!Result.isInvalid()) { 33290fca6ea1SDimitry Andric Result = Actions.OpenMP().ActOnOMPArrayShapingExpr( 33305ffd83dbSDimitry Andric Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges); 33315ffd83dbSDimitry Andric } 33325ffd83dbSDimitry Andric return Result; 33330b57cec5SDimitry Andric } else { 33340b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 33350b57cec5SDimitry Andric 33360b57cec5SDimitry Andric Result = ParseExpression(MaybeTypeCast); 3337bdd1243dSDimitry Andric if (!getLangOpts().CPlusPlus && Result.isUsable()) { 33380b57cec5SDimitry Andric // Correct typos in non-C++ code earlier so that implicit-cast-like 33390b57cec5SDimitry Andric // expressions are parsed correctly. 33400b57cec5SDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(Result); 33410b57cec5SDimitry Andric } 33420b57cec5SDimitry Andric 33430b57cec5SDimitry Andric if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && 33440b57cec5SDimitry Andric NextToken().is(tok::ellipsis)) { 33450b57cec5SDimitry Andric ExprType = FoldExpr; 33460b57cec5SDimitry Andric return ParseFoldExpression(Result, T); 33470b57cec5SDimitry Andric } 33480b57cec5SDimitry Andric ExprType = SimpleExpr; 33490b57cec5SDimitry Andric 33500b57cec5SDimitry Andric // Don't build a paren expression unless we actually match a ')'. 33510b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 33520b57cec5SDimitry Andric Result = 33530b57cec5SDimitry Andric Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get()); 33540b57cec5SDimitry Andric } 33550b57cec5SDimitry Andric 33560b57cec5SDimitry Andric // Match the ')'. 33570b57cec5SDimitry Andric if (Result.isInvalid()) { 33580b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33590b57cec5SDimitry Andric return ExprError(); 33600b57cec5SDimitry Andric } 33610b57cec5SDimitry Andric 33620b57cec5SDimitry Andric T.consumeClose(); 33630b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 33640b57cec5SDimitry Andric return Result; 33650b57cec5SDimitry Andric } 33660b57cec5SDimitry Andric 33670b57cec5SDimitry Andric /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 33680b57cec5SDimitry Andric /// and we are at the left brace. 33690b57cec5SDimitry Andric /// 33700b57cec5SDimitry Andric /// \verbatim 33710b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 33720b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 33730b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 33740b57cec5SDimitry Andric /// \endverbatim 33750b57cec5SDimitry Andric ExprResult 33760b57cec5SDimitry Andric Parser::ParseCompoundLiteralExpression(ParsedType Ty, 33770b57cec5SDimitry Andric SourceLocation LParenLoc, 33780b57cec5SDimitry Andric SourceLocation RParenLoc) { 33790b57cec5SDimitry Andric assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 33800b57cec5SDimitry Andric if (!getLangOpts().C99) // Compound literals don't exist in C90. 33810b57cec5SDimitry Andric Diag(LParenLoc, diag::ext_c99_compound_literal); 3382e8d8bef9SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get()); 33830b57cec5SDimitry Andric ExprResult Result = ParseInitializer(); 33840b57cec5SDimitry Andric if (!Result.isInvalid() && Ty) 33850b57cec5SDimitry Andric return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get()); 33860b57cec5SDimitry Andric return Result; 33870b57cec5SDimitry Andric } 33880b57cec5SDimitry Andric 33890b57cec5SDimitry Andric /// ParseStringLiteralExpression - This handles the various token types that 33900b57cec5SDimitry Andric /// form string literals, and also handles string concatenation [C99 5.1.1.2, 33910b57cec5SDimitry Andric /// translation phase #6]. 33920b57cec5SDimitry Andric /// 33930b57cec5SDimitry Andric /// \verbatim 33940b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 33950b57cec5SDimitry Andric /// string-literal 33960b57cec5SDimitry Andric /// \verbatim 33970b57cec5SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) { 339806c3fb27SDimitry Andric return ParseStringLiteralExpression(AllowUserDefinedLiteral, 339906c3fb27SDimitry Andric /*Unevaluated=*/false); 340006c3fb27SDimitry Andric } 340106c3fb27SDimitry Andric 340206c3fb27SDimitry Andric ExprResult Parser::ParseUnevaluatedStringLiteralExpression() { 340306c3fb27SDimitry Andric return ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false, 340406c3fb27SDimitry Andric /*Unevaluated=*/true); 340506c3fb27SDimitry Andric } 340606c3fb27SDimitry Andric 340706c3fb27SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral, 340806c3fb27SDimitry Andric bool Unevaluated) { 34095f757f3fSDimitry Andric assert(tokenIsLikeStringLiteral(Tok, getLangOpts()) && 34105f757f3fSDimitry Andric "Not a string-literal-like token!"); 34110b57cec5SDimitry Andric 34125f757f3fSDimitry Andric // String concatenation. 34135f757f3fSDimitry Andric // Note: some keywords like __FUNCTION__ are not considered to be strings 34145f757f3fSDimitry Andric // for concatenation purposes, unless Microsoft extensions are enabled. 34150b57cec5SDimitry Andric SmallVector<Token, 4> StringToks; 34160b57cec5SDimitry Andric 34170b57cec5SDimitry Andric do { 34180b57cec5SDimitry Andric StringToks.push_back(Tok); 34195f757f3fSDimitry Andric ConsumeAnyToken(); 34205f757f3fSDimitry Andric } while (tokenIsLikeStringLiteral(Tok, getLangOpts())); 34210b57cec5SDimitry Andric 342206c3fb27SDimitry Andric if (Unevaluated) { 342306c3fb27SDimitry Andric assert(!AllowUserDefinedLiteral && "UDL are always evaluated"); 342406c3fb27SDimitry Andric return Actions.ActOnUnevaluatedStringLiteral(StringToks); 342506c3fb27SDimitry Andric } 342606c3fb27SDimitry Andric 34270b57cec5SDimitry Andric // Pass the set of string tokens, ready for concatenation, to the actions. 34280b57cec5SDimitry Andric return Actions.ActOnStringLiteral(StringToks, 34290b57cec5SDimitry Andric AllowUserDefinedLiteral ? getCurScope() 34300b57cec5SDimitry Andric : nullptr); 34310b57cec5SDimitry Andric } 34320b57cec5SDimitry Andric 34330b57cec5SDimitry Andric /// ParseGenericSelectionExpression - Parse a C11 generic-selection 34340b57cec5SDimitry Andric /// [C11 6.5.1.1]. 34350b57cec5SDimitry Andric /// 34360b57cec5SDimitry Andric /// \verbatim 34370b57cec5SDimitry Andric /// generic-selection: 34380b57cec5SDimitry Andric /// _Generic ( assignment-expression , generic-assoc-list ) 34390b57cec5SDimitry Andric /// generic-assoc-list: 34400b57cec5SDimitry Andric /// generic-association 34410b57cec5SDimitry Andric /// generic-assoc-list , generic-association 34420b57cec5SDimitry Andric /// generic-association: 34430b57cec5SDimitry Andric /// type-name : assignment-expression 34440b57cec5SDimitry Andric /// default : assignment-expression 34450b57cec5SDimitry Andric /// \endverbatim 344606c3fb27SDimitry Andric /// 344706c3fb27SDimitry Andric /// As an extension, Clang also accepts: 344806c3fb27SDimitry Andric /// \verbatim 344906c3fb27SDimitry Andric /// generic-selection: 345006c3fb27SDimitry Andric /// _Generic ( type-name, generic-assoc-list ) 345106c3fb27SDimitry Andric /// \endverbatim 34520b57cec5SDimitry Andric ExprResult Parser::ParseGenericSelectionExpression() { 34530b57cec5SDimitry Andric assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected"); 34540fca6ea1SDimitry Andric 34550fca6ea1SDimitry Andric diagnoseUseOfC11Keyword(Tok); 34560b57cec5SDimitry Andric 3457a7dea167SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 34580b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 34590b57cec5SDimitry Andric if (T.expectAndConsume()) 34600b57cec5SDimitry Andric return ExprError(); 34610b57cec5SDimitry Andric 346206c3fb27SDimitry Andric // We either have a controlling expression or we have a controlling type, and 346306c3fb27SDimitry Andric // we need to figure out which it is. 346406c3fb27SDimitry Andric TypeResult ControllingType; 34650b57cec5SDimitry Andric ExprResult ControllingExpr; 346606c3fb27SDimitry Andric if (isTypeIdForGenericSelection()) { 346706c3fb27SDimitry Andric ControllingType = ParseTypeName(); 346806c3fb27SDimitry Andric if (ControllingType.isInvalid()) { 346906c3fb27SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 347006c3fb27SDimitry Andric return ExprError(); 347106c3fb27SDimitry Andric } 347206c3fb27SDimitry Andric const auto *LIT = cast<LocInfoType>(ControllingType.get().get()); 347306c3fb27SDimitry Andric SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 34740fca6ea1SDimitry Andric Diag(Loc, getLangOpts().C2y ? diag::warn_c2y_compat_generic_with_type_arg 34750fca6ea1SDimitry Andric : diag::ext_c2y_generic_with_type_arg); 347606c3fb27SDimitry Andric } else { 34770b57cec5SDimitry Andric // C11 6.5.1.1p3 "The controlling expression of a generic selection is 34780b57cec5SDimitry Andric // not evaluated." 34790b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 34800b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 34810b57cec5SDimitry Andric ControllingExpr = 34820b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 34830b57cec5SDimitry Andric if (ControllingExpr.isInvalid()) { 34840b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34850b57cec5SDimitry Andric return ExprError(); 34860b57cec5SDimitry Andric } 34870b57cec5SDimitry Andric } 34880b57cec5SDimitry Andric 34890b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 34900b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34910b57cec5SDimitry Andric return ExprError(); 34920b57cec5SDimitry Andric } 34930b57cec5SDimitry Andric 34940b57cec5SDimitry Andric SourceLocation DefaultLoc; 3495bdd1243dSDimitry Andric SmallVector<ParsedType, 12> Types; 34960b57cec5SDimitry Andric ExprVector Exprs; 34970b57cec5SDimitry Andric do { 34980b57cec5SDimitry Andric ParsedType Ty; 34990b57cec5SDimitry Andric if (Tok.is(tok::kw_default)) { 35000b57cec5SDimitry Andric // C11 6.5.1.1p2 "A generic selection shall have no more than one default 35010b57cec5SDimitry Andric // generic association." 35020b57cec5SDimitry Andric if (!DefaultLoc.isInvalid()) { 35030b57cec5SDimitry Andric Diag(Tok, diag::err_duplicate_default_assoc); 35040b57cec5SDimitry Andric Diag(DefaultLoc, diag::note_previous_default_assoc); 35050b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 35060b57cec5SDimitry Andric return ExprError(); 35070b57cec5SDimitry Andric } 35080b57cec5SDimitry Andric DefaultLoc = ConsumeToken(); 35090b57cec5SDimitry Andric Ty = nullptr; 35100b57cec5SDimitry Andric } else { 35110b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 351281ad6265SDimitry Andric TypeResult TR = ParseTypeName(nullptr, DeclaratorContext::Association); 35130b57cec5SDimitry Andric if (TR.isInvalid()) { 35140b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 35150b57cec5SDimitry Andric return ExprError(); 35160b57cec5SDimitry Andric } 35170b57cec5SDimitry Andric Ty = TR.get(); 35180b57cec5SDimitry Andric } 35190b57cec5SDimitry Andric Types.push_back(Ty); 35200b57cec5SDimitry Andric 35210b57cec5SDimitry Andric if (ExpectAndConsume(tok::colon)) { 35220b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 35230b57cec5SDimitry Andric return ExprError(); 35240b57cec5SDimitry Andric } 35250b57cec5SDimitry Andric 35260b57cec5SDimitry Andric // FIXME: These expressions should be parsed in a potentially potentially 35270b57cec5SDimitry Andric // evaluated context. 35280b57cec5SDimitry Andric ExprResult ER( 35290b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); 35300b57cec5SDimitry Andric if (ER.isInvalid()) { 35310b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 35320b57cec5SDimitry Andric return ExprError(); 35330b57cec5SDimitry Andric } 35340b57cec5SDimitry Andric Exprs.push_back(ER.get()); 35350b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 35360b57cec5SDimitry Andric 35370b57cec5SDimitry Andric T.consumeClose(); 35380b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 35390b57cec5SDimitry Andric return ExprError(); 35400b57cec5SDimitry Andric 354106c3fb27SDimitry Andric void *ExprOrTy = ControllingExpr.isUsable() 354206c3fb27SDimitry Andric ? ControllingExpr.get() 354306c3fb27SDimitry Andric : ControllingType.get().getAsOpaquePtr(); 354406c3fb27SDimitry Andric 354506c3fb27SDimitry Andric return Actions.ActOnGenericSelectionExpr( 354606c3fb27SDimitry Andric KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(), 354706c3fb27SDimitry Andric ExprOrTy, Types, Exprs); 35480b57cec5SDimitry Andric } 35490b57cec5SDimitry Andric 35500b57cec5SDimitry Andric /// Parse A C++1z fold-expression after the opening paren and optional 35510b57cec5SDimitry Andric /// left-hand-side expression. 35520b57cec5SDimitry Andric /// 35530b57cec5SDimitry Andric /// \verbatim 35540b57cec5SDimitry Andric /// fold-expression: 35550b57cec5SDimitry Andric /// ( cast-expression fold-operator ... ) 35560b57cec5SDimitry Andric /// ( ... fold-operator cast-expression ) 35570b57cec5SDimitry Andric /// ( cast-expression fold-operator ... fold-operator cast-expression ) 35580b57cec5SDimitry Andric ExprResult Parser::ParseFoldExpression(ExprResult LHS, 35590b57cec5SDimitry Andric BalancedDelimiterTracker &T) { 35600b57cec5SDimitry Andric if (LHS.isInvalid()) { 35610b57cec5SDimitry Andric T.skipToEnd(); 35620b57cec5SDimitry Andric return true; 35630b57cec5SDimitry Andric } 35640b57cec5SDimitry Andric 35650b57cec5SDimitry Andric tok::TokenKind Kind = tok::unknown; 35660b57cec5SDimitry Andric SourceLocation FirstOpLoc; 35670b57cec5SDimitry Andric if (LHS.isUsable()) { 35680b57cec5SDimitry Andric Kind = Tok.getKind(); 35690b57cec5SDimitry Andric assert(isFoldOperator(Kind) && "missing fold-operator"); 35700b57cec5SDimitry Andric FirstOpLoc = ConsumeToken(); 35710b57cec5SDimitry Andric } 35720b57cec5SDimitry Andric 35730b57cec5SDimitry Andric assert(Tok.is(tok::ellipsis) && "not a fold-expression"); 35740b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 35750b57cec5SDimitry Andric 35760b57cec5SDimitry Andric ExprResult RHS; 35770b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 35780b57cec5SDimitry Andric if (!isFoldOperator(Tok.getKind())) 35790b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_fold_operator); 35800b57cec5SDimitry Andric 35810b57cec5SDimitry Andric if (Kind != tok::unknown && Tok.getKind() != Kind) 35820b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_fold_operator_mismatch) 35830b57cec5SDimitry Andric << SourceRange(FirstOpLoc); 35840b57cec5SDimitry Andric Kind = Tok.getKind(); 35850b57cec5SDimitry Andric ConsumeToken(); 35860b57cec5SDimitry Andric 35870b57cec5SDimitry Andric RHS = ParseExpression(); 35880b57cec5SDimitry Andric if (RHS.isInvalid()) { 35890b57cec5SDimitry Andric T.skipToEnd(); 35900b57cec5SDimitry Andric return true; 35910b57cec5SDimitry Andric } 35920b57cec5SDimitry Andric } 35930b57cec5SDimitry Andric 35940b57cec5SDimitry Andric Diag(EllipsisLoc, getLangOpts().CPlusPlus17 35950b57cec5SDimitry Andric ? diag::warn_cxx14_compat_fold_expression 35960b57cec5SDimitry Andric : diag::ext_fold_expression); 35970b57cec5SDimitry Andric 35980b57cec5SDimitry Andric T.consumeClose(); 3599e8d8bef9SDimitry Andric return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(), 3600e8d8bef9SDimitry Andric Kind, EllipsisLoc, RHS.get(), 3601e8d8bef9SDimitry Andric T.getCloseLocation()); 36020b57cec5SDimitry Andric } 36030b57cec5SDimitry Andric 36040fca6ea1SDimitry Andric void Parser::injectEmbedTokens() { 36050fca6ea1SDimitry Andric EmbedAnnotationData *Data = 36060fca6ea1SDimitry Andric reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue()); 36070fca6ea1SDimitry Andric MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>( 36080fca6ea1SDimitry Andric Data->BinaryData.size() * 2 - 1), 36090fca6ea1SDimitry Andric Data->BinaryData.size() * 2 - 1); 36100fca6ea1SDimitry Andric unsigned I = 0; 36110fca6ea1SDimitry Andric for (auto &Byte : Data->BinaryData) { 36120fca6ea1SDimitry Andric Toks[I].startToken(); 36130fca6ea1SDimitry Andric Toks[I].setKind(tok::binary_data); 36140fca6ea1SDimitry Andric Toks[I].setLocation(Tok.getLocation()); 36150fca6ea1SDimitry Andric Toks[I].setLength(1); 36160fca6ea1SDimitry Andric Toks[I].setLiteralData(&Byte); 36170fca6ea1SDimitry Andric if (I != ((Data->BinaryData.size() - 1) * 2)) { 36180fca6ea1SDimitry Andric Toks[I + 1].startToken(); 36190fca6ea1SDimitry Andric Toks[I + 1].setKind(tok::comma); 36200fca6ea1SDimitry Andric Toks[I + 1].setLocation(Tok.getLocation()); 36210fca6ea1SDimitry Andric } 36220fca6ea1SDimitry Andric I += 2; 36230fca6ea1SDimitry Andric } 36240fca6ea1SDimitry Andric PP.EnterTokenStream(std::move(Toks), /*DisableMacroExpansion=*/true, 36250fca6ea1SDimitry Andric /*IsReinject=*/true); 36260fca6ea1SDimitry Andric ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 36270fca6ea1SDimitry Andric } 36280fca6ea1SDimitry Andric 36290b57cec5SDimitry Andric /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 36300b57cec5SDimitry Andric /// 36310b57cec5SDimitry Andric /// \verbatim 36320b57cec5SDimitry Andric /// argument-expression-list: 36330b57cec5SDimitry Andric /// assignment-expression 36340b57cec5SDimitry Andric /// argument-expression-list , assignment-expression 36350b57cec5SDimitry Andric /// 36360b57cec5SDimitry Andric /// [C++] expression-list: 36370b57cec5SDimitry Andric /// [C++] assignment-expression 36380b57cec5SDimitry Andric /// [C++] expression-list , assignment-expression 36390b57cec5SDimitry Andric /// 36400b57cec5SDimitry Andric /// [C++0x] expression-list: 36410b57cec5SDimitry Andric /// [C++0x] initializer-list 36420b57cec5SDimitry Andric /// 36430b57cec5SDimitry Andric /// [C++0x] initializer-list 36440b57cec5SDimitry Andric /// [C++0x] initializer-clause ...[opt] 36450b57cec5SDimitry Andric /// [C++0x] initializer-list , initializer-clause ...[opt] 36460b57cec5SDimitry Andric /// 36470b57cec5SDimitry Andric /// [C++0x] initializer-clause: 36480b57cec5SDimitry Andric /// [C++0x] assignment-expression 36490b57cec5SDimitry Andric /// [C++0x] braced-init-list 36500b57cec5SDimitry Andric /// \endverbatim 36510b57cec5SDimitry Andric bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, 365281ad6265SDimitry Andric llvm::function_ref<void()> ExpressionStarts, 365381ad6265SDimitry Andric bool FailImmediatelyOnInvalidExpr, 365481ad6265SDimitry Andric bool EarlyTypoCorrection) { 36550b57cec5SDimitry Andric bool SawError = false; 365604eeddc0SDimitry Andric while (true) { 36570b57cec5SDimitry Andric if (ExpressionStarts) 36580b57cec5SDimitry Andric ExpressionStarts(); 36590b57cec5SDimitry Andric 36600b57cec5SDimitry Andric ExprResult Expr; 36610b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 36620b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 36630b57cec5SDimitry Andric Expr = ParseBraceInitializer(); 36640b57cec5SDimitry Andric } else 36650b57cec5SDimitry Andric Expr = ParseAssignmentExpression(); 36660b57cec5SDimitry Andric 366781ad6265SDimitry Andric if (EarlyTypoCorrection) 366881ad6265SDimitry Andric Expr = Actions.CorrectDelayedTyposInExpr(Expr); 366981ad6265SDimitry Andric 36700b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) 36710b57cec5SDimitry Andric Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); 36725ffd83dbSDimitry Andric else if (Tok.is(tok::code_completion)) { 36735ffd83dbSDimitry Andric // There's nothing to suggest in here as we parsed a full expression. 36745f757f3fSDimitry Andric // Instead fail and propagate the error since caller might have something 36755ffd83dbSDimitry Andric // the suggest, e.g. signature help in function call. Note that this is 36765ffd83dbSDimitry Andric // performed before pushing the \p Expr, so that signature help can report 36775ffd83dbSDimitry Andric // current argument correctly. 36785ffd83dbSDimitry Andric SawError = true; 36795ffd83dbSDimitry Andric cutOffParsing(); 36805ffd83dbSDimitry Andric break; 36815ffd83dbSDimitry Andric } 36820b57cec5SDimitry Andric if (Expr.isInvalid()) { 36830b57cec5SDimitry Andric SawError = true; 368481ad6265SDimitry Andric if (FailImmediatelyOnInvalidExpr) 368581ad6265SDimitry Andric break; 368681ad6265SDimitry Andric SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); 36870b57cec5SDimitry Andric } else { 36880b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 36890b57cec5SDimitry Andric } 36900b57cec5SDimitry Andric 36910b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 36920b57cec5SDimitry Andric break; 36930b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 36940b57cec5SDimitry Andric Token Comma = Tok; 3695bdd1243dSDimitry Andric ConsumeToken(); 36960b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 36970b57cec5SDimitry Andric } 36980b57cec5SDimitry Andric if (SawError) { 36990b57cec5SDimitry Andric // Ensure typos get diagnosed when errors were encountered while parsing the 37000b57cec5SDimitry Andric // expression list. 37010b57cec5SDimitry Andric for (auto &E : Exprs) { 37020b57cec5SDimitry Andric ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); 37030b57cec5SDimitry Andric if (Expr.isUsable()) E = Expr.get(); 37040b57cec5SDimitry Andric } 37050b57cec5SDimitry Andric } 37060b57cec5SDimitry Andric return SawError; 37070b57cec5SDimitry Andric } 37080b57cec5SDimitry Andric 37090b57cec5SDimitry Andric /// ParseSimpleExpressionList - A simple comma-separated list of expressions, 37100b57cec5SDimitry Andric /// used for misc language extensions. 37110b57cec5SDimitry Andric /// 37120b57cec5SDimitry Andric /// \verbatim 37130b57cec5SDimitry Andric /// simple-expression-list: 37140b57cec5SDimitry Andric /// assignment-expression 37150b57cec5SDimitry Andric /// simple-expression-list , assignment-expression 37160b57cec5SDimitry Andric /// \endverbatim 3717bdd1243dSDimitry Andric bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) { 371804eeddc0SDimitry Andric while (true) { 37190b57cec5SDimitry Andric ExprResult Expr = ParseAssignmentExpression(); 37200b57cec5SDimitry Andric if (Expr.isInvalid()) 37210b57cec5SDimitry Andric return true; 37220b57cec5SDimitry Andric 37230b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 37240b57cec5SDimitry Andric 3725bdd1243dSDimitry Andric // We might be parsing the LHS of a fold-expression. If we reached the fold 3726bdd1243dSDimitry Andric // operator, stop. 3727bdd1243dSDimitry Andric if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis)) 37280b57cec5SDimitry Andric return false; 37290b57cec5SDimitry Andric 37300b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 37310b57cec5SDimitry Andric Token Comma = Tok; 3732bdd1243dSDimitry Andric ConsumeToken(); 37330b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 37340b57cec5SDimitry Andric } 37350b57cec5SDimitry Andric } 37360b57cec5SDimitry Andric 37370b57cec5SDimitry Andric /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 37380b57cec5SDimitry Andric /// 37390b57cec5SDimitry Andric /// \verbatim 37400b57cec5SDimitry Andric /// [clang] block-id: 37410b57cec5SDimitry Andric /// [clang] specifier-qualifier-list block-declarator 37420b57cec5SDimitry Andric /// \endverbatim 37430b57cec5SDimitry Andric void Parser::ParseBlockId(SourceLocation CaretLoc) { 37440b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 3745fe6060f1SDimitry Andric cutOffParsing(); 37460fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteOrdinaryName( 37470fca6ea1SDimitry Andric getCurScope(), SemaCodeCompletion::PCC_Type); 3748fe6060f1SDimitry Andric return; 37490b57cec5SDimitry Andric } 37500b57cec5SDimitry Andric 37510b57cec5SDimitry Andric // Parse the specifier-qualifier-list piece. 37520b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 37530b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 37540b57cec5SDimitry Andric 37550b57cec5SDimitry Andric // Parse the block-declarator. 375681ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 375781ad6265SDimitry Andric DeclaratorContext::BlockLiteral); 3758e8d8bef9SDimitry Andric DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 37590b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 37600b57cec5SDimitry Andric 37610b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 37620b57cec5SDimitry Andric 37630b57cec5SDimitry Andric // Inform sema that we are starting a block. 37640b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope()); 37650b57cec5SDimitry Andric } 37660b57cec5SDimitry Andric 37670b57cec5SDimitry Andric /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 37680b57cec5SDimitry Andric /// like ^(int x){ return x+1; } 37690b57cec5SDimitry Andric /// 37700b57cec5SDimitry Andric /// \verbatim 37710b57cec5SDimitry Andric /// block-literal: 37720b57cec5SDimitry Andric /// [clang] '^' block-args[opt] compound-statement 37730b57cec5SDimitry Andric /// [clang] '^' block-id compound-statement 37740b57cec5SDimitry Andric /// [clang] block-args: 37750b57cec5SDimitry Andric /// [clang] '(' parameter-list ')' 37760b57cec5SDimitry Andric /// \endverbatim 37770b57cec5SDimitry Andric ExprResult Parser::ParseBlockLiteralExpression() { 37780b57cec5SDimitry Andric assert(Tok.is(tok::caret) && "block literal starts with ^"); 37790b57cec5SDimitry Andric SourceLocation CaretLoc = ConsumeToken(); 37800b57cec5SDimitry Andric 37810b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 37820b57cec5SDimitry Andric "block literal parsing"); 37830b57cec5SDimitry Andric 37840b57cec5SDimitry Andric // Enter a scope to hold everything within the block. This includes the 37850b57cec5SDimitry Andric // argument decls, decls within the compound expression, etc. This also 37860b57cec5SDimitry Andric // allows determining whether a variable reference inside the block is 37870b57cec5SDimitry Andric // within or outside of the block. 37880b57cec5SDimitry Andric ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 37890b57cec5SDimitry Andric Scope::CompoundStmtScope | Scope::DeclScope); 37900b57cec5SDimitry Andric 37910b57cec5SDimitry Andric // Inform sema that we are starting a block. 37920b57cec5SDimitry Andric Actions.ActOnBlockStart(CaretLoc, getCurScope()); 37930b57cec5SDimitry Andric 37940b57cec5SDimitry Andric // Parse the return type if present. 37950b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 379681ad6265SDimitry Andric Declarator ParamInfo(DS, ParsedAttributesView::none(), 379781ad6265SDimitry Andric DeclaratorContext::BlockLiteral); 3798e8d8bef9SDimitry Andric ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 37990b57cec5SDimitry Andric // FIXME: Since the return type isn't actually parsed, it can't be used to 38000b57cec5SDimitry Andric // fill ParamInfo with an initial valid range, so do it manually. 38010b57cec5SDimitry Andric ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 38020b57cec5SDimitry Andric 38030b57cec5SDimitry Andric // If this block has arguments, parse them. There is no ambiguity here with 38040b57cec5SDimitry Andric // the expression case, because the expression case requires a parameter list. 38050b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 38060b57cec5SDimitry Andric ParseParenDeclarator(ParamInfo); 38070b57cec5SDimitry Andric // Parse the pieces after the identifier as if we had "int(...)". 38080b57cec5SDimitry Andric // SetIdentifier sets the source range end, but in this case we're past 38090b57cec5SDimitry Andric // that location. 38100b57cec5SDimitry Andric SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 38110b57cec5SDimitry Andric ParamInfo.SetIdentifier(nullptr, CaretLoc); 38120b57cec5SDimitry Andric ParamInfo.SetRangeEnd(Tmp); 38130b57cec5SDimitry Andric if (ParamInfo.isInvalidType()) { 38140b57cec5SDimitry Andric // If there was an error parsing the arguments, they may have 38150b57cec5SDimitry Andric // tried to use ^(x+y) which requires an argument list. Just 38160b57cec5SDimitry Andric // skip the whole block literal. 38170b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 38180b57cec5SDimitry Andric return ExprError(); 38190b57cec5SDimitry Andric } 38200b57cec5SDimitry Andric 38210b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 38220b57cec5SDimitry Andric 38230b57cec5SDimitry Andric // Inform sema that we are starting a block. 38240b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 38250b57cec5SDimitry Andric } else if (!Tok.is(tok::l_brace)) { 38260b57cec5SDimitry Andric ParseBlockId(CaretLoc); 38270b57cec5SDimitry Andric } else { 38280b57cec5SDimitry Andric // Otherwise, pretend we saw (void). 38290b57cec5SDimitry Andric SourceLocation NoLoc; 38300b57cec5SDimitry Andric ParamInfo.AddTypeInfo( 38310b57cec5SDimitry Andric DeclaratorChunk::getFunction(/*HasProto=*/true, 38320b57cec5SDimitry Andric /*IsAmbiguous=*/false, 38330b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 38340b57cec5SDimitry Andric /*ArgInfo=*/nullptr, 38350b57cec5SDimitry Andric /*NumParams=*/0, 38360b57cec5SDimitry Andric /*EllipsisLoc=*/NoLoc, 38370b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 38380b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 38390b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, 38400b57cec5SDimitry Andric /*MutableLoc=*/NoLoc, EST_None, 38410b57cec5SDimitry Andric /*ESpecRange=*/SourceRange(), 38420b57cec5SDimitry Andric /*Exceptions=*/nullptr, 38430b57cec5SDimitry Andric /*ExceptionRanges=*/nullptr, 38440b57cec5SDimitry Andric /*NumExceptions=*/0, 38450b57cec5SDimitry Andric /*NoexceptExpr=*/nullptr, 38460b57cec5SDimitry Andric /*ExceptionSpecTokens=*/nullptr, 3847bdd1243dSDimitry Andric /*DeclsInPrototype=*/std::nullopt, 3848bdd1243dSDimitry Andric CaretLoc, CaretLoc, ParamInfo), 38490b57cec5SDimitry Andric CaretLoc); 38500b57cec5SDimitry Andric 38510b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 38520b57cec5SDimitry Andric 38530b57cec5SDimitry Andric // Inform sema that we are starting a block. 38540b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 38550b57cec5SDimitry Andric } 38560b57cec5SDimitry Andric 38570b57cec5SDimitry Andric 38580b57cec5SDimitry Andric ExprResult Result(true); 38590b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 38600b57cec5SDimitry Andric // Saw something like: ^expr 38610b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 38620b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 38630b57cec5SDimitry Andric return ExprError(); 38640b57cec5SDimitry Andric } 38650b57cec5SDimitry Andric 38660b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 38670b57cec5SDimitry Andric BlockScope.Exit(); 38680b57cec5SDimitry Andric if (!Stmt.isInvalid()) 38690b57cec5SDimitry Andric Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope()); 38700b57cec5SDimitry Andric else 38710b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 38720b57cec5SDimitry Andric return Result; 38730b57cec5SDimitry Andric } 38740b57cec5SDimitry Andric 38750b57cec5SDimitry Andric /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals. 38760b57cec5SDimitry Andric /// 38770b57cec5SDimitry Andric /// '__objc_yes' 38780b57cec5SDimitry Andric /// '__objc_no' 38790b57cec5SDimitry Andric ExprResult Parser::ParseObjCBoolLiteral() { 38800b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 38810fca6ea1SDimitry Andric return Actions.ObjC().ActOnObjCBoolLiteral(ConsumeToken(), Kind); 38820b57cec5SDimitry Andric } 38830b57cec5SDimitry Andric 38840b57cec5SDimitry Andric /// Validate availability spec list, emitting diagnostics if necessary. Returns 38850b57cec5SDimitry Andric /// true if invalid. 38860b57cec5SDimitry Andric static bool CheckAvailabilitySpecList(Parser &P, 38870b57cec5SDimitry Andric ArrayRef<AvailabilitySpec> AvailSpecs) { 38880b57cec5SDimitry Andric llvm::SmallSet<StringRef, 4> Platforms; 38890b57cec5SDimitry Andric bool HasOtherPlatformSpec = false; 38900b57cec5SDimitry Andric bool Valid = true; 38910b57cec5SDimitry Andric for (const auto &Spec : AvailSpecs) { 38920b57cec5SDimitry Andric if (Spec.isOtherPlatformSpec()) { 38930b57cec5SDimitry Andric if (HasOtherPlatformSpec) { 38940b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star); 38950b57cec5SDimitry Andric Valid = false; 38960b57cec5SDimitry Andric } 38970b57cec5SDimitry Andric 38980b57cec5SDimitry Andric HasOtherPlatformSpec = true; 38990b57cec5SDimitry Andric continue; 39000b57cec5SDimitry Andric } 39010b57cec5SDimitry Andric 39020b57cec5SDimitry Andric bool Inserted = Platforms.insert(Spec.getPlatform()).second; 39030b57cec5SDimitry Andric if (!Inserted) { 39040b57cec5SDimitry Andric // Rule out multiple version specs referring to the same platform. 39050b57cec5SDimitry Andric // For example, we emit an error for: 39060b57cec5SDimitry Andric // @available(macos 10.10, macos 10.11, *) 39070b57cec5SDimitry Andric StringRef Platform = Spec.getPlatform(); 39080b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform) 39090b57cec5SDimitry Andric << Spec.getEndLoc() << Platform; 39100b57cec5SDimitry Andric Valid = false; 39110b57cec5SDimitry Andric } 39120b57cec5SDimitry Andric } 39130b57cec5SDimitry Andric 39140b57cec5SDimitry Andric if (!HasOtherPlatformSpec) { 39150b57cec5SDimitry Andric SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc(); 39160b57cec5SDimitry Andric P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required) 39170b57cec5SDimitry Andric << FixItHint::CreateInsertion(InsertWildcardLoc, ", *"); 39180b57cec5SDimitry Andric return true; 39190b57cec5SDimitry Andric } 39200b57cec5SDimitry Andric 39210b57cec5SDimitry Andric return !Valid; 39220b57cec5SDimitry Andric } 39230b57cec5SDimitry Andric 39240b57cec5SDimitry Andric /// Parse availability query specification. 39250b57cec5SDimitry Andric /// 39260b57cec5SDimitry Andric /// availability-spec: 39270b57cec5SDimitry Andric /// '*' 39280b57cec5SDimitry Andric /// identifier version-tuple 3929bdd1243dSDimitry Andric std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() { 39300b57cec5SDimitry Andric if (Tok.is(tok::star)) { 39310b57cec5SDimitry Andric return AvailabilitySpec(ConsumeToken()); 39320b57cec5SDimitry Andric } else { 39330b57cec5SDimitry Andric // Parse the platform name. 39340b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 39350b57cec5SDimitry Andric cutOffParsing(); 39360fca6ea1SDimitry Andric Actions.CodeCompletion().CodeCompleteAvailabilityPlatformName(); 3937bdd1243dSDimitry Andric return std::nullopt; 39380b57cec5SDimitry Andric } 39390b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 39400b57cec5SDimitry Andric Diag(Tok, diag::err_avail_query_expected_platform_name); 3941bdd1243dSDimitry Andric return std::nullopt; 39420b57cec5SDimitry Andric } 39430b57cec5SDimitry Andric 39440b57cec5SDimitry Andric IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc(); 39450b57cec5SDimitry Andric SourceRange VersionRange; 39460b57cec5SDimitry Andric VersionTuple Version = ParseVersionTuple(VersionRange); 39470b57cec5SDimitry Andric 39480b57cec5SDimitry Andric if (Version.empty()) 3949bdd1243dSDimitry Andric return std::nullopt; 39500b57cec5SDimitry Andric 39510b57cec5SDimitry Andric StringRef GivenPlatform = PlatformIdentifier->Ident->getName(); 39520b57cec5SDimitry Andric StringRef Platform = 39530b57cec5SDimitry Andric AvailabilityAttr::canonicalizePlatformName(GivenPlatform); 39540b57cec5SDimitry Andric 39550fca6ea1SDimitry Andric if (AvailabilityAttr::getPrettyPlatformName(Platform).empty() || 39560fca6ea1SDimitry Andric (GivenPlatform.contains("xros") || GivenPlatform.contains("xrOS"))) { 39570b57cec5SDimitry Andric Diag(PlatformIdentifier->Loc, 39580b57cec5SDimitry Andric diag::err_avail_query_unrecognized_platform_name) 39590b57cec5SDimitry Andric << GivenPlatform; 3960bdd1243dSDimitry Andric return std::nullopt; 39610b57cec5SDimitry Andric } 39620b57cec5SDimitry Andric 39630b57cec5SDimitry Andric return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc, 39640b57cec5SDimitry Andric VersionRange.getEnd()); 39650b57cec5SDimitry Andric } 39660b57cec5SDimitry Andric } 39670b57cec5SDimitry Andric 39680b57cec5SDimitry Andric ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { 39690b57cec5SDimitry Andric assert(Tok.is(tok::kw___builtin_available) || 39700b57cec5SDimitry Andric Tok.isObjCAtKeyword(tok::objc_available)); 39710b57cec5SDimitry Andric 39720b57cec5SDimitry Andric // Eat the available or __builtin_available. 39730b57cec5SDimitry Andric ConsumeToken(); 39740b57cec5SDimitry Andric 39750b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 39760b57cec5SDimitry Andric if (Parens.expectAndConsume()) 39770b57cec5SDimitry Andric return ExprError(); 39780b57cec5SDimitry Andric 39790b57cec5SDimitry Andric SmallVector<AvailabilitySpec, 4> AvailSpecs; 39800b57cec5SDimitry Andric bool HasError = false; 39810b57cec5SDimitry Andric while (true) { 3982bdd1243dSDimitry Andric std::optional<AvailabilitySpec> Spec = ParseAvailabilitySpec(); 39830b57cec5SDimitry Andric if (!Spec) 39840b57cec5SDimitry Andric HasError = true; 39850b57cec5SDimitry Andric else 39860b57cec5SDimitry Andric AvailSpecs.push_back(*Spec); 39870b57cec5SDimitry Andric 39880b57cec5SDimitry Andric if (!TryConsumeToken(tok::comma)) 39890b57cec5SDimitry Andric break; 39900b57cec5SDimitry Andric } 39910b57cec5SDimitry Andric 39920b57cec5SDimitry Andric if (HasError) { 39930b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 39940b57cec5SDimitry Andric return ExprError(); 39950b57cec5SDimitry Andric } 39960b57cec5SDimitry Andric 39970b57cec5SDimitry Andric CheckAvailabilitySpecList(*this, AvailSpecs); 39980b57cec5SDimitry Andric 39990b57cec5SDimitry Andric if (Parens.consumeClose()) 40000b57cec5SDimitry Andric return ExprError(); 40010b57cec5SDimitry Andric 40020fca6ea1SDimitry Andric return Actions.ObjC().ActOnObjCAvailabilityCheckExpr( 40030fca6ea1SDimitry Andric AvailSpecs, BeginLoc, Parens.getCloseLocation()); 40040b57cec5SDimitry Andric } 4005