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" 330b57cec5SDimitry Andric #include "clang/Sema/TypoCorrection.h" 340b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 35bdd1243dSDimitry Andric #include <optional> 360b57cec5SDimitry Andric using namespace clang; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric /// Simple precedence-based parser for binary/ternary operators. 390b57cec5SDimitry Andric /// 400b57cec5SDimitry Andric /// Note: we diverge from the C99 grammar when parsing the assignment-expression 410b57cec5SDimitry Andric /// production. C99 specifies that the LHS of an assignment operator should be 420b57cec5SDimitry Andric /// parsed as a unary-expression, but consistency dictates that it be a 430b57cec5SDimitry Andric /// conditional-expession. In practice, the important thing here is that the 440b57cec5SDimitry Andric /// LHS of an assignment has to be an l-value, which productions between 450b57cec5SDimitry Andric /// unary-expression and conditional-expression don't produce. Because we want 460b57cec5SDimitry Andric /// consistency, we parse the LHS as a conditional-expression, then check for 470b57cec5SDimitry Andric /// l-value-ness in semantic analysis stages. 480b57cec5SDimitry Andric /// 490b57cec5SDimitry Andric /// \verbatim 500b57cec5SDimitry Andric /// pm-expression: [C++ 5.5] 510b57cec5SDimitry Andric /// cast-expression 520b57cec5SDimitry Andric /// pm-expression '.*' cast-expression 530b57cec5SDimitry Andric /// pm-expression '->*' cast-expression 540b57cec5SDimitry Andric /// 550b57cec5SDimitry Andric /// multiplicative-expression: [C99 6.5.5] 560b57cec5SDimitry Andric /// Note: in C++, apply pm-expression instead of cast-expression 570b57cec5SDimitry Andric /// cast-expression 580b57cec5SDimitry Andric /// multiplicative-expression '*' cast-expression 590b57cec5SDimitry Andric /// multiplicative-expression '/' cast-expression 600b57cec5SDimitry Andric /// multiplicative-expression '%' cast-expression 610b57cec5SDimitry Andric /// 620b57cec5SDimitry Andric /// additive-expression: [C99 6.5.6] 630b57cec5SDimitry Andric /// multiplicative-expression 640b57cec5SDimitry Andric /// additive-expression '+' multiplicative-expression 650b57cec5SDimitry Andric /// additive-expression '-' multiplicative-expression 660b57cec5SDimitry Andric /// 670b57cec5SDimitry Andric /// shift-expression: [C99 6.5.7] 680b57cec5SDimitry Andric /// additive-expression 690b57cec5SDimitry Andric /// shift-expression '<<' additive-expression 700b57cec5SDimitry Andric /// shift-expression '>>' additive-expression 710b57cec5SDimitry Andric /// 720b57cec5SDimitry Andric /// compare-expression: [C++20 expr.spaceship] 730b57cec5SDimitry Andric /// shift-expression 740b57cec5SDimitry Andric /// compare-expression '<=>' shift-expression 750b57cec5SDimitry Andric /// 760b57cec5SDimitry Andric /// relational-expression: [C99 6.5.8] 770b57cec5SDimitry Andric /// compare-expression 780b57cec5SDimitry Andric /// relational-expression '<' compare-expression 790b57cec5SDimitry Andric /// relational-expression '>' compare-expression 800b57cec5SDimitry Andric /// relational-expression '<=' compare-expression 810b57cec5SDimitry Andric /// relational-expression '>=' compare-expression 820b57cec5SDimitry Andric /// 830b57cec5SDimitry Andric /// equality-expression: [C99 6.5.9] 840b57cec5SDimitry Andric /// relational-expression 850b57cec5SDimitry Andric /// equality-expression '==' relational-expression 860b57cec5SDimitry Andric /// equality-expression '!=' relational-expression 870b57cec5SDimitry Andric /// 880b57cec5SDimitry Andric /// AND-expression: [C99 6.5.10] 890b57cec5SDimitry Andric /// equality-expression 900b57cec5SDimitry Andric /// AND-expression '&' equality-expression 910b57cec5SDimitry Andric /// 920b57cec5SDimitry Andric /// exclusive-OR-expression: [C99 6.5.11] 930b57cec5SDimitry Andric /// AND-expression 940b57cec5SDimitry Andric /// exclusive-OR-expression '^' AND-expression 950b57cec5SDimitry Andric /// 960b57cec5SDimitry Andric /// inclusive-OR-expression: [C99 6.5.12] 970b57cec5SDimitry Andric /// exclusive-OR-expression 980b57cec5SDimitry Andric /// inclusive-OR-expression '|' exclusive-OR-expression 990b57cec5SDimitry Andric /// 1000b57cec5SDimitry Andric /// logical-AND-expression: [C99 6.5.13] 1010b57cec5SDimitry Andric /// inclusive-OR-expression 1020b57cec5SDimitry Andric /// logical-AND-expression '&&' inclusive-OR-expression 1030b57cec5SDimitry Andric /// 1040b57cec5SDimitry Andric /// logical-OR-expression: [C99 6.5.14] 1050b57cec5SDimitry Andric /// logical-AND-expression 1060b57cec5SDimitry Andric /// logical-OR-expression '||' logical-AND-expression 1070b57cec5SDimitry Andric /// 1080b57cec5SDimitry Andric /// conditional-expression: [C99 6.5.15] 1090b57cec5SDimitry Andric /// logical-OR-expression 1100b57cec5SDimitry Andric /// logical-OR-expression '?' expression ':' conditional-expression 1110b57cec5SDimitry Andric /// [GNU] logical-OR-expression '?' ':' conditional-expression 1120b57cec5SDimitry Andric /// [C++] the third operand is an assignment-expression 1130b57cec5SDimitry Andric /// 1140b57cec5SDimitry Andric /// assignment-expression: [C99 6.5.16] 1150b57cec5SDimitry Andric /// conditional-expression 1160b57cec5SDimitry Andric /// unary-expression assignment-operator assignment-expression 1170b57cec5SDimitry Andric /// [C++] throw-expression [C++ 15] 1180b57cec5SDimitry Andric /// 1190b57cec5SDimitry Andric /// assignment-operator: one of 1200b57cec5SDimitry Andric /// = *= /= %= += -= <<= >>= &= ^= |= 1210b57cec5SDimitry Andric /// 1220b57cec5SDimitry Andric /// expression: [C99 6.5.17] 1230b57cec5SDimitry Andric /// assignment-expression ...[opt] 1240b57cec5SDimitry Andric /// expression ',' assignment-expression ...[opt] 1250b57cec5SDimitry Andric /// \endverbatim 1260b57cec5SDimitry Andric ExprResult Parser::ParseExpression(TypeCastState isTypeCast) { 1270b57cec5SDimitry Andric ExprResult LHS(ParseAssignmentExpression(isTypeCast)); 1280b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric /// This routine is called when the '@' is seen and consumed. 1320b57cec5SDimitry Andric /// Current token is an Identifier and is not a 'try'. This 1330b57cec5SDimitry Andric /// routine is necessary to disambiguate \@try-statement from, 1340b57cec5SDimitry Andric /// for example, \@encode-expression. 1350b57cec5SDimitry Andric /// 1360b57cec5SDimitry Andric ExprResult 1370b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { 1380b57cec5SDimitry Andric ExprResult LHS(ParseObjCAtExpression(AtLoc)); 1390b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric /// This routine is called when a leading '__extension__' is seen and 1430b57cec5SDimitry Andric /// consumed. This is necessary because the token gets consumed in the 1440b57cec5SDimitry Andric /// process of disambiguating between an expression and a declaration. 1450b57cec5SDimitry Andric ExprResult 1460b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { 1470b57cec5SDimitry Andric ExprResult LHS(true); 1480b57cec5SDimitry Andric { 1490b57cec5SDimitry Andric // Silence extension warnings in the sub-expression 1500b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); 1510b57cec5SDimitry Andric 152480093f4SDimitry Andric LHS = ParseCastExpression(AnyCastExpr); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric if (!LHS.isInvalid()) 1560b57cec5SDimitry Andric LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__, 1570b57cec5SDimitry Andric LHS.get()); 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric /// Parse an expr that doesn't include (top-level) commas. 1630b57cec5SDimitry Andric ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { 1640b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 165fe6060f1SDimitry Andric cutOffParsing(); 1660b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 1670b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 1680b57cec5SDimitry Andric return ExprError(); 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric if (Tok.is(tok::kw_throw)) 1720b57cec5SDimitry Andric return ParseThrowExpression(); 1730b57cec5SDimitry Andric if (Tok.is(tok::kw_co_yield)) 1740b57cec5SDimitry Andric return ParseCoyieldExpression(); 1750b57cec5SDimitry Andric 176480093f4SDimitry Andric ExprResult LHS = ParseCastExpression(AnyCastExpr, 1770b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 1780b57cec5SDimitry Andric isTypeCast); 1790b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Assignment); 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric /// Parse an assignment expression where part of an Objective-C message 1830b57cec5SDimitry Andric /// send has already been parsed. 1840b57cec5SDimitry Andric /// 1850b57cec5SDimitry Andric /// In this case \p LBracLoc indicates the location of the '[' of the message 1860b57cec5SDimitry Andric /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating 1870b57cec5SDimitry Andric /// the receiver of the message. 1880b57cec5SDimitry Andric /// 1890b57cec5SDimitry Andric /// Since this handles full assignment-expression's, it handles postfix 1900b57cec5SDimitry Andric /// expressions and other binary operators for these expressions as well. 1910b57cec5SDimitry Andric ExprResult 1920b57cec5SDimitry Andric Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, 1930b57cec5SDimitry Andric SourceLocation SuperLoc, 1940b57cec5SDimitry Andric ParsedType ReceiverType, 1950b57cec5SDimitry Andric Expr *ReceiverExpr) { 1960b57cec5SDimitry Andric ExprResult R 1970b57cec5SDimitry Andric = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, 1980b57cec5SDimitry Andric ReceiverType, ReceiverExpr); 1990b57cec5SDimitry Andric R = ParsePostfixExpressionSuffix(R); 2000b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(R, prec::Assignment); 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric ExprResult 2040b57cec5SDimitry Andric Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) { 2050b57cec5SDimitry Andric assert(Actions.ExprEvalContexts.back().Context == 2060b57cec5SDimitry Andric Sema::ExpressionEvaluationContext::ConstantEvaluated && 2070b57cec5SDimitry Andric "Call this function only if your ExpressionEvaluationContext is " 2080b57cec5SDimitry Andric "already ConstantEvaluated"); 209480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, isTypeCast)); 2100b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2110b57cec5SDimitry Andric return Actions.ActOnConstantExpression(Res); 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 214bdd1243dSDimitry Andric ExprResult Parser::ParseConstantExpression() { 2150b57cec5SDimitry Andric // C++03 [basic.def.odr]p2: 2160b57cec5SDimitry Andric // An expression is potentially evaluated unless it appears where an 2170b57cec5SDimitry Andric // integral constant expression is required (see 5.19) [...]. 2180b57cec5SDimitry Andric // C++98 and C++11 have no such rule, but this is only a defect in C++98. 2190b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2200b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 221bdd1243dSDimitry Andric return ParseConstantExpressionInExprEvalContext(NotTypeCast); 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2245f757f3fSDimitry Andric ExprResult Parser::ParseArrayBoundExpression() { 2255f757f3fSDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2265f757f3fSDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 2275f757f3fSDimitry Andric // If we parse the bound of a VLA... we parse a non-constant 2285f757f3fSDimitry Andric // constant-expression! 2295f757f3fSDimitry Andric Actions.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true; 2305f757f3fSDimitry Andric return ParseConstantExpressionInExprEvalContext(NotTypeCast); 2315f757f3fSDimitry Andric } 2325f757f3fSDimitry Andric 2330b57cec5SDimitry Andric ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) { 2340b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2350b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 236480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); 2370b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2380b57cec5SDimitry Andric return Actions.ActOnCaseExpr(CaseLoc, Res); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric /// Parse a constraint-expression. 2420b57cec5SDimitry Andric /// 2430b57cec5SDimitry Andric /// \verbatim 244a7dea167SDimitry Andric /// constraint-expression: C++2a[temp.constr.decl]p1 2450b57cec5SDimitry Andric /// logical-or-expression 2460b57cec5SDimitry Andric /// \endverbatim 2470b57cec5SDimitry Andric ExprResult Parser::ParseConstraintExpression() { 248a7dea167SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 24955e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 250480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr)); 2510b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); 252480093f4SDimitry Andric if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) { 253480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(Res); 254a7dea167SDimitry Andric return ExprError(); 255480093f4SDimitry Andric } 2560b57cec5SDimitry Andric return Res; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 259480093f4SDimitry Andric /// \brief Parse a constraint-logical-and-expression. 260480093f4SDimitry Andric /// 261480093f4SDimitry Andric /// \verbatim 262480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 263480093f4SDimitry Andric /// constraint-logical-and-expression: 264480093f4SDimitry Andric /// primary-expression 265480093f4SDimitry Andric /// constraint-logical-and-expression '&&' primary-expression 266480093f4SDimitry Andric /// 267480093f4SDimitry Andric /// \endverbatim 268480093f4SDimitry Andric ExprResult 269480093f4SDimitry Andric Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { 270480093f4SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 27155e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 272480093f4SDimitry Andric bool NotPrimaryExpression = false; 273480093f4SDimitry Andric auto ParsePrimary = [&] () { 274480093f4SDimitry Andric ExprResult E = ParseCastExpression(PrimaryExprOnly, 275480093f4SDimitry Andric /*isAddressOfOperand=*/false, 276480093f4SDimitry Andric /*isTypeCast=*/NotTypeCast, 277480093f4SDimitry Andric /*isVectorLiteral=*/false, 278480093f4SDimitry Andric &NotPrimaryExpression); 279480093f4SDimitry Andric if (E.isInvalid()) 280480093f4SDimitry Andric return ExprError(); 281480093f4SDimitry Andric auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) { 282480093f4SDimitry Andric E = ParsePostfixExpressionSuffix(E); 283480093f4SDimitry Andric // Use InclusiveOr, the precedence just after '&&' to not parse the 284480093f4SDimitry Andric // next arguments to the logical and. 285480093f4SDimitry Andric E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr); 286480093f4SDimitry Andric if (!E.isInvalid()) 287480093f4SDimitry Andric Diag(E.get()->getExprLoc(), 288480093f4SDimitry Andric Note 289480093f4SDimitry Andric ? diag::note_unparenthesized_non_primary_expr_in_requires_clause 290480093f4SDimitry Andric : diag::err_unparenthesized_non_primary_expr_in_requires_clause) 291480093f4SDimitry Andric << FixItHint::CreateInsertion(E.get()->getBeginLoc(), "(") 292480093f4SDimitry Andric << FixItHint::CreateInsertion( 293480093f4SDimitry Andric PP.getLocForEndOfToken(E.get()->getEndLoc()), ")") 294480093f4SDimitry Andric << E.get()->getSourceRange(); 295480093f4SDimitry Andric return E; 296480093f4SDimitry Andric }; 297480093f4SDimitry Andric 298480093f4SDimitry Andric if (NotPrimaryExpression || 299480093f4SDimitry Andric // Check if the following tokens must be a part of a non-primary 300480093f4SDimitry Andric // expression 301480093f4SDimitry Andric getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 302480093f4SDimitry Andric /*CPlusPlus11=*/true) > prec::LogicalAnd || 303480093f4SDimitry Andric // Postfix operators other than '(' (which will be checked for in 304480093f4SDimitry Andric // CheckConstraintExpression). 305480093f4SDimitry Andric Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) || 306480093f4SDimitry Andric (Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) { 307480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/false); 308480093f4SDimitry Andric if (E.isInvalid()) 309480093f4SDimitry Andric return ExprError(); 310480093f4SDimitry Andric NotPrimaryExpression = false; 311480093f4SDimitry Andric } 312480093f4SDimitry Andric bool PossibleNonPrimary; 313480093f4SDimitry Andric bool IsConstraintExpr = 314480093f4SDimitry Andric Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary, 315480093f4SDimitry Andric IsTrailingRequiresClause); 316480093f4SDimitry Andric if (!IsConstraintExpr || PossibleNonPrimary) { 317480093f4SDimitry Andric // Atomic constraint might be an unparenthesized non-primary expression 318480093f4SDimitry Andric // (such as a binary operator), in which case we might get here (e.g. in 319480093f4SDimitry Andric // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore 320480093f4SDimitry Andric // the rest of the addition expression). Try to parse the rest of it here. 321480093f4SDimitry Andric if (PossibleNonPrimary) 322480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr); 323480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 324480093f4SDimitry Andric return ExprError(); 325480093f4SDimitry Andric } 326480093f4SDimitry Andric return E; 327480093f4SDimitry Andric }; 328480093f4SDimitry Andric ExprResult LHS = ParsePrimary(); 329480093f4SDimitry Andric if (LHS.isInvalid()) 330480093f4SDimitry Andric return ExprError(); 331480093f4SDimitry Andric while (Tok.is(tok::ampamp)) { 332480093f4SDimitry Andric SourceLocation LogicalAndLoc = ConsumeToken(); 333480093f4SDimitry Andric ExprResult RHS = ParsePrimary(); 334480093f4SDimitry Andric if (RHS.isInvalid()) { 335480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 336480093f4SDimitry Andric return ExprError(); 337480093f4SDimitry Andric } 338480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc, 339480093f4SDimitry Andric tok::ampamp, LHS.get(), RHS.get()); 340480093f4SDimitry Andric if (!Op.isUsable()) { 341480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 342480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 343480093f4SDimitry Andric return ExprError(); 344480093f4SDimitry Andric } 345480093f4SDimitry Andric LHS = Op; 346480093f4SDimitry Andric } 347480093f4SDimitry Andric return LHS; 348480093f4SDimitry Andric } 349480093f4SDimitry Andric 350480093f4SDimitry Andric /// \brief Parse a constraint-logical-or-expression. 351480093f4SDimitry Andric /// 352480093f4SDimitry Andric /// \verbatim 353480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 354480093f4SDimitry Andric /// constraint-logical-or-expression: 355480093f4SDimitry Andric /// constraint-logical-and-expression 356480093f4SDimitry Andric /// constraint-logical-or-expression '||' 357480093f4SDimitry Andric /// constraint-logical-and-expression 358480093f4SDimitry Andric /// 359480093f4SDimitry Andric /// \endverbatim 360480093f4SDimitry Andric ExprResult 361480093f4SDimitry Andric Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) { 362480093f4SDimitry Andric ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause)); 363480093f4SDimitry Andric if (!LHS.isUsable()) 364480093f4SDimitry Andric return ExprError(); 365480093f4SDimitry Andric while (Tok.is(tok::pipepipe)) { 366480093f4SDimitry Andric SourceLocation LogicalOrLoc = ConsumeToken(); 367480093f4SDimitry Andric ExprResult RHS = 368480093f4SDimitry Andric ParseConstraintLogicalAndExpression(IsTrailingRequiresClause); 369480093f4SDimitry Andric if (!RHS.isUsable()) { 370480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 371480093f4SDimitry Andric return ExprError(); 372480093f4SDimitry Andric } 373480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc, 374480093f4SDimitry Andric tok::pipepipe, LHS.get(), RHS.get()); 375480093f4SDimitry Andric if (!Op.isUsable()) { 376480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 377480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 378480093f4SDimitry Andric return ExprError(); 379480093f4SDimitry Andric } 380480093f4SDimitry Andric LHS = Op; 381480093f4SDimitry Andric } 382480093f4SDimitry Andric return LHS; 383480093f4SDimitry Andric } 384480093f4SDimitry Andric 3850b57cec5SDimitry Andric bool Parser::isNotExpressionStart() { 3860b57cec5SDimitry Andric tok::TokenKind K = Tok.getKind(); 3870b57cec5SDimitry Andric if (K == tok::l_brace || K == tok::r_brace || 3880b57cec5SDimitry Andric K == tok::kw_for || K == tok::kw_while || 3890b57cec5SDimitry Andric K == tok::kw_if || K == tok::kw_else || 3900b57cec5SDimitry Andric K == tok::kw_goto || K == tok::kw_try) 3910b57cec5SDimitry Andric return true; 3920b57cec5SDimitry Andric // If this is a decl-specifier, we can't be at the start of an expression. 3930b57cec5SDimitry Andric return isKnownToBeDeclarationSpecifier(); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric bool Parser::isFoldOperator(prec::Level Level) const { 3970b57cec5SDimitry Andric return Level > prec::Unknown && Level != prec::Conditional && 3980b57cec5SDimitry Andric Level != prec::Spaceship; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric bool Parser::isFoldOperator(tok::TokenKind Kind) const { 4020b57cec5SDimitry Andric return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric /// Parse a binary expression that starts with \p LHS and has a 4060b57cec5SDimitry Andric /// precedence of at least \p MinPrec. 4070b57cec5SDimitry Andric ExprResult 4080b57cec5SDimitry Andric Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { 4090b57cec5SDimitry Andric prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(), 4100b57cec5SDimitry Andric GreaterThanIsOperator, 4110b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 4120b57cec5SDimitry Andric SourceLocation ColonLoc; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric auto SavedType = PreferredType; 41504eeddc0SDimitry Andric while (true) { 4160b57cec5SDimitry Andric // Every iteration may rely on a preferred type for the whole expression. 4170b57cec5SDimitry Andric PreferredType = SavedType; 4180b57cec5SDimitry Andric // If this token has a lower precedence than we are allowed to parse (e.g. 4190b57cec5SDimitry Andric // because we are called recursively, or because the token is not a binop), 4200b57cec5SDimitry Andric // then we are done! 4210b57cec5SDimitry Andric if (NextTokPrec < MinPrec) 4220b57cec5SDimitry Andric return LHS; 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric // Consume the operator, saving the operator token for error reporting. 4250b57cec5SDimitry Andric Token OpToken = Tok; 4260b57cec5SDimitry Andric ConsumeToken(); 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric if (OpToken.is(tok::caretcaret)) { 4290b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or)); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric // If we're potentially in a template-id, we may now be able to determine 4330b57cec5SDimitry Andric // whether we're actually in one or not. 4340b57cec5SDimitry Andric if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater, 4350b57cec5SDimitry Andric tok::greatergreatergreater) && 4360b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(OpToken)) 4370b57cec5SDimitry Andric return ExprError(); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric // Bail out when encountering a comma followed by a token which can't 4400b57cec5SDimitry Andric // possibly be the start of an expression. For instance: 4410b57cec5SDimitry Andric // int f() { return 1, } 4420b57cec5SDimitry Andric // We can't do this before consuming the comma, because 4430b57cec5SDimitry Andric // isNotExpressionStart() looks at the token stream. 4440b57cec5SDimitry Andric if (OpToken.is(tok::comma) && isNotExpressionStart()) { 4450b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4460b57cec5SDimitry Andric Tok = OpToken; 4470b57cec5SDimitry Andric return LHS; 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric // If the next token is an ellipsis, then this is a fold-expression. Leave 4510b57cec5SDimitry Andric // it alone so we can handle it in the paren expression. 4520b57cec5SDimitry Andric if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) { 4530b57cec5SDimitry Andric // FIXME: We can't check this via lookahead before we consume the token 4540b57cec5SDimitry Andric // because that tickles a lexer bug. 4550b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4560b57cec5SDimitry Andric Tok = OpToken; 4570b57cec5SDimitry Andric return LHS; 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric // In Objective-C++, alternative operator tokens can be used as keyword args 4610b57cec5SDimitry Andric // in message expressions. Unconsume the token so that it can reinterpreted 4620b57cec5SDimitry Andric // as an identifier in ParseObjCMessageExpressionBody. i.e., we support: 4630b57cec5SDimitry Andric // [foo meth:0 and:0]; 4640b57cec5SDimitry Andric // [foo not_eq]; 4650b57cec5SDimitry Andric if (getLangOpts().ObjC && getLangOpts().CPlusPlus && 4660b57cec5SDimitry Andric Tok.isOneOf(tok::colon, tok::r_square) && 4670b57cec5SDimitry Andric OpToken.getIdentifierInfo() != nullptr) { 4680b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4690b57cec5SDimitry Andric Tok = OpToken; 4700b57cec5SDimitry Andric return LHS; 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric // Special case handling for the ternary operator. 4740b57cec5SDimitry Andric ExprResult TernaryMiddle(true); 4750b57cec5SDimitry Andric if (NextTokPrec == prec::Conditional) { 4760b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 4770b57cec5SDimitry Andric // Parse a braced-init-list here for error recovery purposes. 4780b57cec5SDimitry Andric SourceLocation BraceLoc = Tok.getLocation(); 4790b57cec5SDimitry Andric TernaryMiddle = ParseBraceInitializer(); 4800b57cec5SDimitry Andric if (!TernaryMiddle.isInvalid()) { 4810b57cec5SDimitry Andric Diag(BraceLoc, diag::err_init_list_bin_op) 4820b57cec5SDimitry Andric << /*RHS*/ 1 << PP.getSpelling(OpToken) 4830b57cec5SDimitry Andric << Actions.getExprRange(TernaryMiddle.get()); 4840b57cec5SDimitry Andric TernaryMiddle = ExprError(); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric } else if (Tok.isNot(tok::colon)) { 4870b57cec5SDimitry Andric // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 4880b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric // Handle this production specially: 4910b57cec5SDimitry Andric // logical-OR-expression '?' expression ':' conditional-expression 4920b57cec5SDimitry Andric // In particular, the RHS of the '?' is 'expression', not 4930b57cec5SDimitry Andric // 'logical-OR-expression' as we might expect. 4940b57cec5SDimitry Andric TernaryMiddle = ParseExpression(); 4950b57cec5SDimitry Andric } else { 4960b57cec5SDimitry Andric // Special case handling of "X ? Y : Z" where Y is empty: 4970b57cec5SDimitry Andric // logical-OR-expression '?' ':' conditional-expression [GNU] 4980b57cec5SDimitry Andric TernaryMiddle = nullptr; 4990b57cec5SDimitry Andric Diag(Tok, diag::ext_gnu_conditional_expr); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 5030b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5040b57cec5SDimitry Andric LHS = ExprError(); 5050b57cec5SDimitry Andric TernaryMiddle = nullptr; 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric if (!TryConsumeToken(tok::colon, ColonLoc)) { 5090b57cec5SDimitry Andric // Otherwise, we're missing a ':'. Assume that this was a typo that 5100b57cec5SDimitry Andric // the user forgot. If we're not in a macro expansion, we can suggest 5110b57cec5SDimitry Andric // a fixit hint. If there were two spaces before the current token, 5120b57cec5SDimitry Andric // suggest inserting the colon in between them, otherwise insert ": ". 5130b57cec5SDimitry Andric SourceLocation FILoc = Tok.getLocation(); 5140b57cec5SDimitry Andric const char *FIText = ": "; 5150b57cec5SDimitry Andric const SourceManager &SM = PP.getSourceManager(); 5160b57cec5SDimitry Andric if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) { 5170b57cec5SDimitry Andric assert(FILoc.isFileID()); 5180b57cec5SDimitry Andric bool IsInvalid = false; 5190b57cec5SDimitry Andric const char *SourcePtr = 5200b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid); 5210b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5220b57cec5SDimitry Andric SourcePtr = 5230b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid); 5240b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5250b57cec5SDimitry Andric FILoc = FILoc.getLocWithOffset(-1); 5260b57cec5SDimitry Andric FIText = ":"; 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric Diag(Tok, diag::err_expected) 5320b57cec5SDimitry Andric << tok::colon << FixItHint::CreateInsertion(FILoc, FIText); 5330b57cec5SDimitry Andric Diag(OpToken, diag::note_matching) << tok::question; 5340b57cec5SDimitry Andric ColonLoc = Tok.getLocation(); 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(), 5390b57cec5SDimitry Andric OpToken.getKind()); 5400b57cec5SDimitry Andric // Parse another leaf here for the RHS of the operator. 5410b57cec5SDimitry Andric // ParseCastExpression works here because all RHS expressions in C have it 5420b57cec5SDimitry Andric // as a prefix, at least. However, in C++, an assignment-expression could 5430b57cec5SDimitry Andric // be a throw-expression, which is not a valid cast-expression. 5440b57cec5SDimitry Andric // Therefore we need some special-casing here. 5450b57cec5SDimitry Andric // Also note that the third operand of the conditional operator is 5460b57cec5SDimitry Andric // an assignment-expression in C++, and in C++11, we can have a 5470b57cec5SDimitry Andric // braced-init-list on the RHS of an assignment. For better diagnostics, 5480b57cec5SDimitry Andric // parse as if we were allowed braced-init-lists everywhere, and check that 5490b57cec5SDimitry Andric // they only appear on the RHS of assignments later. 5500b57cec5SDimitry Andric ExprResult RHS; 5510b57cec5SDimitry Andric bool RHSIsInitList = false; 5520b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5530b57cec5SDimitry Andric RHS = ParseBraceInitializer(); 5540b57cec5SDimitry Andric RHSIsInitList = true; 5550b57cec5SDimitry Andric } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional) 5560b57cec5SDimitry Andric RHS = ParseAssignmentExpression(); 5570b57cec5SDimitry Andric else 558480093f4SDimitry Andric RHS = ParseCastExpression(AnyCastExpr); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric if (RHS.isInvalid()) { 5610b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5620b57cec5SDimitry Andric // printed before errors from parsing the RHS, not after. 5630b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5640b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 5650b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 5660b57cec5SDimitry Andric LHS = ExprError(); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric // Remember the precedence of this operator and get the precedence of the 5700b57cec5SDimitry Andric // operator immediately to the right of the RHS. 5710b57cec5SDimitry Andric prec::Level ThisPrec = NextTokPrec; 5720b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 5730b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric // Assignment and conditional expressions are right-associative. 5760b57cec5SDimitry Andric bool isRightAssoc = ThisPrec == prec::Conditional || 5770b57cec5SDimitry Andric ThisPrec == prec::Assignment; 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric // Get the precedence of the operator to the right of the RHS. If it binds 5800b57cec5SDimitry Andric // more tightly with RHS than we do, evaluate it completely first. 5810b57cec5SDimitry Andric if (ThisPrec < NextTokPrec || 5820b57cec5SDimitry Andric (ThisPrec == NextTokPrec && isRightAssoc)) { 5830b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 5840b57cec5SDimitry Andric Diag(Tok, diag::err_init_list_bin_op) 5850b57cec5SDimitry Andric << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get()); 5860b57cec5SDimitry Andric RHS = ExprError(); 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric // If this is left-associative, only parse things on the RHS that bind 5890b57cec5SDimitry Andric // more tightly than the current operator. If it is left-associative, it 5900b57cec5SDimitry Andric // is okay, to bind exactly as tightly. For example, compile A=B=C=D as 5910b57cec5SDimitry Andric // A=(B=(C=D)), where each paren is a level of recursion here. 5920b57cec5SDimitry Andric // The function takes ownership of the RHS. 5930b57cec5SDimitry Andric RHS = ParseRHSOfBinaryExpression(RHS, 5940b57cec5SDimitry Andric static_cast<prec::Level>(ThisPrec + !isRightAssoc)); 5950b57cec5SDimitry Andric RHSIsInitList = false; 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric if (RHS.isInvalid()) { 5980b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5990b57cec5SDimitry Andric // printed before errors from ParseRHSOfBinaryExpression, not after. 6000b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 6010b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 6020b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6030b57cec5SDimitry Andric LHS = ExprError(); 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 6070b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 6110b57cec5SDimitry Andric if (ThisPrec == prec::Assignment) { 6120b57cec5SDimitry Andric Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists) 6130b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6140b57cec5SDimitry Andric } else if (ColonLoc.isValid()) { 6150b57cec5SDimitry Andric Diag(ColonLoc, diag::err_init_list_bin_op) 6160b57cec5SDimitry Andric << /*RHS*/1 << ":" 6170b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6180b57cec5SDimitry Andric LHS = ExprError(); 6190b57cec5SDimitry Andric } else { 6200b57cec5SDimitry Andric Diag(OpToken, diag::err_init_list_bin_op) 6210b57cec5SDimitry Andric << /*RHS*/1 << PP.getSpelling(OpToken) 6220b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6230b57cec5SDimitry Andric LHS = ExprError(); 6240b57cec5SDimitry Andric } 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric ExprResult OrigLHS = LHS; 6280b57cec5SDimitry Andric if (!LHS.isInvalid()) { 6290b57cec5SDimitry Andric // Combine the LHS and RHS into the LHS (e.g. build AST). 6300b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 6310b57cec5SDimitry Andric // If we're using '>>' as an operator within a template 6320b57cec5SDimitry Andric // argument list (in C++98), suggest the addition of 6330b57cec5SDimitry Andric // parentheses so that the code remains well-formed in C++0x. 6340b57cec5SDimitry Andric if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) 6350b57cec5SDimitry Andric SuggestParentheses(OpToken.getLocation(), 6360b57cec5SDimitry Andric diag::warn_cxx11_right_shift_in_template_arg, 6370b57cec5SDimitry Andric SourceRange(Actions.getExprRange(LHS.get()).getBegin(), 6380b57cec5SDimitry Andric Actions.getExprRange(RHS.get()).getEnd())); 6390b57cec5SDimitry Andric 6405ffd83dbSDimitry Andric ExprResult BinOp = 6415ffd83dbSDimitry Andric Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), 6420b57cec5SDimitry Andric OpToken.getKind(), LHS.get(), RHS.get()); 6435ffd83dbSDimitry Andric if (BinOp.isInvalid()) 6445ffd83dbSDimitry Andric BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6455ffd83dbSDimitry Andric RHS.get()->getEndLoc(), 6465ffd83dbSDimitry Andric {LHS.get(), RHS.get()}); 6470b57cec5SDimitry Andric 6485ffd83dbSDimitry Andric LHS = BinOp; 6490b57cec5SDimitry Andric } else { 6505ffd83dbSDimitry Andric ExprResult CondOp = Actions.ActOnConditionalOp( 6515ffd83dbSDimitry Andric OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), 6520b57cec5SDimitry Andric RHS.get()); 6535ffd83dbSDimitry Andric if (CondOp.isInvalid()) { 6545ffd83dbSDimitry Andric std::vector<clang::Expr *> Args; 6555ffd83dbSDimitry Andric // TernaryMiddle can be null for the GNU conditional expr extension. 6565ffd83dbSDimitry Andric if (TernaryMiddle.get()) 6575ffd83dbSDimitry Andric Args = {LHS.get(), TernaryMiddle.get(), RHS.get()}; 6585ffd83dbSDimitry Andric else 6595ffd83dbSDimitry Andric Args = {LHS.get(), RHS.get()}; 6605ffd83dbSDimitry Andric CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6615ffd83dbSDimitry Andric RHS.get()->getEndLoc(), Args); 6625ffd83dbSDimitry Andric } 6635ffd83dbSDimitry Andric 6645ffd83dbSDimitry Andric LHS = CondOp; 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric // In this case, ActOnBinOp or ActOnConditionalOp performed the 6670b57cec5SDimitry Andric // CorrectDelayedTyposInExpr check. 6680b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 6690b57cec5SDimitry Andric continue; 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric // Ensure potential typos aren't left undiagnosed. 6730b57cec5SDimitry Andric if (LHS.isInvalid()) { 6740b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(OrigLHS); 6750b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6760b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 6770b57cec5SDimitry Andric } 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric 681480093f4SDimitry Andric /// Parse a cast-expression, unary-expression or primary-expression, based 682480093f4SDimitry Andric /// on \p ExprType. 6830b57cec5SDimitry Andric /// 6840b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the 6850b57cec5SDimitry Andric /// operand of address-of gets special treatment due to member pointers. 6860b57cec5SDimitry Andric /// 687480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 6880b57cec5SDimitry Andric bool isAddressOfOperand, 6890b57cec5SDimitry Andric TypeCastState isTypeCast, 690480093f4SDimitry Andric bool isVectorLiteral, 691480093f4SDimitry Andric bool *NotPrimaryExpression) { 6920b57cec5SDimitry Andric bool NotCastExpr; 693480093f4SDimitry Andric ExprResult Res = ParseCastExpression(ParseKind, 6940b57cec5SDimitry Andric isAddressOfOperand, 6950b57cec5SDimitry Andric NotCastExpr, 6960b57cec5SDimitry Andric isTypeCast, 697480093f4SDimitry Andric isVectorLiteral, 698480093f4SDimitry Andric NotPrimaryExpression); 6990b57cec5SDimitry Andric if (NotCastExpr) 7000b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 7010b57cec5SDimitry Andric return Res; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric namespace { 7050b57cec5SDimitry Andric class CastExpressionIdValidator final : public CorrectionCandidateCallback { 7060b57cec5SDimitry Andric public: 7070b57cec5SDimitry Andric CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes) 7080b57cec5SDimitry Andric : NextToken(Next), AllowNonTypes(AllowNonTypes) { 7090b57cec5SDimitry Andric WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes; 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric bool ValidateCandidate(const TypoCorrection &candidate) override { 7130b57cec5SDimitry Andric NamedDecl *ND = candidate.getCorrectionDecl(); 7140b57cec5SDimitry Andric if (!ND) 7150b57cec5SDimitry Andric return candidate.isKeyword(); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric if (isa<TypeDecl>(ND)) 7180b57cec5SDimitry Andric return WantTypeSpecifiers; 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andric if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate)) 7210b57cec5SDimitry Andric return false; 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period)) 7240b57cec5SDimitry Andric return true; 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric for (auto *C : candidate) { 7270b57cec5SDimitry Andric NamedDecl *ND = C->getUnderlyingDecl(); 7280b57cec5SDimitry Andric if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND)) 7290b57cec5SDimitry Andric return true; 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric return false; 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric std::unique_ptr<CorrectionCandidateCallback> clone() override { 735a7dea167SDimitry Andric return std::make_unique<CastExpressionIdValidator>(*this); 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric private: 7390b57cec5SDimitry Andric Token NextToken; 7400b57cec5SDimitry Andric bool AllowNonTypes; 7410b57cec5SDimitry Andric }; 7420b57cec5SDimitry Andric } 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse 7450b57cec5SDimitry Andric /// a unary-expression. 7460b57cec5SDimitry Andric /// 7470b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the operand 7480b57cec5SDimitry Andric /// of address-of gets special treatment due to member pointers. NotCastExpr 7490b57cec5SDimitry Andric /// is set to true if the token is not the start of a cast-expression, and no 7500b57cec5SDimitry Andric /// diagnostic is emitted in this case and no tokens are consumed. 7510b57cec5SDimitry Andric /// 7520b57cec5SDimitry Andric /// \verbatim 7530b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 7540b57cec5SDimitry Andric /// unary-expression 7550b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 7560b57cec5SDimitry Andric /// 7570b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 7580b57cec5SDimitry Andric /// postfix-expression 7590b57cec5SDimitry Andric /// '++' unary-expression 7600b57cec5SDimitry Andric /// '--' unary-expression 7610b57cec5SDimitry Andric /// [Coro] 'co_await' cast-expression 7620b57cec5SDimitry Andric /// unary-operator cast-expression 7630b57cec5SDimitry Andric /// 'sizeof' unary-expression 7640b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 7650b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 7660b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 7670b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 7680b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 7690b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 7700b57cec5SDimitry Andric /// [GNU] '&&' identifier 7710b57cec5SDimitry Andric /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7] 7720b57cec5SDimitry Andric /// [C++] new-expression 7730b57cec5SDimitry Andric /// [C++] delete-expression 7740b57cec5SDimitry Andric /// 7750b57cec5SDimitry Andric /// unary-operator: one of 7760b57cec5SDimitry Andric /// '&' '*' '+' '-' '~' '!' 7770b57cec5SDimitry Andric /// [GNU] '__extension__' '__real' '__imag' 7780b57cec5SDimitry Andric /// 7790b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 7800b57cec5SDimitry Andric /// [C99] identifier 7810b57cec5SDimitry Andric /// [C++] id-expression 7820b57cec5SDimitry Andric /// constant 7830b57cec5SDimitry Andric /// string-literal 7840b57cec5SDimitry Andric /// [C++] boolean-literal [C++ 2.13.5] 7850b57cec5SDimitry Andric /// [C++11] 'nullptr' [C++11 2.14.7] 7860b57cec5SDimitry Andric /// [C++11] user-defined-literal 7870b57cec5SDimitry Andric /// '(' expression ')' 7880b57cec5SDimitry Andric /// [C11] generic-selection 78955e4f9d5SDimitry Andric /// [C++2a] requires-expression 7900b57cec5SDimitry Andric /// '__func__' [C99 6.4.2.2] 7910b57cec5SDimitry Andric /// [GNU] '__FUNCTION__' 7920b57cec5SDimitry Andric /// [MS] '__FUNCDNAME__' 7930b57cec5SDimitry Andric /// [MS] 'L__FUNCTION__' 7940b57cec5SDimitry Andric /// [MS] '__FUNCSIG__' 7950b57cec5SDimitry Andric /// [MS] 'L__FUNCSIG__' 7960b57cec5SDimitry Andric /// [GNU] '__PRETTY_FUNCTION__' 7970b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' 7980b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 7990b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 8000b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 8010b57cec5SDimitry Andric /// assign-expr ')' 8020b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 80306c3fb27SDimitry Andric /// [CLANG] '__builtin_FILE_NAME' '(' ')' 8040b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 80506c3fb27SDimitry Andric /// [MS] '__builtin_FUNCSIG' '(' ')' 8060b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 8070b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 80881ad6265SDimitry Andric /// [GNU] '__builtin_source_location' '(' ')' 8090b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 8100b57cec5SDimitry Andric /// [GNU] '__null' 8110b57cec5SDimitry Andric /// [OBJC] '[' objc-message-expr ']' 8120b57cec5SDimitry Andric /// [OBJC] '\@selector' '(' objc-selector-arg ')' 8130b57cec5SDimitry Andric /// [OBJC] '\@protocol' '(' identifier ')' 8140b57cec5SDimitry Andric /// [OBJC] '\@encode' '(' type-name ')' 8150b57cec5SDimitry Andric /// [OBJC] objc-string-literal 8160b57cec5SDimitry Andric /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 8170b57cec5SDimitry Andric /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] 8180b57cec5SDimitry Andric /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 8190b57cec5SDimitry Andric /// [C++11] typename-specifier braced-init-list [C++11 5.2.3] 8200b57cec5SDimitry Andric /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8210b57cec5SDimitry Andric /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8220b57cec5SDimitry Andric /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8230b57cec5SDimitry Andric /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8240b57cec5SDimitry Andric /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 8250b57cec5SDimitry Andric /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 8260b57cec5SDimitry Andric /// [C++] 'this' [C++ 9.3.2] 8270b57cec5SDimitry Andric /// [G++] unary-type-trait '(' type-id ')' 8280b57cec5SDimitry Andric /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 8290b57cec5SDimitry Andric /// [EMBT] array-type-trait '(' type-id ',' integer ')' 8300b57cec5SDimitry Andric /// [clang] '^' block-literal 8310b57cec5SDimitry Andric /// 8320b57cec5SDimitry Andric /// constant: [C99 6.4.4] 8330b57cec5SDimitry Andric /// integer-constant 8340b57cec5SDimitry Andric /// floating-constant 8350b57cec5SDimitry Andric /// enumeration-constant -> identifier 8360b57cec5SDimitry Andric /// character-constant 8370b57cec5SDimitry Andric /// 8380b57cec5SDimitry Andric /// id-expression: [C++ 5.1] 8390b57cec5SDimitry Andric /// unqualified-id 8400b57cec5SDimitry Andric /// qualified-id 8410b57cec5SDimitry Andric /// 8420b57cec5SDimitry Andric /// unqualified-id: [C++ 5.1] 8430b57cec5SDimitry Andric /// identifier 8440b57cec5SDimitry Andric /// operator-function-id 8450b57cec5SDimitry Andric /// conversion-function-id 8460b57cec5SDimitry Andric /// '~' class-name 8470b57cec5SDimitry Andric /// template-id 8480b57cec5SDimitry Andric /// 8490b57cec5SDimitry Andric /// new-expression: [C++ 5.3.4] 8500b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 8510b57cec5SDimitry Andric /// new-initializer[opt] 8520b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8530b57cec5SDimitry Andric /// new-initializer[opt] 8540b57cec5SDimitry Andric /// 8550b57cec5SDimitry Andric /// delete-expression: [C++ 5.3.5] 8560b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 8570b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 8580b57cec5SDimitry Andric /// 8590b57cec5SDimitry Andric /// [GNU/Embarcadero] unary-type-trait: 8600b57cec5SDimitry Andric /// '__is_arithmetic' 8610b57cec5SDimitry Andric /// '__is_floating_point' 8620b57cec5SDimitry Andric /// '__is_integral' 8630b57cec5SDimitry Andric /// '__is_lvalue_expr' 8640b57cec5SDimitry Andric /// '__is_rvalue_expr' 8650b57cec5SDimitry Andric /// '__is_complete_type' 8660b57cec5SDimitry Andric /// '__is_void' 8670b57cec5SDimitry Andric /// '__is_array' 8680b57cec5SDimitry Andric /// '__is_function' 8690b57cec5SDimitry Andric /// '__is_reference' 8700b57cec5SDimitry Andric /// '__is_lvalue_reference' 8710b57cec5SDimitry Andric /// '__is_rvalue_reference' 8720b57cec5SDimitry Andric /// '__is_fundamental' 8730b57cec5SDimitry Andric /// '__is_object' 8740b57cec5SDimitry Andric /// '__is_scalar' 8750b57cec5SDimitry Andric /// '__is_compound' 8760b57cec5SDimitry Andric /// '__is_pointer' 8770b57cec5SDimitry Andric /// '__is_member_object_pointer' 8780b57cec5SDimitry Andric /// '__is_member_function_pointer' 8790b57cec5SDimitry Andric /// '__is_member_pointer' 8800b57cec5SDimitry Andric /// '__is_const' 8810b57cec5SDimitry Andric /// '__is_volatile' 8820b57cec5SDimitry Andric /// '__is_trivial' 8830b57cec5SDimitry Andric /// '__is_standard_layout' 8840b57cec5SDimitry Andric /// '__is_signed' 8850b57cec5SDimitry Andric /// '__is_unsigned' 8860b57cec5SDimitry Andric /// 8870b57cec5SDimitry Andric /// [GNU] unary-type-trait: 8880b57cec5SDimitry Andric /// '__has_nothrow_assign' 8890b57cec5SDimitry Andric /// '__has_nothrow_copy' 8900b57cec5SDimitry Andric /// '__has_nothrow_constructor' 8910b57cec5SDimitry Andric /// '__has_trivial_assign' [TODO] 8920b57cec5SDimitry Andric /// '__has_trivial_copy' [TODO] 8930b57cec5SDimitry Andric /// '__has_trivial_constructor' 8940b57cec5SDimitry Andric /// '__has_trivial_destructor' 8950b57cec5SDimitry Andric /// '__has_virtual_destructor' 8960b57cec5SDimitry Andric /// '__is_abstract' [TODO] 8970b57cec5SDimitry Andric /// '__is_class' 8980b57cec5SDimitry Andric /// '__is_empty' [TODO] 8990b57cec5SDimitry Andric /// '__is_enum' 9000b57cec5SDimitry Andric /// '__is_final' 9010b57cec5SDimitry Andric /// '__is_pod' 9020b57cec5SDimitry Andric /// '__is_polymorphic' 9030b57cec5SDimitry Andric /// '__is_sealed' [MS] 9040b57cec5SDimitry Andric /// '__is_trivial' 9050b57cec5SDimitry Andric /// '__is_union' 9060b57cec5SDimitry Andric /// '__has_unique_object_representations' 9070b57cec5SDimitry Andric /// 9080b57cec5SDimitry Andric /// [Clang] unary-type-trait: 9090b57cec5SDimitry Andric /// '__is_aggregate' 9100b57cec5SDimitry Andric /// '__trivially_copyable' 9110b57cec5SDimitry Andric /// 9120b57cec5SDimitry Andric /// binary-type-trait: 9130b57cec5SDimitry Andric /// [GNU] '__is_base_of' 9140b57cec5SDimitry Andric /// [MS] '__is_convertible_to' 9150b57cec5SDimitry Andric /// '__is_convertible' 9160b57cec5SDimitry Andric /// '__is_same' 9170b57cec5SDimitry Andric /// 9180b57cec5SDimitry Andric /// [Embarcadero] array-type-trait: 9190b57cec5SDimitry Andric /// '__array_rank' 9200b57cec5SDimitry Andric /// '__array_extent' 9210b57cec5SDimitry Andric /// 9220b57cec5SDimitry Andric /// [Embarcadero] expression-trait: 9230b57cec5SDimitry Andric /// '__is_lvalue_expr' 9240b57cec5SDimitry Andric /// '__is_rvalue_expr' 9250b57cec5SDimitry Andric /// \endverbatim 9260b57cec5SDimitry Andric /// 927480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 9280b57cec5SDimitry Andric bool isAddressOfOperand, 9290b57cec5SDimitry Andric bool &NotCastExpr, 9300b57cec5SDimitry Andric TypeCastState isTypeCast, 931480093f4SDimitry Andric bool isVectorLiteral, 932480093f4SDimitry Andric bool *NotPrimaryExpression) { 9330b57cec5SDimitry Andric ExprResult Res; 9340b57cec5SDimitry Andric tok::TokenKind SavedKind = Tok.getKind(); 9350b57cec5SDimitry Andric auto SavedType = PreferredType; 9360b57cec5SDimitry Andric NotCastExpr = false; 9370b57cec5SDimitry Andric 9385ffd83dbSDimitry Andric // Are postfix-expression suffix operators permitted after this 9395ffd83dbSDimitry Andric // cast-expression? If not, and we find some, we'll parse them anyway and 9405ffd83dbSDimitry Andric // diagnose them. 9415ffd83dbSDimitry Andric bool AllowSuffix = true; 9425ffd83dbSDimitry Andric 9430b57cec5SDimitry Andric // This handles all of cast-expression, unary-expression, postfix-expression, 9440b57cec5SDimitry Andric // and primary-expression. We handle them together like this for efficiency 9450b57cec5SDimitry Andric // and to simplify handling of an expression starting with a '(' token: which 9460b57cec5SDimitry Andric // may be one of a parenthesized expression, cast-expression, compound literal 9470b57cec5SDimitry Andric // expression, or statement expression. 9480b57cec5SDimitry Andric // 9490b57cec5SDimitry Andric // If the parsed tokens consist of a primary-expression, the cases below 9500b57cec5SDimitry Andric // break out of the switch; at the end we call ParsePostfixExpressionSuffix 9510b57cec5SDimitry Andric // to handle the postfix expression suffixes. Cases that cannot be followed 9525ffd83dbSDimitry Andric // by postfix exprs should set AllowSuffix to false. 9530b57cec5SDimitry Andric switch (SavedKind) { 9540b57cec5SDimitry Andric case tok::l_paren: { 955480093f4SDimitry Andric // If this expression is limited to being a unary-expression, the paren can 9560b57cec5SDimitry Andric // not start a cast expression. 957480093f4SDimitry Andric ParenParseOption ParenExprType; 958480093f4SDimitry Andric switch (ParseKind) { 959480093f4SDimitry Andric case CastParseKind::UnaryExprOnly: 960bdd1243dSDimitry Andric assert(getLangOpts().CPlusPlus && "not possible to get here in C"); 961bdd1243dSDimitry Andric [[fallthrough]]; 962480093f4SDimitry Andric case CastParseKind::AnyCastExpr: 963480093f4SDimitry Andric ParenExprType = ParenParseOption::CastExpr; 964480093f4SDimitry Andric break; 965480093f4SDimitry Andric case CastParseKind::PrimaryExprOnly: 966480093f4SDimitry Andric ParenExprType = FoldExpr; 967480093f4SDimitry Andric break; 968480093f4SDimitry Andric } 9690b57cec5SDimitry Andric ParsedType CastTy; 9700b57cec5SDimitry Andric SourceLocation RParenLoc; 9710b57cec5SDimitry Andric Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 9720b57cec5SDimitry Andric isTypeCast == IsTypeCast, CastTy, RParenLoc); 9730b57cec5SDimitry Andric 9745ffd83dbSDimitry Andric // FIXME: What should we do if a vector literal is followed by a 9755ffd83dbSDimitry Andric // postfix-expression suffix? Usually postfix operators are permitted on 9765ffd83dbSDimitry Andric // literals. 9770b57cec5SDimitry Andric if (isVectorLiteral) 9780b57cec5SDimitry Andric return Res; 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric switch (ParenExprType) { 9810b57cec5SDimitry Andric case SimpleExpr: break; // Nothing else to do. 9820b57cec5SDimitry Andric case CompoundStmt: break; // Nothing else to do. 9830b57cec5SDimitry Andric case CompoundLiteral: 9840b57cec5SDimitry Andric // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 9850b57cec5SDimitry Andric // postfix-expression exist, parse them now. 9860b57cec5SDimitry Andric break; 9870b57cec5SDimitry Andric case CastExpr: 9880b57cec5SDimitry Andric // We have parsed the cast-expression and no postfix-expr pieces are 9890b57cec5SDimitry Andric // following. 9900b57cec5SDimitry Andric return Res; 9910b57cec5SDimitry Andric case FoldExpr: 9920b57cec5SDimitry Andric // We only parsed a fold-expression. There might be postfix-expr pieces 9930b57cec5SDimitry Andric // afterwards; parse them now. 9940b57cec5SDimitry Andric break; 9950b57cec5SDimitry Andric } 9960b57cec5SDimitry Andric 9970b57cec5SDimitry Andric break; 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric // primary-expression 10010b57cec5SDimitry Andric case tok::numeric_constant: 10020b57cec5SDimitry Andric // constant: integer-constant 10030b57cec5SDimitry Andric // constant: floating-constant 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope()); 10060b57cec5SDimitry Andric ConsumeToken(); 10070b57cec5SDimitry Andric break; 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric case tok::kw_true: 10100b57cec5SDimitry Andric case tok::kw_false: 10110b57cec5SDimitry Andric Res = ParseCXXBoolLiteral(); 10120b57cec5SDimitry Andric break; 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric case tok::kw___objc_yes: 10150b57cec5SDimitry Andric case tok::kw___objc_no: 10165ffd83dbSDimitry Andric Res = ParseObjCBoolLiteral(); 10175ffd83dbSDimitry Andric break; 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric case tok::kw_nullptr: 1020bdd1243dSDimitry Andric if (getLangOpts().CPlusPlus) 10210b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_nullptr); 1022bdd1243dSDimitry Andric else 10235f757f3fSDimitry Andric Diag(Tok, getLangOpts().C23 ? diag::warn_c23_compat_keyword 102406c3fb27SDimitry Andric : diag::ext_c_nullptr) << Tok.getName(); 1025bdd1243dSDimitry Andric 10265ffd83dbSDimitry Andric Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 10275ffd83dbSDimitry Andric break; 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric case tok::annot_primary_expr: 1030e8d8bef9SDimitry Andric case tok::annot_overload_set: 10310b57cec5SDimitry Andric Res = getExprAnnotation(Tok); 1032e8d8bef9SDimitry Andric if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set) 1033e8d8bef9SDimitry Andric Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get()); 10340b57cec5SDimitry Andric ConsumeAnnotationToken(); 10350b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 10360b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 10370b57cec5SDimitry Andric break; 10380b57cec5SDimitry Andric 1039a7dea167SDimitry Andric case tok::annot_non_type: 1040a7dea167SDimitry Andric case tok::annot_non_type_dependent: 1041a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 1042a7dea167SDimitry Andric CXXScopeSpec SS; 1043a7dea167SDimitry Andric Token Replacement; 1044a7dea167SDimitry Andric Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 1045a7dea167SDimitry Andric assert(!Res.isUnset() && 1046a7dea167SDimitry Andric "should not perform typo correction on annotation token"); 1047a7dea167SDimitry Andric break; 1048a7dea167SDimitry Andric } 1049a7dea167SDimitry Andric 10500b57cec5SDimitry Andric case tok::kw___super: 10510b57cec5SDimitry Andric case tok::kw_decltype: 10520b57cec5SDimitry Andric // Annotate the token and tail recurse. 10530b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 10540b57cec5SDimitry Andric return ExprError(); 10550b57cec5SDimitry Andric assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); 1056480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1057480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 10580b57cec5SDimitry Andric 1059bdd1243dSDimitry Andric case tok::identifier: 1060bdd1243dSDimitry Andric ParseIdentifier: { // primary-expression: identifier 10610b57cec5SDimitry Andric // unqualified-id: identifier 10620b57cec5SDimitry Andric // constant: enumeration-constant 10630b57cec5SDimitry Andric // Turn a potentially qualified name into a annot_typename or 10640b57cec5SDimitry Andric // annot_cxxscope if it would be valid. This handles things like x::y, etc. 10650b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) { 10660b57cec5SDimitry Andric // Avoid the unnecessary parse-time lookup in the common case 10670b57cec5SDimitry Andric // where the syntax forbids a type. 10680b57cec5SDimitry Andric const Token &Next = NextToken(); 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric // If this identifier was reverted from a token ID, and the next token 10710b57cec5SDimitry Andric // is a parenthesis, this is likely to be a use of a type trait. Check 10720b57cec5SDimitry Andric // those tokens. 10730b57cec5SDimitry Andric if (Next.is(tok::l_paren) && 10740b57cec5SDimitry Andric Tok.is(tok::identifier) && 10750b57cec5SDimitry Andric Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { 10760b57cec5SDimitry Andric IdentifierInfo *II = Tok.getIdentifierInfo(); 10770b57cec5SDimitry Andric // Build up the mapping of revertible type traits, for future use. 10780b57cec5SDimitry Andric if (RevertibleTypeTraits.empty()) { 10790b57cec5SDimitry Andric #define RTT_JOIN(X,Y) X##Y 10800b57cec5SDimitry Andric #define REVERTIBLE_TYPE_TRAIT(Name) \ 10810b57cec5SDimitry Andric RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ 10820b57cec5SDimitry Andric = RTT_JOIN(tok::kw_,Name) 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_abstract); 10850b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_aggregate); 10860b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_arithmetic); 10870b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_array); 10880b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_assignable); 10890b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_base_of); 1090bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_bounded_array); 10910b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_class); 10920b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_complete_type); 10930b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_compound); 10940b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_const); 10950b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_constructible); 10960b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible); 10970b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible_to); 10980b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_destructible); 10990b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_empty); 11000b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_enum); 11010b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_floating_point); 11020b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_final); 11030b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_function); 11040b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_fundamental); 11050b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_integral); 11060b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_interface_class); 11070b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_literal); 11080b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); 11090b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); 11100b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); 11110b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); 11120b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_pointer); 11130b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); 11140b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); 11150b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); 1116bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nullptr); 11170b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_object); 11180b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pod); 11190b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pointer); 11200b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_polymorphic); 11210b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_reference); 1122bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_referenceable); 11230b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); 11240b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); 11250b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_same); 11260b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scalar); 1127bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); 11280b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_sealed); 11290b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_signed); 11300b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_standard_layout); 11310b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivial); 11320b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); 11330b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); 11340b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); 1135bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); 11360b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_union); 11370b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unsigned); 11380b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_void); 11390b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_volatile); 11405f757f3fSDimitry Andric REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary); 11415f757f3fSDimitry Andric REVERTIBLE_TYPE_TRAIT(__reference_constructs_from_temporary); 1142bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ 1143bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait)); 1144bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 11450b57cec5SDimitry Andric #undef REVERTIBLE_TYPE_TRAIT 11460b57cec5SDimitry Andric #undef RTT_JOIN 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric 11490b57cec5SDimitry Andric // If we find that this is in fact the name of a type trait, 11500b57cec5SDimitry Andric // update the token kind in place and parse again to treat it as 11510b57cec5SDimitry Andric // the appropriate kind of type trait. 11520b57cec5SDimitry Andric llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known 11530b57cec5SDimitry Andric = RevertibleTypeTraits.find(II); 11540b57cec5SDimitry Andric if (Known != RevertibleTypeTraits.end()) { 11550b57cec5SDimitry Andric Tok.setKind(Known->second); 1156480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1157480093f4SDimitry Andric NotCastExpr, isTypeCast, 1158480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 11590b57cec5SDimitry Andric } 11600b57cec5SDimitry Andric } 11610b57cec5SDimitry Andric 11620b57cec5SDimitry Andric if ((!ColonIsSacred && Next.is(tok::colon)) || 11630b57cec5SDimitry Andric Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren, 11640b57cec5SDimitry Andric tok::l_brace)) { 11650b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 11660b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 11670b57cec5SDimitry Andric return ExprError(); 11680b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) 1169480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1170480093f4SDimitry Andric NotCastExpr, isTypeCast, 1171480093f4SDimitry Andric isVectorLiteral, 1172480093f4SDimitry Andric NotPrimaryExpression); 11730b57cec5SDimitry Andric } 11740b57cec5SDimitry Andric } 11750b57cec5SDimitry Andric 11760b57cec5SDimitry Andric // Consume the identifier so that we can see if it is followed by a '(' or 11770b57cec5SDimitry Andric // '.'. 11780b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 11790b57cec5SDimitry Andric SourceLocation ILoc = ConsumeToken(); 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric // Support 'Class.property' and 'super.property' notation. 11820b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.is(tok::period) && 11830b57cec5SDimitry Andric (Actions.getTypeName(II, ILoc, getCurScope()) || 11840b57cec5SDimitry Andric // Allow the base to be 'super' if in an objc-method. 11850b57cec5SDimitry Andric (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { 11860b57cec5SDimitry Andric ConsumeToken(); 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && &II != Ident_super) { 1189fe6060f1SDimitry Andric cutOffParsing(); 11900b57cec5SDimitry Andric Actions.CodeCompleteObjCClassPropertyRefExpr( 11910b57cec5SDimitry Andric getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); 11920b57cec5SDimitry Andric return ExprError(); 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric // Allow either an identifier or the keyword 'class' (in C++). 11950b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) && 11960b57cec5SDimitry Andric !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { 11970b57cec5SDimitry Andric Diag(Tok, diag::err_expected_property_name); 11980b57cec5SDimitry Andric return ExprError(); 11990b57cec5SDimitry Andric } 12000b57cec5SDimitry Andric IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 12010b57cec5SDimitry Andric SourceLocation PropertyLoc = ConsumeToken(); 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, 12040b57cec5SDimitry Andric ILoc, PropertyLoc); 12050b57cec5SDimitry Andric break; 12060b57cec5SDimitry Andric } 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric // In an Objective-C method, if we have "super" followed by an identifier, 12090b57cec5SDimitry Andric // the token sequence is ill-formed. However, if there's a ':' or ']' after 12100b57cec5SDimitry Andric // that identifier, this is probably a message send with a missing open 12110b57cec5SDimitry Andric // bracket. Treat it as such. 12120b57cec5SDimitry Andric if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression && 12130b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 12140b57cec5SDimitry Andric ((Tok.is(tok::identifier) && 12150b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || 12160b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12170b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr, 12180b57cec5SDimitry Andric nullptr); 12190b57cec5SDimitry Andric break; 12200b57cec5SDimitry Andric } 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric // If we have an Objective-C class name followed by an identifier 12230b57cec5SDimitry Andric // and either ':' or ']', this is an Objective-C class message 12240b57cec5SDimitry Andric // send that's missing the opening '['. Recovery 12250b57cec5SDimitry Andric // appropriately. Also take this path if we're performing code 12260b57cec5SDimitry Andric // completion after an Objective-C class name. 12270b57cec5SDimitry Andric if (getLangOpts().ObjC && 12280b57cec5SDimitry Andric ((Tok.is(tok::identifier) && !InMessageExpression) || 12290b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12300b57cec5SDimitry Andric const Token& Next = NextToken(); 12310b57cec5SDimitry Andric if (Tok.is(tok::code_completion) || 12320b57cec5SDimitry Andric Next.is(tok::colon) || Next.is(tok::r_square)) 12330b57cec5SDimitry Andric if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) 12340b57cec5SDimitry Andric if (Typ.get()->isObjCObjectOrInterfaceType()) { 12350b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 12360b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 12370b57cec5SDimitry Andric DS.SetRangeStart(ILoc); 12380b57cec5SDimitry Andric DS.SetRangeEnd(ILoc); 12390b57cec5SDimitry Andric const char *PrevSpec = nullptr; 12400b57cec5SDimitry Andric unsigned DiagID; 12410b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, 12420b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 12430b57cec5SDimitry Andric 124481ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 124581ad6265SDimitry Andric DeclaratorContext::TypeName); 1246*7a6dacacSDimitry Andric TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo); 12470b57cec5SDimitry Andric if (Ty.isInvalid()) 12480b57cec5SDimitry Andric break; 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), 12510b57cec5SDimitry Andric SourceLocation(), 12520b57cec5SDimitry Andric Ty.get(), nullptr); 12530b57cec5SDimitry Andric break; 12540b57cec5SDimitry Andric } 12550b57cec5SDimitry Andric } 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric // Make sure to pass down the right value for isAddressOfOperand. 12580b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 12590b57cec5SDimitry Andric isAddressOfOperand = false; 12600b57cec5SDimitry Andric 12610b57cec5SDimitry Andric // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 12620b57cec5SDimitry Andric // need to know whether or not this identifier is a function designator or 12630b57cec5SDimitry Andric // not. 12640b57cec5SDimitry Andric UnqualifiedId Name; 12650b57cec5SDimitry Andric CXXScopeSpec ScopeSpec; 12660b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 12670b57cec5SDimitry Andric Token Replacement; 12680b57cec5SDimitry Andric CastExpressionIdValidator Validator( 12690b57cec5SDimitry Andric /*Next=*/Tok, 12700b57cec5SDimitry Andric /*AllowTypes=*/isTypeCast != NotTypeCast, 12710b57cec5SDimitry Andric /*AllowNonTypes=*/isTypeCast != IsTypeCast); 12720b57cec5SDimitry Andric Validator.IsAddressOfOperand = isAddressOfOperand; 12730b57cec5SDimitry Andric if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) { 12740b57cec5SDimitry Andric Validator.WantExpressionKeywords = false; 12750b57cec5SDimitry Andric Validator.WantRemainingKeywords = false; 12760b57cec5SDimitry Andric } else { 12770b57cec5SDimitry Andric Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren); 12780b57cec5SDimitry Andric } 12790b57cec5SDimitry Andric Name.setIdentifier(&II, ILoc); 12800b57cec5SDimitry Andric Res = Actions.ActOnIdExpression( 12810b57cec5SDimitry Andric getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), 12820b57cec5SDimitry Andric isAddressOfOperand, &Validator, 12830b57cec5SDimitry Andric /*IsInlineAsmIdentifier=*/false, 12840b57cec5SDimitry Andric Tok.is(tok::r_paren) ? nullptr : &Replacement); 12850b57cec5SDimitry Andric if (!Res.isInvalid() && Res.isUnset()) { 12860b57cec5SDimitry Andric UnconsumeToken(Replacement); 1287480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1288480093f4SDimitry Andric NotCastExpr, isTypeCast, 1289480093f4SDimitry Andric /*isVectorLiteral=*/false, 1290480093f4SDimitry Andric NotPrimaryExpression); 12910b57cec5SDimitry Andric } 12920b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 12930b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 12940b57cec5SDimitry Andric break; 12950b57cec5SDimitry Andric } 12960b57cec5SDimitry Andric case tok::char_constant: // constant: character-constant 12970b57cec5SDimitry Andric case tok::wide_char_constant: 12980b57cec5SDimitry Andric case tok::utf8_char_constant: 12990b57cec5SDimitry Andric case tok::utf16_char_constant: 13000b57cec5SDimitry Andric case tok::utf32_char_constant: 13010b57cec5SDimitry Andric Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope()); 13020b57cec5SDimitry Andric ConsumeToken(); 13030b57cec5SDimitry Andric break; 13040b57cec5SDimitry Andric case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 13050b57cec5SDimitry Andric case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 13060b57cec5SDimitry Andric case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] 13070b57cec5SDimitry Andric case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS] 13080b57cec5SDimitry Andric case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] 13090b57cec5SDimitry Andric case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] 13100b57cec5SDimitry Andric case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 13115f757f3fSDimitry Andric // Function local predefined macros are represented by PredefinedExpr except 13125f757f3fSDimitry Andric // when Microsoft extensions are enabled and one of these macros is adjacent 13135f757f3fSDimitry Andric // to a string literal or another one of these macros. 13145f757f3fSDimitry Andric if (!(getLangOpts().MicrosoftExt && 13155f757f3fSDimitry Andric tokenIsLikeStringLiteral(Tok, getLangOpts()) && 13165f757f3fSDimitry Andric tokenIsLikeStringLiteral(NextToken(), getLangOpts()))) { 13170b57cec5SDimitry Andric Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 13180b57cec5SDimitry Andric ConsumeToken(); 13190b57cec5SDimitry Andric break; 13205f757f3fSDimitry Andric } 13215f757f3fSDimitry Andric [[fallthrough]]; // treat MS function local macros as concatenable strings 13220b57cec5SDimitry Andric case tok::string_literal: // primary-expression: string-literal 13230b57cec5SDimitry Andric case tok::wide_string_literal: 13240b57cec5SDimitry Andric case tok::utf8_string_literal: 13250b57cec5SDimitry Andric case tok::utf16_string_literal: 13260b57cec5SDimitry Andric case tok::utf32_string_literal: 13270b57cec5SDimitry Andric Res = ParseStringLiteralExpression(true); 13280b57cec5SDimitry Andric break; 13290b57cec5SDimitry Andric case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1] 13300b57cec5SDimitry Andric Res = ParseGenericSelectionExpression(); 13310b57cec5SDimitry Andric break; 13320b57cec5SDimitry Andric case tok::kw___builtin_available: 13335ffd83dbSDimitry Andric Res = ParseAvailabilityCheckExpr(Tok.getLocation()); 13345ffd83dbSDimitry Andric break; 13350b57cec5SDimitry Andric case tok::kw___builtin_va_arg: 13360b57cec5SDimitry Andric case tok::kw___builtin_offsetof: 13370b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: 13380b57cec5SDimitry Andric case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() 13390b57cec5SDimitry Andric case tok::kw___builtin_convertvector: 13400b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 13410b57cec5SDimitry Andric case tok::kw___builtin_FILE: 134206c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 13430b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 134406c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 13450b57cec5SDimitry Andric case tok::kw___builtin_LINE: 134681ad6265SDimitry Andric case tok::kw___builtin_source_location: 1347480093f4SDimitry Andric if (NotPrimaryExpression) 1348480093f4SDimitry Andric *NotPrimaryExpression = true; 13495ffd83dbSDimitry Andric // This parses the complete suffix; we can return early. 13500b57cec5SDimitry Andric return ParseBuiltinPrimaryExpression(); 13510b57cec5SDimitry Andric case tok::kw___null: 13525ffd83dbSDimitry Andric Res = Actions.ActOnGNUNullExpr(ConsumeToken()); 13535ffd83dbSDimitry Andric break; 13540b57cec5SDimitry Andric 13550b57cec5SDimitry Andric case tok::plusplus: // unary-expression: '++' unary-expression [C99] 13560b57cec5SDimitry Andric case tok::minusminus: { // unary-expression: '--' unary-expression [C99] 1357480093f4SDimitry Andric if (NotPrimaryExpression) 1358480093f4SDimitry Andric *NotPrimaryExpression = true; 13590b57cec5SDimitry Andric // C++ [expr.unary] has: 13600b57cec5SDimitry Andric // unary-expression: 13610b57cec5SDimitry Andric // ++ cast-expression 13620b57cec5SDimitry Andric // -- cast-expression 13630b57cec5SDimitry Andric Token SavedTok = Tok; 13640b57cec5SDimitry Andric ConsumeToken(); 13650b57cec5SDimitry Andric 13660b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(), 13670b57cec5SDimitry Andric SavedTok.getLocation()); 13680b57cec5SDimitry Andric // One special case is implicitly handled here: if the preceding tokens are 13690b57cec5SDimitry Andric // an ambiguous cast expression, such as "(T())++", then we recurse to 13700b57cec5SDimitry Andric // determine whether the '++' is prefix or postfix. 1371480093f4SDimitry Andric Res = ParseCastExpression(getLangOpts().CPlusPlus ? 1372480093f4SDimitry Andric UnaryExprOnly : AnyCastExpr, 13730b57cec5SDimitry Andric /*isAddressOfOperand*/false, NotCastExpr, 13740b57cec5SDimitry Andric NotTypeCast); 13750b57cec5SDimitry Andric if (NotCastExpr) { 13760b57cec5SDimitry Andric // If we return with NotCastExpr = true, we must not consume any tokens, 13770b57cec5SDimitry Andric // so put the token back where we found it. 13780b57cec5SDimitry Andric assert(Res.isInvalid()); 13790b57cec5SDimitry Andric UnconsumeToken(SavedTok); 13800b57cec5SDimitry Andric return ExprError(); 13810b57cec5SDimitry Andric } 13825ffd83dbSDimitry Andric if (!Res.isInvalid()) { 13835ffd83dbSDimitry Andric Expr *Arg = Res.get(); 13840b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(), 13855ffd83dbSDimitry Andric SavedKind, Arg); 13865ffd83dbSDimitry Andric if (Res.isInvalid()) 13875ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(), 13885ffd83dbSDimitry Andric Arg->getEndLoc(), Arg); 13895ffd83dbSDimitry Andric } 13900b57cec5SDimitry Andric return Res; 13910b57cec5SDimitry Andric } 13920b57cec5SDimitry Andric case tok::amp: { // unary-expression: '&' cast-expression 1393480093f4SDimitry Andric if (NotPrimaryExpression) 1394480093f4SDimitry Andric *NotPrimaryExpression = true; 13950b57cec5SDimitry Andric // Special treatment because of member pointers 13960b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 13970b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); 1398bdd1243dSDimitry Andric 1399bdd1243dSDimitry Andric Res = ParseCastExpression(AnyCastExpr, /*isAddressOfOperand=*/true); 14005ffd83dbSDimitry Andric if (!Res.isInvalid()) { 14015ffd83dbSDimitry Andric Expr *Arg = Res.get(); 14025ffd83dbSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); 14035ffd83dbSDimitry Andric if (Res.isInvalid()) 14045ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(), 14055ffd83dbSDimitry Andric Arg); 14065ffd83dbSDimitry Andric } 14070b57cec5SDimitry Andric return Res; 14080b57cec5SDimitry Andric } 14090b57cec5SDimitry Andric 14100b57cec5SDimitry Andric case tok::star: // unary-expression: '*' cast-expression 14110b57cec5SDimitry Andric case tok::plus: // unary-expression: '+' cast-expression 14120b57cec5SDimitry Andric case tok::minus: // unary-expression: '-' cast-expression 14130b57cec5SDimitry Andric case tok::tilde: // unary-expression: '~' cast-expression 14140b57cec5SDimitry Andric case tok::exclaim: // unary-expression: '!' cast-expression 14150b57cec5SDimitry Andric case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 14160b57cec5SDimitry Andric case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 1417480093f4SDimitry Andric if (NotPrimaryExpression) 1418480093f4SDimitry Andric *NotPrimaryExpression = true; 14190b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 14200b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); 1421480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14225ffd83dbSDimitry Andric if (!Res.isInvalid()) { 14235ffd83dbSDimitry Andric Expr *Arg = Res.get(); 1424bdd1243dSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg, 1425bdd1243dSDimitry Andric isAddressOfOperand); 14265ffd83dbSDimitry Andric if (Res.isInvalid()) 14275ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg); 14285ffd83dbSDimitry Andric } 14290b57cec5SDimitry Andric return Res; 14300b57cec5SDimitry Andric } 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression 1433480093f4SDimitry Andric if (NotPrimaryExpression) 1434480093f4SDimitry Andric *NotPrimaryExpression = true; 14350b57cec5SDimitry Andric SourceLocation CoawaitLoc = ConsumeToken(); 1436480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14370b57cec5SDimitry Andric if (!Res.isInvalid()) 14380b57cec5SDimitry Andric Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get()); 14390b57cec5SDimitry Andric return Res; 14400b57cec5SDimitry Andric } 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 14430b57cec5SDimitry Andric // __extension__ silences extension warnings in the subexpression. 1444480093f4SDimitry Andric if (NotPrimaryExpression) 1445480093f4SDimitry Andric *NotPrimaryExpression = true; 14460b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); // Use RAII to do this. 14470b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 1448480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14490b57cec5SDimitry Andric if (!Res.isInvalid()) 14500b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 14510b57cec5SDimitry Andric return Res; 14520b57cec5SDimitry Andric } 14530b57cec5SDimitry Andric case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' 14540b57cec5SDimitry Andric if (!getLangOpts().C11) 1455a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 1456bdd1243dSDimitry Andric [[fallthrough]]; 14570b57cec5SDimitry Andric case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' 14580b57cec5SDimitry Andric case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 14590b57cec5SDimitry Andric // unary-expression: '__alignof' '(' type-name ')' 14600b57cec5SDimitry Andric case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 14610b57cec5SDimitry Andric // unary-expression: 'sizeof' '(' type-name ')' 14625f757f3fSDimitry Andric // unary-expression: '__datasizeof' unary-expression 14635f757f3fSDimitry Andric // unary-expression: '__datasizeof' '(' type-name ')' 14645f757f3fSDimitry Andric case tok::kw___datasizeof: 14650b57cec5SDimitry Andric case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression 14660b57cec5SDimitry Andric // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' 14670b57cec5SDimitry Andric case tok::kw___builtin_omp_required_simd_align: 14685f757f3fSDimitry Andric case tok::kw___builtin_vectorelements: 1469480093f4SDimitry Andric if (NotPrimaryExpression) 1470480093f4SDimitry Andric *NotPrimaryExpression = true; 14715ffd83dbSDimitry Andric AllowSuffix = false; 14725ffd83dbSDimitry Andric Res = ParseUnaryExprOrTypeTraitExpression(); 14735ffd83dbSDimitry Andric break; 14740b57cec5SDimitry Andric case tok::ampamp: { // unary-expression: '&&' identifier 1475480093f4SDimitry Andric if (NotPrimaryExpression) 1476480093f4SDimitry Andric *NotPrimaryExpression = true; 14770b57cec5SDimitry Andric SourceLocation AmpAmpLoc = ConsumeToken(); 14780b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 14790b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric if (getCurScope()->getFnParent() == nullptr) 14820b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); 14830b57cec5SDimitry Andric 14840b57cec5SDimitry Andric Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 14850b57cec5SDimitry Andric LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 14860b57cec5SDimitry Andric Tok.getLocation()); 14870b57cec5SDimitry Andric Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); 14880b57cec5SDimitry Andric ConsumeToken(); 14895ffd83dbSDimitry Andric AllowSuffix = false; 14905ffd83dbSDimitry Andric break; 14910b57cec5SDimitry Andric } 14920b57cec5SDimitry Andric case tok::kw_const_cast: 14930b57cec5SDimitry Andric case tok::kw_dynamic_cast: 14940b57cec5SDimitry Andric case tok::kw_reinterpret_cast: 14950b57cec5SDimitry Andric case tok::kw_static_cast: 14965ffd83dbSDimitry Andric case tok::kw_addrspace_cast: 1497480093f4SDimitry Andric if (NotPrimaryExpression) 1498480093f4SDimitry Andric *NotPrimaryExpression = true; 14990b57cec5SDimitry Andric Res = ParseCXXCasts(); 15000b57cec5SDimitry Andric break; 15010b57cec5SDimitry Andric case tok::kw___builtin_bit_cast: 1502480093f4SDimitry Andric if (NotPrimaryExpression) 1503480093f4SDimitry Andric *NotPrimaryExpression = true; 15040b57cec5SDimitry Andric Res = ParseBuiltinBitCast(); 15050b57cec5SDimitry Andric break; 15060b57cec5SDimitry Andric case tok::kw_typeid: 1507480093f4SDimitry Andric if (NotPrimaryExpression) 1508480093f4SDimitry Andric *NotPrimaryExpression = true; 15090b57cec5SDimitry Andric Res = ParseCXXTypeid(); 15100b57cec5SDimitry Andric break; 15110b57cec5SDimitry Andric case tok::kw___uuidof: 1512480093f4SDimitry Andric if (NotPrimaryExpression) 1513480093f4SDimitry Andric *NotPrimaryExpression = true; 15140b57cec5SDimitry Andric Res = ParseCXXUuidof(); 15150b57cec5SDimitry Andric break; 15160b57cec5SDimitry Andric case tok::kw_this: 15170b57cec5SDimitry Andric Res = ParseCXXThis(); 15180b57cec5SDimitry Andric break; 1519fe6060f1SDimitry Andric case tok::kw___builtin_sycl_unique_stable_name: 1520fe6060f1SDimitry Andric Res = ParseSYCLUniqueStableNameExpression(); 1521fe6060f1SDimitry Andric break; 1522e8d8bef9SDimitry Andric 15230b57cec5SDimitry Andric case tok::annot_typename: 15240b57cec5SDimitry Andric if (isStartOfObjCClassMessageMissingOpenBracket()) { 15255ffd83dbSDimitry Andric TypeResult Type = getTypeAnnotation(Tok); 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 15280b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 15290b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 15300b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getLastLoc()); 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric const char *PrevSpec = nullptr; 15330b57cec5SDimitry Andric unsigned DiagID; 15340b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(), 15350b57cec5SDimitry Andric PrevSpec, DiagID, Type, 15360b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 15370b57cec5SDimitry Andric 153881ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 153981ad6265SDimitry Andric DeclaratorContext::TypeName); 1540*7a6dacacSDimitry Andric TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo); 15410b57cec5SDimitry Andric if (Ty.isInvalid()) 15420b57cec5SDimitry Andric break; 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric ConsumeAnnotationToken(); 15450b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 15460b57cec5SDimitry Andric Ty.get(), nullptr); 15470b57cec5SDimitry Andric break; 15480b57cec5SDimitry Andric } 1549bdd1243dSDimitry Andric [[fallthrough]]; 15500b57cec5SDimitry Andric 15510b57cec5SDimitry Andric case tok::annot_decltype: 15520b57cec5SDimitry Andric case tok::kw_char: 15530b57cec5SDimitry Andric case tok::kw_wchar_t: 15540b57cec5SDimitry Andric case tok::kw_char8_t: 15550b57cec5SDimitry Andric case tok::kw_char16_t: 15560b57cec5SDimitry Andric case tok::kw_char32_t: 15570b57cec5SDimitry Andric case tok::kw_bool: 15580b57cec5SDimitry Andric case tok::kw_short: 15590b57cec5SDimitry Andric case tok::kw_int: 15600b57cec5SDimitry Andric case tok::kw_long: 15610b57cec5SDimitry Andric case tok::kw___int64: 15620b57cec5SDimitry Andric case tok::kw___int128: 15635ffd83dbSDimitry Andric case tok::kw__ExtInt: 15640eae32dcSDimitry Andric case tok::kw__BitInt: 15650b57cec5SDimitry Andric case tok::kw_signed: 15660b57cec5SDimitry Andric case tok::kw_unsigned: 15670b57cec5SDimitry Andric case tok::kw_half: 15680b57cec5SDimitry Andric case tok::kw_float: 15690b57cec5SDimitry Andric case tok::kw_double: 15705ffd83dbSDimitry Andric case tok::kw___bf16: 15710b57cec5SDimitry Andric case tok::kw__Float16: 15720b57cec5SDimitry Andric case tok::kw___float128: 1573349cc55cSDimitry Andric case tok::kw___ibm128: 15740b57cec5SDimitry Andric case tok::kw_void: 157581ad6265SDimitry Andric case tok::kw_auto: 15760b57cec5SDimitry Andric case tok::kw_typename: 15770b57cec5SDimitry Andric case tok::kw_typeof: 15780b57cec5SDimitry Andric case tok::kw___vector: 15795f757f3fSDimitry Andric case tok::kw__Accum: 15805f757f3fSDimitry Andric case tok::kw__Fract: 15815f757f3fSDimitry Andric case tok::kw__Sat: 15820b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 15830b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 15840b57cec5SDimitry Andric { 15850b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 15860b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 15870b57cec5SDimitry Andric return ExprError(); 15880b57cec5SDimitry Andric } 15890b57cec5SDimitry Andric 1590480093f4SDimitry Andric // Everything henceforth is a postfix-expression. 1591480093f4SDimitry Andric if (NotPrimaryExpression) 1592480093f4SDimitry Andric *NotPrimaryExpression = true; 1593480093f4SDimitry Andric 15940b57cec5SDimitry Andric if (SavedKind == tok::kw_typename) { 15950b57cec5SDimitry Andric // postfix-expression: typename-specifier '(' expression-list[opt] ')' 15960b57cec5SDimitry Andric // typename-specifier braced-init-list 15970b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 15980b57cec5SDimitry Andric return ExprError(); 15990b57cec5SDimitry Andric 16000b57cec5SDimitry Andric if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) 16010b57cec5SDimitry Andric // We are trying to parse a simple-type-specifier but might not get such 16020b57cec5SDimitry Andric // a token after error recovery. 16030b57cec5SDimitry Andric return ExprError(); 16040b57cec5SDimitry Andric } 16050b57cec5SDimitry Andric 16060b57cec5SDimitry Andric // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 16070b57cec5SDimitry Andric // simple-type-specifier braced-init-list 16080b57cec5SDimitry Andric // 16090b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 16100b57cec5SDimitry Andric 16110b57cec5SDimitry Andric ParseCXXSimpleTypeSpecifier(DS); 16120b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren) && 16130b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) 16140b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 16150b57cec5SDimitry Andric << DS.getSourceRange()); 16160b57cec5SDimitry Andric 16170b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) 16180b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 16190b57cec5SDimitry Andric 16200b57cec5SDimitry Andric Res = ParseCXXTypeConstructExpression(DS); 16210b57cec5SDimitry Andric break; 16220b57cec5SDimitry Andric } 16230b57cec5SDimitry Andric 16240b57cec5SDimitry Andric case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 16250b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 16260b57cec5SDimitry Andric // (We can end up in this situation after tentative parsing.) 16270b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16280b57cec5SDimitry Andric return ExprError(); 16290b57cec5SDimitry Andric if (!Tok.is(tok::annot_cxxscope)) 1630480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1631480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1632480093f4SDimitry Andric NotPrimaryExpression); 16330b57cec5SDimitry Andric 16340b57cec5SDimitry Andric Token Next = NextToken(); 16350b57cec5SDimitry Andric if (Next.is(tok::annot_template_id)) { 16360b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 16370b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 16380b57cec5SDimitry Andric // We have a qualified template-id that we know refers to a 16390b57cec5SDimitry Andric // type, translate it into a type and continue parsing as a 16400b57cec5SDimitry Andric // cast expression. 16410b57cec5SDimitry Andric CXXScopeSpec SS; 16425ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 164304eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 16440b57cec5SDimitry Andric /*EnteringContext=*/false); 1645bdd1243dSDimitry Andric AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); 1646480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1647480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1648480093f4SDimitry Andric NotPrimaryExpression); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric } 16510b57cec5SDimitry Andric 16520b57cec5SDimitry Andric // Parse as an id-expression. 16530b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 16540b57cec5SDimitry Andric break; 16550b57cec5SDimitry Andric } 16560b57cec5SDimitry Andric 16570b57cec5SDimitry Andric case tok::annot_template_id: { // [C++] template-id 16580b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 16590b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 16600b57cec5SDimitry Andric // We have a template-id that we know refers to a type, 16610b57cec5SDimitry Andric // translate it into a type and continue parsing as a cast 16620b57cec5SDimitry Andric // expression. 166355e4f9d5SDimitry Andric CXXScopeSpec SS; 1664bdd1243dSDimitry Andric AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); 1665480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1666480093f4SDimitry Andric NotCastExpr, isTypeCast, isVectorLiteral, 1667480093f4SDimitry Andric NotPrimaryExpression); 16680b57cec5SDimitry Andric } 16690b57cec5SDimitry Andric 16700b57cec5SDimitry Andric // Fall through to treat the template-id as an id-expression. 1671bdd1243dSDimitry Andric [[fallthrough]]; 16720b57cec5SDimitry Andric } 16730b57cec5SDimitry Andric 16740b57cec5SDimitry Andric case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 16750b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 16760b57cec5SDimitry Andric break; 16770b57cec5SDimitry Andric 16780b57cec5SDimitry Andric case tok::coloncolon: { 16790b57cec5SDimitry Andric // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 16800b57cec5SDimitry Andric // annotates the token, tail recurse. 16810b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16820b57cec5SDimitry Andric return ExprError(); 16830b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) 1684480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1685480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric // ::new -> [C++] new-expression 16880b57cec5SDimitry Andric // ::delete -> [C++] delete-expression 16890b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 1690480093f4SDimitry Andric if (Tok.is(tok::kw_new)) { 1691480093f4SDimitry Andric if (NotPrimaryExpression) 1692480093f4SDimitry Andric *NotPrimaryExpression = true; 16935ffd83dbSDimitry Andric Res = ParseCXXNewExpression(true, CCLoc); 16945ffd83dbSDimitry Andric AllowSuffix = false; 16955ffd83dbSDimitry Andric break; 1696480093f4SDimitry Andric } 1697480093f4SDimitry Andric if (Tok.is(tok::kw_delete)) { 1698480093f4SDimitry Andric if (NotPrimaryExpression) 1699480093f4SDimitry Andric *NotPrimaryExpression = true; 17005ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(true, CCLoc); 17015ffd83dbSDimitry Andric AllowSuffix = false; 17025ffd83dbSDimitry Andric break; 1703480093f4SDimitry Andric } 17040b57cec5SDimitry Andric 17050b57cec5SDimitry Andric // This is not a type name or scope specifier, it is an invalid expression. 17060b57cec5SDimitry Andric Diag(CCLoc, diag::err_expected_expression); 17070b57cec5SDimitry Andric return ExprError(); 17080b57cec5SDimitry Andric } 17090b57cec5SDimitry Andric 17100b57cec5SDimitry Andric case tok::kw_new: // [C++] new-expression 1711480093f4SDimitry Andric if (NotPrimaryExpression) 1712480093f4SDimitry Andric *NotPrimaryExpression = true; 17135ffd83dbSDimitry Andric Res = ParseCXXNewExpression(false, Tok.getLocation()); 17145ffd83dbSDimitry Andric AllowSuffix = false; 17155ffd83dbSDimitry Andric break; 17160b57cec5SDimitry Andric 17170b57cec5SDimitry Andric case tok::kw_delete: // [C++] delete-expression 1718480093f4SDimitry Andric if (NotPrimaryExpression) 1719480093f4SDimitry Andric *NotPrimaryExpression = true; 17205ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(false, Tok.getLocation()); 17215ffd83dbSDimitry Andric AllowSuffix = false; 17225ffd83dbSDimitry Andric break; 17230b57cec5SDimitry Andric 172455e4f9d5SDimitry Andric case tok::kw_requires: // [C++2a] requires-expression 17255ffd83dbSDimitry Andric Res = ParseRequiresExpression(); 17265ffd83dbSDimitry Andric AllowSuffix = false; 17275ffd83dbSDimitry Andric break; 172855e4f9d5SDimitry Andric 17290b57cec5SDimitry Andric case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' 1730480093f4SDimitry Andric if (NotPrimaryExpression) 1731480093f4SDimitry Andric *NotPrimaryExpression = true; 17320b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_noexcept_expr); 17330b57cec5SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 17340b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 17350b57cec5SDimitry Andric 17360b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept")) 17370b57cec5SDimitry Andric return ExprError(); 17380b57cec5SDimitry Andric // C++11 [expr.unary.noexcept]p1: 17390b57cec5SDimitry Andric // The noexcept operator determines whether the evaluation of its operand, 17400b57cec5SDimitry Andric // which is an unevaluated operand, can throw an exception. 17410b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 17420b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 17435ffd83dbSDimitry Andric Res = ParseExpression(); 17440b57cec5SDimitry Andric 17450b57cec5SDimitry Andric T.consumeClose(); 17460b57cec5SDimitry Andric 17475ffd83dbSDimitry Andric if (!Res.isInvalid()) 17485ffd83dbSDimitry Andric Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(), 17495ffd83dbSDimitry Andric T.getCloseLocation()); 17505ffd83dbSDimitry Andric AllowSuffix = false; 17515ffd83dbSDimitry Andric break; 17520b57cec5SDimitry Andric } 17530b57cec5SDimitry Andric 17540b57cec5SDimitry Andric #define TYPE_TRAIT(N,Spelling,K) \ 17550b57cec5SDimitry Andric case tok::kw_##Spelling: 17560b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 17575ffd83dbSDimitry Andric Res = ParseTypeTrait(); 17585ffd83dbSDimitry Andric break; 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric case tok::kw___array_rank: 17610b57cec5SDimitry Andric case tok::kw___array_extent: 1762480093f4SDimitry Andric if (NotPrimaryExpression) 1763480093f4SDimitry Andric *NotPrimaryExpression = true; 17645ffd83dbSDimitry Andric Res = ParseArrayTypeTrait(); 17655ffd83dbSDimitry Andric break; 17660b57cec5SDimitry Andric 17670b57cec5SDimitry Andric case tok::kw___is_lvalue_expr: 17680b57cec5SDimitry Andric case tok::kw___is_rvalue_expr: 1769480093f4SDimitry Andric if (NotPrimaryExpression) 1770480093f4SDimitry Andric *NotPrimaryExpression = true; 17715ffd83dbSDimitry Andric Res = ParseExpressionTrait(); 17725ffd83dbSDimitry Andric break; 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric case tok::at: { 1775480093f4SDimitry Andric if (NotPrimaryExpression) 1776480093f4SDimitry Andric *NotPrimaryExpression = true; 17770b57cec5SDimitry Andric SourceLocation AtLoc = ConsumeToken(); 17780b57cec5SDimitry Andric return ParseObjCAtExpression(AtLoc); 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric case tok::caret: 17810b57cec5SDimitry Andric Res = ParseBlockLiteralExpression(); 17820b57cec5SDimitry Andric break; 17830b57cec5SDimitry Andric case tok::code_completion: { 1784fe6060f1SDimitry Andric cutOffParsing(); 17850b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 17860b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 17870b57cec5SDimitry Andric return ExprError(); 17880b57cec5SDimitry Andric } 1789bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: 1790bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 1791bdd1243dSDimitry Andric // HACK: libstdc++ uses some of the transform-type-traits as alias 1792bdd1243dSDimitry Andric // templates, so we need to work around this. 1793bdd1243dSDimitry Andric if (!NextToken().is(tok::l_paren)) { 1794bdd1243dSDimitry Andric Tok.setKind(tok::identifier); 1795bdd1243dSDimitry Andric Diag(Tok, diag::ext_keyword_as_ident) 1796bdd1243dSDimitry Andric << Tok.getIdentifierInfo()->getName() << 0; 1797bdd1243dSDimitry Andric goto ParseIdentifier; 1798bdd1243dSDimitry Andric } 1799bdd1243dSDimitry Andric goto ExpectedExpression; 18000b57cec5SDimitry Andric case tok::l_square: 18010b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11) { 18020b57cec5SDimitry Andric if (getLangOpts().ObjC) { 18030b57cec5SDimitry Andric // C++11 lambda expressions and Objective-C message sends both start with a 18040b57cec5SDimitry Andric // square bracket. There are three possibilities here: 18050b57cec5SDimitry Andric // we have a valid lambda expression, we have an invalid lambda 18060b57cec5SDimitry Andric // expression, or we have something that doesn't appear to be a lambda. 18070b57cec5SDimitry Andric // If we're in the last case, we fall back to ParseObjCMessageExpression. 18080b57cec5SDimitry Andric Res = TryParseLambdaExpression(); 1809480093f4SDimitry Andric if (!Res.isInvalid() && !Res.get()) { 1810480093f4SDimitry Andric // We assume Objective-C++ message expressions are not 1811480093f4SDimitry Andric // primary-expressions. 1812480093f4SDimitry Andric if (NotPrimaryExpression) 1813480093f4SDimitry Andric *NotPrimaryExpression = true; 18140b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 1815480093f4SDimitry Andric } 18160b57cec5SDimitry Andric break; 18170b57cec5SDimitry Andric } 18180b57cec5SDimitry Andric Res = ParseLambdaExpression(); 18190b57cec5SDimitry Andric break; 18200b57cec5SDimitry Andric } 18210b57cec5SDimitry Andric if (getLangOpts().ObjC) { 18220b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 18230b57cec5SDimitry Andric break; 18240b57cec5SDimitry Andric } 1825bdd1243dSDimitry Andric [[fallthrough]]; 18260b57cec5SDimitry Andric default: 1827bdd1243dSDimitry Andric ExpectedExpression: 18280b57cec5SDimitry Andric NotCastExpr = true; 18290b57cec5SDimitry Andric return ExprError(); 18300b57cec5SDimitry Andric } 18310b57cec5SDimitry Andric 18320b57cec5SDimitry Andric // Check to see whether Res is a function designator only. If it is and we 18330b57cec5SDimitry Andric // are compiling for OpenCL, we need to return an error as this implies 18340b57cec5SDimitry Andric // that the address of the function is being taken, which is illegal in CL. 18350b57cec5SDimitry Andric 1836480093f4SDimitry Andric if (ParseKind == PrimaryExprOnly) 1837480093f4SDimitry Andric // This is strictly a primary-expression - no postfix-expr pieces should be 1838480093f4SDimitry Andric // parsed. 1839480093f4SDimitry Andric return Res; 1840480093f4SDimitry Andric 18415ffd83dbSDimitry Andric if (!AllowSuffix) { 18425ffd83dbSDimitry Andric // FIXME: Don't parse a primary-expression suffix if we encountered a parse 18435ffd83dbSDimitry Andric // error already. 18445ffd83dbSDimitry Andric if (Res.isInvalid()) 18455ffd83dbSDimitry Andric return Res; 18465ffd83dbSDimitry Andric 18475ffd83dbSDimitry Andric switch (Tok.getKind()) { 18485ffd83dbSDimitry Andric case tok::l_square: 18495ffd83dbSDimitry Andric case tok::l_paren: 18505ffd83dbSDimitry Andric case tok::plusplus: 18515ffd83dbSDimitry Andric case tok::minusminus: 18525ffd83dbSDimitry Andric // "expected ';'" or similar is probably the right diagnostic here. Let 18535ffd83dbSDimitry Andric // the caller decide what to do. 18545ffd83dbSDimitry Andric if (Tok.isAtStartOfLine()) 18555ffd83dbSDimitry Andric return Res; 18565ffd83dbSDimitry Andric 1857bdd1243dSDimitry Andric [[fallthrough]]; 18585ffd83dbSDimitry Andric case tok::period: 18595ffd83dbSDimitry Andric case tok::arrow: 18605ffd83dbSDimitry Andric break; 18615ffd83dbSDimitry Andric 18625ffd83dbSDimitry Andric default: 18635ffd83dbSDimitry Andric return Res; 18645ffd83dbSDimitry Andric } 18655ffd83dbSDimitry Andric 18665ffd83dbSDimitry Andric // This was a unary-expression for which a postfix-expression suffix is 18675ffd83dbSDimitry Andric // not permitted by the grammar (eg, a sizeof expression or 18685ffd83dbSDimitry Andric // new-expression or similar). Diagnose but parse the suffix anyway. 18695ffd83dbSDimitry Andric Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens) 18705ffd83dbSDimitry Andric << Tok.getKind() << Res.get()->getSourceRange() 18715ffd83dbSDimitry Andric << FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(") 18725ffd83dbSDimitry Andric << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation), 18735ffd83dbSDimitry Andric ")"); 18745ffd83dbSDimitry Andric } 18755ffd83dbSDimitry Andric 18760b57cec5SDimitry Andric // These can be followed by postfix-expr pieces. 18770b57cec5SDimitry Andric PreferredType = SavedType; 18780b57cec5SDimitry Andric Res = ParsePostfixExpressionSuffix(Res); 1879fe6060f1SDimitry Andric if (getLangOpts().OpenCL && 1880fe6060f1SDimitry Andric !getActions().getOpenCLOptions().isAvailableOption( 1881fe6060f1SDimitry Andric "__cl_clang_function_pointers", getLangOpts())) 18820b57cec5SDimitry Andric if (Expr *PostfixExpr = Res.get()) { 18830b57cec5SDimitry Andric QualType Ty = PostfixExpr->getType(); 18840b57cec5SDimitry Andric if (!Ty.isNull() && Ty->isFunctionType()) { 18850b57cec5SDimitry Andric Diag(PostfixExpr->getExprLoc(), 18860b57cec5SDimitry Andric diag::err_opencl_taking_function_address_parser); 18870b57cec5SDimitry Andric return ExprError(); 18880b57cec5SDimitry Andric } 18890b57cec5SDimitry Andric } 18900b57cec5SDimitry Andric 18910b57cec5SDimitry Andric return Res; 18920b57cec5SDimitry Andric } 18930b57cec5SDimitry Andric 18940b57cec5SDimitry Andric /// Once the leading part of a postfix-expression is parsed, this 18950b57cec5SDimitry Andric /// method parses any suffixes that apply. 18960b57cec5SDimitry Andric /// 18970b57cec5SDimitry Andric /// \verbatim 18980b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 18990b57cec5SDimitry Andric /// primary-expression 19000b57cec5SDimitry Andric /// postfix-expression '[' expression ']' 19010b57cec5SDimitry Andric /// postfix-expression '[' braced-init-list ']' 190206c3fb27SDimitry Andric /// postfix-expression '[' expression-list [opt] ']' [C++23 12.4.5] 19030b57cec5SDimitry Andric /// postfix-expression '(' argument-expression-list[opt] ')' 19040b57cec5SDimitry Andric /// postfix-expression '.' identifier 19050b57cec5SDimitry Andric /// postfix-expression '->' identifier 19060b57cec5SDimitry Andric /// postfix-expression '++' 19070b57cec5SDimitry Andric /// postfix-expression '--' 19080b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 19090b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 19100b57cec5SDimitry Andric /// 19110b57cec5SDimitry Andric /// argument-expression-list: [C99 6.5.2] 19120b57cec5SDimitry Andric /// argument-expression ...[opt] 19130b57cec5SDimitry Andric /// argument-expression-list ',' assignment-expression ...[opt] 19140b57cec5SDimitry Andric /// \endverbatim 19150b57cec5SDimitry Andric ExprResult 19160b57cec5SDimitry Andric Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { 19170b57cec5SDimitry Andric // Now that the primary-expression piece of the postfix-expression has been 19180b57cec5SDimitry Andric // parsed, see if there are any postfix-expression pieces here. 19190b57cec5SDimitry Andric SourceLocation Loc; 19200b57cec5SDimitry Andric auto SavedType = PreferredType; 192104eeddc0SDimitry Andric while (true) { 19220b57cec5SDimitry Andric // Each iteration relies on preferred type for the whole expression. 19230b57cec5SDimitry Andric PreferredType = SavedType; 19240b57cec5SDimitry Andric switch (Tok.getKind()) { 19250b57cec5SDimitry Andric case tok::code_completion: 19260b57cec5SDimitry Andric if (InMessageExpression) 19270b57cec5SDimitry Andric return LHS; 19280b57cec5SDimitry Andric 1929fe6060f1SDimitry Andric cutOffParsing(); 19300b57cec5SDimitry Andric Actions.CodeCompletePostfixExpression( 19310b57cec5SDimitry Andric getCurScope(), LHS, PreferredType.get(Tok.getLocation())); 19320b57cec5SDimitry Andric return ExprError(); 19330b57cec5SDimitry Andric 19340b57cec5SDimitry Andric case tok::identifier: 19350b57cec5SDimitry Andric // If we see identifier: after an expression, and we're not already in a 19360b57cec5SDimitry Andric // message send, then this is probably a message send with a missing 19370b57cec5SDimitry Andric // opening bracket '['. 19380b57cec5SDimitry Andric if (getLangOpts().ObjC && !InMessageExpression && 19390b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 19400b57cec5SDimitry Andric LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 19410b57cec5SDimitry Andric nullptr, LHS.get()); 19420b57cec5SDimitry Andric break; 19430b57cec5SDimitry Andric } 19440b57cec5SDimitry Andric // Fall through; this isn't a message send. 1945bdd1243dSDimitry Andric [[fallthrough]]; 19460b57cec5SDimitry Andric 19470b57cec5SDimitry Andric default: // Not a postfix-expression suffix. 19480b57cec5SDimitry Andric return LHS; 19490b57cec5SDimitry Andric case tok::l_square: { // postfix-expression: p-e '[' expression ']' 19500b57cec5SDimitry Andric // If we have a array postfix expression that starts on a new line and 19510b57cec5SDimitry Andric // Objective-C is enabled, it is highly likely that the user forgot a 19520b57cec5SDimitry Andric // semicolon after the base expression and that the array postfix-expr is 19530b57cec5SDimitry Andric // actually another message send. In this case, do some look-ahead to see 19540b57cec5SDimitry Andric // if the contents of the square brackets are obviously not a valid 19550b57cec5SDimitry Andric // expression and recover by pretending there is no suffix. 19560b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.isAtStartOfLine() && 19570b57cec5SDimitry Andric isSimpleObjCMessageExpression()) 19580b57cec5SDimitry Andric return LHS; 19590b57cec5SDimitry Andric 19600b57cec5SDimitry Andric // Reject array indices starting with a lambda-expression. '[[' is 19610b57cec5SDimitry Andric // reserved for attributes. 19620b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) { 19630b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 19640b57cec5SDimitry Andric return ExprError(); 19650b57cec5SDimitry Andric } 19660b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 19670b57cec5SDimitry Andric T.consumeOpen(); 19680b57cec5SDimitry Andric Loc = T.getOpenLocation(); 196981ad6265SDimitry Andric ExprResult Length, Stride; 19705ffd83dbSDimitry Andric SourceLocation ColonLocFirst, ColonLocSecond; 197181ad6265SDimitry Andric ExprVector ArgExprs; 197281ad6265SDimitry Andric bool HasError = false; 19730b57cec5SDimitry Andric PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); 197481ad6265SDimitry Andric 197581ad6265SDimitry Andric // We try to parse a list of indexes in all language mode first 1976297eecfbSDimitry Andric // and, in we find 0 or one index, we try to parse an OpenMP/OpenACC array 197706c3fb27SDimitry Andric // section. This allow us to support C++23 multi dimensional subscript and 1978297eecfbSDimitry Andric // OpenMP/OpenACC sections in the same language mode. 1979297eecfbSDimitry Andric if ((!getLangOpts().OpenMP && !AllowOpenACCArraySections) || 1980297eecfbSDimitry Andric Tok.isNot(tok::colon)) { 198106c3fb27SDimitry Andric if (!getLangOpts().CPlusPlus23) { 198281ad6265SDimitry Andric ExprResult Idx; 19830b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 19840b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 19850b57cec5SDimitry Andric Idx = ParseBraceInitializer(); 198681ad6265SDimitry Andric } else { 198781ad6265SDimitry Andric Idx = ParseExpression(); // May be a comma expression 19880b57cec5SDimitry Andric } 198981ad6265SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 199081ad6265SDimitry Andric Idx = Actions.CorrectDelayedTyposInExpr(Idx); 199181ad6265SDimitry Andric if (Idx.isInvalid()) { 199281ad6265SDimitry Andric HasError = true; 199381ad6265SDimitry Andric } else { 199481ad6265SDimitry Andric ArgExprs.push_back(Idx.get()); 199581ad6265SDimitry Andric } 199681ad6265SDimitry Andric } else if (Tok.isNot(tok::r_square)) { 1997bdd1243dSDimitry Andric if (ParseExpressionList(ArgExprs)) { 199881ad6265SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 199981ad6265SDimitry Andric HasError = true; 200081ad6265SDimitry Andric } 200181ad6265SDimitry Andric } 200281ad6265SDimitry Andric } 200381ad6265SDimitry Andric 2004297eecfbSDimitry Andric // Handle OpenACC first, since 'AllowOpenACCArraySections' is only enabled 2005297eecfbSDimitry Andric // when actively parsing a 'var' in a 'var-list' during clause/'cache' 2006297eecfbSDimitry Andric // parsing, so it is the most specific, and best allows us to handle 2007297eecfbSDimitry Andric // OpenACC and OpenMP at the same time. 2008297eecfbSDimitry Andric if (ArgExprs.size() <= 1 && AllowOpenACCArraySections) { 2009297eecfbSDimitry Andric ColonProtectionRAIIObject RAII(*this); 2010297eecfbSDimitry Andric if (Tok.is(tok::colon)) { 2011297eecfbSDimitry Andric // Consume ':' 2012297eecfbSDimitry Andric ColonLocFirst = ConsumeToken(); 2013297eecfbSDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); 2014297eecfbSDimitry Andric } 2015297eecfbSDimitry Andric } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { 201681ad6265SDimitry Andric ColonProtectionRAIIObject RAII(*this); 20170b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 20180b57cec5SDimitry Andric // Consume ':' 20195ffd83dbSDimitry Andric ColonLocFirst = ConsumeToken(); 20205ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square) && 20215ffd83dbSDimitry Andric (getLangOpts().OpenMP < 50 || 202281ad6265SDimitry Andric ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) { 20230b57cec5SDimitry Andric Length = ParseExpression(); 202481ad6265SDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(Length); 202581ad6265SDimitry Andric } 20260b57cec5SDimitry Andric } 20275ffd83dbSDimitry Andric if (getLangOpts().OpenMP >= 50 && 20285ffd83dbSDimitry Andric (OMPClauseKind == llvm::omp::Clause::OMPC_to || 20295ffd83dbSDimitry Andric OMPClauseKind == llvm::omp::Clause::OMPC_from) && 20305ffd83dbSDimitry Andric Tok.is(tok::colon)) { 20315ffd83dbSDimitry Andric // Consume ':' 20325ffd83dbSDimitry Andric ColonLocSecond = ConsumeToken(); 20335ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) { 20345ffd83dbSDimitry Andric Stride = ParseExpression(); 20355ffd83dbSDimitry Andric } 20365ffd83dbSDimitry Andric } 203781ad6265SDimitry Andric } 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric SourceLocation RLoc = Tok.getLocation(); 20400b57cec5SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 204181ad6265SDimitry Andric 204281ad6265SDimitry Andric if (!LHS.isInvalid() && !HasError && !Length.isInvalid() && 20435ffd83dbSDimitry Andric !Stride.isInvalid() && Tok.is(tok::r_square)) { 20445ffd83dbSDimitry Andric if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { 2045297eecfbSDimitry Andric // FIXME: OpenACC hasn't implemented Sema/Array section handling at a 2046297eecfbSDimitry Andric // semantic level yet. For now, just reuse the OpenMP implementation 2047297eecfbSDimitry Andric // as it gets the parsing/type management mostly right, and we can 2048297eecfbSDimitry Andric // replace this call to ActOnOpenACCArraySectionExpr in the future. 2049297eecfbSDimitry Andric // Eventually we'll genericize the OPenMPArraySectionExpr type as 2050297eecfbSDimitry Andric // well. 20515ffd83dbSDimitry Andric LHS = Actions.ActOnOMPArraySectionExpr( 205281ad6265SDimitry Andric LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], 205381ad6265SDimitry Andric ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), RLoc); 20540b57cec5SDimitry Andric } else { 20550b57cec5SDimitry Andric LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, 205681ad6265SDimitry Andric ArgExprs, RLoc); 20570b57cec5SDimitry Andric } 20580b57cec5SDimitry Andric } else { 20590b57cec5SDimitry Andric LHS = ExprError(); 20600b57cec5SDimitry Andric } 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric // Match the ']'. 20630b57cec5SDimitry Andric T.consumeClose(); 20640b57cec5SDimitry Andric break; 20650b57cec5SDimitry Andric } 20660b57cec5SDimitry Andric 20670b57cec5SDimitry Andric case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' 20680b57cec5SDimitry Andric case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>' 20690b57cec5SDimitry Andric // '(' argument-expression-list[opt] ')' 20700b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 20710b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 20720b57cec5SDimitry Andric 20730b57cec5SDimitry Andric Expr *ExecConfig = nullptr; 20740b57cec5SDimitry Andric 20750b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 20760b57cec5SDimitry Andric 20770b57cec5SDimitry Andric if (OpKind == tok::lesslessless) { 20780b57cec5SDimitry Andric ExprVector ExecConfigExprs; 20790b57cec5SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 20800b57cec5SDimitry Andric 2081bdd1243dSDimitry Andric if (ParseSimpleExpressionList(ExecConfigExprs)) { 20820b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 20830b57cec5SDimitry Andric LHS = ExprError(); 20840b57cec5SDimitry Andric } 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andric SourceLocation CloseLoc; 20870b57cec5SDimitry Andric if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) { 20880b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 20890b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 20900b57cec5SDimitry Andric } else { 20910b57cec5SDimitry Andric // There was an error closing the brackets 20920b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::greatergreatergreater; 20930b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::lesslessless; 20940b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 20950b57cec5SDimitry Andric LHS = ExprError(); 20960b57cec5SDimitry Andric } 20970b57cec5SDimitry Andric 20980b57cec5SDimitry Andric if (!LHS.isInvalid()) { 20990b57cec5SDimitry Andric if (ExpectAndConsume(tok::l_paren)) 21000b57cec5SDimitry Andric LHS = ExprError(); 21010b57cec5SDimitry Andric else 21020b57cec5SDimitry Andric Loc = PrevTokLocation; 21030b57cec5SDimitry Andric } 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric if (!LHS.isInvalid()) { 21060b57cec5SDimitry Andric ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), 21070b57cec5SDimitry Andric OpenLoc, 21080b57cec5SDimitry Andric ExecConfigExprs, 21090b57cec5SDimitry Andric CloseLoc); 21100b57cec5SDimitry Andric if (ECResult.isInvalid()) 21110b57cec5SDimitry Andric LHS = ExprError(); 21120b57cec5SDimitry Andric else 21130b57cec5SDimitry Andric ExecConfig = ECResult.get(); 21140b57cec5SDimitry Andric } 21150b57cec5SDimitry Andric } else { 21160b57cec5SDimitry Andric PT.consumeOpen(); 21170b57cec5SDimitry Andric Loc = PT.getOpenLocation(); 21180b57cec5SDimitry Andric } 21190b57cec5SDimitry Andric 21200b57cec5SDimitry Andric ExprVector ArgExprs; 21210b57cec5SDimitry Andric auto RunSignatureHelp = [&]() -> QualType { 21220b57cec5SDimitry Andric QualType PreferredType = Actions.ProduceCallSignatureHelp( 212304eeddc0SDimitry Andric LHS.get(), ArgExprs, PT.getOpenLocation()); 21240b57cec5SDimitry Andric CalledSignatureHelp = true; 21250b57cec5SDimitry Andric return PreferredType; 21260b57cec5SDimitry Andric }; 21270b57cec5SDimitry Andric if (OpKind == tok::l_paren || !LHS.isInvalid()) { 21280b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 2129bdd1243dSDimitry Andric if (ParseExpressionList(ArgExprs, [&] { 21300b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 21310b57cec5SDimitry Andric RunSignatureHelp); 21320b57cec5SDimitry Andric })) { 21330b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 21340b57cec5SDimitry Andric // If we got an error when parsing expression list, we don't call 21350b57cec5SDimitry Andric // the CodeCompleteCall handler inside the parser. So call it here 21360b57cec5SDimitry Andric // to make sure we get overload suggestions even when we are in the 21370b57cec5SDimitry Andric // middle of a parameter. 21380b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 21390b57cec5SDimitry Andric RunSignatureHelp(); 21400b57cec5SDimitry Andric LHS = ExprError(); 21410b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 21420b57cec5SDimitry Andric for (auto &E : ArgExprs) 21430b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 21440b57cec5SDimitry Andric } 21450b57cec5SDimitry Andric } 21460b57cec5SDimitry Andric } 21470b57cec5SDimitry Andric 21480b57cec5SDimitry Andric // Match the ')'. 21490b57cec5SDimitry Andric if (LHS.isInvalid()) { 21500b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 21510b57cec5SDimitry Andric } else if (Tok.isNot(tok::r_paren)) { 21520b57cec5SDimitry Andric bool HadDelayedTypo = false; 21530b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get()) 21540b57cec5SDimitry Andric HadDelayedTypo = true; 21550b57cec5SDimitry Andric for (auto &E : ArgExprs) 21560b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(E).get() != E) 21570b57cec5SDimitry Andric HadDelayedTypo = true; 21580b57cec5SDimitry Andric // If there were delayed typos in the LHS or ArgExprs, call SkipUntil 21590b57cec5SDimitry Andric // instead of PT.consumeClose() to avoid emitting extra diagnostics for 21600b57cec5SDimitry Andric // the unmatched l_paren. 21610b57cec5SDimitry Andric if (HadDelayedTypo) 21620b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 21630b57cec5SDimitry Andric else 21640b57cec5SDimitry Andric PT.consumeClose(); 21650b57cec5SDimitry Andric LHS = ExprError(); 21660b57cec5SDimitry Andric } else { 21675ffd83dbSDimitry Andric Expr *Fn = LHS.get(); 21685ffd83dbSDimitry Andric SourceLocation RParLoc = Tok.getLocation(); 21695ffd83dbSDimitry Andric LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc, 21700b57cec5SDimitry Andric ExecConfig); 21715ffd83dbSDimitry Andric if (LHS.isInvalid()) { 21725ffd83dbSDimitry Andric ArgExprs.insert(ArgExprs.begin(), Fn); 21735ffd83dbSDimitry Andric LHS = 21745ffd83dbSDimitry Andric Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs); 21755ffd83dbSDimitry Andric } 21760b57cec5SDimitry Andric PT.consumeClose(); 21770b57cec5SDimitry Andric } 21780b57cec5SDimitry Andric 21790b57cec5SDimitry Andric break; 21800b57cec5SDimitry Andric } 21810b57cec5SDimitry Andric case tok::arrow: 21820b57cec5SDimitry Andric case tok::period: { 21830b57cec5SDimitry Andric // postfix-expression: p-e '->' template[opt] id-expression 21840b57cec5SDimitry Andric // postfix-expression: p-e '.' template[opt] id-expression 21850b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 21860b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 21870b57cec5SDimitry Andric 21880b57cec5SDimitry Andric CXXScopeSpec SS; 21890b57cec5SDimitry Andric ParsedType ObjectType; 21900b57cec5SDimitry Andric bool MayBePseudoDestructor = false; 21910b57cec5SDimitry Andric Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; 21920b57cec5SDimitry Andric 21930b57cec5SDimitry Andric PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS); 21940b57cec5SDimitry Andric 21950b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { 21960b57cec5SDimitry Andric Expr *Base = OrigLHS; 21970b57cec5SDimitry Andric const Type* BaseType = Base->getType().getTypePtrOrNull(); 21980b57cec5SDimitry Andric if (BaseType && Tok.is(tok::l_paren) && 21990b57cec5SDimitry Andric (BaseType->isFunctionType() || 22000b57cec5SDimitry Andric BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { 22010b57cec5SDimitry Andric Diag(OpLoc, diag::err_function_is_not_record) 22020b57cec5SDimitry Andric << OpKind << Base->getSourceRange() 22030b57cec5SDimitry Andric << FixItHint::CreateRemoval(OpLoc); 22040b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Base); 22050b57cec5SDimitry Andric } 22060b57cec5SDimitry Andric 22075ffd83dbSDimitry Andric LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, 22085ffd83dbSDimitry Andric OpKind, ObjectType, 22090b57cec5SDimitry Andric MayBePseudoDestructor); 22105ffd83dbSDimitry Andric if (LHS.isInvalid()) { 22115ffd83dbSDimitry Andric // Clang will try to perform expression based completion as a 22125ffd83dbSDimitry Andric // fallback, which is confusing in case of member references. So we 22135ffd83dbSDimitry Andric // stop here without any completions. 22145ffd83dbSDimitry Andric if (Tok.is(tok::code_completion)) { 22155ffd83dbSDimitry Andric cutOffParsing(); 22165ffd83dbSDimitry Andric return ExprError(); 22175ffd83dbSDimitry Andric } 22180b57cec5SDimitry Andric break; 22195ffd83dbSDimitry Andric } 22205ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier( 22215ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 22225ffd83dbSDimitry Andric /*EnteringContext=*/false, &MayBePseudoDestructor); 22230b57cec5SDimitry Andric if (SS.isNotEmpty()) 22240b57cec5SDimitry Andric ObjectType = nullptr; 22250b57cec5SDimitry Andric } 22260b57cec5SDimitry Andric 22270b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 22280b57cec5SDimitry Andric tok::TokenKind CorrectedOpKind = 22290b57cec5SDimitry Andric OpKind == tok::arrow ? tok::period : tok::arrow; 22300b57cec5SDimitry Andric ExprResult CorrectedLHS(/*Invalid=*/true); 22310b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && OrigLHS) { 2232a7dea167SDimitry Andric // FIXME: Creating a TentativeAnalysisScope from outside Sema is a 2233a7dea167SDimitry Andric // hack. 2234a7dea167SDimitry Andric Sema::TentativeAnalysisScope Trap(Actions); 22350b57cec5SDimitry Andric CorrectedLHS = Actions.ActOnStartCXXMemberReference( 22360b57cec5SDimitry Andric getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType, 22370b57cec5SDimitry Andric MayBePseudoDestructor); 22380b57cec5SDimitry Andric } 22390b57cec5SDimitry Andric 22400b57cec5SDimitry Andric Expr *Base = LHS.get(); 22410b57cec5SDimitry Andric Expr *CorrectedBase = CorrectedLHS.get(); 22420b57cec5SDimitry Andric if (!CorrectedBase && !getLangOpts().CPlusPlus) 22430b57cec5SDimitry Andric CorrectedBase = Base; 22440b57cec5SDimitry Andric 22450b57cec5SDimitry Andric // Code completion for a member access expression. 2246fe6060f1SDimitry Andric cutOffParsing(); 22470b57cec5SDimitry Andric Actions.CodeCompleteMemberReferenceExpr( 22480b57cec5SDimitry Andric getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, 22490b57cec5SDimitry Andric Base && ExprStatementTokLoc == Base->getBeginLoc(), 22500b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 22510b57cec5SDimitry Andric 22520b57cec5SDimitry Andric return ExprError(); 22530b57cec5SDimitry Andric } 22540b57cec5SDimitry Andric 22550b57cec5SDimitry Andric if (MayBePseudoDestructor && !LHS.isInvalid()) { 22560b57cec5SDimitry Andric LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 22570b57cec5SDimitry Andric ObjectType); 22580b57cec5SDimitry Andric break; 22590b57cec5SDimitry Andric } 22600b57cec5SDimitry Andric 22610b57cec5SDimitry Andric // Either the action has told us that this cannot be a 22620b57cec5SDimitry Andric // pseudo-destructor expression (based on the type of base 22630b57cec5SDimitry Andric // expression), or we didn't see a '~' in the right place. We 22640b57cec5SDimitry Andric // can still parse a destructor name here, but in that case it 22650b57cec5SDimitry Andric // names a real destructor. 22660b57cec5SDimitry Andric // Allow explicit constructor calls in Microsoft mode. 22670b57cec5SDimitry Andric // FIXME: Add support for explicit call of template constructor. 22680b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 22690b57cec5SDimitry Andric UnqualifiedId Name; 22700b57cec5SDimitry Andric if (getLangOpts().ObjC && OpKind == tok::period && 22710b57cec5SDimitry Andric Tok.is(tok::kw_class)) { 22720b57cec5SDimitry Andric // Objective-C++: 22730b57cec5SDimitry Andric // After a '.' in a member access expression, treat the keyword 22740b57cec5SDimitry Andric // 'class' as if it were an identifier. 22750b57cec5SDimitry Andric // 22760b57cec5SDimitry Andric // This hack allows property access to the 'class' method because it is 22770b57cec5SDimitry Andric // such a common method name. For other C++ keywords that are 22780b57cec5SDimitry Andric // Objective-C method names, one must use the message send syntax. 22790b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 22800b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 22810b57cec5SDimitry Andric Name.setIdentifier(Id, Loc); 22825ffd83dbSDimitry Andric } else if (ParseUnqualifiedId( 22835ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 22840b57cec5SDimitry Andric /*EnteringContext=*/false, 22850b57cec5SDimitry Andric /*AllowDestructorName=*/true, 22860b57cec5SDimitry Andric /*AllowConstructorName=*/ 22875ffd83dbSDimitry Andric getLangOpts().MicrosoftExt && SS.isNotEmpty(), 22885ffd83dbSDimitry Andric /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) { 22890b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 22900b57cec5SDimitry Andric LHS = ExprError(); 22910b57cec5SDimitry Andric } 22920b57cec5SDimitry Andric 22930b57cec5SDimitry Andric if (!LHS.isInvalid()) 22940b57cec5SDimitry Andric LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 22950b57cec5SDimitry Andric OpKind, SS, TemplateKWLoc, Name, 22960b57cec5SDimitry Andric CurParsedObjCImpl ? CurParsedObjCImpl->Dcl 22970b57cec5SDimitry Andric : nullptr); 22985ffd83dbSDimitry Andric if (!LHS.isInvalid()) { 22995ffd83dbSDimitry Andric if (Tok.is(tok::less)) 23000b57cec5SDimitry Andric checkPotentialAngleBracket(LHS); 23015ffd83dbSDimitry Andric } else if (OrigLHS && Name.isValid()) { 23025ffd83dbSDimitry Andric // Preserve the LHS if the RHS is an invalid member. 23035ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), 23045ffd83dbSDimitry Andric Name.getEndLoc(), {OrigLHS}); 23055ffd83dbSDimitry Andric } 23060b57cec5SDimitry Andric break; 23070b57cec5SDimitry Andric } 23080b57cec5SDimitry Andric case tok::plusplus: // postfix-expression: postfix-expression '++' 23090b57cec5SDimitry Andric case tok::minusminus: // postfix-expression: postfix-expression '--' 23100b57cec5SDimitry Andric if (!LHS.isInvalid()) { 23115ffd83dbSDimitry Andric Expr *Arg = LHS.get(); 23120b57cec5SDimitry Andric LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), 23135ffd83dbSDimitry Andric Tok.getKind(), Arg); 23145ffd83dbSDimitry Andric if (LHS.isInvalid()) 23155ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(), 23165ffd83dbSDimitry Andric Tok.getLocation(), Arg); 23170b57cec5SDimitry Andric } 23180b57cec5SDimitry Andric ConsumeToken(); 23190b57cec5SDimitry Andric break; 23200b57cec5SDimitry Andric } 23210b57cec5SDimitry Andric } 23220b57cec5SDimitry Andric } 23230b57cec5SDimitry Andric 23240b57cec5SDimitry Andric /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/ 23250b57cec5SDimitry Andric /// vec_step and we are at the start of an expression or a parenthesized 23260b57cec5SDimitry Andric /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the 23270b57cec5SDimitry Andric /// expression (isCastExpr == false) or the type (isCastExpr == true). 23280b57cec5SDimitry Andric /// 23290b57cec5SDimitry Andric /// \verbatim 23300b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 23310b57cec5SDimitry Andric /// 'sizeof' unary-expression 23320b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 23335f757f3fSDimitry Andric /// [Clang] '__datasizeof' unary-expression 23345f757f3fSDimitry Andric /// [Clang] '__datasizeof' '(' type-name ')' 23350b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 23360b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 23370b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 23380b57cec5SDimitry Andric /// [C++0x] 'alignof' '(' type-id ')' 23390b57cec5SDimitry Andric /// 23400b57cec5SDimitry Andric /// [GNU] typeof-specifier: 23410b57cec5SDimitry Andric /// typeof ( expressions ) 23420b57cec5SDimitry Andric /// typeof ( type-name ) 23430b57cec5SDimitry Andric /// [GNU/C++] typeof unary-expression 23445f757f3fSDimitry Andric /// [C23] typeof-specifier: 2345bdd1243dSDimitry Andric /// typeof '(' typeof-specifier-argument ')' 2346bdd1243dSDimitry Andric /// typeof_unqual '(' typeof-specifier-argument ')' 2347bdd1243dSDimitry Andric /// 2348bdd1243dSDimitry Andric /// typeof-specifier-argument: 2349bdd1243dSDimitry Andric /// expression 2350bdd1243dSDimitry Andric /// type-name 23510b57cec5SDimitry Andric /// 23520b57cec5SDimitry Andric /// [OpenCL 1.1 6.11.12] vec_step built-in function: 23530b57cec5SDimitry Andric /// vec_step ( expressions ) 23540b57cec5SDimitry Andric /// vec_step ( type-name ) 23550b57cec5SDimitry Andric /// \endverbatim 23560b57cec5SDimitry Andric ExprResult 23570b57cec5SDimitry Andric Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, 23580b57cec5SDimitry Andric bool &isCastExpr, 23590b57cec5SDimitry Andric ParsedType &CastTy, 23600b57cec5SDimitry Andric SourceRange &CastRange) { 23610b57cec5SDimitry Andric 2362bdd1243dSDimitry Andric assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof, 23635f757f3fSDimitry Andric tok::kw___datasizeof, tok::kw___alignof, tok::kw_alignof, 23645f757f3fSDimitry Andric tok::kw__Alignof, tok::kw_vec_step, 23655f757f3fSDimitry Andric tok::kw___builtin_omp_required_simd_align, 23665f757f3fSDimitry Andric tok::kw___builtin_vectorelements) && 23670b57cec5SDimitry Andric "Not a typeof/sizeof/alignof/vec_step expression!"); 23680b57cec5SDimitry Andric 23690b57cec5SDimitry Andric ExprResult Operand; 23700b57cec5SDimitry Andric 23710b57cec5SDimitry Andric // If the operand doesn't start with an '(', it must be an expression. 23720b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) { 23730b57cec5SDimitry Andric // If construct allows a form without parenthesis, user may forget to put 23740b57cec5SDimitry Andric // pathenthesis around type name. 23755f757f3fSDimitry Andric if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, 23765f757f3fSDimitry Andric tok::kw_alignof, tok::kw__Alignof)) { 23770b57cec5SDimitry Andric if (isTypeIdUnambiguously()) { 23780b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 23790b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 238081ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 238181ad6265SDimitry Andric DeclaratorContext::TypeName); 23820b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 23830b57cec5SDimitry Andric 23840b57cec5SDimitry Andric SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); 23850b57cec5SDimitry Andric SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); 2386e8d8bef9SDimitry Andric if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) { 2387e8d8bef9SDimitry Andric Diag(OpTok.getLocation(), 2388e8d8bef9SDimitry Andric diag::err_expected_parentheses_around_typename) 2389e8d8bef9SDimitry Andric << OpTok.getName(); 2390e8d8bef9SDimitry Andric } else { 23910b57cec5SDimitry Andric Diag(LParenLoc, diag::err_expected_parentheses_around_typename) 2392e8d8bef9SDimitry Andric << OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(") 23930b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 2394e8d8bef9SDimitry Andric } 23950b57cec5SDimitry Andric isCastExpr = true; 23960b57cec5SDimitry Andric return ExprEmpty(); 23970b57cec5SDimitry Andric } 23980b57cec5SDimitry Andric } 23990b57cec5SDimitry Andric 24000b57cec5SDimitry Andric isCastExpr = false; 2401bdd1243dSDimitry Andric if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) && 2402bdd1243dSDimitry Andric !getLangOpts().CPlusPlus) { 24030b57cec5SDimitry Andric Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo() 24040b57cec5SDimitry Andric << tok::l_paren; 24050b57cec5SDimitry Andric return ExprError(); 24060b57cec5SDimitry Andric } 24070b57cec5SDimitry Andric 2408480093f4SDimitry Andric Operand = ParseCastExpression(UnaryExprOnly); 24090b57cec5SDimitry Andric } else { 24100b57cec5SDimitry Andric // If it starts with a '(', we know that it is either a parenthesized 24110b57cec5SDimitry Andric // type-name, or it is a unary-expression that starts with a compound 24120b57cec5SDimitry Andric // literal, or starts with a primary-expression that is a parenthesized 24130b57cec5SDimitry Andric // expression. 24140b57cec5SDimitry Andric ParenParseOption ExprType = CastExpr; 24150b57cec5SDimitry Andric SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 24160b57cec5SDimitry Andric 24170b57cec5SDimitry Andric Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 24180b57cec5SDimitry Andric false, CastTy, RParenLoc); 24190b57cec5SDimitry Andric CastRange = SourceRange(LParenLoc, RParenLoc); 24200b57cec5SDimitry Andric 24210b57cec5SDimitry Andric // If ParseParenExpression parsed a '(typename)' sequence only, then this is 24220b57cec5SDimitry Andric // a type. 24230b57cec5SDimitry Andric if (ExprType == CastExpr) { 24240b57cec5SDimitry Andric isCastExpr = true; 24250b57cec5SDimitry Andric return ExprEmpty(); 24260b57cec5SDimitry Andric } 24270b57cec5SDimitry Andric 2428bdd1243dSDimitry Andric if (getLangOpts().CPlusPlus || 2429bdd1243dSDimitry Andric !OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) { 24300b57cec5SDimitry Andric // GNU typeof in C requires the expression to be parenthesized. Not so for 24310b57cec5SDimitry Andric // sizeof/alignof or in C++. Therefore, the parenthesized expression is 24320b57cec5SDimitry Andric // the start of a unary-expression, but doesn't include any postfix 24330b57cec5SDimitry Andric // pieces. Parse these now if present. 24340b57cec5SDimitry Andric if (!Operand.isInvalid()) 24350b57cec5SDimitry Andric Operand = ParsePostfixExpressionSuffix(Operand.get()); 24360b57cec5SDimitry Andric } 24370b57cec5SDimitry Andric } 24380b57cec5SDimitry Andric 24390b57cec5SDimitry Andric // If we get here, the operand to the typeof/sizeof/alignof was an expression. 24400b57cec5SDimitry Andric isCastExpr = false; 24410b57cec5SDimitry Andric return Operand; 24420b57cec5SDimitry Andric } 24430b57cec5SDimitry Andric 2444fe6060f1SDimitry Andric /// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as 2445fe6060f1SDimitry Andric /// a parameter. 2446fe6060f1SDimitry Andric ExprResult Parser::ParseSYCLUniqueStableNameExpression() { 2447fe6060f1SDimitry Andric assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) && 2448349cc55cSDimitry Andric "Not __builtin_sycl_unique_stable_name"); 2449fe6060f1SDimitry Andric 2450fe6060f1SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 2451fe6060f1SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 2452fe6060f1SDimitry Andric 2453fe6060f1SDimitry Andric // __builtin_sycl_unique_stable_name expressions are always parenthesized. 2454fe6060f1SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, 2455fe6060f1SDimitry Andric "__builtin_sycl_unique_stable_name")) 2456fe6060f1SDimitry Andric return ExprError(); 2457fe6060f1SDimitry Andric 2458fe6060f1SDimitry Andric TypeResult Ty = ParseTypeName(); 2459fe6060f1SDimitry Andric 2460fe6060f1SDimitry Andric if (Ty.isInvalid()) { 2461fe6060f1SDimitry Andric T.skipToEnd(); 2462fe6060f1SDimitry Andric return ExprError(); 2463fe6060f1SDimitry Andric } 2464fe6060f1SDimitry Andric 2465fe6060f1SDimitry Andric if (T.consumeClose()) 2466fe6060f1SDimitry Andric return ExprError(); 2467fe6060f1SDimitry Andric 2468fe6060f1SDimitry Andric return Actions.ActOnSYCLUniqueStableNameExpr(OpLoc, T.getOpenLocation(), 2469fe6060f1SDimitry Andric T.getCloseLocation(), Ty.get()); 2470fe6060f1SDimitry Andric } 24710b57cec5SDimitry Andric 24720b57cec5SDimitry Andric /// Parse a sizeof or alignof expression. 24730b57cec5SDimitry Andric /// 24740b57cec5SDimitry Andric /// \verbatim 24750b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 24760b57cec5SDimitry Andric /// 'sizeof' unary-expression 24770b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 24780b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 24795f757f3fSDimitry Andric /// [Clang] '__datasizeof' unary-expression 24805f757f3fSDimitry Andric /// [Clang] '__datasizeof' '(' type-name ')' 24810b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 24820b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 24830b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 24840b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 24850b57cec5SDimitry Andric /// \endverbatim 24860b57cec5SDimitry Andric ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { 24875f757f3fSDimitry Andric assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, 24885f757f3fSDimitry Andric tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, 24895f757f3fSDimitry Andric tok::kw___builtin_omp_required_simd_align, 24905f757f3fSDimitry Andric tok::kw___builtin_vectorelements) && 24910b57cec5SDimitry Andric "Not a sizeof/alignof/vec_step expression!"); 24920b57cec5SDimitry Andric Token OpTok = Tok; 24930b57cec5SDimitry Andric ConsumeToken(); 24940b57cec5SDimitry Andric 24950b57cec5SDimitry Andric // [C++11] 'sizeof' '...' '(' identifier ')' 24960b57cec5SDimitry Andric if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { 24970b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 24980b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 24990b57cec5SDimitry Andric IdentifierInfo *Name = nullptr; 25000b57cec5SDimitry Andric SourceLocation NameLoc; 25010b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 25020b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 25030b57cec5SDimitry Andric T.consumeOpen(); 25040b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 25050b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 25060b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 25070b57cec5SDimitry Andric NameLoc = ConsumeToken(); 25080b57cec5SDimitry Andric T.consumeClose(); 25090b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 25100b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 25110b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 25120b57cec5SDimitry Andric } else { 25130b57cec5SDimitry Andric Diag(Tok, diag::err_expected_parameter_pack); 25140b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25150b57cec5SDimitry Andric } 25160b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 25170b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 25180b57cec5SDimitry Andric NameLoc = ConsumeToken(); 25190b57cec5SDimitry Andric LParenLoc = PP.getLocForEndOfToken(EllipsisLoc); 25200b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 25210b57cec5SDimitry Andric Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack) 25220b57cec5SDimitry Andric << Name 25230b57cec5SDimitry Andric << FixItHint::CreateInsertion(LParenLoc, "(") 25240b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 25250b57cec5SDimitry Andric } else { 25260b57cec5SDimitry Andric Diag(Tok, diag::err_sizeof_parameter_pack); 25270b57cec5SDimitry Andric } 25280b57cec5SDimitry Andric 25290b57cec5SDimitry Andric if (!Name) 25300b57cec5SDimitry Andric return ExprError(); 25310b57cec5SDimitry Andric 25320b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 25330b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 25340b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 25350b57cec5SDimitry Andric 25360b57cec5SDimitry Andric return Actions.ActOnSizeofParameterPackExpr(getCurScope(), 25370b57cec5SDimitry Andric OpTok.getLocation(), 25380b57cec5SDimitry Andric *Name, NameLoc, 25390b57cec5SDimitry Andric RParenLoc); 25400b57cec5SDimitry Andric } 25410b57cec5SDimitry Andric 254206c3fb27SDimitry Andric if (getLangOpts().CPlusPlus && 254306c3fb27SDimitry Andric OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 25440b57cec5SDimitry Andric Diag(OpTok, diag::warn_cxx98_compat_alignof); 25455f757f3fSDimitry Andric else if (getLangOpts().C23 && OpTok.is(tok::kw_alignof)) 25465f757f3fSDimitry Andric Diag(OpTok, diag::warn_c23_compat_keyword) << OpTok.getName(); 25470b57cec5SDimitry Andric 25480b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 25490b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 25500b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 25510b57cec5SDimitry Andric 25520b57cec5SDimitry Andric bool isCastExpr; 25530b57cec5SDimitry Andric ParsedType CastTy; 25540b57cec5SDimitry Andric SourceRange CastRange; 25550b57cec5SDimitry Andric ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, 25560b57cec5SDimitry Andric isCastExpr, 25570b57cec5SDimitry Andric CastTy, 25580b57cec5SDimitry Andric CastRange); 25590b57cec5SDimitry Andric 25600b57cec5SDimitry Andric UnaryExprOrTypeTrait ExprKind = UETT_SizeOf; 25615f757f3fSDimitry Andric switch (OpTok.getKind()) { 25625f757f3fSDimitry Andric case tok::kw_alignof: 25635f757f3fSDimitry Andric case tok::kw__Alignof: 25640b57cec5SDimitry Andric ExprKind = UETT_AlignOf; 25655f757f3fSDimitry Andric break; 25665f757f3fSDimitry Andric case tok::kw___alignof: 25670b57cec5SDimitry Andric ExprKind = UETT_PreferredAlignOf; 25685f757f3fSDimitry Andric break; 25695f757f3fSDimitry Andric case tok::kw_vec_step: 25700b57cec5SDimitry Andric ExprKind = UETT_VecStep; 25715f757f3fSDimitry Andric break; 25725f757f3fSDimitry Andric case tok::kw___builtin_omp_required_simd_align: 25730b57cec5SDimitry Andric ExprKind = UETT_OpenMPRequiredSimdAlign; 25745f757f3fSDimitry Andric break; 25755f757f3fSDimitry Andric case tok::kw___datasizeof: 25765f757f3fSDimitry Andric ExprKind = UETT_DataSizeOf; 25775f757f3fSDimitry Andric break; 25785f757f3fSDimitry Andric case tok::kw___builtin_vectorelements: 25795f757f3fSDimitry Andric ExprKind = UETT_VectorElements; 25805f757f3fSDimitry Andric break; 25815f757f3fSDimitry Andric default: 25825f757f3fSDimitry Andric break; 25835f757f3fSDimitry Andric } 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andric if (isCastExpr) 25860b57cec5SDimitry Andric return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 25870b57cec5SDimitry Andric ExprKind, 25880b57cec5SDimitry Andric /*IsType=*/true, 25890b57cec5SDimitry Andric CastTy.getAsOpaquePtr(), 25900b57cec5SDimitry Andric CastRange); 25910b57cec5SDimitry Andric 25920b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 25930b57cec5SDimitry Andric Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); 25940b57cec5SDimitry Andric 25950b57cec5SDimitry Andric // If we get here, the operand to the sizeof/alignof was an expression. 25960b57cec5SDimitry Andric if (!Operand.isInvalid()) 25970b57cec5SDimitry Andric Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 25980b57cec5SDimitry Andric ExprKind, 25990b57cec5SDimitry Andric /*IsType=*/false, 26000b57cec5SDimitry Andric Operand.get(), 26010b57cec5SDimitry Andric CastRange); 26020b57cec5SDimitry Andric return Operand; 26030b57cec5SDimitry Andric } 26040b57cec5SDimitry Andric 26050b57cec5SDimitry Andric /// ParseBuiltinPrimaryExpression 26060b57cec5SDimitry Andric /// 26070b57cec5SDimitry Andric /// \verbatim 26080b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 26090b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 26100b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 26110b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 26120b57cec5SDimitry Andric /// assign-expr ')' 26130b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 26140b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 261506c3fb27SDimitry Andric /// [CLANG] '__builtin_FILE_NAME' '(' ')' 26160b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 261706c3fb27SDimitry Andric /// [MS] '__builtin_FUNCSIG' '(' ')' 26180b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 26190b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 262081ad6265SDimitry Andric /// [GNU] '__builtin_source_location' '(' ')' 26210b57cec5SDimitry Andric /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' 26220b57cec5SDimitry Andric /// 26230b57cec5SDimitry Andric /// [GNU] offsetof-member-designator: 26240b57cec5SDimitry Andric /// [GNU] identifier 26250b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '.' identifier 26260b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '[' expression ']' 26270b57cec5SDimitry Andric /// \endverbatim 26280b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinPrimaryExpression() { 26290b57cec5SDimitry Andric ExprResult Res; 26300b57cec5SDimitry Andric const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric tok::TokenKind T = Tok.getKind(); 26330b57cec5SDimitry Andric SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 26340b57cec5SDimitry Andric 26350b57cec5SDimitry Andric // All of these start with an open paren. 26360b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) 26370b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII 26380b57cec5SDimitry Andric << tok::l_paren); 26390b57cec5SDimitry Andric 26400b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 26410b57cec5SDimitry Andric PT.consumeOpen(); 26420b57cec5SDimitry Andric 26430b57cec5SDimitry Andric // TODO: Build AST. 26440b57cec5SDimitry Andric 26450b57cec5SDimitry Andric switch (T) { 26460b57cec5SDimitry Andric default: llvm_unreachable("Not a builtin primary expression!"); 26470b57cec5SDimitry Andric case tok::kw___builtin_va_arg: { 26480b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 26490b57cec5SDimitry Andric 26500b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26510b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26520b57cec5SDimitry Andric Expr = ExprError(); 26530b57cec5SDimitry Andric } 26540b57cec5SDimitry Andric 26550b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 26560b57cec5SDimitry Andric 26570b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 26580b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 26590b57cec5SDimitry Andric Expr = ExprError(); 26600b57cec5SDimitry Andric } 26610b57cec5SDimitry Andric 26620b57cec5SDimitry Andric if (Expr.isInvalid() || Ty.isInvalid()) 26630b57cec5SDimitry Andric Res = ExprError(); 26640b57cec5SDimitry Andric else 26650b57cec5SDimitry Andric Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen()); 26660b57cec5SDimitry Andric break; 26670b57cec5SDimitry Andric } 26680b57cec5SDimitry Andric case tok::kw___builtin_offsetof: { 26690b57cec5SDimitry Andric SourceLocation TypeLoc = Tok.getLocation(); 2670bdd1243dSDimitry Andric auto OOK = Sema::OffsetOfKind::OOK_Builtin; 2671bdd1243dSDimitry Andric if (Tok.getLocation().isMacroID()) { 2672bdd1243dSDimitry Andric StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics( 2673bdd1243dSDimitry Andric Tok.getLocation(), PP.getSourceManager(), getLangOpts()); 2674bdd1243dSDimitry Andric if (MacroName == "offsetof") 2675bdd1243dSDimitry Andric OOK = Sema::OffsetOfKind::OOK_Macro; 2676bdd1243dSDimitry Andric } 2677bdd1243dSDimitry Andric TypeResult Ty; 2678bdd1243dSDimitry Andric { 2679bdd1243dSDimitry Andric OffsetOfStateRAIIObject InOffsetof(*this, OOK); 2680bdd1243dSDimitry Andric Ty = ParseTypeName(); 26810b57cec5SDimitry Andric if (Ty.isInvalid()) { 26820b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26830b57cec5SDimitry Andric return ExprError(); 26840b57cec5SDimitry Andric } 2685bdd1243dSDimitry Andric } 26860b57cec5SDimitry Andric 26870b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26880b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26890b57cec5SDimitry Andric return ExprError(); 26900b57cec5SDimitry Andric } 26910b57cec5SDimitry Andric 26920b57cec5SDimitry Andric // We must have at least one identifier here. 26930b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 26940b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 26950b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26960b57cec5SDimitry Andric return ExprError(); 26970b57cec5SDimitry Andric } 26980b57cec5SDimitry Andric 26990b57cec5SDimitry Andric // Keep track of the various subcomponents we see. 27000b57cec5SDimitry Andric SmallVector<Sema::OffsetOfComponent, 4> Comps; 27010b57cec5SDimitry Andric 27020b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 27030b57cec5SDimitry Andric Comps.back().isBrackets = false; 27040b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 27050b57cec5SDimitry Andric Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 27060b57cec5SDimitry Andric 27070b57cec5SDimitry Andric // FIXME: This loop leaks the index expressions on error. 270804eeddc0SDimitry Andric while (true) { 27090b57cec5SDimitry Andric if (Tok.is(tok::period)) { 27100b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-designator '.' identifier 27110b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 27120b57cec5SDimitry Andric Comps.back().isBrackets = false; 27130b57cec5SDimitry Andric Comps.back().LocStart = ConsumeToken(); 27140b57cec5SDimitry Andric 27150b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 27160b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 27170b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27180b57cec5SDimitry Andric return ExprError(); 27190b57cec5SDimitry Andric } 27200b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 27210b57cec5SDimitry Andric Comps.back().LocEnd = ConsumeToken(); 27220b57cec5SDimitry Andric } else if (Tok.is(tok::l_square)) { 27230b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 27240b57cec5SDimitry Andric return ExprError(); 27250b57cec5SDimitry Andric 27260b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-design '[' expression ']' 27270b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 27280b57cec5SDimitry Andric Comps.back().isBrackets = true; 27290b57cec5SDimitry Andric BalancedDelimiterTracker ST(*this, tok::l_square); 27300b57cec5SDimitry Andric ST.consumeOpen(); 27310b57cec5SDimitry Andric Comps.back().LocStart = ST.getOpenLocation(); 27320b57cec5SDimitry Andric Res = ParseExpression(); 27330b57cec5SDimitry Andric if (Res.isInvalid()) { 27340b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27350b57cec5SDimitry Andric return Res; 27360b57cec5SDimitry Andric } 27370b57cec5SDimitry Andric Comps.back().U.E = Res.get(); 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andric ST.consumeClose(); 27400b57cec5SDimitry Andric Comps.back().LocEnd = ST.getCloseLocation(); 27410b57cec5SDimitry Andric } else { 27420b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27430b57cec5SDimitry Andric PT.consumeClose(); 27440b57cec5SDimitry Andric Res = ExprError(); 27450b57cec5SDimitry Andric } else if (Ty.isInvalid()) { 27460b57cec5SDimitry Andric Res = ExprError(); 27470b57cec5SDimitry Andric } else { 27480b57cec5SDimitry Andric PT.consumeClose(); 27490b57cec5SDimitry Andric Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc, 27500b57cec5SDimitry Andric Ty.get(), Comps, 27510b57cec5SDimitry Andric PT.getCloseLocation()); 27520b57cec5SDimitry Andric } 27530b57cec5SDimitry Andric break; 27540b57cec5SDimitry Andric } 27550b57cec5SDimitry Andric } 27560b57cec5SDimitry Andric break; 27570b57cec5SDimitry Andric } 27580b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: { 27590b57cec5SDimitry Andric ExprResult Cond(ParseAssignmentExpression()); 27600b57cec5SDimitry Andric if (Cond.isInvalid()) { 27610b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27620b57cec5SDimitry Andric return Cond; 27630b57cec5SDimitry Andric } 27640b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27650b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27660b57cec5SDimitry Andric return ExprError(); 27670b57cec5SDimitry Andric } 27680b57cec5SDimitry Andric 27690b57cec5SDimitry Andric ExprResult Expr1(ParseAssignmentExpression()); 27700b57cec5SDimitry Andric if (Expr1.isInvalid()) { 27710b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27720b57cec5SDimitry Andric return Expr1; 27730b57cec5SDimitry Andric } 27740b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27750b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27760b57cec5SDimitry Andric return ExprError(); 27770b57cec5SDimitry Andric } 27780b57cec5SDimitry Andric 27790b57cec5SDimitry Andric ExprResult Expr2(ParseAssignmentExpression()); 27800b57cec5SDimitry Andric if (Expr2.isInvalid()) { 27810b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27820b57cec5SDimitry Andric return Expr2; 27830b57cec5SDimitry Andric } 27840b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27850b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27860b57cec5SDimitry Andric return ExprError(); 27870b57cec5SDimitry Andric } 27880b57cec5SDimitry Andric Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(), 27890b57cec5SDimitry Andric Expr2.get(), ConsumeParen()); 27900b57cec5SDimitry Andric break; 27910b57cec5SDimitry Andric } 27920b57cec5SDimitry Andric case tok::kw___builtin_astype: { 27930b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 27940b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 27950b57cec5SDimitry Andric if (Expr.isInvalid()) { 27960b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27970b57cec5SDimitry Andric return ExprError(); 27980b57cec5SDimitry Andric } 27990b57cec5SDimitry Andric 28000b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 28010b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28020b57cec5SDimitry Andric return ExprError(); 28030b57cec5SDimitry Andric } 28040b57cec5SDimitry Andric 28050b57cec5SDimitry Andric // Second argument is the type to bitcast to. 28060b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 28070b57cec5SDimitry Andric if (DestTy.isInvalid()) 28080b57cec5SDimitry Andric return ExprError(); 28090b57cec5SDimitry Andric 28100b57cec5SDimitry Andric // Attempt to consume the r-paren. 28110b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 28120b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 28130b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28140b57cec5SDimitry Andric return ExprError(); 28150b57cec5SDimitry Andric } 28160b57cec5SDimitry Andric 28170b57cec5SDimitry Andric Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 28180b57cec5SDimitry Andric ConsumeParen()); 28190b57cec5SDimitry Andric break; 28200b57cec5SDimitry Andric } 28210b57cec5SDimitry Andric case tok::kw___builtin_convertvector: { 28220b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 28230b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 28240b57cec5SDimitry Andric if (Expr.isInvalid()) { 28250b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28260b57cec5SDimitry Andric return ExprError(); 28270b57cec5SDimitry Andric } 28280b57cec5SDimitry Andric 28290b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 28300b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28310b57cec5SDimitry Andric return ExprError(); 28320b57cec5SDimitry Andric } 28330b57cec5SDimitry Andric 28340b57cec5SDimitry Andric // Second argument is the type to bitcast to. 28350b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 28360b57cec5SDimitry Andric if (DestTy.isInvalid()) 28370b57cec5SDimitry Andric return ExprError(); 28380b57cec5SDimitry Andric 28390b57cec5SDimitry Andric // Attempt to consume the r-paren. 28400b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 28410b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 28420b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28430b57cec5SDimitry Andric return ExprError(); 28440b57cec5SDimitry Andric } 28450b57cec5SDimitry Andric 28460b57cec5SDimitry Andric Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 28470b57cec5SDimitry Andric ConsumeParen()); 28480b57cec5SDimitry Andric break; 28490b57cec5SDimitry Andric } 28500b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 28510b57cec5SDimitry Andric case tok::kw___builtin_FILE: 285206c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 28530b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 285406c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 285581ad6265SDimitry Andric case tok::kw___builtin_LINE: 285681ad6265SDimitry Andric case tok::kw___builtin_source_location: { 28570b57cec5SDimitry Andric // Attempt to consume the r-paren. 28580b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 28590b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 28600b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28610b57cec5SDimitry Andric return ExprError(); 28620b57cec5SDimitry Andric } 28635f757f3fSDimitry Andric SourceLocIdentKind Kind = [&] { 28640b57cec5SDimitry Andric switch (T) { 28650b57cec5SDimitry Andric case tok::kw___builtin_FILE: 28665f757f3fSDimitry Andric return SourceLocIdentKind::File; 286706c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 28685f757f3fSDimitry Andric return SourceLocIdentKind::FileName; 28690b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 28705f757f3fSDimitry Andric return SourceLocIdentKind::Function; 287106c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 28725f757f3fSDimitry Andric return SourceLocIdentKind::FuncSig; 28730b57cec5SDimitry Andric case tok::kw___builtin_LINE: 28745f757f3fSDimitry Andric return SourceLocIdentKind::Line; 28750b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 28765f757f3fSDimitry Andric return SourceLocIdentKind::Column; 287781ad6265SDimitry Andric case tok::kw___builtin_source_location: 28785f757f3fSDimitry Andric return SourceLocIdentKind::SourceLocStruct; 28790b57cec5SDimitry Andric default: 28800b57cec5SDimitry Andric llvm_unreachable("invalid keyword"); 28810b57cec5SDimitry Andric } 28820b57cec5SDimitry Andric }(); 28830b57cec5SDimitry Andric Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen()); 28840b57cec5SDimitry Andric break; 28850b57cec5SDimitry Andric } 28860b57cec5SDimitry Andric } 28870b57cec5SDimitry Andric 28880b57cec5SDimitry Andric if (Res.isInvalid()) 28890b57cec5SDimitry Andric return ExprError(); 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric // These can be followed by postfix-expr pieces because they are 28920b57cec5SDimitry Andric // primary-expressions. 28930b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Res.get()); 28940b57cec5SDimitry Andric } 28950b57cec5SDimitry Andric 28965ffd83dbSDimitry Andric bool Parser::tryParseOpenMPArrayShapingCastPart() { 28975ffd83dbSDimitry Andric assert(Tok.is(tok::l_square) && "Expected open bracket"); 28985ffd83dbSDimitry Andric bool ErrorFound = true; 28995ffd83dbSDimitry Andric TentativeParsingAction TPA(*this); 29005ffd83dbSDimitry Andric do { 29015ffd83dbSDimitry Andric if (Tok.isNot(tok::l_square)) 29025ffd83dbSDimitry Andric break; 29035ffd83dbSDimitry Andric // Consume '[' 29045ffd83dbSDimitry Andric ConsumeBracket(); 29055ffd83dbSDimitry Andric // Skip inner expression. 29065ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end, 29075ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 29085ffd83dbSDimitry Andric ; 29095ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) 29105ffd83dbSDimitry Andric break; 29115ffd83dbSDimitry Andric // Consume ']' 29125ffd83dbSDimitry Andric ConsumeBracket(); 29135ffd83dbSDimitry Andric // Found ')' - done. 29145ffd83dbSDimitry Andric if (Tok.is(tok::r_paren)) { 29155ffd83dbSDimitry Andric ErrorFound = false; 29165ffd83dbSDimitry Andric break; 29175ffd83dbSDimitry Andric } 29185ffd83dbSDimitry Andric } while (Tok.isNot(tok::annot_pragma_openmp_end)); 29195ffd83dbSDimitry Andric TPA.Revert(); 29205ffd83dbSDimitry Andric return !ErrorFound; 29215ffd83dbSDimitry Andric } 29225ffd83dbSDimitry Andric 29230b57cec5SDimitry Andric /// ParseParenExpression - This parses the unit that starts with a '(' token, 29240b57cec5SDimitry Andric /// based on what is allowed by ExprType. The actual thing parsed is returned 29250b57cec5SDimitry Andric /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 29260b57cec5SDimitry Andric /// not the parsed cast-expression. 29270b57cec5SDimitry Andric /// 29280b57cec5SDimitry Andric /// \verbatim 29290b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 29300b57cec5SDimitry Andric /// '(' expression ')' 29310b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 29320b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 29330b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 29340b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 29350b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 29360b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 29370b57cec5SDimitry Andric /// [ARC] bridged-cast-expression 29380b57cec5SDimitry Andric /// [ARC] bridged-cast-expression: 29390b57cec5SDimitry Andric /// (__bridge type-name) cast-expression 29400b57cec5SDimitry Andric /// (__bridge_transfer type-name) cast-expression 29410b57cec5SDimitry Andric /// (__bridge_retained type-name) cast-expression 29420b57cec5SDimitry Andric /// fold-expression: [C++1z] 29430b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' ')' 29440b57cec5SDimitry Andric /// '(' '...' fold-operator cast-expression ')' 29450b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' 29460b57cec5SDimitry Andric /// fold-operator cast-expression ')' 29475ffd83dbSDimitry Andric /// [OPENMP] Array shaping operation 29485ffd83dbSDimitry Andric /// '(' '[' expression ']' { '[' expression ']' } cast-expression 29490b57cec5SDimitry Andric /// \endverbatim 29500b57cec5SDimitry Andric ExprResult 29510b57cec5SDimitry Andric Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 29520b57cec5SDimitry Andric bool isTypeCast, ParsedType &CastTy, 29530b57cec5SDimitry Andric SourceLocation &RParenLoc) { 29540b57cec5SDimitry Andric assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 29550b57cec5SDimitry Andric ColonProtectionRAIIObject ColonProtection(*this, false); 29560b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 29570b57cec5SDimitry Andric if (T.consumeOpen()) 29580b57cec5SDimitry Andric return ExprError(); 29590b57cec5SDimitry Andric SourceLocation OpenLoc = T.getOpenLocation(); 29600b57cec5SDimitry Andric 29610b57cec5SDimitry Andric PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc); 29620b57cec5SDimitry Andric 29630b57cec5SDimitry Andric ExprResult Result(true); 29640b57cec5SDimitry Andric bool isAmbiguousTypeId; 29650b57cec5SDimitry Andric CastTy = nullptr; 29660b57cec5SDimitry Andric 29670b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 2968fe6060f1SDimitry Andric cutOffParsing(); 29690b57cec5SDimitry Andric Actions.CodeCompleteExpression( 29700b57cec5SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation()), 29710b57cec5SDimitry Andric /*IsParenthesized=*/ExprType >= CompoundLiteral); 29720b57cec5SDimitry Andric return ExprError(); 29730b57cec5SDimitry Andric } 29740b57cec5SDimitry Andric 29750b57cec5SDimitry Andric // Diagnose use of bridge casts in non-arc mode. 29760b57cec5SDimitry Andric bool BridgeCast = (getLangOpts().ObjC && 29770b57cec5SDimitry Andric Tok.isOneOf(tok::kw___bridge, 29780b57cec5SDimitry Andric tok::kw___bridge_transfer, 29790b57cec5SDimitry Andric tok::kw___bridge_retained, 29800b57cec5SDimitry Andric tok::kw___bridge_retain)); 29810b57cec5SDimitry Andric if (BridgeCast && !getLangOpts().ObjCAutoRefCount) { 29820b57cec5SDimitry Andric if (!TryConsumeToken(tok::kw___bridge)) { 29830b57cec5SDimitry Andric StringRef BridgeCastName = Tok.getName(); 29840b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 29850b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 29860b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc) 29870b57cec5SDimitry Andric << BridgeCastName 29880b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, ""); 29890b57cec5SDimitry Andric } 29900b57cec5SDimitry Andric BridgeCast = false; 29910b57cec5SDimitry Andric } 29920b57cec5SDimitry Andric 29930b57cec5SDimitry Andric // None of these cases should fall through with an invalid Result 29940b57cec5SDimitry Andric // unless they've already reported an error. 29950b57cec5SDimitry Andric if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 299681ad6265SDimitry Andric Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro 299781ad6265SDimitry Andric : diag::ext_gnu_statement_expr); 29980b57cec5SDimitry Andric 2999e8d8bef9SDimitry Andric checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin); 3000e8d8bef9SDimitry Andric 30010b57cec5SDimitry Andric if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) { 30020b57cec5SDimitry Andric Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope)); 30030b57cec5SDimitry Andric } else { 30040b57cec5SDimitry Andric // Find the nearest non-record decl context. Variables declared in a 30050b57cec5SDimitry Andric // statement expression behave as if they were declared in the enclosing 30060b57cec5SDimitry Andric // function, block, or other code construct. 30070b57cec5SDimitry Andric DeclContext *CodeDC = Actions.CurContext; 30080b57cec5SDimitry Andric while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) { 30090b57cec5SDimitry Andric CodeDC = CodeDC->getParent(); 30100b57cec5SDimitry Andric assert(CodeDC && !CodeDC->isFileContext() && 30110b57cec5SDimitry Andric "statement expr not in code context"); 30120b57cec5SDimitry Andric } 30130b57cec5SDimitry Andric Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false); 30140b57cec5SDimitry Andric 30150b57cec5SDimitry Andric Actions.ActOnStartStmtExpr(); 30160b57cec5SDimitry Andric 30170b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatement(true)); 30180b57cec5SDimitry Andric ExprType = CompoundStmt; 30190b57cec5SDimitry Andric 30200b57cec5SDimitry Andric // If the substmt parsed correctly, build the AST node. 30210b57cec5SDimitry Andric if (!Stmt.isInvalid()) { 30228c27c554SDimitry Andric Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(), 30238c27c554SDimitry Andric Tok.getLocation()); 30240b57cec5SDimitry Andric } else { 30250b57cec5SDimitry Andric Actions.ActOnStmtExprError(); 30260b57cec5SDimitry Andric } 30270b57cec5SDimitry Andric } 30280b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && BridgeCast) { 30290b57cec5SDimitry Andric tok::TokenKind tokenKind = Tok.getKind(); 30300b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 30310b57cec5SDimitry Andric 30320b57cec5SDimitry Andric // Parse an Objective-C ARC ownership cast expression. 30330b57cec5SDimitry Andric ObjCBridgeCastKind Kind; 30340b57cec5SDimitry Andric if (tokenKind == tok::kw___bridge) 30350b57cec5SDimitry Andric Kind = OBC_Bridge; 30360b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_transfer) 30370b57cec5SDimitry Andric Kind = OBC_BridgeTransfer; 30380b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_retained) 30390b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 30400b57cec5SDimitry Andric else { 30410b57cec5SDimitry Andric // As a hopefully temporary workaround, allow __bridge_retain as 30420b57cec5SDimitry Andric // a synonym for __bridge_retained, but only in system headers. 30430b57cec5SDimitry Andric assert(tokenKind == tok::kw___bridge_retain); 30440b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 30450b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 30460b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain) 30470b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, 30480b57cec5SDimitry Andric "__bridge_retained"); 30490b57cec5SDimitry Andric } 30500b57cec5SDimitry Andric 30510b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 30520b57cec5SDimitry Andric T.consumeClose(); 30530b57cec5SDimitry Andric ColonProtection.restore(); 30540b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 30550b57cec5SDimitry Andric 30560b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); 3057480093f4SDimitry Andric ExprResult SubExpr = ParseCastExpression(AnyCastExpr); 30580b57cec5SDimitry Andric 30590b57cec5SDimitry Andric if (Ty.isInvalid() || SubExpr.isInvalid()) 30600b57cec5SDimitry Andric return ExprError(); 30610b57cec5SDimitry Andric 30620b57cec5SDimitry Andric return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, 30630b57cec5SDimitry Andric BridgeKeywordLoc, Ty.get(), 30640b57cec5SDimitry Andric RParenLoc, SubExpr.get()); 30650b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && 30660b57cec5SDimitry Andric isTypeIdInParens(isAmbiguousTypeId)) { 30670b57cec5SDimitry Andric 30680b57cec5SDimitry Andric // Otherwise, this is a compound literal expression or cast expression. 30690b57cec5SDimitry Andric 30700b57cec5SDimitry Andric // In C++, if the type-id is ambiguous we disambiguate based on context. 30710b57cec5SDimitry Andric // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 30720b57cec5SDimitry Andric // in which case we should treat it as type-id. 30730b57cec5SDimitry Andric // if stopIfCastExpr is false, we need to determine the context past the 30740b57cec5SDimitry Andric // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 30750b57cec5SDimitry Andric if (isAmbiguousTypeId && !stopIfCastExpr) { 30760b57cec5SDimitry Andric ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T, 30770b57cec5SDimitry Andric ColonProtection); 30780b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 30790b57cec5SDimitry Andric return res; 30800b57cec5SDimitry Andric } 30810b57cec5SDimitry Andric 30820b57cec5SDimitry Andric // Parse the type declarator. 30830b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 30840b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 308581ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 308681ad6265SDimitry Andric DeclaratorContext::TypeName); 30870b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric // If our type is followed by an identifier and either ':' or ']', then 30900b57cec5SDimitry Andric // this is probably an Objective-C message send where the leading '[' is 30910b57cec5SDimitry Andric // missing. Recover as if that were the case. 30920b57cec5SDimitry Andric if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && 30930b57cec5SDimitry Andric !InMessageExpression && getLangOpts().ObjC && 30940b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 30950b57cec5SDimitry Andric TypeResult Ty; 30960b57cec5SDimitry Andric { 30970b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 3098*7a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 30990b57cec5SDimitry Andric } 31000b57cec5SDimitry Andric Result = ParseObjCMessageExpressionBody(SourceLocation(), 31010b57cec5SDimitry Andric SourceLocation(), 31020b57cec5SDimitry Andric Ty.get(), nullptr); 31030b57cec5SDimitry Andric } else { 31040b57cec5SDimitry Andric // Match the ')'. 31050b57cec5SDimitry Andric T.consumeClose(); 31060b57cec5SDimitry Andric ColonProtection.restore(); 31070b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 31080b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 31090b57cec5SDimitry Andric ExprType = CompoundLiteral; 31100b57cec5SDimitry Andric TypeResult Ty; 31110b57cec5SDimitry Andric { 31120b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 3113*7a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 31140b57cec5SDimitry Andric } 31150b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 31160b57cec5SDimitry Andric } 31170b57cec5SDimitry Andric 31180b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 31190b57cec5SDimitry Andric // This could be OpenCL vector Literals 31200b57cec5SDimitry Andric if (getLangOpts().OpenCL) 31210b57cec5SDimitry Andric { 31220b57cec5SDimitry Andric TypeResult Ty; 31230b57cec5SDimitry Andric { 31240b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 3125*7a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 31260b57cec5SDimitry Andric } 31270b57cec5SDimitry Andric if(Ty.isInvalid()) 31280b57cec5SDimitry Andric { 31290b57cec5SDimitry Andric return ExprError(); 31300b57cec5SDimitry Andric } 31310b57cec5SDimitry Andric QualType QT = Ty.get().get().getCanonicalType(); 31320b57cec5SDimitry Andric if (QT->isVectorType()) 31330b57cec5SDimitry Andric { 31340b57cec5SDimitry Andric // We parsed '(' vector-type-name ')' followed by '(' 31350b57cec5SDimitry Andric 31360b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 31370b57cec5SDimitry Andric // isVectorLiteral = true will make sure we don't parse any 31380b57cec5SDimitry Andric // Postfix expression yet 3139480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 31400b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 31410b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast, 31420b57cec5SDimitry Andric /*isVectorLiteral=*/true); 31430b57cec5SDimitry Andric 31440b57cec5SDimitry Andric if (!Result.isInvalid()) { 31450b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 31460b57cec5SDimitry Andric DeclaratorInfo, CastTy, 31470b57cec5SDimitry Andric RParenLoc, Result.get()); 31480b57cec5SDimitry Andric } 31490b57cec5SDimitry Andric 31500b57cec5SDimitry Andric // After we performed the cast we can check for postfix-expr pieces. 31510b57cec5SDimitry Andric if (!Result.isInvalid()) { 31520b57cec5SDimitry Andric Result = ParsePostfixExpressionSuffix(Result); 31530b57cec5SDimitry Andric } 31540b57cec5SDimitry Andric 31550b57cec5SDimitry Andric return Result; 31560b57cec5SDimitry Andric } 31570b57cec5SDimitry Andric } 31580b57cec5SDimitry Andric } 31590b57cec5SDimitry Andric 31600b57cec5SDimitry Andric if (ExprType == CastExpr) { 31610b57cec5SDimitry Andric // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 31620b57cec5SDimitry Andric 31630b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 31640b57cec5SDimitry Andric return ExprError(); 31650b57cec5SDimitry Andric 31660b57cec5SDimitry Andric // Note that this doesn't parse the subsequent cast-expression, it just 31670b57cec5SDimitry Andric // returns the parsed type to the callee. 31680b57cec5SDimitry Andric if (stopIfCastExpr) { 31690b57cec5SDimitry Andric TypeResult Ty; 31700b57cec5SDimitry Andric { 31710b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 3172*7a6dacacSDimitry Andric Ty = Actions.ActOnTypeName(DeclaratorInfo); 31730b57cec5SDimitry Andric } 31740b57cec5SDimitry Andric CastTy = Ty.get(); 31750b57cec5SDimitry Andric return ExprResult(); 31760b57cec5SDimitry Andric } 31770b57cec5SDimitry Andric 31780b57cec5SDimitry Andric // Reject the cast of super idiom in ObjC. 31790b57cec5SDimitry Andric if (Tok.is(tok::identifier) && getLangOpts().ObjC && 31800b57cec5SDimitry Andric Tok.getIdentifierInfo() == Ident_super && 31810b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 31820b57cec5SDimitry Andric GetLookAheadToken(1).isNot(tok::period)) { 31830b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_illegal_super_cast) 31840b57cec5SDimitry Andric << SourceRange(OpenLoc, RParenLoc); 31850b57cec5SDimitry Andric return ExprError(); 31860b57cec5SDimitry Andric } 31870b57cec5SDimitry Andric 31880b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get()); 31890b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 31900b57cec5SDimitry Andric // TODO: For cast expression with CastTy. 3191480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 31920b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 31930b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast); 31940b57cec5SDimitry Andric if (!Result.isInvalid()) { 31950b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 31960b57cec5SDimitry Andric DeclaratorInfo, CastTy, 31970b57cec5SDimitry Andric RParenLoc, Result.get()); 31980b57cec5SDimitry Andric } 31990b57cec5SDimitry Andric return Result; 32000b57cec5SDimitry Andric } 32010b57cec5SDimitry Andric 32020b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 32030b57cec5SDimitry Andric return ExprError(); 32040b57cec5SDimitry Andric } 32050b57cec5SDimitry Andric } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && 32060b57cec5SDimitry Andric isFoldOperator(NextToken().getKind())) { 32070b57cec5SDimitry Andric ExprType = FoldExpr; 32080b57cec5SDimitry Andric return ParseFoldExpression(ExprResult(), T); 32090b57cec5SDimitry Andric } else if (isTypeCast) { 32100b57cec5SDimitry Andric // Parse the expression-list. 32110b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 32120b57cec5SDimitry Andric ExprVector ArgExprs; 32130b57cec5SDimitry Andric 3214bdd1243dSDimitry Andric if (!ParseSimpleExpressionList(ArgExprs)) { 32150b57cec5SDimitry Andric // FIXME: If we ever support comma expressions as operands to 32160b57cec5SDimitry Andric // fold-expressions, we'll need to allow multiple ArgExprs here. 32170b57cec5SDimitry Andric if (ExprType >= FoldExpr && ArgExprs.size() == 1 && 32180b57cec5SDimitry Andric isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { 32190b57cec5SDimitry Andric ExprType = FoldExpr; 32200b57cec5SDimitry Andric return ParseFoldExpression(ArgExprs[0], T); 32210b57cec5SDimitry Andric } 32220b57cec5SDimitry Andric 32230b57cec5SDimitry Andric ExprType = SimpleExpr; 32240b57cec5SDimitry Andric Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), 32250b57cec5SDimitry Andric ArgExprs); 32260b57cec5SDimitry Andric } 32275ffd83dbSDimitry Andric } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing && 32285ffd83dbSDimitry Andric ExprType == CastExpr && Tok.is(tok::l_square) && 32295ffd83dbSDimitry Andric tryParseOpenMPArrayShapingCastPart()) { 32305ffd83dbSDimitry Andric bool ErrorFound = false; 32315ffd83dbSDimitry Andric SmallVector<Expr *, 4> OMPDimensions; 32325ffd83dbSDimitry Andric SmallVector<SourceRange, 4> OMPBracketsRanges; 32335ffd83dbSDimitry Andric do { 32345ffd83dbSDimitry Andric BalancedDelimiterTracker TS(*this, tok::l_square); 32355ffd83dbSDimitry Andric TS.consumeOpen(); 32365ffd83dbSDimitry Andric ExprResult NumElements = 32375ffd83dbSDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 32385ffd83dbSDimitry Andric if (!NumElements.isUsable()) { 32395ffd83dbSDimitry Andric ErrorFound = true; 32405ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::r_paren, 32415ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 32425ffd83dbSDimitry Andric ; 32435ffd83dbSDimitry Andric } 32445ffd83dbSDimitry Andric TS.consumeClose(); 32455ffd83dbSDimitry Andric OMPDimensions.push_back(NumElements.get()); 32465ffd83dbSDimitry Andric OMPBracketsRanges.push_back(TS.getRange()); 32475ffd83dbSDimitry Andric } while (Tok.isNot(tok::r_paren)); 32485ffd83dbSDimitry Andric // Match the ')'. 32495ffd83dbSDimitry Andric T.consumeClose(); 32505ffd83dbSDimitry Andric RParenLoc = T.getCloseLocation(); 32515ffd83dbSDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 32525ffd83dbSDimitry Andric if (ErrorFound) { 32535ffd83dbSDimitry Andric Result = ExprError(); 32545ffd83dbSDimitry Andric } else if (!Result.isInvalid()) { 32555ffd83dbSDimitry Andric Result = Actions.ActOnOMPArrayShapingExpr( 32565ffd83dbSDimitry Andric Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges); 32575ffd83dbSDimitry Andric } 32585ffd83dbSDimitry Andric return Result; 32590b57cec5SDimitry Andric } else { 32600b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 32610b57cec5SDimitry Andric 32620b57cec5SDimitry Andric Result = ParseExpression(MaybeTypeCast); 3263bdd1243dSDimitry Andric if (!getLangOpts().CPlusPlus && Result.isUsable()) { 32640b57cec5SDimitry Andric // Correct typos in non-C++ code earlier so that implicit-cast-like 32650b57cec5SDimitry Andric // expressions are parsed correctly. 32660b57cec5SDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(Result); 32670b57cec5SDimitry Andric } 32680b57cec5SDimitry Andric 32690b57cec5SDimitry Andric if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && 32700b57cec5SDimitry Andric NextToken().is(tok::ellipsis)) { 32710b57cec5SDimitry Andric ExprType = FoldExpr; 32720b57cec5SDimitry Andric return ParseFoldExpression(Result, T); 32730b57cec5SDimitry Andric } 32740b57cec5SDimitry Andric ExprType = SimpleExpr; 32750b57cec5SDimitry Andric 32760b57cec5SDimitry Andric // Don't build a paren expression unless we actually match a ')'. 32770b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 32780b57cec5SDimitry Andric Result = 32790b57cec5SDimitry Andric Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get()); 32800b57cec5SDimitry Andric } 32810b57cec5SDimitry Andric 32820b57cec5SDimitry Andric // Match the ')'. 32830b57cec5SDimitry Andric if (Result.isInvalid()) { 32840b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32850b57cec5SDimitry Andric return ExprError(); 32860b57cec5SDimitry Andric } 32870b57cec5SDimitry Andric 32880b57cec5SDimitry Andric T.consumeClose(); 32890b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 32900b57cec5SDimitry Andric return Result; 32910b57cec5SDimitry Andric } 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andric /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 32940b57cec5SDimitry Andric /// and we are at the left brace. 32950b57cec5SDimitry Andric /// 32960b57cec5SDimitry Andric /// \verbatim 32970b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 32980b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 32990b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 33000b57cec5SDimitry Andric /// \endverbatim 33010b57cec5SDimitry Andric ExprResult 33020b57cec5SDimitry Andric Parser::ParseCompoundLiteralExpression(ParsedType Ty, 33030b57cec5SDimitry Andric SourceLocation LParenLoc, 33040b57cec5SDimitry Andric SourceLocation RParenLoc) { 33050b57cec5SDimitry Andric assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 33060b57cec5SDimitry Andric if (!getLangOpts().C99) // Compound literals don't exist in C90. 33070b57cec5SDimitry Andric Diag(LParenLoc, diag::ext_c99_compound_literal); 3308e8d8bef9SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get()); 33090b57cec5SDimitry Andric ExprResult Result = ParseInitializer(); 33100b57cec5SDimitry Andric if (!Result.isInvalid() && Ty) 33110b57cec5SDimitry Andric return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get()); 33120b57cec5SDimitry Andric return Result; 33130b57cec5SDimitry Andric } 33140b57cec5SDimitry Andric 33150b57cec5SDimitry Andric /// ParseStringLiteralExpression - This handles the various token types that 33160b57cec5SDimitry Andric /// form string literals, and also handles string concatenation [C99 5.1.1.2, 33170b57cec5SDimitry Andric /// translation phase #6]. 33180b57cec5SDimitry Andric /// 33190b57cec5SDimitry Andric /// \verbatim 33200b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 33210b57cec5SDimitry Andric /// string-literal 33220b57cec5SDimitry Andric /// \verbatim 33230b57cec5SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) { 332406c3fb27SDimitry Andric return ParseStringLiteralExpression(AllowUserDefinedLiteral, 332506c3fb27SDimitry Andric /*Unevaluated=*/false); 332606c3fb27SDimitry Andric } 332706c3fb27SDimitry Andric 332806c3fb27SDimitry Andric ExprResult Parser::ParseUnevaluatedStringLiteralExpression() { 332906c3fb27SDimitry Andric return ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false, 333006c3fb27SDimitry Andric /*Unevaluated=*/true); 333106c3fb27SDimitry Andric } 333206c3fb27SDimitry Andric 333306c3fb27SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral, 333406c3fb27SDimitry Andric bool Unevaluated) { 33355f757f3fSDimitry Andric assert(tokenIsLikeStringLiteral(Tok, getLangOpts()) && 33365f757f3fSDimitry Andric "Not a string-literal-like token!"); 33370b57cec5SDimitry Andric 33385f757f3fSDimitry Andric // String concatenation. 33395f757f3fSDimitry Andric // Note: some keywords like __FUNCTION__ are not considered to be strings 33405f757f3fSDimitry Andric // for concatenation purposes, unless Microsoft extensions are enabled. 33410b57cec5SDimitry Andric SmallVector<Token, 4> StringToks; 33420b57cec5SDimitry Andric 33430b57cec5SDimitry Andric do { 33440b57cec5SDimitry Andric StringToks.push_back(Tok); 33455f757f3fSDimitry Andric ConsumeAnyToken(); 33465f757f3fSDimitry Andric } while (tokenIsLikeStringLiteral(Tok, getLangOpts())); 33470b57cec5SDimitry Andric 334806c3fb27SDimitry Andric if (Unevaluated) { 334906c3fb27SDimitry Andric assert(!AllowUserDefinedLiteral && "UDL are always evaluated"); 335006c3fb27SDimitry Andric return Actions.ActOnUnevaluatedStringLiteral(StringToks); 335106c3fb27SDimitry Andric } 335206c3fb27SDimitry Andric 33530b57cec5SDimitry Andric // Pass the set of string tokens, ready for concatenation, to the actions. 33540b57cec5SDimitry Andric return Actions.ActOnStringLiteral(StringToks, 33550b57cec5SDimitry Andric AllowUserDefinedLiteral ? getCurScope() 33560b57cec5SDimitry Andric : nullptr); 33570b57cec5SDimitry Andric } 33580b57cec5SDimitry Andric 33590b57cec5SDimitry Andric /// ParseGenericSelectionExpression - Parse a C11 generic-selection 33600b57cec5SDimitry Andric /// [C11 6.5.1.1]. 33610b57cec5SDimitry Andric /// 33620b57cec5SDimitry Andric /// \verbatim 33630b57cec5SDimitry Andric /// generic-selection: 33640b57cec5SDimitry Andric /// _Generic ( assignment-expression , generic-assoc-list ) 33650b57cec5SDimitry Andric /// generic-assoc-list: 33660b57cec5SDimitry Andric /// generic-association 33670b57cec5SDimitry Andric /// generic-assoc-list , generic-association 33680b57cec5SDimitry Andric /// generic-association: 33690b57cec5SDimitry Andric /// type-name : assignment-expression 33700b57cec5SDimitry Andric /// default : assignment-expression 33710b57cec5SDimitry Andric /// \endverbatim 337206c3fb27SDimitry Andric /// 337306c3fb27SDimitry Andric /// As an extension, Clang also accepts: 337406c3fb27SDimitry Andric /// \verbatim 337506c3fb27SDimitry Andric /// generic-selection: 337606c3fb27SDimitry Andric /// _Generic ( type-name, generic-assoc-list ) 337706c3fb27SDimitry Andric /// \endverbatim 33780b57cec5SDimitry Andric ExprResult Parser::ParseGenericSelectionExpression() { 33790b57cec5SDimitry Andric assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected"); 33800b57cec5SDimitry Andric if (!getLangOpts().C11) 3381a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 33820b57cec5SDimitry Andric 3383a7dea167SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 33840b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 33850b57cec5SDimitry Andric if (T.expectAndConsume()) 33860b57cec5SDimitry Andric return ExprError(); 33870b57cec5SDimitry Andric 338806c3fb27SDimitry Andric // We either have a controlling expression or we have a controlling type, and 338906c3fb27SDimitry Andric // we need to figure out which it is. 339006c3fb27SDimitry Andric TypeResult ControllingType; 33910b57cec5SDimitry Andric ExprResult ControllingExpr; 339206c3fb27SDimitry Andric if (isTypeIdForGenericSelection()) { 339306c3fb27SDimitry Andric ControllingType = ParseTypeName(); 339406c3fb27SDimitry Andric if (ControllingType.isInvalid()) { 339506c3fb27SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 339606c3fb27SDimitry Andric return ExprError(); 339706c3fb27SDimitry Andric } 339806c3fb27SDimitry Andric const auto *LIT = cast<LocInfoType>(ControllingType.get().get()); 339906c3fb27SDimitry Andric SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 340006c3fb27SDimitry Andric Diag(Loc, diag::ext_generic_with_type_arg); 340106c3fb27SDimitry Andric } else { 34020b57cec5SDimitry Andric // C11 6.5.1.1p3 "The controlling expression of a generic selection is 34030b57cec5SDimitry Andric // not evaluated." 34040b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 34050b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 34060b57cec5SDimitry Andric ControllingExpr = 34070b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 34080b57cec5SDimitry Andric if (ControllingExpr.isInvalid()) { 34090b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34100b57cec5SDimitry Andric return ExprError(); 34110b57cec5SDimitry Andric } 34120b57cec5SDimitry Andric } 34130b57cec5SDimitry Andric 34140b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 34150b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34160b57cec5SDimitry Andric return ExprError(); 34170b57cec5SDimitry Andric } 34180b57cec5SDimitry Andric 34190b57cec5SDimitry Andric SourceLocation DefaultLoc; 3420bdd1243dSDimitry Andric SmallVector<ParsedType, 12> Types; 34210b57cec5SDimitry Andric ExprVector Exprs; 34220b57cec5SDimitry Andric do { 34230b57cec5SDimitry Andric ParsedType Ty; 34240b57cec5SDimitry Andric if (Tok.is(tok::kw_default)) { 34250b57cec5SDimitry Andric // C11 6.5.1.1p2 "A generic selection shall have no more than one default 34260b57cec5SDimitry Andric // generic association." 34270b57cec5SDimitry Andric if (!DefaultLoc.isInvalid()) { 34280b57cec5SDimitry Andric Diag(Tok, diag::err_duplicate_default_assoc); 34290b57cec5SDimitry Andric Diag(DefaultLoc, diag::note_previous_default_assoc); 34300b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34310b57cec5SDimitry Andric return ExprError(); 34320b57cec5SDimitry Andric } 34330b57cec5SDimitry Andric DefaultLoc = ConsumeToken(); 34340b57cec5SDimitry Andric Ty = nullptr; 34350b57cec5SDimitry Andric } else { 34360b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 343781ad6265SDimitry Andric TypeResult TR = ParseTypeName(nullptr, DeclaratorContext::Association); 34380b57cec5SDimitry Andric if (TR.isInvalid()) { 34390b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34400b57cec5SDimitry Andric return ExprError(); 34410b57cec5SDimitry Andric } 34420b57cec5SDimitry Andric Ty = TR.get(); 34430b57cec5SDimitry Andric } 34440b57cec5SDimitry Andric Types.push_back(Ty); 34450b57cec5SDimitry Andric 34460b57cec5SDimitry Andric if (ExpectAndConsume(tok::colon)) { 34470b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34480b57cec5SDimitry Andric return ExprError(); 34490b57cec5SDimitry Andric } 34500b57cec5SDimitry Andric 34510b57cec5SDimitry Andric // FIXME: These expressions should be parsed in a potentially potentially 34520b57cec5SDimitry Andric // evaluated context. 34530b57cec5SDimitry Andric ExprResult ER( 34540b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); 34550b57cec5SDimitry Andric if (ER.isInvalid()) { 34560b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34570b57cec5SDimitry Andric return ExprError(); 34580b57cec5SDimitry Andric } 34590b57cec5SDimitry Andric Exprs.push_back(ER.get()); 34600b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 34610b57cec5SDimitry Andric 34620b57cec5SDimitry Andric T.consumeClose(); 34630b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 34640b57cec5SDimitry Andric return ExprError(); 34650b57cec5SDimitry Andric 346606c3fb27SDimitry Andric void *ExprOrTy = ControllingExpr.isUsable() 346706c3fb27SDimitry Andric ? ControllingExpr.get() 346806c3fb27SDimitry Andric : ControllingType.get().getAsOpaquePtr(); 346906c3fb27SDimitry Andric 347006c3fb27SDimitry Andric return Actions.ActOnGenericSelectionExpr( 347106c3fb27SDimitry Andric KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(), 347206c3fb27SDimitry Andric ExprOrTy, Types, Exprs); 34730b57cec5SDimitry Andric } 34740b57cec5SDimitry Andric 34750b57cec5SDimitry Andric /// Parse A C++1z fold-expression after the opening paren and optional 34760b57cec5SDimitry Andric /// left-hand-side expression. 34770b57cec5SDimitry Andric /// 34780b57cec5SDimitry Andric /// \verbatim 34790b57cec5SDimitry Andric /// fold-expression: 34800b57cec5SDimitry Andric /// ( cast-expression fold-operator ... ) 34810b57cec5SDimitry Andric /// ( ... fold-operator cast-expression ) 34820b57cec5SDimitry Andric /// ( cast-expression fold-operator ... fold-operator cast-expression ) 34830b57cec5SDimitry Andric ExprResult Parser::ParseFoldExpression(ExprResult LHS, 34840b57cec5SDimitry Andric BalancedDelimiterTracker &T) { 34850b57cec5SDimitry Andric if (LHS.isInvalid()) { 34860b57cec5SDimitry Andric T.skipToEnd(); 34870b57cec5SDimitry Andric return true; 34880b57cec5SDimitry Andric } 34890b57cec5SDimitry Andric 34900b57cec5SDimitry Andric tok::TokenKind Kind = tok::unknown; 34910b57cec5SDimitry Andric SourceLocation FirstOpLoc; 34920b57cec5SDimitry Andric if (LHS.isUsable()) { 34930b57cec5SDimitry Andric Kind = Tok.getKind(); 34940b57cec5SDimitry Andric assert(isFoldOperator(Kind) && "missing fold-operator"); 34950b57cec5SDimitry Andric FirstOpLoc = ConsumeToken(); 34960b57cec5SDimitry Andric } 34970b57cec5SDimitry Andric 34980b57cec5SDimitry Andric assert(Tok.is(tok::ellipsis) && "not a fold-expression"); 34990b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 35000b57cec5SDimitry Andric 35010b57cec5SDimitry Andric ExprResult RHS; 35020b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 35030b57cec5SDimitry Andric if (!isFoldOperator(Tok.getKind())) 35040b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_fold_operator); 35050b57cec5SDimitry Andric 35060b57cec5SDimitry Andric if (Kind != tok::unknown && Tok.getKind() != Kind) 35070b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_fold_operator_mismatch) 35080b57cec5SDimitry Andric << SourceRange(FirstOpLoc); 35090b57cec5SDimitry Andric Kind = Tok.getKind(); 35100b57cec5SDimitry Andric ConsumeToken(); 35110b57cec5SDimitry Andric 35120b57cec5SDimitry Andric RHS = ParseExpression(); 35130b57cec5SDimitry Andric if (RHS.isInvalid()) { 35140b57cec5SDimitry Andric T.skipToEnd(); 35150b57cec5SDimitry Andric return true; 35160b57cec5SDimitry Andric } 35170b57cec5SDimitry Andric } 35180b57cec5SDimitry Andric 35190b57cec5SDimitry Andric Diag(EllipsisLoc, getLangOpts().CPlusPlus17 35200b57cec5SDimitry Andric ? diag::warn_cxx14_compat_fold_expression 35210b57cec5SDimitry Andric : diag::ext_fold_expression); 35220b57cec5SDimitry Andric 35230b57cec5SDimitry Andric T.consumeClose(); 3524e8d8bef9SDimitry Andric return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(), 3525e8d8bef9SDimitry Andric Kind, EllipsisLoc, RHS.get(), 3526e8d8bef9SDimitry Andric T.getCloseLocation()); 35270b57cec5SDimitry Andric } 35280b57cec5SDimitry Andric 35290b57cec5SDimitry Andric /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 35300b57cec5SDimitry Andric /// 35310b57cec5SDimitry Andric /// \verbatim 35320b57cec5SDimitry Andric /// argument-expression-list: 35330b57cec5SDimitry Andric /// assignment-expression 35340b57cec5SDimitry Andric /// argument-expression-list , assignment-expression 35350b57cec5SDimitry Andric /// 35360b57cec5SDimitry Andric /// [C++] expression-list: 35370b57cec5SDimitry Andric /// [C++] assignment-expression 35380b57cec5SDimitry Andric /// [C++] expression-list , assignment-expression 35390b57cec5SDimitry Andric /// 35400b57cec5SDimitry Andric /// [C++0x] expression-list: 35410b57cec5SDimitry Andric /// [C++0x] initializer-list 35420b57cec5SDimitry Andric /// 35430b57cec5SDimitry Andric /// [C++0x] initializer-list 35440b57cec5SDimitry Andric /// [C++0x] initializer-clause ...[opt] 35450b57cec5SDimitry Andric /// [C++0x] initializer-list , initializer-clause ...[opt] 35460b57cec5SDimitry Andric /// 35470b57cec5SDimitry Andric /// [C++0x] initializer-clause: 35480b57cec5SDimitry Andric /// [C++0x] assignment-expression 35490b57cec5SDimitry Andric /// [C++0x] braced-init-list 35500b57cec5SDimitry Andric /// \endverbatim 35510b57cec5SDimitry Andric bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, 355281ad6265SDimitry Andric llvm::function_ref<void()> ExpressionStarts, 355381ad6265SDimitry Andric bool FailImmediatelyOnInvalidExpr, 355481ad6265SDimitry Andric bool EarlyTypoCorrection) { 35550b57cec5SDimitry Andric bool SawError = false; 355604eeddc0SDimitry Andric while (true) { 35570b57cec5SDimitry Andric if (ExpressionStarts) 35580b57cec5SDimitry Andric ExpressionStarts(); 35590b57cec5SDimitry Andric 35600b57cec5SDimitry Andric ExprResult Expr; 35610b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 35620b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 35630b57cec5SDimitry Andric Expr = ParseBraceInitializer(); 35640b57cec5SDimitry Andric } else 35650b57cec5SDimitry Andric Expr = ParseAssignmentExpression(); 35660b57cec5SDimitry Andric 356781ad6265SDimitry Andric if (EarlyTypoCorrection) 356881ad6265SDimitry Andric Expr = Actions.CorrectDelayedTyposInExpr(Expr); 356981ad6265SDimitry Andric 35700b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) 35710b57cec5SDimitry Andric Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); 35725ffd83dbSDimitry Andric else if (Tok.is(tok::code_completion)) { 35735ffd83dbSDimitry Andric // There's nothing to suggest in here as we parsed a full expression. 35745f757f3fSDimitry Andric // Instead fail and propagate the error since caller might have something 35755ffd83dbSDimitry Andric // the suggest, e.g. signature help in function call. Note that this is 35765ffd83dbSDimitry Andric // performed before pushing the \p Expr, so that signature help can report 35775ffd83dbSDimitry Andric // current argument correctly. 35785ffd83dbSDimitry Andric SawError = true; 35795ffd83dbSDimitry Andric cutOffParsing(); 35805ffd83dbSDimitry Andric break; 35815ffd83dbSDimitry Andric } 35820b57cec5SDimitry Andric if (Expr.isInvalid()) { 35830b57cec5SDimitry Andric SawError = true; 358481ad6265SDimitry Andric if (FailImmediatelyOnInvalidExpr) 358581ad6265SDimitry Andric break; 358681ad6265SDimitry Andric SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); 35870b57cec5SDimitry Andric } else { 35880b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 35890b57cec5SDimitry Andric } 35900b57cec5SDimitry Andric 35910b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 35920b57cec5SDimitry Andric break; 35930b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 35940b57cec5SDimitry Andric Token Comma = Tok; 3595bdd1243dSDimitry Andric ConsumeToken(); 35960b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 35970b57cec5SDimitry Andric } 35980b57cec5SDimitry Andric if (SawError) { 35990b57cec5SDimitry Andric // Ensure typos get diagnosed when errors were encountered while parsing the 36000b57cec5SDimitry Andric // expression list. 36010b57cec5SDimitry Andric for (auto &E : Exprs) { 36020b57cec5SDimitry Andric ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); 36030b57cec5SDimitry Andric if (Expr.isUsable()) E = Expr.get(); 36040b57cec5SDimitry Andric } 36050b57cec5SDimitry Andric } 36060b57cec5SDimitry Andric return SawError; 36070b57cec5SDimitry Andric } 36080b57cec5SDimitry Andric 36090b57cec5SDimitry Andric /// ParseSimpleExpressionList - A simple comma-separated list of expressions, 36100b57cec5SDimitry Andric /// used for misc language extensions. 36110b57cec5SDimitry Andric /// 36120b57cec5SDimitry Andric /// \verbatim 36130b57cec5SDimitry Andric /// simple-expression-list: 36140b57cec5SDimitry Andric /// assignment-expression 36150b57cec5SDimitry Andric /// simple-expression-list , assignment-expression 36160b57cec5SDimitry Andric /// \endverbatim 3617bdd1243dSDimitry Andric bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) { 361804eeddc0SDimitry Andric while (true) { 36190b57cec5SDimitry Andric ExprResult Expr = ParseAssignmentExpression(); 36200b57cec5SDimitry Andric if (Expr.isInvalid()) 36210b57cec5SDimitry Andric return true; 36220b57cec5SDimitry Andric 36230b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 36240b57cec5SDimitry Andric 3625bdd1243dSDimitry Andric // We might be parsing the LHS of a fold-expression. If we reached the fold 3626bdd1243dSDimitry Andric // operator, stop. 3627bdd1243dSDimitry Andric if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis)) 36280b57cec5SDimitry Andric return false; 36290b57cec5SDimitry Andric 36300b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 36310b57cec5SDimitry Andric Token Comma = Tok; 3632bdd1243dSDimitry Andric ConsumeToken(); 36330b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 36340b57cec5SDimitry Andric } 36350b57cec5SDimitry Andric } 36360b57cec5SDimitry Andric 36370b57cec5SDimitry Andric /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 36380b57cec5SDimitry Andric /// 36390b57cec5SDimitry Andric /// \verbatim 36400b57cec5SDimitry Andric /// [clang] block-id: 36410b57cec5SDimitry Andric /// [clang] specifier-qualifier-list block-declarator 36420b57cec5SDimitry Andric /// \endverbatim 36430b57cec5SDimitry Andric void Parser::ParseBlockId(SourceLocation CaretLoc) { 36440b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 3645fe6060f1SDimitry Andric cutOffParsing(); 36460b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); 3647fe6060f1SDimitry Andric return; 36480b57cec5SDimitry Andric } 36490b57cec5SDimitry Andric 36500b57cec5SDimitry Andric // Parse the specifier-qualifier-list piece. 36510b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 36520b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 36530b57cec5SDimitry Andric 36540b57cec5SDimitry Andric // Parse the block-declarator. 365581ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 365681ad6265SDimitry Andric DeclaratorContext::BlockLiteral); 3657e8d8bef9SDimitry Andric DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 36580b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 36590b57cec5SDimitry Andric 36600b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 36610b57cec5SDimitry Andric 36620b57cec5SDimitry Andric // Inform sema that we are starting a block. 36630b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope()); 36640b57cec5SDimitry Andric } 36650b57cec5SDimitry Andric 36660b57cec5SDimitry Andric /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 36670b57cec5SDimitry Andric /// like ^(int x){ return x+1; } 36680b57cec5SDimitry Andric /// 36690b57cec5SDimitry Andric /// \verbatim 36700b57cec5SDimitry Andric /// block-literal: 36710b57cec5SDimitry Andric /// [clang] '^' block-args[opt] compound-statement 36720b57cec5SDimitry Andric /// [clang] '^' block-id compound-statement 36730b57cec5SDimitry Andric /// [clang] block-args: 36740b57cec5SDimitry Andric /// [clang] '(' parameter-list ')' 36750b57cec5SDimitry Andric /// \endverbatim 36760b57cec5SDimitry Andric ExprResult Parser::ParseBlockLiteralExpression() { 36770b57cec5SDimitry Andric assert(Tok.is(tok::caret) && "block literal starts with ^"); 36780b57cec5SDimitry Andric SourceLocation CaretLoc = ConsumeToken(); 36790b57cec5SDimitry Andric 36800b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 36810b57cec5SDimitry Andric "block literal parsing"); 36820b57cec5SDimitry Andric 36830b57cec5SDimitry Andric // Enter a scope to hold everything within the block. This includes the 36840b57cec5SDimitry Andric // argument decls, decls within the compound expression, etc. This also 36850b57cec5SDimitry Andric // allows determining whether a variable reference inside the block is 36860b57cec5SDimitry Andric // within or outside of the block. 36870b57cec5SDimitry Andric ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 36880b57cec5SDimitry Andric Scope::CompoundStmtScope | Scope::DeclScope); 36890b57cec5SDimitry Andric 36900b57cec5SDimitry Andric // Inform sema that we are starting a block. 36910b57cec5SDimitry Andric Actions.ActOnBlockStart(CaretLoc, getCurScope()); 36920b57cec5SDimitry Andric 36930b57cec5SDimitry Andric // Parse the return type if present. 36940b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 369581ad6265SDimitry Andric Declarator ParamInfo(DS, ParsedAttributesView::none(), 369681ad6265SDimitry Andric DeclaratorContext::BlockLiteral); 3697e8d8bef9SDimitry Andric ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 36980b57cec5SDimitry Andric // FIXME: Since the return type isn't actually parsed, it can't be used to 36990b57cec5SDimitry Andric // fill ParamInfo with an initial valid range, so do it manually. 37000b57cec5SDimitry Andric ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 37010b57cec5SDimitry Andric 37020b57cec5SDimitry Andric // If this block has arguments, parse them. There is no ambiguity here with 37030b57cec5SDimitry Andric // the expression case, because the expression case requires a parameter list. 37040b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 37050b57cec5SDimitry Andric ParseParenDeclarator(ParamInfo); 37060b57cec5SDimitry Andric // Parse the pieces after the identifier as if we had "int(...)". 37070b57cec5SDimitry Andric // SetIdentifier sets the source range end, but in this case we're past 37080b57cec5SDimitry Andric // that location. 37090b57cec5SDimitry Andric SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 37100b57cec5SDimitry Andric ParamInfo.SetIdentifier(nullptr, CaretLoc); 37110b57cec5SDimitry Andric ParamInfo.SetRangeEnd(Tmp); 37120b57cec5SDimitry Andric if (ParamInfo.isInvalidType()) { 37130b57cec5SDimitry Andric // If there was an error parsing the arguments, they may have 37140b57cec5SDimitry Andric // tried to use ^(x+y) which requires an argument list. Just 37150b57cec5SDimitry Andric // skip the whole block literal. 37160b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 37170b57cec5SDimitry Andric return ExprError(); 37180b57cec5SDimitry Andric } 37190b57cec5SDimitry Andric 37200b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 37210b57cec5SDimitry Andric 37220b57cec5SDimitry Andric // Inform sema that we are starting a block. 37230b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 37240b57cec5SDimitry Andric } else if (!Tok.is(tok::l_brace)) { 37250b57cec5SDimitry Andric ParseBlockId(CaretLoc); 37260b57cec5SDimitry Andric } else { 37270b57cec5SDimitry Andric // Otherwise, pretend we saw (void). 37280b57cec5SDimitry Andric SourceLocation NoLoc; 37290b57cec5SDimitry Andric ParamInfo.AddTypeInfo( 37300b57cec5SDimitry Andric DeclaratorChunk::getFunction(/*HasProto=*/true, 37310b57cec5SDimitry Andric /*IsAmbiguous=*/false, 37320b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 37330b57cec5SDimitry Andric /*ArgInfo=*/nullptr, 37340b57cec5SDimitry Andric /*NumParams=*/0, 37350b57cec5SDimitry Andric /*EllipsisLoc=*/NoLoc, 37360b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 37370b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 37380b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, 37390b57cec5SDimitry Andric /*MutableLoc=*/NoLoc, EST_None, 37400b57cec5SDimitry Andric /*ESpecRange=*/SourceRange(), 37410b57cec5SDimitry Andric /*Exceptions=*/nullptr, 37420b57cec5SDimitry Andric /*ExceptionRanges=*/nullptr, 37430b57cec5SDimitry Andric /*NumExceptions=*/0, 37440b57cec5SDimitry Andric /*NoexceptExpr=*/nullptr, 37450b57cec5SDimitry Andric /*ExceptionSpecTokens=*/nullptr, 3746bdd1243dSDimitry Andric /*DeclsInPrototype=*/std::nullopt, 3747bdd1243dSDimitry Andric CaretLoc, CaretLoc, ParamInfo), 37480b57cec5SDimitry Andric CaretLoc); 37490b57cec5SDimitry Andric 37500b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 37510b57cec5SDimitry Andric 37520b57cec5SDimitry Andric // Inform sema that we are starting a block. 37530b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 37540b57cec5SDimitry Andric } 37550b57cec5SDimitry Andric 37560b57cec5SDimitry Andric 37570b57cec5SDimitry Andric ExprResult Result(true); 37580b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 37590b57cec5SDimitry Andric // Saw something like: ^expr 37600b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 37610b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 37620b57cec5SDimitry Andric return ExprError(); 37630b57cec5SDimitry Andric } 37640b57cec5SDimitry Andric 37650b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 37660b57cec5SDimitry Andric BlockScope.Exit(); 37670b57cec5SDimitry Andric if (!Stmt.isInvalid()) 37680b57cec5SDimitry Andric Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope()); 37690b57cec5SDimitry Andric else 37700b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 37710b57cec5SDimitry Andric return Result; 37720b57cec5SDimitry Andric } 37730b57cec5SDimitry Andric 37740b57cec5SDimitry Andric /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals. 37750b57cec5SDimitry Andric /// 37760b57cec5SDimitry Andric /// '__objc_yes' 37770b57cec5SDimitry Andric /// '__objc_no' 37780b57cec5SDimitry Andric ExprResult Parser::ParseObjCBoolLiteral() { 37790b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 37800b57cec5SDimitry Andric return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind); 37810b57cec5SDimitry Andric } 37820b57cec5SDimitry Andric 37830b57cec5SDimitry Andric /// Validate availability spec list, emitting diagnostics if necessary. Returns 37840b57cec5SDimitry Andric /// true if invalid. 37850b57cec5SDimitry Andric static bool CheckAvailabilitySpecList(Parser &P, 37860b57cec5SDimitry Andric ArrayRef<AvailabilitySpec> AvailSpecs) { 37870b57cec5SDimitry Andric llvm::SmallSet<StringRef, 4> Platforms; 37880b57cec5SDimitry Andric bool HasOtherPlatformSpec = false; 37890b57cec5SDimitry Andric bool Valid = true; 37900b57cec5SDimitry Andric for (const auto &Spec : AvailSpecs) { 37910b57cec5SDimitry Andric if (Spec.isOtherPlatformSpec()) { 37920b57cec5SDimitry Andric if (HasOtherPlatformSpec) { 37930b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star); 37940b57cec5SDimitry Andric Valid = false; 37950b57cec5SDimitry Andric } 37960b57cec5SDimitry Andric 37970b57cec5SDimitry Andric HasOtherPlatformSpec = true; 37980b57cec5SDimitry Andric continue; 37990b57cec5SDimitry Andric } 38000b57cec5SDimitry Andric 38010b57cec5SDimitry Andric bool Inserted = Platforms.insert(Spec.getPlatform()).second; 38020b57cec5SDimitry Andric if (!Inserted) { 38030b57cec5SDimitry Andric // Rule out multiple version specs referring to the same platform. 38040b57cec5SDimitry Andric // For example, we emit an error for: 38050b57cec5SDimitry Andric // @available(macos 10.10, macos 10.11, *) 38060b57cec5SDimitry Andric StringRef Platform = Spec.getPlatform(); 38070b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform) 38080b57cec5SDimitry Andric << Spec.getEndLoc() << Platform; 38090b57cec5SDimitry Andric Valid = false; 38100b57cec5SDimitry Andric } 38110b57cec5SDimitry Andric } 38120b57cec5SDimitry Andric 38130b57cec5SDimitry Andric if (!HasOtherPlatformSpec) { 38140b57cec5SDimitry Andric SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc(); 38150b57cec5SDimitry Andric P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required) 38160b57cec5SDimitry Andric << FixItHint::CreateInsertion(InsertWildcardLoc, ", *"); 38170b57cec5SDimitry Andric return true; 38180b57cec5SDimitry Andric } 38190b57cec5SDimitry Andric 38200b57cec5SDimitry Andric return !Valid; 38210b57cec5SDimitry Andric } 38220b57cec5SDimitry Andric 38230b57cec5SDimitry Andric /// Parse availability query specification. 38240b57cec5SDimitry Andric /// 38250b57cec5SDimitry Andric /// availability-spec: 38260b57cec5SDimitry Andric /// '*' 38270b57cec5SDimitry Andric /// identifier version-tuple 3828bdd1243dSDimitry Andric std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() { 38290b57cec5SDimitry Andric if (Tok.is(tok::star)) { 38300b57cec5SDimitry Andric return AvailabilitySpec(ConsumeToken()); 38310b57cec5SDimitry Andric } else { 38320b57cec5SDimitry Andric // Parse the platform name. 38330b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 38340b57cec5SDimitry Andric cutOffParsing(); 3835fe6060f1SDimitry Andric Actions.CodeCompleteAvailabilityPlatformName(); 3836bdd1243dSDimitry Andric return std::nullopt; 38370b57cec5SDimitry Andric } 38380b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 38390b57cec5SDimitry Andric Diag(Tok, diag::err_avail_query_expected_platform_name); 3840bdd1243dSDimitry Andric return std::nullopt; 38410b57cec5SDimitry Andric } 38420b57cec5SDimitry Andric 38430b57cec5SDimitry Andric IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc(); 38440b57cec5SDimitry Andric SourceRange VersionRange; 38450b57cec5SDimitry Andric VersionTuple Version = ParseVersionTuple(VersionRange); 38460b57cec5SDimitry Andric 38470b57cec5SDimitry Andric if (Version.empty()) 3848bdd1243dSDimitry Andric return std::nullopt; 38490b57cec5SDimitry Andric 38500b57cec5SDimitry Andric StringRef GivenPlatform = PlatformIdentifier->Ident->getName(); 38510b57cec5SDimitry Andric StringRef Platform = 38520b57cec5SDimitry Andric AvailabilityAttr::canonicalizePlatformName(GivenPlatform); 38530b57cec5SDimitry Andric 38540b57cec5SDimitry Andric if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) { 38550b57cec5SDimitry Andric Diag(PlatformIdentifier->Loc, 38560b57cec5SDimitry Andric diag::err_avail_query_unrecognized_platform_name) 38570b57cec5SDimitry Andric << GivenPlatform; 3858bdd1243dSDimitry Andric return std::nullopt; 38590b57cec5SDimitry Andric } 38600b57cec5SDimitry Andric 38610b57cec5SDimitry Andric return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc, 38620b57cec5SDimitry Andric VersionRange.getEnd()); 38630b57cec5SDimitry Andric } 38640b57cec5SDimitry Andric } 38650b57cec5SDimitry Andric 38660b57cec5SDimitry Andric ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { 38670b57cec5SDimitry Andric assert(Tok.is(tok::kw___builtin_available) || 38680b57cec5SDimitry Andric Tok.isObjCAtKeyword(tok::objc_available)); 38690b57cec5SDimitry Andric 38700b57cec5SDimitry Andric // Eat the available or __builtin_available. 38710b57cec5SDimitry Andric ConsumeToken(); 38720b57cec5SDimitry Andric 38730b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 38740b57cec5SDimitry Andric if (Parens.expectAndConsume()) 38750b57cec5SDimitry Andric return ExprError(); 38760b57cec5SDimitry Andric 38770b57cec5SDimitry Andric SmallVector<AvailabilitySpec, 4> AvailSpecs; 38780b57cec5SDimitry Andric bool HasError = false; 38790b57cec5SDimitry Andric while (true) { 3880bdd1243dSDimitry Andric std::optional<AvailabilitySpec> Spec = ParseAvailabilitySpec(); 38810b57cec5SDimitry Andric if (!Spec) 38820b57cec5SDimitry Andric HasError = true; 38830b57cec5SDimitry Andric else 38840b57cec5SDimitry Andric AvailSpecs.push_back(*Spec); 38850b57cec5SDimitry Andric 38860b57cec5SDimitry Andric if (!TryConsumeToken(tok::comma)) 38870b57cec5SDimitry Andric break; 38880b57cec5SDimitry Andric } 38890b57cec5SDimitry Andric 38900b57cec5SDimitry Andric if (HasError) { 38910b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 38920b57cec5SDimitry Andric return ExprError(); 38930b57cec5SDimitry Andric } 38940b57cec5SDimitry Andric 38950b57cec5SDimitry Andric CheckAvailabilitySpecList(*this, AvailSpecs); 38960b57cec5SDimitry Andric 38970b57cec5SDimitry Andric if (Parens.consumeClose()) 38980b57cec5SDimitry Andric return ExprError(); 38990b57cec5SDimitry Andric 39000b57cec5SDimitry Andric return Actions.ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, 39010b57cec5SDimitry Andric Parens.getCloseLocation()); 39020b57cec5SDimitry Andric } 3903