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/Parse/Parser.h" 240b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 25480093f4SDimitry Andric #include "clang/AST/ExprCXX.h" 260b57cec5SDimitry Andric #include "clang/Basic/PrettyStackTrace.h" 270b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 280b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 290b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 300b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 310b57cec5SDimitry Andric #include "clang/Sema/TypoCorrection.h" 320b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 330b57cec5SDimitry Andric using namespace clang; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric /// Simple precedence-based parser for binary/ternary operators. 360b57cec5SDimitry Andric /// 370b57cec5SDimitry Andric /// Note: we diverge from the C99 grammar when parsing the assignment-expression 380b57cec5SDimitry Andric /// production. C99 specifies that the LHS of an assignment operator should be 390b57cec5SDimitry Andric /// parsed as a unary-expression, but consistency dictates that it be a 400b57cec5SDimitry Andric /// conditional-expession. In practice, the important thing here is that the 410b57cec5SDimitry Andric /// LHS of an assignment has to be an l-value, which productions between 420b57cec5SDimitry Andric /// unary-expression and conditional-expression don't produce. Because we want 430b57cec5SDimitry Andric /// consistency, we parse the LHS as a conditional-expression, then check for 440b57cec5SDimitry Andric /// l-value-ness in semantic analysis stages. 450b57cec5SDimitry Andric /// 460b57cec5SDimitry Andric /// \verbatim 470b57cec5SDimitry Andric /// pm-expression: [C++ 5.5] 480b57cec5SDimitry Andric /// cast-expression 490b57cec5SDimitry Andric /// pm-expression '.*' cast-expression 500b57cec5SDimitry Andric /// pm-expression '->*' cast-expression 510b57cec5SDimitry Andric /// 520b57cec5SDimitry Andric /// multiplicative-expression: [C99 6.5.5] 530b57cec5SDimitry Andric /// Note: in C++, apply pm-expression instead of cast-expression 540b57cec5SDimitry Andric /// cast-expression 550b57cec5SDimitry Andric /// multiplicative-expression '*' cast-expression 560b57cec5SDimitry Andric /// multiplicative-expression '/' cast-expression 570b57cec5SDimitry Andric /// multiplicative-expression '%' cast-expression 580b57cec5SDimitry Andric /// 590b57cec5SDimitry Andric /// additive-expression: [C99 6.5.6] 600b57cec5SDimitry Andric /// multiplicative-expression 610b57cec5SDimitry Andric /// additive-expression '+' multiplicative-expression 620b57cec5SDimitry Andric /// additive-expression '-' multiplicative-expression 630b57cec5SDimitry Andric /// 640b57cec5SDimitry Andric /// shift-expression: [C99 6.5.7] 650b57cec5SDimitry Andric /// additive-expression 660b57cec5SDimitry Andric /// shift-expression '<<' additive-expression 670b57cec5SDimitry Andric /// shift-expression '>>' additive-expression 680b57cec5SDimitry Andric /// 690b57cec5SDimitry Andric /// compare-expression: [C++20 expr.spaceship] 700b57cec5SDimitry Andric /// shift-expression 710b57cec5SDimitry Andric /// compare-expression '<=>' shift-expression 720b57cec5SDimitry Andric /// 730b57cec5SDimitry Andric /// relational-expression: [C99 6.5.8] 740b57cec5SDimitry Andric /// compare-expression 750b57cec5SDimitry Andric /// relational-expression '<' compare-expression 760b57cec5SDimitry Andric /// relational-expression '>' compare-expression 770b57cec5SDimitry Andric /// relational-expression '<=' compare-expression 780b57cec5SDimitry Andric /// relational-expression '>=' compare-expression 790b57cec5SDimitry Andric /// 800b57cec5SDimitry Andric /// equality-expression: [C99 6.5.9] 810b57cec5SDimitry Andric /// relational-expression 820b57cec5SDimitry Andric /// equality-expression '==' relational-expression 830b57cec5SDimitry Andric /// equality-expression '!=' relational-expression 840b57cec5SDimitry Andric /// 850b57cec5SDimitry Andric /// AND-expression: [C99 6.5.10] 860b57cec5SDimitry Andric /// equality-expression 870b57cec5SDimitry Andric /// AND-expression '&' equality-expression 880b57cec5SDimitry Andric /// 890b57cec5SDimitry Andric /// exclusive-OR-expression: [C99 6.5.11] 900b57cec5SDimitry Andric /// AND-expression 910b57cec5SDimitry Andric /// exclusive-OR-expression '^' AND-expression 920b57cec5SDimitry Andric /// 930b57cec5SDimitry Andric /// inclusive-OR-expression: [C99 6.5.12] 940b57cec5SDimitry Andric /// exclusive-OR-expression 950b57cec5SDimitry Andric /// inclusive-OR-expression '|' exclusive-OR-expression 960b57cec5SDimitry Andric /// 970b57cec5SDimitry Andric /// logical-AND-expression: [C99 6.5.13] 980b57cec5SDimitry Andric /// inclusive-OR-expression 990b57cec5SDimitry Andric /// logical-AND-expression '&&' inclusive-OR-expression 1000b57cec5SDimitry Andric /// 1010b57cec5SDimitry Andric /// logical-OR-expression: [C99 6.5.14] 1020b57cec5SDimitry Andric /// logical-AND-expression 1030b57cec5SDimitry Andric /// logical-OR-expression '||' logical-AND-expression 1040b57cec5SDimitry Andric /// 1050b57cec5SDimitry Andric /// conditional-expression: [C99 6.5.15] 1060b57cec5SDimitry Andric /// logical-OR-expression 1070b57cec5SDimitry Andric /// logical-OR-expression '?' expression ':' conditional-expression 1080b57cec5SDimitry Andric /// [GNU] logical-OR-expression '?' ':' conditional-expression 1090b57cec5SDimitry Andric /// [C++] the third operand is an assignment-expression 1100b57cec5SDimitry Andric /// 1110b57cec5SDimitry Andric /// assignment-expression: [C99 6.5.16] 1120b57cec5SDimitry Andric /// conditional-expression 1130b57cec5SDimitry Andric /// unary-expression assignment-operator assignment-expression 1140b57cec5SDimitry Andric /// [C++] throw-expression [C++ 15] 1150b57cec5SDimitry Andric /// 1160b57cec5SDimitry Andric /// assignment-operator: one of 1170b57cec5SDimitry Andric /// = *= /= %= += -= <<= >>= &= ^= |= 1180b57cec5SDimitry Andric /// 1190b57cec5SDimitry Andric /// expression: [C99 6.5.17] 1200b57cec5SDimitry Andric /// assignment-expression ...[opt] 1210b57cec5SDimitry Andric /// expression ',' assignment-expression ...[opt] 1220b57cec5SDimitry Andric /// \endverbatim 1230b57cec5SDimitry Andric ExprResult Parser::ParseExpression(TypeCastState isTypeCast) { 1240b57cec5SDimitry Andric ExprResult LHS(ParseAssignmentExpression(isTypeCast)); 1250b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// This routine is called when the '@' is seen and consumed. 1290b57cec5SDimitry Andric /// Current token is an Identifier and is not a 'try'. This 1300b57cec5SDimitry Andric /// routine is necessary to disambiguate \@try-statement from, 1310b57cec5SDimitry Andric /// for example, \@encode-expression. 1320b57cec5SDimitry Andric /// 1330b57cec5SDimitry Andric ExprResult 1340b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { 1350b57cec5SDimitry Andric ExprResult LHS(ParseObjCAtExpression(AtLoc)); 1360b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric /// This routine is called when a leading '__extension__' is seen and 1400b57cec5SDimitry Andric /// consumed. This is necessary because the token gets consumed in the 1410b57cec5SDimitry Andric /// process of disambiguating between an expression and a declaration. 1420b57cec5SDimitry Andric ExprResult 1430b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { 1440b57cec5SDimitry Andric ExprResult LHS(true); 1450b57cec5SDimitry Andric { 1460b57cec5SDimitry Andric // Silence extension warnings in the sub-expression 1470b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); 1480b57cec5SDimitry Andric 149480093f4SDimitry Andric LHS = ParseCastExpression(AnyCastExpr); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric if (!LHS.isInvalid()) 1530b57cec5SDimitry Andric LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__, 1540b57cec5SDimitry Andric LHS.get()); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// Parse an expr that doesn't include (top-level) commas. 1600b57cec5SDimitry Andric ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { 1610b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 162fe6060f1SDimitry Andric cutOffParsing(); 1630b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 1640b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 1650b57cec5SDimitry Andric return ExprError(); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric if (Tok.is(tok::kw_throw)) 1690b57cec5SDimitry Andric return ParseThrowExpression(); 1700b57cec5SDimitry Andric if (Tok.is(tok::kw_co_yield)) 1710b57cec5SDimitry Andric return ParseCoyieldExpression(); 1720b57cec5SDimitry Andric 173480093f4SDimitry Andric ExprResult LHS = ParseCastExpression(AnyCastExpr, 1740b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 1750b57cec5SDimitry Andric isTypeCast); 1760b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Assignment); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric /// Parse an assignment expression where part of an Objective-C message 1800b57cec5SDimitry Andric /// send has already been parsed. 1810b57cec5SDimitry Andric /// 1820b57cec5SDimitry Andric /// In this case \p LBracLoc indicates the location of the '[' of the message 1830b57cec5SDimitry Andric /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating 1840b57cec5SDimitry Andric /// the receiver of the message. 1850b57cec5SDimitry Andric /// 1860b57cec5SDimitry Andric /// Since this handles full assignment-expression's, it handles postfix 1870b57cec5SDimitry Andric /// expressions and other binary operators for these expressions as well. 1880b57cec5SDimitry Andric ExprResult 1890b57cec5SDimitry Andric Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, 1900b57cec5SDimitry Andric SourceLocation SuperLoc, 1910b57cec5SDimitry Andric ParsedType ReceiverType, 1920b57cec5SDimitry Andric Expr *ReceiverExpr) { 1930b57cec5SDimitry Andric ExprResult R 1940b57cec5SDimitry Andric = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, 1950b57cec5SDimitry Andric ReceiverType, ReceiverExpr); 1960b57cec5SDimitry Andric R = ParsePostfixExpressionSuffix(R); 1970b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(R, prec::Assignment); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric ExprResult 2010b57cec5SDimitry Andric Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) { 2020b57cec5SDimitry Andric assert(Actions.ExprEvalContexts.back().Context == 2030b57cec5SDimitry Andric Sema::ExpressionEvaluationContext::ConstantEvaluated && 2040b57cec5SDimitry Andric "Call this function only if your ExpressionEvaluationContext is " 2050b57cec5SDimitry Andric "already ConstantEvaluated"); 206480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, isTypeCast)); 2070b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2080b57cec5SDimitry Andric return Actions.ActOnConstantExpression(Res); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) { 2120b57cec5SDimitry Andric // C++03 [basic.def.odr]p2: 2130b57cec5SDimitry Andric // An expression is potentially evaluated unless it appears where an 2140b57cec5SDimitry Andric // integral constant expression is required (see 5.19) [...]. 2150b57cec5SDimitry Andric // C++98 and C++11 have no such rule, but this is only a defect in C++98. 2160b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2170b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 2180b57cec5SDimitry Andric return ParseConstantExpressionInExprEvalContext(isTypeCast); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) { 2220b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2230b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 224480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); 2250b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2260b57cec5SDimitry Andric return Actions.ActOnCaseExpr(CaseLoc, Res); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// Parse a constraint-expression. 2300b57cec5SDimitry Andric /// 2310b57cec5SDimitry Andric /// \verbatim 232a7dea167SDimitry Andric /// constraint-expression: C++2a[temp.constr.decl]p1 2330b57cec5SDimitry Andric /// logical-or-expression 2340b57cec5SDimitry Andric /// \endverbatim 2350b57cec5SDimitry Andric ExprResult Parser::ParseConstraintExpression() { 236a7dea167SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 23755e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 238480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr)); 2390b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); 240480093f4SDimitry Andric if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) { 241480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(Res); 242a7dea167SDimitry Andric return ExprError(); 243480093f4SDimitry Andric } 2440b57cec5SDimitry Andric return Res; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 247480093f4SDimitry Andric /// \brief Parse a constraint-logical-and-expression. 248480093f4SDimitry Andric /// 249480093f4SDimitry Andric /// \verbatim 250480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 251480093f4SDimitry Andric /// constraint-logical-and-expression: 252480093f4SDimitry Andric /// primary-expression 253480093f4SDimitry Andric /// constraint-logical-and-expression '&&' primary-expression 254480093f4SDimitry Andric /// 255480093f4SDimitry Andric /// \endverbatim 256480093f4SDimitry Andric ExprResult 257480093f4SDimitry Andric Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { 258480093f4SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 25955e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 260480093f4SDimitry Andric bool NotPrimaryExpression = false; 261480093f4SDimitry Andric auto ParsePrimary = [&] () { 262480093f4SDimitry Andric ExprResult E = ParseCastExpression(PrimaryExprOnly, 263480093f4SDimitry Andric /*isAddressOfOperand=*/false, 264480093f4SDimitry Andric /*isTypeCast=*/NotTypeCast, 265480093f4SDimitry Andric /*isVectorLiteral=*/false, 266480093f4SDimitry Andric &NotPrimaryExpression); 267480093f4SDimitry Andric if (E.isInvalid()) 268480093f4SDimitry Andric return ExprError(); 269480093f4SDimitry Andric auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) { 270480093f4SDimitry Andric E = ParsePostfixExpressionSuffix(E); 271480093f4SDimitry Andric // Use InclusiveOr, the precedence just after '&&' to not parse the 272480093f4SDimitry Andric // next arguments to the logical and. 273480093f4SDimitry Andric E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr); 274480093f4SDimitry Andric if (!E.isInvalid()) 275480093f4SDimitry Andric Diag(E.get()->getExprLoc(), 276480093f4SDimitry Andric Note 277480093f4SDimitry Andric ? diag::note_unparenthesized_non_primary_expr_in_requires_clause 278480093f4SDimitry Andric : diag::err_unparenthesized_non_primary_expr_in_requires_clause) 279480093f4SDimitry Andric << FixItHint::CreateInsertion(E.get()->getBeginLoc(), "(") 280480093f4SDimitry Andric << FixItHint::CreateInsertion( 281480093f4SDimitry Andric PP.getLocForEndOfToken(E.get()->getEndLoc()), ")") 282480093f4SDimitry Andric << E.get()->getSourceRange(); 283480093f4SDimitry Andric return E; 284480093f4SDimitry Andric }; 285480093f4SDimitry Andric 286480093f4SDimitry Andric if (NotPrimaryExpression || 287480093f4SDimitry Andric // Check if the following tokens must be a part of a non-primary 288480093f4SDimitry Andric // expression 289480093f4SDimitry Andric getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 290480093f4SDimitry Andric /*CPlusPlus11=*/true) > prec::LogicalAnd || 291480093f4SDimitry Andric // Postfix operators other than '(' (which will be checked for in 292480093f4SDimitry Andric // CheckConstraintExpression). 293480093f4SDimitry Andric Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) || 294480093f4SDimitry Andric (Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) { 295480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/false); 296480093f4SDimitry Andric if (E.isInvalid()) 297480093f4SDimitry Andric return ExprError(); 298480093f4SDimitry Andric NotPrimaryExpression = false; 299480093f4SDimitry Andric } 300480093f4SDimitry Andric bool PossibleNonPrimary; 301480093f4SDimitry Andric bool IsConstraintExpr = 302480093f4SDimitry Andric Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary, 303480093f4SDimitry Andric IsTrailingRequiresClause); 304480093f4SDimitry Andric if (!IsConstraintExpr || PossibleNonPrimary) { 305480093f4SDimitry Andric // Atomic constraint might be an unparenthesized non-primary expression 306480093f4SDimitry Andric // (such as a binary operator), in which case we might get here (e.g. in 307480093f4SDimitry Andric // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore 308480093f4SDimitry Andric // the rest of the addition expression). Try to parse the rest of it here. 309480093f4SDimitry Andric if (PossibleNonPrimary) 310480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr); 311480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 312480093f4SDimitry Andric return ExprError(); 313480093f4SDimitry Andric } 314480093f4SDimitry Andric return E; 315480093f4SDimitry Andric }; 316480093f4SDimitry Andric ExprResult LHS = ParsePrimary(); 317480093f4SDimitry Andric if (LHS.isInvalid()) 318480093f4SDimitry Andric return ExprError(); 319480093f4SDimitry Andric while (Tok.is(tok::ampamp)) { 320480093f4SDimitry Andric SourceLocation LogicalAndLoc = ConsumeToken(); 321480093f4SDimitry Andric ExprResult RHS = ParsePrimary(); 322480093f4SDimitry Andric if (RHS.isInvalid()) { 323480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 324480093f4SDimitry Andric return ExprError(); 325480093f4SDimitry Andric } 326480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc, 327480093f4SDimitry Andric tok::ampamp, LHS.get(), RHS.get()); 328480093f4SDimitry Andric if (!Op.isUsable()) { 329480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 330480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 331480093f4SDimitry Andric return ExprError(); 332480093f4SDimitry Andric } 333480093f4SDimitry Andric LHS = Op; 334480093f4SDimitry Andric } 335480093f4SDimitry Andric return LHS; 336480093f4SDimitry Andric } 337480093f4SDimitry Andric 338480093f4SDimitry Andric /// \brief Parse a constraint-logical-or-expression. 339480093f4SDimitry Andric /// 340480093f4SDimitry Andric /// \verbatim 341480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 342480093f4SDimitry Andric /// constraint-logical-or-expression: 343480093f4SDimitry Andric /// constraint-logical-and-expression 344480093f4SDimitry Andric /// constraint-logical-or-expression '||' 345480093f4SDimitry Andric /// constraint-logical-and-expression 346480093f4SDimitry Andric /// 347480093f4SDimitry Andric /// \endverbatim 348480093f4SDimitry Andric ExprResult 349480093f4SDimitry Andric Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) { 350480093f4SDimitry Andric ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause)); 351480093f4SDimitry Andric if (!LHS.isUsable()) 352480093f4SDimitry Andric return ExprError(); 353480093f4SDimitry Andric while (Tok.is(tok::pipepipe)) { 354480093f4SDimitry Andric SourceLocation LogicalOrLoc = ConsumeToken(); 355480093f4SDimitry Andric ExprResult RHS = 356480093f4SDimitry Andric ParseConstraintLogicalAndExpression(IsTrailingRequiresClause); 357480093f4SDimitry Andric if (!RHS.isUsable()) { 358480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 359480093f4SDimitry Andric return ExprError(); 360480093f4SDimitry Andric } 361480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc, 362480093f4SDimitry Andric tok::pipepipe, LHS.get(), RHS.get()); 363480093f4SDimitry Andric if (!Op.isUsable()) { 364480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 365480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 366480093f4SDimitry Andric return ExprError(); 367480093f4SDimitry Andric } 368480093f4SDimitry Andric LHS = Op; 369480093f4SDimitry Andric } 370480093f4SDimitry Andric return LHS; 371480093f4SDimitry Andric } 372480093f4SDimitry Andric 3730b57cec5SDimitry Andric bool Parser::isNotExpressionStart() { 3740b57cec5SDimitry Andric tok::TokenKind K = Tok.getKind(); 3750b57cec5SDimitry Andric if (K == tok::l_brace || K == tok::r_brace || 3760b57cec5SDimitry Andric K == tok::kw_for || K == tok::kw_while || 3770b57cec5SDimitry Andric K == tok::kw_if || K == tok::kw_else || 3780b57cec5SDimitry Andric K == tok::kw_goto || K == tok::kw_try) 3790b57cec5SDimitry Andric return true; 3800b57cec5SDimitry Andric // If this is a decl-specifier, we can't be at the start of an expression. 3810b57cec5SDimitry Andric return isKnownToBeDeclarationSpecifier(); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric bool Parser::isFoldOperator(prec::Level Level) const { 3850b57cec5SDimitry Andric return Level > prec::Unknown && Level != prec::Conditional && 3860b57cec5SDimitry Andric Level != prec::Spaceship; 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric bool Parser::isFoldOperator(tok::TokenKind Kind) const { 3900b57cec5SDimitry Andric return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric /// Parse a binary expression that starts with \p LHS and has a 3940b57cec5SDimitry Andric /// precedence of at least \p MinPrec. 3950b57cec5SDimitry Andric ExprResult 3960b57cec5SDimitry Andric Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { 3970b57cec5SDimitry Andric prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(), 3980b57cec5SDimitry Andric GreaterThanIsOperator, 3990b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 4000b57cec5SDimitry Andric SourceLocation ColonLoc; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric auto SavedType = PreferredType; 4030b57cec5SDimitry Andric while (1) { 4040b57cec5SDimitry Andric // Every iteration may rely on a preferred type for the whole expression. 4050b57cec5SDimitry Andric PreferredType = SavedType; 4060b57cec5SDimitry Andric // If this token has a lower precedence than we are allowed to parse (e.g. 4070b57cec5SDimitry Andric // because we are called recursively, or because the token is not a binop), 4080b57cec5SDimitry Andric // then we are done! 4090b57cec5SDimitry Andric if (NextTokPrec < MinPrec) 4100b57cec5SDimitry Andric return LHS; 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric // Consume the operator, saving the operator token for error reporting. 4130b57cec5SDimitry Andric Token OpToken = Tok; 4140b57cec5SDimitry Andric ConsumeToken(); 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric if (OpToken.is(tok::caretcaret)) { 4170b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or)); 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric // If we're potentially in a template-id, we may now be able to determine 4210b57cec5SDimitry Andric // whether we're actually in one or not. 4220b57cec5SDimitry Andric if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater, 4230b57cec5SDimitry Andric tok::greatergreatergreater) && 4240b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(OpToken)) 4250b57cec5SDimitry Andric return ExprError(); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric // Bail out when encountering a comma followed by a token which can't 4280b57cec5SDimitry Andric // possibly be the start of an expression. For instance: 4290b57cec5SDimitry Andric // int f() { return 1, } 4300b57cec5SDimitry Andric // We can't do this before consuming the comma, because 4310b57cec5SDimitry Andric // isNotExpressionStart() looks at the token stream. 4320b57cec5SDimitry Andric if (OpToken.is(tok::comma) && isNotExpressionStart()) { 4330b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4340b57cec5SDimitry Andric Tok = OpToken; 4350b57cec5SDimitry Andric return LHS; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric // If the next token is an ellipsis, then this is a fold-expression. Leave 4390b57cec5SDimitry Andric // it alone so we can handle it in the paren expression. 4400b57cec5SDimitry Andric if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) { 4410b57cec5SDimitry Andric // FIXME: We can't check this via lookahead before we consume the token 4420b57cec5SDimitry Andric // because that tickles a lexer bug. 4430b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4440b57cec5SDimitry Andric Tok = OpToken; 4450b57cec5SDimitry Andric return LHS; 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric // In Objective-C++, alternative operator tokens can be used as keyword args 4490b57cec5SDimitry Andric // in message expressions. Unconsume the token so that it can reinterpreted 4500b57cec5SDimitry Andric // as an identifier in ParseObjCMessageExpressionBody. i.e., we support: 4510b57cec5SDimitry Andric // [foo meth:0 and:0]; 4520b57cec5SDimitry Andric // [foo not_eq]; 4530b57cec5SDimitry Andric if (getLangOpts().ObjC && getLangOpts().CPlusPlus && 4540b57cec5SDimitry Andric Tok.isOneOf(tok::colon, tok::r_square) && 4550b57cec5SDimitry Andric OpToken.getIdentifierInfo() != nullptr) { 4560b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4570b57cec5SDimitry Andric Tok = OpToken; 4580b57cec5SDimitry Andric return LHS; 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric // Special case handling for the ternary operator. 4620b57cec5SDimitry Andric ExprResult TernaryMiddle(true); 4630b57cec5SDimitry Andric if (NextTokPrec == prec::Conditional) { 4640b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 4650b57cec5SDimitry Andric // Parse a braced-init-list here for error recovery purposes. 4660b57cec5SDimitry Andric SourceLocation BraceLoc = Tok.getLocation(); 4670b57cec5SDimitry Andric TernaryMiddle = ParseBraceInitializer(); 4680b57cec5SDimitry Andric if (!TernaryMiddle.isInvalid()) { 4690b57cec5SDimitry Andric Diag(BraceLoc, diag::err_init_list_bin_op) 4700b57cec5SDimitry Andric << /*RHS*/ 1 << PP.getSpelling(OpToken) 4710b57cec5SDimitry Andric << Actions.getExprRange(TernaryMiddle.get()); 4720b57cec5SDimitry Andric TernaryMiddle = ExprError(); 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric } else if (Tok.isNot(tok::colon)) { 4750b57cec5SDimitry Andric // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 4760b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric // Handle this production specially: 4790b57cec5SDimitry Andric // logical-OR-expression '?' expression ':' conditional-expression 4800b57cec5SDimitry Andric // In particular, the RHS of the '?' is 'expression', not 4810b57cec5SDimitry Andric // 'logical-OR-expression' as we might expect. 4820b57cec5SDimitry Andric TernaryMiddle = ParseExpression(); 4830b57cec5SDimitry Andric } else { 4840b57cec5SDimitry Andric // Special case handling of "X ? Y : Z" where Y is empty: 4850b57cec5SDimitry Andric // logical-OR-expression '?' ':' conditional-expression [GNU] 4860b57cec5SDimitry Andric TernaryMiddle = nullptr; 4870b57cec5SDimitry Andric Diag(Tok, diag::ext_gnu_conditional_expr); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 4910b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 4920b57cec5SDimitry Andric LHS = ExprError(); 4930b57cec5SDimitry Andric TernaryMiddle = nullptr; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric if (!TryConsumeToken(tok::colon, ColonLoc)) { 4970b57cec5SDimitry Andric // Otherwise, we're missing a ':'. Assume that this was a typo that 4980b57cec5SDimitry Andric // the user forgot. If we're not in a macro expansion, we can suggest 4990b57cec5SDimitry Andric // a fixit hint. If there were two spaces before the current token, 5000b57cec5SDimitry Andric // suggest inserting the colon in between them, otherwise insert ": ". 5010b57cec5SDimitry Andric SourceLocation FILoc = Tok.getLocation(); 5020b57cec5SDimitry Andric const char *FIText = ": "; 5030b57cec5SDimitry Andric const SourceManager &SM = PP.getSourceManager(); 5040b57cec5SDimitry Andric if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) { 5050b57cec5SDimitry Andric assert(FILoc.isFileID()); 5060b57cec5SDimitry Andric bool IsInvalid = false; 5070b57cec5SDimitry Andric const char *SourcePtr = 5080b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid); 5090b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5100b57cec5SDimitry Andric SourcePtr = 5110b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid); 5120b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5130b57cec5SDimitry Andric FILoc = FILoc.getLocWithOffset(-1); 5140b57cec5SDimitry Andric FIText = ":"; 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric Diag(Tok, diag::err_expected) 5200b57cec5SDimitry Andric << tok::colon << FixItHint::CreateInsertion(FILoc, FIText); 5210b57cec5SDimitry Andric Diag(OpToken, diag::note_matching) << tok::question; 5220b57cec5SDimitry Andric ColonLoc = Tok.getLocation(); 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(), 5270b57cec5SDimitry Andric OpToken.getKind()); 5280b57cec5SDimitry Andric // Parse another leaf here for the RHS of the operator. 5290b57cec5SDimitry Andric // ParseCastExpression works here because all RHS expressions in C have it 5300b57cec5SDimitry Andric // as a prefix, at least. However, in C++, an assignment-expression could 5310b57cec5SDimitry Andric // be a throw-expression, which is not a valid cast-expression. 5320b57cec5SDimitry Andric // Therefore we need some special-casing here. 5330b57cec5SDimitry Andric // Also note that the third operand of the conditional operator is 5340b57cec5SDimitry Andric // an assignment-expression in C++, and in C++11, we can have a 5350b57cec5SDimitry Andric // braced-init-list on the RHS of an assignment. For better diagnostics, 5360b57cec5SDimitry Andric // parse as if we were allowed braced-init-lists everywhere, and check that 5370b57cec5SDimitry Andric // they only appear on the RHS of assignments later. 5380b57cec5SDimitry Andric ExprResult RHS; 5390b57cec5SDimitry Andric bool RHSIsInitList = false; 5400b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5410b57cec5SDimitry Andric RHS = ParseBraceInitializer(); 5420b57cec5SDimitry Andric RHSIsInitList = true; 5430b57cec5SDimitry Andric } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional) 5440b57cec5SDimitry Andric RHS = ParseAssignmentExpression(); 5450b57cec5SDimitry Andric else 546480093f4SDimitry Andric RHS = ParseCastExpression(AnyCastExpr); 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric if (RHS.isInvalid()) { 5490b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5500b57cec5SDimitry Andric // printed before errors from parsing the RHS, not after. 5510b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5520b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 5530b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 5540b57cec5SDimitry Andric LHS = ExprError(); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric // Remember the precedence of this operator and get the precedence of the 5580b57cec5SDimitry Andric // operator immediately to the right of the RHS. 5590b57cec5SDimitry Andric prec::Level ThisPrec = NextTokPrec; 5600b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 5610b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric // Assignment and conditional expressions are right-associative. 5640b57cec5SDimitry Andric bool isRightAssoc = ThisPrec == prec::Conditional || 5650b57cec5SDimitry Andric ThisPrec == prec::Assignment; 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric // Get the precedence of the operator to the right of the RHS. If it binds 5680b57cec5SDimitry Andric // more tightly with RHS than we do, evaluate it completely first. 5690b57cec5SDimitry Andric if (ThisPrec < NextTokPrec || 5700b57cec5SDimitry Andric (ThisPrec == NextTokPrec && isRightAssoc)) { 5710b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 5720b57cec5SDimitry Andric Diag(Tok, diag::err_init_list_bin_op) 5730b57cec5SDimitry Andric << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get()); 5740b57cec5SDimitry Andric RHS = ExprError(); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric // If this is left-associative, only parse things on the RHS that bind 5770b57cec5SDimitry Andric // more tightly than the current operator. If it is left-associative, it 5780b57cec5SDimitry Andric // is okay, to bind exactly as tightly. For example, compile A=B=C=D as 5790b57cec5SDimitry Andric // A=(B=(C=D)), where each paren is a level of recursion here. 5800b57cec5SDimitry Andric // The function takes ownership of the RHS. 5810b57cec5SDimitry Andric RHS = ParseRHSOfBinaryExpression(RHS, 5820b57cec5SDimitry Andric static_cast<prec::Level>(ThisPrec + !isRightAssoc)); 5830b57cec5SDimitry Andric RHSIsInitList = false; 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric if (RHS.isInvalid()) { 5860b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5870b57cec5SDimitry Andric // printed before errors from ParseRHSOfBinaryExpression, not after. 5880b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5890b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 5900b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 5910b57cec5SDimitry Andric LHS = ExprError(); 5920b57cec5SDimitry Andric } 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 5950b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 5990b57cec5SDimitry Andric if (ThisPrec == prec::Assignment) { 6000b57cec5SDimitry Andric Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists) 6010b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6020b57cec5SDimitry Andric } else if (ColonLoc.isValid()) { 6030b57cec5SDimitry Andric Diag(ColonLoc, diag::err_init_list_bin_op) 6040b57cec5SDimitry Andric << /*RHS*/1 << ":" 6050b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6060b57cec5SDimitry Andric LHS = ExprError(); 6070b57cec5SDimitry Andric } else { 6080b57cec5SDimitry Andric Diag(OpToken, diag::err_init_list_bin_op) 6090b57cec5SDimitry Andric << /*RHS*/1 << PP.getSpelling(OpToken) 6100b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6110b57cec5SDimitry Andric LHS = ExprError(); 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric ExprResult OrigLHS = LHS; 6160b57cec5SDimitry Andric if (!LHS.isInvalid()) { 6170b57cec5SDimitry Andric // Combine the LHS and RHS into the LHS (e.g. build AST). 6180b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 6190b57cec5SDimitry Andric // If we're using '>>' as an operator within a template 6200b57cec5SDimitry Andric // argument list (in C++98), suggest the addition of 6210b57cec5SDimitry Andric // parentheses so that the code remains well-formed in C++0x. 6220b57cec5SDimitry Andric if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) 6230b57cec5SDimitry Andric SuggestParentheses(OpToken.getLocation(), 6240b57cec5SDimitry Andric diag::warn_cxx11_right_shift_in_template_arg, 6250b57cec5SDimitry Andric SourceRange(Actions.getExprRange(LHS.get()).getBegin(), 6260b57cec5SDimitry Andric Actions.getExprRange(RHS.get()).getEnd())); 6270b57cec5SDimitry Andric 6285ffd83dbSDimitry Andric ExprResult BinOp = 6295ffd83dbSDimitry Andric Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), 6300b57cec5SDimitry Andric OpToken.getKind(), LHS.get(), RHS.get()); 6315ffd83dbSDimitry Andric if (BinOp.isInvalid()) 6325ffd83dbSDimitry Andric BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6335ffd83dbSDimitry Andric RHS.get()->getEndLoc(), 6345ffd83dbSDimitry Andric {LHS.get(), RHS.get()}); 6350b57cec5SDimitry Andric 6365ffd83dbSDimitry Andric LHS = BinOp; 6370b57cec5SDimitry Andric } else { 6385ffd83dbSDimitry Andric ExprResult CondOp = Actions.ActOnConditionalOp( 6395ffd83dbSDimitry Andric OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), 6400b57cec5SDimitry Andric RHS.get()); 6415ffd83dbSDimitry Andric if (CondOp.isInvalid()) { 6425ffd83dbSDimitry Andric std::vector<clang::Expr *> Args; 6435ffd83dbSDimitry Andric // TernaryMiddle can be null for the GNU conditional expr extension. 6445ffd83dbSDimitry Andric if (TernaryMiddle.get()) 6455ffd83dbSDimitry Andric Args = {LHS.get(), TernaryMiddle.get(), RHS.get()}; 6465ffd83dbSDimitry Andric else 6475ffd83dbSDimitry Andric Args = {LHS.get(), RHS.get()}; 6485ffd83dbSDimitry Andric CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6495ffd83dbSDimitry Andric RHS.get()->getEndLoc(), Args); 6505ffd83dbSDimitry Andric } 6515ffd83dbSDimitry Andric 6525ffd83dbSDimitry Andric LHS = CondOp; 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric // In this case, ActOnBinOp or ActOnConditionalOp performed the 6550b57cec5SDimitry Andric // CorrectDelayedTyposInExpr check. 6560b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 6570b57cec5SDimitry Andric continue; 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric // Ensure potential typos aren't left undiagnosed. 6610b57cec5SDimitry Andric if (LHS.isInvalid()) { 6620b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(OrigLHS); 6630b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6640b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric } 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric 669480093f4SDimitry Andric /// Parse a cast-expression, unary-expression or primary-expression, based 670480093f4SDimitry Andric /// on \p ExprType. 6710b57cec5SDimitry Andric /// 6720b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the 6730b57cec5SDimitry Andric /// operand of address-of gets special treatment due to member pointers. 6740b57cec5SDimitry Andric /// 675480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 6760b57cec5SDimitry Andric bool isAddressOfOperand, 6770b57cec5SDimitry Andric TypeCastState isTypeCast, 678480093f4SDimitry Andric bool isVectorLiteral, 679480093f4SDimitry Andric bool *NotPrimaryExpression) { 6800b57cec5SDimitry Andric bool NotCastExpr; 681480093f4SDimitry Andric ExprResult Res = ParseCastExpression(ParseKind, 6820b57cec5SDimitry Andric isAddressOfOperand, 6830b57cec5SDimitry Andric NotCastExpr, 6840b57cec5SDimitry Andric isTypeCast, 685480093f4SDimitry Andric isVectorLiteral, 686480093f4SDimitry Andric NotPrimaryExpression); 6870b57cec5SDimitry Andric if (NotCastExpr) 6880b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 6890b57cec5SDimitry Andric return Res; 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric namespace { 6930b57cec5SDimitry Andric class CastExpressionIdValidator final : public CorrectionCandidateCallback { 6940b57cec5SDimitry Andric public: 6950b57cec5SDimitry Andric CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes) 6960b57cec5SDimitry Andric : NextToken(Next), AllowNonTypes(AllowNonTypes) { 6970b57cec5SDimitry Andric WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes; 6980b57cec5SDimitry Andric } 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric bool ValidateCandidate(const TypoCorrection &candidate) override { 7010b57cec5SDimitry Andric NamedDecl *ND = candidate.getCorrectionDecl(); 7020b57cec5SDimitry Andric if (!ND) 7030b57cec5SDimitry Andric return candidate.isKeyword(); 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric if (isa<TypeDecl>(ND)) 7060b57cec5SDimitry Andric return WantTypeSpecifiers; 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate)) 7090b57cec5SDimitry Andric return false; 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period)) 7120b57cec5SDimitry Andric return true; 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric for (auto *C : candidate) { 7150b57cec5SDimitry Andric NamedDecl *ND = C->getUnderlyingDecl(); 7160b57cec5SDimitry Andric if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND)) 7170b57cec5SDimitry Andric return true; 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric return false; 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric std::unique_ptr<CorrectionCandidateCallback> clone() override { 723a7dea167SDimitry Andric return std::make_unique<CastExpressionIdValidator>(*this); 7240b57cec5SDimitry Andric } 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric private: 7270b57cec5SDimitry Andric Token NextToken; 7280b57cec5SDimitry Andric bool AllowNonTypes; 7290b57cec5SDimitry Andric }; 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse 7330b57cec5SDimitry Andric /// a unary-expression. 7340b57cec5SDimitry Andric /// 7350b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the operand 7360b57cec5SDimitry Andric /// of address-of gets special treatment due to member pointers. NotCastExpr 7370b57cec5SDimitry Andric /// is set to true if the token is not the start of a cast-expression, and no 7380b57cec5SDimitry Andric /// diagnostic is emitted in this case and no tokens are consumed. 7390b57cec5SDimitry Andric /// 7400b57cec5SDimitry Andric /// \verbatim 7410b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 7420b57cec5SDimitry Andric /// unary-expression 7430b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 7440b57cec5SDimitry Andric /// 7450b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 7460b57cec5SDimitry Andric /// postfix-expression 7470b57cec5SDimitry Andric /// '++' unary-expression 7480b57cec5SDimitry Andric /// '--' unary-expression 7490b57cec5SDimitry Andric /// [Coro] 'co_await' cast-expression 7500b57cec5SDimitry Andric /// unary-operator cast-expression 7510b57cec5SDimitry Andric /// 'sizeof' unary-expression 7520b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 7530b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 7540b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 7550b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 7560b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 7570b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 7580b57cec5SDimitry Andric /// [GNU] '&&' identifier 7590b57cec5SDimitry Andric /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7] 7600b57cec5SDimitry Andric /// [C++] new-expression 7610b57cec5SDimitry Andric /// [C++] delete-expression 7620b57cec5SDimitry Andric /// 7630b57cec5SDimitry Andric /// unary-operator: one of 7640b57cec5SDimitry Andric /// '&' '*' '+' '-' '~' '!' 7650b57cec5SDimitry Andric /// [GNU] '__extension__' '__real' '__imag' 7660b57cec5SDimitry Andric /// 7670b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 7680b57cec5SDimitry Andric /// [C99] identifier 7690b57cec5SDimitry Andric /// [C++] id-expression 7700b57cec5SDimitry Andric /// constant 7710b57cec5SDimitry Andric /// string-literal 7720b57cec5SDimitry Andric /// [C++] boolean-literal [C++ 2.13.5] 7730b57cec5SDimitry Andric /// [C++11] 'nullptr' [C++11 2.14.7] 7740b57cec5SDimitry Andric /// [C++11] user-defined-literal 7750b57cec5SDimitry Andric /// '(' expression ')' 7760b57cec5SDimitry Andric /// [C11] generic-selection 77755e4f9d5SDimitry Andric /// [C++2a] requires-expression 7780b57cec5SDimitry Andric /// '__func__' [C99 6.4.2.2] 7790b57cec5SDimitry Andric /// [GNU] '__FUNCTION__' 7800b57cec5SDimitry Andric /// [MS] '__FUNCDNAME__' 7810b57cec5SDimitry Andric /// [MS] 'L__FUNCTION__' 7820b57cec5SDimitry Andric /// [MS] '__FUNCSIG__' 7830b57cec5SDimitry Andric /// [MS] 'L__FUNCSIG__' 7840b57cec5SDimitry Andric /// [GNU] '__PRETTY_FUNCTION__' 7850b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' 7860b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 7870b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 7880b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 7890b57cec5SDimitry Andric /// assign-expr ')' 7900b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 7910b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 7920b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 7930b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 7940b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 7950b57cec5SDimitry Andric /// [GNU] '__null' 7960b57cec5SDimitry Andric /// [OBJC] '[' objc-message-expr ']' 7970b57cec5SDimitry Andric /// [OBJC] '\@selector' '(' objc-selector-arg ')' 7980b57cec5SDimitry Andric /// [OBJC] '\@protocol' '(' identifier ')' 7990b57cec5SDimitry Andric /// [OBJC] '\@encode' '(' type-name ')' 8000b57cec5SDimitry Andric /// [OBJC] objc-string-literal 8010b57cec5SDimitry Andric /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 8020b57cec5SDimitry Andric /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] 8030b57cec5SDimitry Andric /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 8040b57cec5SDimitry Andric /// [C++11] typename-specifier braced-init-list [C++11 5.2.3] 8050b57cec5SDimitry Andric /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8060b57cec5SDimitry Andric /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8070b57cec5SDimitry Andric /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8080b57cec5SDimitry Andric /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8090b57cec5SDimitry Andric /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 8100b57cec5SDimitry Andric /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 8110b57cec5SDimitry Andric /// [C++] 'this' [C++ 9.3.2] 8120b57cec5SDimitry Andric /// [G++] unary-type-trait '(' type-id ')' 8130b57cec5SDimitry Andric /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 8140b57cec5SDimitry Andric /// [EMBT] array-type-trait '(' type-id ',' integer ')' 8150b57cec5SDimitry Andric /// [clang] '^' block-literal 8160b57cec5SDimitry Andric /// 8170b57cec5SDimitry Andric /// constant: [C99 6.4.4] 8180b57cec5SDimitry Andric /// integer-constant 8190b57cec5SDimitry Andric /// floating-constant 8200b57cec5SDimitry Andric /// enumeration-constant -> identifier 8210b57cec5SDimitry Andric /// character-constant 8220b57cec5SDimitry Andric /// 8230b57cec5SDimitry Andric /// id-expression: [C++ 5.1] 8240b57cec5SDimitry Andric /// unqualified-id 8250b57cec5SDimitry Andric /// qualified-id 8260b57cec5SDimitry Andric /// 8270b57cec5SDimitry Andric /// unqualified-id: [C++ 5.1] 8280b57cec5SDimitry Andric /// identifier 8290b57cec5SDimitry Andric /// operator-function-id 8300b57cec5SDimitry Andric /// conversion-function-id 8310b57cec5SDimitry Andric /// '~' class-name 8320b57cec5SDimitry Andric /// template-id 8330b57cec5SDimitry Andric /// 8340b57cec5SDimitry Andric /// new-expression: [C++ 5.3.4] 8350b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 8360b57cec5SDimitry Andric /// new-initializer[opt] 8370b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8380b57cec5SDimitry Andric /// new-initializer[opt] 8390b57cec5SDimitry Andric /// 8400b57cec5SDimitry Andric /// delete-expression: [C++ 5.3.5] 8410b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 8420b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 8430b57cec5SDimitry Andric /// 8440b57cec5SDimitry Andric /// [GNU/Embarcadero] unary-type-trait: 8450b57cec5SDimitry Andric /// '__is_arithmetic' 8460b57cec5SDimitry Andric /// '__is_floating_point' 8470b57cec5SDimitry Andric /// '__is_integral' 8480b57cec5SDimitry Andric /// '__is_lvalue_expr' 8490b57cec5SDimitry Andric /// '__is_rvalue_expr' 8500b57cec5SDimitry Andric /// '__is_complete_type' 8510b57cec5SDimitry Andric /// '__is_void' 8520b57cec5SDimitry Andric /// '__is_array' 8530b57cec5SDimitry Andric /// '__is_function' 8540b57cec5SDimitry Andric /// '__is_reference' 8550b57cec5SDimitry Andric /// '__is_lvalue_reference' 8560b57cec5SDimitry Andric /// '__is_rvalue_reference' 8570b57cec5SDimitry Andric /// '__is_fundamental' 8580b57cec5SDimitry Andric /// '__is_object' 8590b57cec5SDimitry Andric /// '__is_scalar' 8600b57cec5SDimitry Andric /// '__is_compound' 8610b57cec5SDimitry Andric /// '__is_pointer' 8620b57cec5SDimitry Andric /// '__is_member_object_pointer' 8630b57cec5SDimitry Andric /// '__is_member_function_pointer' 8640b57cec5SDimitry Andric /// '__is_member_pointer' 8650b57cec5SDimitry Andric /// '__is_const' 8660b57cec5SDimitry Andric /// '__is_volatile' 8670b57cec5SDimitry Andric /// '__is_trivial' 8680b57cec5SDimitry Andric /// '__is_standard_layout' 8690b57cec5SDimitry Andric /// '__is_signed' 8700b57cec5SDimitry Andric /// '__is_unsigned' 8710b57cec5SDimitry Andric /// 8720b57cec5SDimitry Andric /// [GNU] unary-type-trait: 8730b57cec5SDimitry Andric /// '__has_nothrow_assign' 8740b57cec5SDimitry Andric /// '__has_nothrow_copy' 8750b57cec5SDimitry Andric /// '__has_nothrow_constructor' 8760b57cec5SDimitry Andric /// '__has_trivial_assign' [TODO] 8770b57cec5SDimitry Andric /// '__has_trivial_copy' [TODO] 8780b57cec5SDimitry Andric /// '__has_trivial_constructor' 8790b57cec5SDimitry Andric /// '__has_trivial_destructor' 8800b57cec5SDimitry Andric /// '__has_virtual_destructor' 8810b57cec5SDimitry Andric /// '__is_abstract' [TODO] 8820b57cec5SDimitry Andric /// '__is_class' 8830b57cec5SDimitry Andric /// '__is_empty' [TODO] 8840b57cec5SDimitry Andric /// '__is_enum' 8850b57cec5SDimitry Andric /// '__is_final' 8860b57cec5SDimitry Andric /// '__is_pod' 8870b57cec5SDimitry Andric /// '__is_polymorphic' 8880b57cec5SDimitry Andric /// '__is_sealed' [MS] 8890b57cec5SDimitry Andric /// '__is_trivial' 8900b57cec5SDimitry Andric /// '__is_union' 8910b57cec5SDimitry Andric /// '__has_unique_object_representations' 8920b57cec5SDimitry Andric /// 8930b57cec5SDimitry Andric /// [Clang] unary-type-trait: 8940b57cec5SDimitry Andric /// '__is_aggregate' 8950b57cec5SDimitry Andric /// '__trivially_copyable' 8960b57cec5SDimitry Andric /// 8970b57cec5SDimitry Andric /// binary-type-trait: 8980b57cec5SDimitry Andric /// [GNU] '__is_base_of' 8990b57cec5SDimitry Andric /// [MS] '__is_convertible_to' 9000b57cec5SDimitry Andric /// '__is_convertible' 9010b57cec5SDimitry Andric /// '__is_same' 9020b57cec5SDimitry Andric /// 9030b57cec5SDimitry Andric /// [Embarcadero] array-type-trait: 9040b57cec5SDimitry Andric /// '__array_rank' 9050b57cec5SDimitry Andric /// '__array_extent' 9060b57cec5SDimitry Andric /// 9070b57cec5SDimitry Andric /// [Embarcadero] expression-trait: 9080b57cec5SDimitry Andric /// '__is_lvalue_expr' 9090b57cec5SDimitry Andric /// '__is_rvalue_expr' 9100b57cec5SDimitry Andric /// \endverbatim 9110b57cec5SDimitry Andric /// 912480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 9130b57cec5SDimitry Andric bool isAddressOfOperand, 9140b57cec5SDimitry Andric bool &NotCastExpr, 9150b57cec5SDimitry Andric TypeCastState isTypeCast, 916480093f4SDimitry Andric bool isVectorLiteral, 917480093f4SDimitry Andric bool *NotPrimaryExpression) { 9180b57cec5SDimitry Andric ExprResult Res; 9190b57cec5SDimitry Andric tok::TokenKind SavedKind = Tok.getKind(); 9200b57cec5SDimitry Andric auto SavedType = PreferredType; 9210b57cec5SDimitry Andric NotCastExpr = false; 9220b57cec5SDimitry Andric 9235ffd83dbSDimitry Andric // Are postfix-expression suffix operators permitted after this 9245ffd83dbSDimitry Andric // cast-expression? If not, and we find some, we'll parse them anyway and 9255ffd83dbSDimitry Andric // diagnose them. 9265ffd83dbSDimitry Andric bool AllowSuffix = true; 9275ffd83dbSDimitry Andric 9280b57cec5SDimitry Andric // This handles all of cast-expression, unary-expression, postfix-expression, 9290b57cec5SDimitry Andric // and primary-expression. We handle them together like this for efficiency 9300b57cec5SDimitry Andric // and to simplify handling of an expression starting with a '(' token: which 9310b57cec5SDimitry Andric // may be one of a parenthesized expression, cast-expression, compound literal 9320b57cec5SDimitry Andric // expression, or statement expression. 9330b57cec5SDimitry Andric // 9340b57cec5SDimitry Andric // If the parsed tokens consist of a primary-expression, the cases below 9350b57cec5SDimitry Andric // break out of the switch; at the end we call ParsePostfixExpressionSuffix 9360b57cec5SDimitry Andric // to handle the postfix expression suffixes. Cases that cannot be followed 9375ffd83dbSDimitry Andric // by postfix exprs should set AllowSuffix to false. 9380b57cec5SDimitry Andric switch (SavedKind) { 9390b57cec5SDimitry Andric case tok::l_paren: { 940480093f4SDimitry Andric // If this expression is limited to being a unary-expression, the paren can 9410b57cec5SDimitry Andric // not start a cast expression. 942480093f4SDimitry Andric ParenParseOption ParenExprType; 943480093f4SDimitry Andric switch (ParseKind) { 944480093f4SDimitry Andric case CastParseKind::UnaryExprOnly: 945480093f4SDimitry Andric if (!getLangOpts().CPlusPlus) 946480093f4SDimitry Andric ParenExprType = CompoundLiteral; 947480093f4SDimitry Andric LLVM_FALLTHROUGH; 948480093f4SDimitry Andric case CastParseKind::AnyCastExpr: 949480093f4SDimitry Andric ParenExprType = ParenParseOption::CastExpr; 950480093f4SDimitry Andric break; 951480093f4SDimitry Andric case CastParseKind::PrimaryExprOnly: 952480093f4SDimitry Andric ParenExprType = FoldExpr; 953480093f4SDimitry Andric break; 954480093f4SDimitry Andric } 9550b57cec5SDimitry Andric ParsedType CastTy; 9560b57cec5SDimitry Andric SourceLocation RParenLoc; 9570b57cec5SDimitry Andric Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 9580b57cec5SDimitry Andric isTypeCast == IsTypeCast, CastTy, RParenLoc); 9590b57cec5SDimitry Andric 9605ffd83dbSDimitry Andric // FIXME: What should we do if a vector literal is followed by a 9615ffd83dbSDimitry Andric // postfix-expression suffix? Usually postfix operators are permitted on 9625ffd83dbSDimitry Andric // literals. 9630b57cec5SDimitry Andric if (isVectorLiteral) 9640b57cec5SDimitry Andric return Res; 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric switch (ParenExprType) { 9670b57cec5SDimitry Andric case SimpleExpr: break; // Nothing else to do. 9680b57cec5SDimitry Andric case CompoundStmt: break; // Nothing else to do. 9690b57cec5SDimitry Andric case CompoundLiteral: 9700b57cec5SDimitry Andric // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 9710b57cec5SDimitry Andric // postfix-expression exist, parse them now. 9720b57cec5SDimitry Andric break; 9730b57cec5SDimitry Andric case CastExpr: 9740b57cec5SDimitry Andric // We have parsed the cast-expression and no postfix-expr pieces are 9750b57cec5SDimitry Andric // following. 9760b57cec5SDimitry Andric return Res; 9770b57cec5SDimitry Andric case FoldExpr: 9780b57cec5SDimitry Andric // We only parsed a fold-expression. There might be postfix-expr pieces 9790b57cec5SDimitry Andric // afterwards; parse them now. 9800b57cec5SDimitry Andric break; 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric break; 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric // primary-expression 9870b57cec5SDimitry Andric case tok::numeric_constant: 9880b57cec5SDimitry Andric // constant: integer-constant 9890b57cec5SDimitry Andric // constant: floating-constant 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope()); 9920b57cec5SDimitry Andric ConsumeToken(); 9930b57cec5SDimitry Andric break; 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric case tok::kw_true: 9960b57cec5SDimitry Andric case tok::kw_false: 9970b57cec5SDimitry Andric Res = ParseCXXBoolLiteral(); 9980b57cec5SDimitry Andric break; 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric case tok::kw___objc_yes: 10010b57cec5SDimitry Andric case tok::kw___objc_no: 10025ffd83dbSDimitry Andric Res = ParseObjCBoolLiteral(); 10035ffd83dbSDimitry Andric break; 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric case tok::kw_nullptr: 10060b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_nullptr); 10075ffd83dbSDimitry Andric Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 10085ffd83dbSDimitry Andric break; 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric case tok::annot_primary_expr: 1011e8d8bef9SDimitry Andric case tok::annot_overload_set: 10120b57cec5SDimitry Andric Res = getExprAnnotation(Tok); 1013e8d8bef9SDimitry Andric if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set) 1014e8d8bef9SDimitry Andric Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get()); 10150b57cec5SDimitry Andric ConsumeAnnotationToken(); 10160b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 10170b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 10180b57cec5SDimitry Andric break; 10190b57cec5SDimitry Andric 1020a7dea167SDimitry Andric case tok::annot_non_type: 1021a7dea167SDimitry Andric case tok::annot_non_type_dependent: 1022a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 1023a7dea167SDimitry Andric CXXScopeSpec SS; 1024a7dea167SDimitry Andric Token Replacement; 1025a7dea167SDimitry Andric Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 1026a7dea167SDimitry Andric assert(!Res.isUnset() && 1027a7dea167SDimitry Andric "should not perform typo correction on annotation token"); 1028a7dea167SDimitry Andric break; 1029a7dea167SDimitry Andric } 1030a7dea167SDimitry Andric 10310b57cec5SDimitry Andric case tok::kw___super: 10320b57cec5SDimitry Andric case tok::kw_decltype: 10330b57cec5SDimitry Andric // Annotate the token and tail recurse. 10340b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 10350b57cec5SDimitry Andric return ExprError(); 10360b57cec5SDimitry Andric assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); 1037480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1038480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric case tok::identifier: { // primary-expression: identifier 10410b57cec5SDimitry Andric // unqualified-id: identifier 10420b57cec5SDimitry Andric // constant: enumeration-constant 10430b57cec5SDimitry Andric // Turn a potentially qualified name into a annot_typename or 10440b57cec5SDimitry Andric // annot_cxxscope if it would be valid. This handles things like x::y, etc. 10450b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) { 10460b57cec5SDimitry Andric // Avoid the unnecessary parse-time lookup in the common case 10470b57cec5SDimitry Andric // where the syntax forbids a type. 10480b57cec5SDimitry Andric const Token &Next = NextToken(); 10490b57cec5SDimitry Andric 10500b57cec5SDimitry Andric // If this identifier was reverted from a token ID, and the next token 10510b57cec5SDimitry Andric // is a parenthesis, this is likely to be a use of a type trait. Check 10520b57cec5SDimitry Andric // those tokens. 10530b57cec5SDimitry Andric if (Next.is(tok::l_paren) && 10540b57cec5SDimitry Andric Tok.is(tok::identifier) && 10550b57cec5SDimitry Andric Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { 10560b57cec5SDimitry Andric IdentifierInfo *II = Tok.getIdentifierInfo(); 10570b57cec5SDimitry Andric // Build up the mapping of revertible type traits, for future use. 10580b57cec5SDimitry Andric if (RevertibleTypeTraits.empty()) { 10590b57cec5SDimitry Andric #define RTT_JOIN(X,Y) X##Y 10600b57cec5SDimitry Andric #define REVERTIBLE_TYPE_TRAIT(Name) \ 10610b57cec5SDimitry Andric RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ 10620b57cec5SDimitry Andric = RTT_JOIN(tok::kw_,Name) 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_abstract); 10650b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_aggregate); 10660b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_arithmetic); 10670b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_array); 10680b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_assignable); 10690b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_base_of); 10700b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_class); 10710b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_complete_type); 10720b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_compound); 10730b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_const); 10740b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_constructible); 10750b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible); 10760b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible_to); 10770b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_destructible); 10780b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_empty); 10790b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_enum); 10800b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_floating_point); 10810b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_final); 10820b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_function); 10830b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_fundamental); 10840b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_integral); 10850b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_interface_class); 10860b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_literal); 10870b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); 10880b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); 10890b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); 10900b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); 10910b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_pointer); 10920b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); 10930b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); 10940b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); 10950b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_object); 10960b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pod); 10970b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pointer); 10980b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_polymorphic); 10990b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_reference); 11000b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); 11010b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); 11020b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_same); 11030b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scalar); 11040b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_sealed); 11050b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_signed); 11060b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_standard_layout); 11070b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivial); 11080b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); 11090b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); 11100b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); 11110b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_union); 11120b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unsigned); 11130b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_void); 11140b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_volatile); 11150b57cec5SDimitry Andric #undef REVERTIBLE_TYPE_TRAIT 11160b57cec5SDimitry Andric #undef RTT_JOIN 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric // If we find that this is in fact the name of a type trait, 11200b57cec5SDimitry Andric // update the token kind in place and parse again to treat it as 11210b57cec5SDimitry Andric // the appropriate kind of type trait. 11220b57cec5SDimitry Andric llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known 11230b57cec5SDimitry Andric = RevertibleTypeTraits.find(II); 11240b57cec5SDimitry Andric if (Known != RevertibleTypeTraits.end()) { 11250b57cec5SDimitry Andric Tok.setKind(Known->second); 1126480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1127480093f4SDimitry Andric NotCastExpr, isTypeCast, 1128480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric } 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric if ((!ColonIsSacred && Next.is(tok::colon)) || 11330b57cec5SDimitry Andric Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren, 11340b57cec5SDimitry Andric tok::l_brace)) { 11350b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 11360b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 11370b57cec5SDimitry Andric return ExprError(); 11380b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) 1139480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1140480093f4SDimitry Andric NotCastExpr, isTypeCast, 1141480093f4SDimitry Andric isVectorLiteral, 1142480093f4SDimitry Andric NotPrimaryExpression); 11430b57cec5SDimitry Andric } 11440b57cec5SDimitry Andric } 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric // Consume the identifier so that we can see if it is followed by a '(' or 11470b57cec5SDimitry Andric // '.'. 11480b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 11490b57cec5SDimitry Andric SourceLocation ILoc = ConsumeToken(); 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric // Support 'Class.property' and 'super.property' notation. 11520b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.is(tok::period) && 11530b57cec5SDimitry Andric (Actions.getTypeName(II, ILoc, getCurScope()) || 11540b57cec5SDimitry Andric // Allow the base to be 'super' if in an objc-method. 11550b57cec5SDimitry Andric (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { 11560b57cec5SDimitry Andric ConsumeToken(); 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && &II != Ident_super) { 1159fe6060f1SDimitry Andric cutOffParsing(); 11600b57cec5SDimitry Andric Actions.CodeCompleteObjCClassPropertyRefExpr( 11610b57cec5SDimitry Andric getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); 11620b57cec5SDimitry Andric return ExprError(); 11630b57cec5SDimitry Andric } 11640b57cec5SDimitry Andric // Allow either an identifier or the keyword 'class' (in C++). 11650b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) && 11660b57cec5SDimitry Andric !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { 11670b57cec5SDimitry Andric Diag(Tok, diag::err_expected_property_name); 11680b57cec5SDimitry Andric return ExprError(); 11690b57cec5SDimitry Andric } 11700b57cec5SDimitry Andric IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 11710b57cec5SDimitry Andric SourceLocation PropertyLoc = ConsumeToken(); 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, 11740b57cec5SDimitry Andric ILoc, PropertyLoc); 11750b57cec5SDimitry Andric break; 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric // In an Objective-C method, if we have "super" followed by an identifier, 11790b57cec5SDimitry Andric // the token sequence is ill-formed. However, if there's a ':' or ']' after 11800b57cec5SDimitry Andric // that identifier, this is probably a message send with a missing open 11810b57cec5SDimitry Andric // bracket. Treat it as such. 11820b57cec5SDimitry Andric if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression && 11830b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 11840b57cec5SDimitry Andric ((Tok.is(tok::identifier) && 11850b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || 11860b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 11870b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr, 11880b57cec5SDimitry Andric nullptr); 11890b57cec5SDimitry Andric break; 11900b57cec5SDimitry Andric } 11910b57cec5SDimitry Andric 11920b57cec5SDimitry Andric // If we have an Objective-C class name followed by an identifier 11930b57cec5SDimitry Andric // and either ':' or ']', this is an Objective-C class message 11940b57cec5SDimitry Andric // send that's missing the opening '['. Recovery 11950b57cec5SDimitry Andric // appropriately. Also take this path if we're performing code 11960b57cec5SDimitry Andric // completion after an Objective-C class name. 11970b57cec5SDimitry Andric if (getLangOpts().ObjC && 11980b57cec5SDimitry Andric ((Tok.is(tok::identifier) && !InMessageExpression) || 11990b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12000b57cec5SDimitry Andric const Token& Next = NextToken(); 12010b57cec5SDimitry Andric if (Tok.is(tok::code_completion) || 12020b57cec5SDimitry Andric Next.is(tok::colon) || Next.is(tok::r_square)) 12030b57cec5SDimitry Andric if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) 12040b57cec5SDimitry Andric if (Typ.get()->isObjCObjectOrInterfaceType()) { 12050b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 12060b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 12070b57cec5SDimitry Andric DS.SetRangeStart(ILoc); 12080b57cec5SDimitry Andric DS.SetRangeEnd(ILoc); 12090b57cec5SDimitry Andric const char *PrevSpec = nullptr; 12100b57cec5SDimitry Andric unsigned DiagID; 12110b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, 12120b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 12130b57cec5SDimitry Andric 1214e8d8bef9SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); 12150b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), 12160b57cec5SDimitry Andric DeclaratorInfo); 12170b57cec5SDimitry Andric if (Ty.isInvalid()) 12180b57cec5SDimitry Andric break; 12190b57cec5SDimitry Andric 12200b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), 12210b57cec5SDimitry Andric SourceLocation(), 12220b57cec5SDimitry Andric Ty.get(), nullptr); 12230b57cec5SDimitry Andric break; 12240b57cec5SDimitry Andric } 12250b57cec5SDimitry Andric } 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric // Make sure to pass down the right value for isAddressOfOperand. 12280b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 12290b57cec5SDimitry Andric isAddressOfOperand = false; 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 12320b57cec5SDimitry Andric // need to know whether or not this identifier is a function designator or 12330b57cec5SDimitry Andric // not. 12340b57cec5SDimitry Andric UnqualifiedId Name; 12350b57cec5SDimitry Andric CXXScopeSpec ScopeSpec; 12360b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 12370b57cec5SDimitry Andric Token Replacement; 12380b57cec5SDimitry Andric CastExpressionIdValidator Validator( 12390b57cec5SDimitry Andric /*Next=*/Tok, 12400b57cec5SDimitry Andric /*AllowTypes=*/isTypeCast != NotTypeCast, 12410b57cec5SDimitry Andric /*AllowNonTypes=*/isTypeCast != IsTypeCast); 12420b57cec5SDimitry Andric Validator.IsAddressOfOperand = isAddressOfOperand; 12430b57cec5SDimitry Andric if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) { 12440b57cec5SDimitry Andric Validator.WantExpressionKeywords = false; 12450b57cec5SDimitry Andric Validator.WantRemainingKeywords = false; 12460b57cec5SDimitry Andric } else { 12470b57cec5SDimitry Andric Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren); 12480b57cec5SDimitry Andric } 12490b57cec5SDimitry Andric Name.setIdentifier(&II, ILoc); 12500b57cec5SDimitry Andric Res = Actions.ActOnIdExpression( 12510b57cec5SDimitry Andric getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), 12520b57cec5SDimitry Andric isAddressOfOperand, &Validator, 12530b57cec5SDimitry Andric /*IsInlineAsmIdentifier=*/false, 12540b57cec5SDimitry Andric Tok.is(tok::r_paren) ? nullptr : &Replacement); 12550b57cec5SDimitry Andric if (!Res.isInvalid() && Res.isUnset()) { 12560b57cec5SDimitry Andric UnconsumeToken(Replacement); 1257480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1258480093f4SDimitry Andric NotCastExpr, isTypeCast, 1259480093f4SDimitry Andric /*isVectorLiteral=*/false, 1260480093f4SDimitry Andric NotPrimaryExpression); 12610b57cec5SDimitry Andric } 12620b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 12630b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 12640b57cec5SDimitry Andric break; 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric case tok::char_constant: // constant: character-constant 12670b57cec5SDimitry Andric case tok::wide_char_constant: 12680b57cec5SDimitry Andric case tok::utf8_char_constant: 12690b57cec5SDimitry Andric case tok::utf16_char_constant: 12700b57cec5SDimitry Andric case tok::utf32_char_constant: 12710b57cec5SDimitry Andric Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope()); 12720b57cec5SDimitry Andric ConsumeToken(); 12730b57cec5SDimitry Andric break; 12740b57cec5SDimitry Andric case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 12750b57cec5SDimitry Andric case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 12760b57cec5SDimitry Andric case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] 12770b57cec5SDimitry Andric case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS] 12780b57cec5SDimitry Andric case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] 12790b57cec5SDimitry Andric case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] 12800b57cec5SDimitry Andric case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 12810b57cec5SDimitry Andric Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 12820b57cec5SDimitry Andric ConsumeToken(); 12830b57cec5SDimitry Andric break; 12840b57cec5SDimitry Andric case tok::string_literal: // primary-expression: string-literal 12850b57cec5SDimitry Andric case tok::wide_string_literal: 12860b57cec5SDimitry Andric case tok::utf8_string_literal: 12870b57cec5SDimitry Andric case tok::utf16_string_literal: 12880b57cec5SDimitry Andric case tok::utf32_string_literal: 12890b57cec5SDimitry Andric Res = ParseStringLiteralExpression(true); 12900b57cec5SDimitry Andric break; 12910b57cec5SDimitry Andric case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1] 12920b57cec5SDimitry Andric Res = ParseGenericSelectionExpression(); 12930b57cec5SDimitry Andric break; 12940b57cec5SDimitry Andric case tok::kw___builtin_available: 12955ffd83dbSDimitry Andric Res = ParseAvailabilityCheckExpr(Tok.getLocation()); 12965ffd83dbSDimitry Andric break; 12970b57cec5SDimitry Andric case tok::kw___builtin_va_arg: 12980b57cec5SDimitry Andric case tok::kw___builtin_offsetof: 12990b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: 13000b57cec5SDimitry Andric case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() 13010b57cec5SDimitry Andric case tok::kw___builtin_convertvector: 13020b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 13030b57cec5SDimitry Andric case tok::kw___builtin_FILE: 13040b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 13050b57cec5SDimitry Andric case tok::kw___builtin_LINE: 1306480093f4SDimitry Andric if (NotPrimaryExpression) 1307480093f4SDimitry Andric *NotPrimaryExpression = true; 13085ffd83dbSDimitry Andric // This parses the complete suffix; we can return early. 13090b57cec5SDimitry Andric return ParseBuiltinPrimaryExpression(); 13100b57cec5SDimitry Andric case tok::kw___null: 13115ffd83dbSDimitry Andric Res = Actions.ActOnGNUNullExpr(ConsumeToken()); 13125ffd83dbSDimitry Andric break; 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric case tok::plusplus: // unary-expression: '++' unary-expression [C99] 13150b57cec5SDimitry Andric case tok::minusminus: { // unary-expression: '--' unary-expression [C99] 1316480093f4SDimitry Andric if (NotPrimaryExpression) 1317480093f4SDimitry Andric *NotPrimaryExpression = true; 13180b57cec5SDimitry Andric // C++ [expr.unary] has: 13190b57cec5SDimitry Andric // unary-expression: 13200b57cec5SDimitry Andric // ++ cast-expression 13210b57cec5SDimitry Andric // -- cast-expression 13220b57cec5SDimitry Andric Token SavedTok = Tok; 13230b57cec5SDimitry Andric ConsumeToken(); 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(), 13260b57cec5SDimitry Andric SavedTok.getLocation()); 13270b57cec5SDimitry Andric // One special case is implicitly handled here: if the preceding tokens are 13280b57cec5SDimitry Andric // an ambiguous cast expression, such as "(T())++", then we recurse to 13290b57cec5SDimitry Andric // determine whether the '++' is prefix or postfix. 1330480093f4SDimitry Andric Res = ParseCastExpression(getLangOpts().CPlusPlus ? 1331480093f4SDimitry Andric UnaryExprOnly : AnyCastExpr, 13320b57cec5SDimitry Andric /*isAddressOfOperand*/false, NotCastExpr, 13330b57cec5SDimitry Andric NotTypeCast); 13340b57cec5SDimitry Andric if (NotCastExpr) { 13350b57cec5SDimitry Andric // If we return with NotCastExpr = true, we must not consume any tokens, 13360b57cec5SDimitry Andric // so put the token back where we found it. 13370b57cec5SDimitry Andric assert(Res.isInvalid()); 13380b57cec5SDimitry Andric UnconsumeToken(SavedTok); 13390b57cec5SDimitry Andric return ExprError(); 13400b57cec5SDimitry Andric } 13415ffd83dbSDimitry Andric if (!Res.isInvalid()) { 13425ffd83dbSDimitry Andric Expr *Arg = Res.get(); 13430b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(), 13445ffd83dbSDimitry Andric SavedKind, Arg); 13455ffd83dbSDimitry Andric if (Res.isInvalid()) 13465ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(), 13475ffd83dbSDimitry Andric Arg->getEndLoc(), Arg); 13485ffd83dbSDimitry Andric } 13490b57cec5SDimitry Andric return Res; 13500b57cec5SDimitry Andric } 13510b57cec5SDimitry Andric case tok::amp: { // unary-expression: '&' cast-expression 1352480093f4SDimitry Andric if (NotPrimaryExpression) 1353480093f4SDimitry Andric *NotPrimaryExpression = true; 13540b57cec5SDimitry Andric // Special treatment because of member pointers 13550b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 13560b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); 1357480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr, true); 13585ffd83dbSDimitry Andric if (!Res.isInvalid()) { 13595ffd83dbSDimitry Andric Expr *Arg = Res.get(); 13605ffd83dbSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); 13615ffd83dbSDimitry Andric if (Res.isInvalid()) 13625ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(), 13635ffd83dbSDimitry Andric Arg); 13645ffd83dbSDimitry Andric } 13650b57cec5SDimitry Andric return Res; 13660b57cec5SDimitry Andric } 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric case tok::star: // unary-expression: '*' cast-expression 13690b57cec5SDimitry Andric case tok::plus: // unary-expression: '+' cast-expression 13700b57cec5SDimitry Andric case tok::minus: // unary-expression: '-' cast-expression 13710b57cec5SDimitry Andric case tok::tilde: // unary-expression: '~' cast-expression 13720b57cec5SDimitry Andric case tok::exclaim: // unary-expression: '!' cast-expression 13730b57cec5SDimitry Andric case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 13740b57cec5SDimitry Andric case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 1375480093f4SDimitry Andric if (NotPrimaryExpression) 1376480093f4SDimitry Andric *NotPrimaryExpression = true; 13770b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 13780b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); 1379480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 13805ffd83dbSDimitry Andric if (!Res.isInvalid()) { 13815ffd83dbSDimitry Andric Expr *Arg = Res.get(); 13825ffd83dbSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); 13835ffd83dbSDimitry Andric if (Res.isInvalid()) 13845ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg); 13855ffd83dbSDimitry Andric } 13860b57cec5SDimitry Andric return Res; 13870b57cec5SDimitry Andric } 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression 1390480093f4SDimitry Andric if (NotPrimaryExpression) 1391480093f4SDimitry Andric *NotPrimaryExpression = true; 13920b57cec5SDimitry Andric SourceLocation CoawaitLoc = ConsumeToken(); 1393480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 13940b57cec5SDimitry Andric if (!Res.isInvalid()) 13950b57cec5SDimitry Andric Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get()); 13960b57cec5SDimitry Andric return Res; 13970b57cec5SDimitry Andric } 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andric case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 14000b57cec5SDimitry Andric // __extension__ silences extension warnings in the subexpression. 1401480093f4SDimitry Andric if (NotPrimaryExpression) 1402480093f4SDimitry Andric *NotPrimaryExpression = true; 14030b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); // Use RAII to do this. 14040b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 1405480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14060b57cec5SDimitry Andric if (!Res.isInvalid()) 14070b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 14080b57cec5SDimitry Andric return Res; 14090b57cec5SDimitry Andric } 14100b57cec5SDimitry Andric case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' 14110b57cec5SDimitry Andric if (!getLangOpts().C11) 1412a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 14130b57cec5SDimitry Andric LLVM_FALLTHROUGH; 14140b57cec5SDimitry Andric case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' 14150b57cec5SDimitry Andric case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 14160b57cec5SDimitry Andric // unary-expression: '__alignof' '(' type-name ')' 14170b57cec5SDimitry Andric case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 14180b57cec5SDimitry Andric // unary-expression: 'sizeof' '(' type-name ')' 14190b57cec5SDimitry Andric case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression 14200b57cec5SDimitry Andric // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' 14210b57cec5SDimitry Andric case tok::kw___builtin_omp_required_simd_align: 1422480093f4SDimitry Andric if (NotPrimaryExpression) 1423480093f4SDimitry Andric *NotPrimaryExpression = true; 14245ffd83dbSDimitry Andric AllowSuffix = false; 14255ffd83dbSDimitry Andric Res = ParseUnaryExprOrTypeTraitExpression(); 14265ffd83dbSDimitry Andric break; 14270b57cec5SDimitry Andric case tok::ampamp: { // unary-expression: '&&' identifier 1428480093f4SDimitry Andric if (NotPrimaryExpression) 1429480093f4SDimitry Andric *NotPrimaryExpression = true; 14300b57cec5SDimitry Andric SourceLocation AmpAmpLoc = ConsumeToken(); 14310b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 14320b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 14330b57cec5SDimitry Andric 14340b57cec5SDimitry Andric if (getCurScope()->getFnParent() == nullptr) 14350b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andric Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 14380b57cec5SDimitry Andric LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 14390b57cec5SDimitry Andric Tok.getLocation()); 14400b57cec5SDimitry Andric Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); 14410b57cec5SDimitry Andric ConsumeToken(); 14425ffd83dbSDimitry Andric AllowSuffix = false; 14435ffd83dbSDimitry Andric break; 14440b57cec5SDimitry Andric } 14450b57cec5SDimitry Andric case tok::kw_const_cast: 14460b57cec5SDimitry Andric case tok::kw_dynamic_cast: 14470b57cec5SDimitry Andric case tok::kw_reinterpret_cast: 14480b57cec5SDimitry Andric case tok::kw_static_cast: 14495ffd83dbSDimitry Andric case tok::kw_addrspace_cast: 1450480093f4SDimitry Andric if (NotPrimaryExpression) 1451480093f4SDimitry Andric *NotPrimaryExpression = true; 14520b57cec5SDimitry Andric Res = ParseCXXCasts(); 14530b57cec5SDimitry Andric break; 14540b57cec5SDimitry Andric case tok::kw___builtin_bit_cast: 1455480093f4SDimitry Andric if (NotPrimaryExpression) 1456480093f4SDimitry Andric *NotPrimaryExpression = true; 14570b57cec5SDimitry Andric Res = ParseBuiltinBitCast(); 14580b57cec5SDimitry Andric break; 14590b57cec5SDimitry Andric case tok::kw_typeid: 1460480093f4SDimitry Andric if (NotPrimaryExpression) 1461480093f4SDimitry Andric *NotPrimaryExpression = true; 14620b57cec5SDimitry Andric Res = ParseCXXTypeid(); 14630b57cec5SDimitry Andric break; 14640b57cec5SDimitry Andric case tok::kw___uuidof: 1465480093f4SDimitry Andric if (NotPrimaryExpression) 1466480093f4SDimitry Andric *NotPrimaryExpression = true; 14670b57cec5SDimitry Andric Res = ParseCXXUuidof(); 14680b57cec5SDimitry Andric break; 14690b57cec5SDimitry Andric case tok::kw_this: 14700b57cec5SDimitry Andric Res = ParseCXXThis(); 14710b57cec5SDimitry Andric break; 1472fe6060f1SDimitry Andric case tok::kw___builtin_sycl_unique_stable_name: 1473fe6060f1SDimitry Andric Res = ParseSYCLUniqueStableNameExpression(); 1474fe6060f1SDimitry Andric break; 1475e8d8bef9SDimitry Andric 14760b57cec5SDimitry Andric case tok::annot_typename: 14770b57cec5SDimitry Andric if (isStartOfObjCClassMessageMissingOpenBracket()) { 14785ffd83dbSDimitry Andric TypeResult Type = getTypeAnnotation(Tok); 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 14810b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 14820b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 14830b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getLastLoc()); 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric const char *PrevSpec = nullptr; 14860b57cec5SDimitry Andric unsigned DiagID; 14870b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(), 14880b57cec5SDimitry Andric PrevSpec, DiagID, Type, 14890b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 14900b57cec5SDimitry Andric 1491e8d8bef9SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); 14920b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 14930b57cec5SDimitry Andric if (Ty.isInvalid()) 14940b57cec5SDimitry Andric break; 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric ConsumeAnnotationToken(); 14970b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 14980b57cec5SDimitry Andric Ty.get(), nullptr); 14990b57cec5SDimitry Andric break; 15000b57cec5SDimitry Andric } 15010b57cec5SDimitry Andric LLVM_FALLTHROUGH; 15020b57cec5SDimitry Andric 15030b57cec5SDimitry Andric case tok::annot_decltype: 15040b57cec5SDimitry Andric case tok::kw_char: 15050b57cec5SDimitry Andric case tok::kw_wchar_t: 15060b57cec5SDimitry Andric case tok::kw_char8_t: 15070b57cec5SDimitry Andric case tok::kw_char16_t: 15080b57cec5SDimitry Andric case tok::kw_char32_t: 15090b57cec5SDimitry Andric case tok::kw_bool: 15100b57cec5SDimitry Andric case tok::kw_short: 15110b57cec5SDimitry Andric case tok::kw_int: 15120b57cec5SDimitry Andric case tok::kw_long: 15130b57cec5SDimitry Andric case tok::kw___int64: 15140b57cec5SDimitry Andric case tok::kw___int128: 15155ffd83dbSDimitry Andric case tok::kw__ExtInt: 15160b57cec5SDimitry Andric case tok::kw_signed: 15170b57cec5SDimitry Andric case tok::kw_unsigned: 15180b57cec5SDimitry Andric case tok::kw_half: 15190b57cec5SDimitry Andric case tok::kw_float: 15200b57cec5SDimitry Andric case tok::kw_double: 15215ffd83dbSDimitry Andric case tok::kw___bf16: 15220b57cec5SDimitry Andric case tok::kw__Float16: 15230b57cec5SDimitry Andric case tok::kw___float128: 1524*349cc55cSDimitry Andric case tok::kw___ibm128: 15250b57cec5SDimitry Andric case tok::kw_void: 15260b57cec5SDimitry Andric case tok::kw_typename: 15270b57cec5SDimitry Andric case tok::kw_typeof: 15280b57cec5SDimitry Andric case tok::kw___vector: 15290b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 15300b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 15310b57cec5SDimitry Andric { 15320b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 15330b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 15340b57cec5SDimitry Andric return ExprError(); 15350b57cec5SDimitry Andric } 15360b57cec5SDimitry Andric 1537480093f4SDimitry Andric // Everything henceforth is a postfix-expression. 1538480093f4SDimitry Andric if (NotPrimaryExpression) 1539480093f4SDimitry Andric *NotPrimaryExpression = true; 1540480093f4SDimitry Andric 15410b57cec5SDimitry Andric if (SavedKind == tok::kw_typename) { 15420b57cec5SDimitry Andric // postfix-expression: typename-specifier '(' expression-list[opt] ')' 15430b57cec5SDimitry Andric // typename-specifier braced-init-list 15440b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 15450b57cec5SDimitry Andric return ExprError(); 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) 15480b57cec5SDimitry Andric // We are trying to parse a simple-type-specifier but might not get such 15490b57cec5SDimitry Andric // a token after error recovery. 15500b57cec5SDimitry Andric return ExprError(); 15510b57cec5SDimitry Andric } 15520b57cec5SDimitry Andric 15530b57cec5SDimitry Andric // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 15540b57cec5SDimitry Andric // simple-type-specifier braced-init-list 15550b57cec5SDimitry Andric // 15560b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 15570b57cec5SDimitry Andric 15580b57cec5SDimitry Andric ParseCXXSimpleTypeSpecifier(DS); 15590b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren) && 15600b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) 15610b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 15620b57cec5SDimitry Andric << DS.getSourceRange()); 15630b57cec5SDimitry Andric 15640b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) 15650b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 15660b57cec5SDimitry Andric 15670b57cec5SDimitry Andric Res = ParseCXXTypeConstructExpression(DS); 15680b57cec5SDimitry Andric break; 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 15720b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 15730b57cec5SDimitry Andric // (We can end up in this situation after tentative parsing.) 15740b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 15750b57cec5SDimitry Andric return ExprError(); 15760b57cec5SDimitry Andric if (!Tok.is(tok::annot_cxxscope)) 1577480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1578480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1579480093f4SDimitry Andric NotPrimaryExpression); 15800b57cec5SDimitry Andric 15810b57cec5SDimitry Andric Token Next = NextToken(); 15820b57cec5SDimitry Andric if (Next.is(tok::annot_template_id)) { 15830b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 15840b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 15850b57cec5SDimitry Andric // We have a qualified template-id that we know refers to a 15860b57cec5SDimitry Andric // type, translate it into a type and continue parsing as a 15870b57cec5SDimitry Andric // cast expression. 15880b57cec5SDimitry Andric CXXScopeSpec SS; 15895ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 15905ffd83dbSDimitry Andric /*ObjectHadErrors=*/false, 15910b57cec5SDimitry Andric /*EnteringContext=*/false); 159255e4f9d5SDimitry Andric AnnotateTemplateIdTokenAsType(SS); 1593480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1594480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1595480093f4SDimitry Andric NotPrimaryExpression); 15960b57cec5SDimitry Andric } 15970b57cec5SDimitry Andric } 15980b57cec5SDimitry Andric 15990b57cec5SDimitry Andric // Parse as an id-expression. 16000b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 16010b57cec5SDimitry Andric break; 16020b57cec5SDimitry Andric } 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andric case tok::annot_template_id: { // [C++] template-id 16050b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 16060b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 16070b57cec5SDimitry Andric // We have a template-id that we know refers to a type, 16080b57cec5SDimitry Andric // translate it into a type and continue parsing as a cast 16090b57cec5SDimitry Andric // expression. 161055e4f9d5SDimitry Andric CXXScopeSpec SS; 161155e4f9d5SDimitry Andric AnnotateTemplateIdTokenAsType(SS); 1612480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1613480093f4SDimitry Andric NotCastExpr, isTypeCast, isVectorLiteral, 1614480093f4SDimitry Andric NotPrimaryExpression); 16150b57cec5SDimitry Andric } 16160b57cec5SDimitry Andric 16170b57cec5SDimitry Andric // Fall through to treat the template-id as an id-expression. 16180b57cec5SDimitry Andric LLVM_FALLTHROUGH; 16190b57cec5SDimitry Andric } 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 16220b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 16230b57cec5SDimitry Andric break; 16240b57cec5SDimitry Andric 16250b57cec5SDimitry Andric case tok::coloncolon: { 16260b57cec5SDimitry Andric // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 16270b57cec5SDimitry Andric // annotates the token, tail recurse. 16280b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16290b57cec5SDimitry Andric return ExprError(); 16300b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) 1631480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1632480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 16330b57cec5SDimitry Andric 16340b57cec5SDimitry Andric // ::new -> [C++] new-expression 16350b57cec5SDimitry Andric // ::delete -> [C++] delete-expression 16360b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 1637480093f4SDimitry Andric if (Tok.is(tok::kw_new)) { 1638480093f4SDimitry Andric if (NotPrimaryExpression) 1639480093f4SDimitry Andric *NotPrimaryExpression = true; 16405ffd83dbSDimitry Andric Res = ParseCXXNewExpression(true, CCLoc); 16415ffd83dbSDimitry Andric AllowSuffix = false; 16425ffd83dbSDimitry Andric break; 1643480093f4SDimitry Andric } 1644480093f4SDimitry Andric if (Tok.is(tok::kw_delete)) { 1645480093f4SDimitry Andric if (NotPrimaryExpression) 1646480093f4SDimitry Andric *NotPrimaryExpression = true; 16475ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(true, CCLoc); 16485ffd83dbSDimitry Andric AllowSuffix = false; 16495ffd83dbSDimitry Andric break; 1650480093f4SDimitry Andric } 16510b57cec5SDimitry Andric 16520b57cec5SDimitry Andric // This is not a type name or scope specifier, it is an invalid expression. 16530b57cec5SDimitry Andric Diag(CCLoc, diag::err_expected_expression); 16540b57cec5SDimitry Andric return ExprError(); 16550b57cec5SDimitry Andric } 16560b57cec5SDimitry Andric 16570b57cec5SDimitry Andric case tok::kw_new: // [C++] new-expression 1658480093f4SDimitry Andric if (NotPrimaryExpression) 1659480093f4SDimitry Andric *NotPrimaryExpression = true; 16605ffd83dbSDimitry Andric Res = ParseCXXNewExpression(false, Tok.getLocation()); 16615ffd83dbSDimitry Andric AllowSuffix = false; 16625ffd83dbSDimitry Andric break; 16630b57cec5SDimitry Andric 16640b57cec5SDimitry Andric case tok::kw_delete: // [C++] delete-expression 1665480093f4SDimitry Andric if (NotPrimaryExpression) 1666480093f4SDimitry Andric *NotPrimaryExpression = true; 16675ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(false, Tok.getLocation()); 16685ffd83dbSDimitry Andric AllowSuffix = false; 16695ffd83dbSDimitry Andric break; 16700b57cec5SDimitry Andric 167155e4f9d5SDimitry Andric case tok::kw_requires: // [C++2a] requires-expression 16725ffd83dbSDimitry Andric Res = ParseRequiresExpression(); 16735ffd83dbSDimitry Andric AllowSuffix = false; 16745ffd83dbSDimitry Andric break; 167555e4f9d5SDimitry Andric 16760b57cec5SDimitry Andric case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' 1677480093f4SDimitry Andric if (NotPrimaryExpression) 1678480093f4SDimitry Andric *NotPrimaryExpression = true; 16790b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_noexcept_expr); 16800b57cec5SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 16810b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 16820b57cec5SDimitry Andric 16830b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept")) 16840b57cec5SDimitry Andric return ExprError(); 16850b57cec5SDimitry Andric // C++11 [expr.unary.noexcept]p1: 16860b57cec5SDimitry Andric // The noexcept operator determines whether the evaluation of its operand, 16870b57cec5SDimitry Andric // which is an unevaluated operand, can throw an exception. 16880b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 16890b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 16905ffd83dbSDimitry Andric Res = ParseExpression(); 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric T.consumeClose(); 16930b57cec5SDimitry Andric 16945ffd83dbSDimitry Andric if (!Res.isInvalid()) 16955ffd83dbSDimitry Andric Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(), 16965ffd83dbSDimitry Andric T.getCloseLocation()); 16975ffd83dbSDimitry Andric AllowSuffix = false; 16985ffd83dbSDimitry Andric break; 16990b57cec5SDimitry Andric } 17000b57cec5SDimitry Andric 17010b57cec5SDimitry Andric #define TYPE_TRAIT(N,Spelling,K) \ 17020b57cec5SDimitry Andric case tok::kw_##Spelling: 17030b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 17045ffd83dbSDimitry Andric Res = ParseTypeTrait(); 17055ffd83dbSDimitry Andric break; 17060b57cec5SDimitry Andric 17070b57cec5SDimitry Andric case tok::kw___array_rank: 17080b57cec5SDimitry Andric case tok::kw___array_extent: 1709480093f4SDimitry Andric if (NotPrimaryExpression) 1710480093f4SDimitry Andric *NotPrimaryExpression = true; 17115ffd83dbSDimitry Andric Res = ParseArrayTypeTrait(); 17125ffd83dbSDimitry Andric break; 17130b57cec5SDimitry Andric 17140b57cec5SDimitry Andric case tok::kw___is_lvalue_expr: 17150b57cec5SDimitry Andric case tok::kw___is_rvalue_expr: 1716480093f4SDimitry Andric if (NotPrimaryExpression) 1717480093f4SDimitry Andric *NotPrimaryExpression = true; 17185ffd83dbSDimitry Andric Res = ParseExpressionTrait(); 17195ffd83dbSDimitry Andric break; 17200b57cec5SDimitry Andric 17210b57cec5SDimitry Andric case tok::at: { 1722480093f4SDimitry Andric if (NotPrimaryExpression) 1723480093f4SDimitry Andric *NotPrimaryExpression = true; 17240b57cec5SDimitry Andric SourceLocation AtLoc = ConsumeToken(); 17250b57cec5SDimitry Andric return ParseObjCAtExpression(AtLoc); 17260b57cec5SDimitry Andric } 17270b57cec5SDimitry Andric case tok::caret: 17280b57cec5SDimitry Andric Res = ParseBlockLiteralExpression(); 17290b57cec5SDimitry Andric break; 17300b57cec5SDimitry Andric case tok::code_completion: { 1731fe6060f1SDimitry Andric cutOffParsing(); 17320b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 17330b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 17340b57cec5SDimitry Andric return ExprError(); 17350b57cec5SDimitry Andric } 17360b57cec5SDimitry Andric case tok::l_square: 17370b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11) { 17380b57cec5SDimitry Andric if (getLangOpts().ObjC) { 17390b57cec5SDimitry Andric // C++11 lambda expressions and Objective-C message sends both start with a 17400b57cec5SDimitry Andric // square bracket. There are three possibilities here: 17410b57cec5SDimitry Andric // we have a valid lambda expression, we have an invalid lambda 17420b57cec5SDimitry Andric // expression, or we have something that doesn't appear to be a lambda. 17430b57cec5SDimitry Andric // If we're in the last case, we fall back to ParseObjCMessageExpression. 17440b57cec5SDimitry Andric Res = TryParseLambdaExpression(); 1745480093f4SDimitry Andric if (!Res.isInvalid() && !Res.get()) { 1746480093f4SDimitry Andric // We assume Objective-C++ message expressions are not 1747480093f4SDimitry Andric // primary-expressions. 1748480093f4SDimitry Andric if (NotPrimaryExpression) 1749480093f4SDimitry Andric *NotPrimaryExpression = true; 17500b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 1751480093f4SDimitry Andric } 17520b57cec5SDimitry Andric break; 17530b57cec5SDimitry Andric } 17540b57cec5SDimitry Andric Res = ParseLambdaExpression(); 17550b57cec5SDimitry Andric break; 17560b57cec5SDimitry Andric } 17570b57cec5SDimitry Andric if (getLangOpts().ObjC) { 17580b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 17590b57cec5SDimitry Andric break; 17600b57cec5SDimitry Andric } 17610b57cec5SDimitry Andric LLVM_FALLTHROUGH; 17620b57cec5SDimitry Andric default: 17630b57cec5SDimitry Andric NotCastExpr = true; 17640b57cec5SDimitry Andric return ExprError(); 17650b57cec5SDimitry Andric } 17660b57cec5SDimitry Andric 17670b57cec5SDimitry Andric // Check to see whether Res is a function designator only. If it is and we 17680b57cec5SDimitry Andric // are compiling for OpenCL, we need to return an error as this implies 17690b57cec5SDimitry Andric // that the address of the function is being taken, which is illegal in CL. 17700b57cec5SDimitry Andric 1771480093f4SDimitry Andric if (ParseKind == PrimaryExprOnly) 1772480093f4SDimitry Andric // This is strictly a primary-expression - no postfix-expr pieces should be 1773480093f4SDimitry Andric // parsed. 1774480093f4SDimitry Andric return Res; 1775480093f4SDimitry Andric 17765ffd83dbSDimitry Andric if (!AllowSuffix) { 17775ffd83dbSDimitry Andric // FIXME: Don't parse a primary-expression suffix if we encountered a parse 17785ffd83dbSDimitry Andric // error already. 17795ffd83dbSDimitry Andric if (Res.isInvalid()) 17805ffd83dbSDimitry Andric return Res; 17815ffd83dbSDimitry Andric 17825ffd83dbSDimitry Andric switch (Tok.getKind()) { 17835ffd83dbSDimitry Andric case tok::l_square: 17845ffd83dbSDimitry Andric case tok::l_paren: 17855ffd83dbSDimitry Andric case tok::plusplus: 17865ffd83dbSDimitry Andric case tok::minusminus: 17875ffd83dbSDimitry Andric // "expected ';'" or similar is probably the right diagnostic here. Let 17885ffd83dbSDimitry Andric // the caller decide what to do. 17895ffd83dbSDimitry Andric if (Tok.isAtStartOfLine()) 17905ffd83dbSDimitry Andric return Res; 17915ffd83dbSDimitry Andric 17925ffd83dbSDimitry Andric LLVM_FALLTHROUGH; 17935ffd83dbSDimitry Andric case tok::period: 17945ffd83dbSDimitry Andric case tok::arrow: 17955ffd83dbSDimitry Andric break; 17965ffd83dbSDimitry Andric 17975ffd83dbSDimitry Andric default: 17985ffd83dbSDimitry Andric return Res; 17995ffd83dbSDimitry Andric } 18005ffd83dbSDimitry Andric 18015ffd83dbSDimitry Andric // This was a unary-expression for which a postfix-expression suffix is 18025ffd83dbSDimitry Andric // not permitted by the grammar (eg, a sizeof expression or 18035ffd83dbSDimitry Andric // new-expression or similar). Diagnose but parse the suffix anyway. 18045ffd83dbSDimitry Andric Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens) 18055ffd83dbSDimitry Andric << Tok.getKind() << Res.get()->getSourceRange() 18065ffd83dbSDimitry Andric << FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(") 18075ffd83dbSDimitry Andric << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation), 18085ffd83dbSDimitry Andric ")"); 18095ffd83dbSDimitry Andric } 18105ffd83dbSDimitry Andric 18110b57cec5SDimitry Andric // These can be followed by postfix-expr pieces. 18120b57cec5SDimitry Andric PreferredType = SavedType; 18130b57cec5SDimitry Andric Res = ParsePostfixExpressionSuffix(Res); 1814fe6060f1SDimitry Andric if (getLangOpts().OpenCL && 1815fe6060f1SDimitry Andric !getActions().getOpenCLOptions().isAvailableOption( 1816fe6060f1SDimitry Andric "__cl_clang_function_pointers", getLangOpts())) 18170b57cec5SDimitry Andric if (Expr *PostfixExpr = Res.get()) { 18180b57cec5SDimitry Andric QualType Ty = PostfixExpr->getType(); 18190b57cec5SDimitry Andric if (!Ty.isNull() && Ty->isFunctionType()) { 18200b57cec5SDimitry Andric Diag(PostfixExpr->getExprLoc(), 18210b57cec5SDimitry Andric diag::err_opencl_taking_function_address_parser); 18220b57cec5SDimitry Andric return ExprError(); 18230b57cec5SDimitry Andric } 18240b57cec5SDimitry Andric } 18250b57cec5SDimitry Andric 18260b57cec5SDimitry Andric return Res; 18270b57cec5SDimitry Andric } 18280b57cec5SDimitry Andric 18290b57cec5SDimitry Andric /// Once the leading part of a postfix-expression is parsed, this 18300b57cec5SDimitry Andric /// method parses any suffixes that apply. 18310b57cec5SDimitry Andric /// 18320b57cec5SDimitry Andric /// \verbatim 18330b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 18340b57cec5SDimitry Andric /// primary-expression 18350b57cec5SDimitry Andric /// postfix-expression '[' expression ']' 18360b57cec5SDimitry Andric /// postfix-expression '[' braced-init-list ']' 18370b57cec5SDimitry Andric /// postfix-expression '(' argument-expression-list[opt] ')' 18380b57cec5SDimitry Andric /// postfix-expression '.' identifier 18390b57cec5SDimitry Andric /// postfix-expression '->' identifier 18400b57cec5SDimitry Andric /// postfix-expression '++' 18410b57cec5SDimitry Andric /// postfix-expression '--' 18420b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 18430b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 18440b57cec5SDimitry Andric /// 18450b57cec5SDimitry Andric /// argument-expression-list: [C99 6.5.2] 18460b57cec5SDimitry Andric /// argument-expression ...[opt] 18470b57cec5SDimitry Andric /// argument-expression-list ',' assignment-expression ...[opt] 18480b57cec5SDimitry Andric /// \endverbatim 18490b57cec5SDimitry Andric ExprResult 18500b57cec5SDimitry Andric Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { 18510b57cec5SDimitry Andric // Now that the primary-expression piece of the postfix-expression has been 18520b57cec5SDimitry Andric // parsed, see if there are any postfix-expression pieces here. 18530b57cec5SDimitry Andric SourceLocation Loc; 18540b57cec5SDimitry Andric auto SavedType = PreferredType; 18550b57cec5SDimitry Andric while (1) { 18560b57cec5SDimitry Andric // Each iteration relies on preferred type for the whole expression. 18570b57cec5SDimitry Andric PreferredType = SavedType; 18580b57cec5SDimitry Andric switch (Tok.getKind()) { 18590b57cec5SDimitry Andric case tok::code_completion: 18600b57cec5SDimitry Andric if (InMessageExpression) 18610b57cec5SDimitry Andric return LHS; 18620b57cec5SDimitry Andric 1863fe6060f1SDimitry Andric cutOffParsing(); 18640b57cec5SDimitry Andric Actions.CodeCompletePostfixExpression( 18650b57cec5SDimitry Andric getCurScope(), LHS, PreferredType.get(Tok.getLocation())); 18660b57cec5SDimitry Andric return ExprError(); 18670b57cec5SDimitry Andric 18680b57cec5SDimitry Andric case tok::identifier: 18690b57cec5SDimitry Andric // If we see identifier: after an expression, and we're not already in a 18700b57cec5SDimitry Andric // message send, then this is probably a message send with a missing 18710b57cec5SDimitry Andric // opening bracket '['. 18720b57cec5SDimitry Andric if (getLangOpts().ObjC && !InMessageExpression && 18730b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 18740b57cec5SDimitry Andric LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 18750b57cec5SDimitry Andric nullptr, LHS.get()); 18760b57cec5SDimitry Andric break; 18770b57cec5SDimitry Andric } 18780b57cec5SDimitry Andric // Fall through; this isn't a message send. 18790b57cec5SDimitry Andric LLVM_FALLTHROUGH; 18800b57cec5SDimitry Andric 18810b57cec5SDimitry Andric default: // Not a postfix-expression suffix. 18820b57cec5SDimitry Andric return LHS; 18830b57cec5SDimitry Andric case tok::l_square: { // postfix-expression: p-e '[' expression ']' 18840b57cec5SDimitry Andric // If we have a array postfix expression that starts on a new line and 18850b57cec5SDimitry Andric // Objective-C is enabled, it is highly likely that the user forgot a 18860b57cec5SDimitry Andric // semicolon after the base expression and that the array postfix-expr is 18870b57cec5SDimitry Andric // actually another message send. In this case, do some look-ahead to see 18880b57cec5SDimitry Andric // if the contents of the square brackets are obviously not a valid 18890b57cec5SDimitry Andric // expression and recover by pretending there is no suffix. 18900b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.isAtStartOfLine() && 18910b57cec5SDimitry Andric isSimpleObjCMessageExpression()) 18920b57cec5SDimitry Andric return LHS; 18930b57cec5SDimitry Andric 18940b57cec5SDimitry Andric // Reject array indices starting with a lambda-expression. '[[' is 18950b57cec5SDimitry Andric // reserved for attributes. 18960b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) { 18970b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 18980b57cec5SDimitry Andric return ExprError(); 18990b57cec5SDimitry Andric } 19000b57cec5SDimitry Andric 19010b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 19020b57cec5SDimitry Andric T.consumeOpen(); 19030b57cec5SDimitry Andric Loc = T.getOpenLocation(); 19045ffd83dbSDimitry Andric ExprResult Idx, Length, Stride; 19055ffd83dbSDimitry Andric SourceLocation ColonLocFirst, ColonLocSecond; 19060b57cec5SDimitry Andric PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); 19070b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 19080b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 19090b57cec5SDimitry Andric Idx = ParseBraceInitializer(); 19100b57cec5SDimitry Andric } else if (getLangOpts().OpenMP) { 19110b57cec5SDimitry Andric ColonProtectionRAIIObject RAII(*this); 19120b57cec5SDimitry Andric // Parse [: or [ expr or [ expr : 19130b57cec5SDimitry Andric if (!Tok.is(tok::colon)) { 19140b57cec5SDimitry Andric // [ expr 19150b57cec5SDimitry Andric Idx = ParseExpression(); 19160b57cec5SDimitry Andric } 19170b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 19180b57cec5SDimitry Andric // Consume ':' 19195ffd83dbSDimitry Andric ColonLocFirst = ConsumeToken(); 19205ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square) && 19215ffd83dbSDimitry Andric (getLangOpts().OpenMP < 50 || 19225ffd83dbSDimitry Andric ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) 19230b57cec5SDimitry Andric Length = ParseExpression(); 19240b57cec5SDimitry Andric } 19255ffd83dbSDimitry Andric if (getLangOpts().OpenMP >= 50 && 19265ffd83dbSDimitry Andric (OMPClauseKind == llvm::omp::Clause::OMPC_to || 19275ffd83dbSDimitry Andric OMPClauseKind == llvm::omp::Clause::OMPC_from) && 19285ffd83dbSDimitry Andric Tok.is(tok::colon)) { 19295ffd83dbSDimitry Andric // Consume ':' 19305ffd83dbSDimitry Andric ColonLocSecond = ConsumeToken(); 19315ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) { 19325ffd83dbSDimitry Andric Stride = ParseExpression(); 19335ffd83dbSDimitry Andric } 19345ffd83dbSDimitry Andric } 19350b57cec5SDimitry Andric } else 19360b57cec5SDimitry Andric Idx = ParseExpression(); 19370b57cec5SDimitry Andric 19380b57cec5SDimitry Andric SourceLocation RLoc = Tok.getLocation(); 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 19410b57cec5SDimitry Andric Idx = Actions.CorrectDelayedTyposInExpr(Idx); 19420b57cec5SDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(Length); 19430b57cec5SDimitry Andric if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() && 19445ffd83dbSDimitry Andric !Stride.isInvalid() && Tok.is(tok::r_square)) { 19455ffd83dbSDimitry Andric if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { 19465ffd83dbSDimitry Andric LHS = Actions.ActOnOMPArraySectionExpr( 19475ffd83dbSDimitry Andric LHS.get(), Loc, Idx.get(), ColonLocFirst, ColonLocSecond, 19485ffd83dbSDimitry Andric Length.get(), Stride.get(), RLoc); 19490b57cec5SDimitry Andric } else { 19500b57cec5SDimitry Andric LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, 19510b57cec5SDimitry Andric Idx.get(), RLoc); 19520b57cec5SDimitry Andric } 19530b57cec5SDimitry Andric } else { 19540b57cec5SDimitry Andric LHS = ExprError(); 19550b57cec5SDimitry Andric Idx = ExprError(); 19560b57cec5SDimitry Andric } 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric // Match the ']'. 19590b57cec5SDimitry Andric T.consumeClose(); 19600b57cec5SDimitry Andric break; 19610b57cec5SDimitry Andric } 19620b57cec5SDimitry Andric 19630b57cec5SDimitry Andric case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' 19640b57cec5SDimitry Andric case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>' 19650b57cec5SDimitry Andric // '(' argument-expression-list[opt] ')' 19660b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 19670b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 19680b57cec5SDimitry Andric 19690b57cec5SDimitry Andric Expr *ExecConfig = nullptr; 19700b57cec5SDimitry Andric 19710b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 19720b57cec5SDimitry Andric 19730b57cec5SDimitry Andric if (OpKind == tok::lesslessless) { 19740b57cec5SDimitry Andric ExprVector ExecConfigExprs; 19750b57cec5SDimitry Andric CommaLocsTy ExecConfigCommaLocs; 19760b57cec5SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 19770b57cec5SDimitry Andric 19780b57cec5SDimitry Andric if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { 19790b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 19800b57cec5SDimitry Andric LHS = ExprError(); 19810b57cec5SDimitry Andric } 19820b57cec5SDimitry Andric 19830b57cec5SDimitry Andric SourceLocation CloseLoc; 19840b57cec5SDimitry Andric if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) { 19850b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 19860b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 19870b57cec5SDimitry Andric } else { 19880b57cec5SDimitry Andric // There was an error closing the brackets 19890b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::greatergreatergreater; 19900b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::lesslessless; 19910b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 19920b57cec5SDimitry Andric LHS = ExprError(); 19930b57cec5SDimitry Andric } 19940b57cec5SDimitry Andric 19950b57cec5SDimitry Andric if (!LHS.isInvalid()) { 19960b57cec5SDimitry Andric if (ExpectAndConsume(tok::l_paren)) 19970b57cec5SDimitry Andric LHS = ExprError(); 19980b57cec5SDimitry Andric else 19990b57cec5SDimitry Andric Loc = PrevTokLocation; 20000b57cec5SDimitry Andric } 20010b57cec5SDimitry Andric 20020b57cec5SDimitry Andric if (!LHS.isInvalid()) { 20030b57cec5SDimitry Andric ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), 20040b57cec5SDimitry Andric OpenLoc, 20050b57cec5SDimitry Andric ExecConfigExprs, 20060b57cec5SDimitry Andric CloseLoc); 20070b57cec5SDimitry Andric if (ECResult.isInvalid()) 20080b57cec5SDimitry Andric LHS = ExprError(); 20090b57cec5SDimitry Andric else 20100b57cec5SDimitry Andric ExecConfig = ECResult.get(); 20110b57cec5SDimitry Andric } 20120b57cec5SDimitry Andric } else { 20130b57cec5SDimitry Andric PT.consumeOpen(); 20140b57cec5SDimitry Andric Loc = PT.getOpenLocation(); 20150b57cec5SDimitry Andric } 20160b57cec5SDimitry Andric 20170b57cec5SDimitry Andric ExprVector ArgExprs; 20180b57cec5SDimitry Andric CommaLocsTy CommaLocs; 20190b57cec5SDimitry Andric auto RunSignatureHelp = [&]() -> QualType { 20200b57cec5SDimitry Andric QualType PreferredType = Actions.ProduceCallSignatureHelp( 20210b57cec5SDimitry Andric getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation()); 20220b57cec5SDimitry Andric CalledSignatureHelp = true; 20230b57cec5SDimitry Andric return PreferredType; 20240b57cec5SDimitry Andric }; 20250b57cec5SDimitry Andric if (OpKind == tok::l_paren || !LHS.isInvalid()) { 20260b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 20270b57cec5SDimitry Andric if (ParseExpressionList(ArgExprs, CommaLocs, [&] { 20280b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 20290b57cec5SDimitry Andric RunSignatureHelp); 20300b57cec5SDimitry Andric })) { 20310b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 20320b57cec5SDimitry Andric // If we got an error when parsing expression list, we don't call 20330b57cec5SDimitry Andric // the CodeCompleteCall handler inside the parser. So call it here 20340b57cec5SDimitry Andric // to make sure we get overload suggestions even when we are in the 20350b57cec5SDimitry Andric // middle of a parameter. 20360b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 20370b57cec5SDimitry Andric RunSignatureHelp(); 20380b57cec5SDimitry Andric LHS = ExprError(); 20390b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 20400b57cec5SDimitry Andric for (auto &E : ArgExprs) 20410b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 20420b57cec5SDimitry Andric } 20430b57cec5SDimitry Andric } 20440b57cec5SDimitry Andric } 20450b57cec5SDimitry Andric 20460b57cec5SDimitry Andric // Match the ')'. 20470b57cec5SDimitry Andric if (LHS.isInvalid()) { 20480b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 20490b57cec5SDimitry Andric } else if (Tok.isNot(tok::r_paren)) { 20500b57cec5SDimitry Andric bool HadDelayedTypo = false; 20510b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get()) 20520b57cec5SDimitry Andric HadDelayedTypo = true; 20530b57cec5SDimitry Andric for (auto &E : ArgExprs) 20540b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(E).get() != E) 20550b57cec5SDimitry Andric HadDelayedTypo = true; 20560b57cec5SDimitry Andric // If there were delayed typos in the LHS or ArgExprs, call SkipUntil 20570b57cec5SDimitry Andric // instead of PT.consumeClose() to avoid emitting extra diagnostics for 20580b57cec5SDimitry Andric // the unmatched l_paren. 20590b57cec5SDimitry Andric if (HadDelayedTypo) 20600b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 20610b57cec5SDimitry Andric else 20620b57cec5SDimitry Andric PT.consumeClose(); 20630b57cec5SDimitry Andric LHS = ExprError(); 20640b57cec5SDimitry Andric } else { 20655ffd83dbSDimitry Andric assert( 20665ffd83dbSDimitry Andric (ArgExprs.size() == 0 || ArgExprs.size() - 1 == CommaLocs.size()) && 20670b57cec5SDimitry Andric "Unexpected number of commas!"); 20685ffd83dbSDimitry Andric Expr *Fn = LHS.get(); 20695ffd83dbSDimitry Andric SourceLocation RParLoc = Tok.getLocation(); 20705ffd83dbSDimitry Andric LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc, 20710b57cec5SDimitry Andric ExecConfig); 20725ffd83dbSDimitry Andric if (LHS.isInvalid()) { 20735ffd83dbSDimitry Andric ArgExprs.insert(ArgExprs.begin(), Fn); 20745ffd83dbSDimitry Andric LHS = 20755ffd83dbSDimitry Andric Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs); 20765ffd83dbSDimitry Andric } 20770b57cec5SDimitry Andric PT.consumeClose(); 20780b57cec5SDimitry Andric } 20790b57cec5SDimitry Andric 20800b57cec5SDimitry Andric break; 20810b57cec5SDimitry Andric } 20820b57cec5SDimitry Andric case tok::arrow: 20830b57cec5SDimitry Andric case tok::period: { 20840b57cec5SDimitry Andric // postfix-expression: p-e '->' template[opt] id-expression 20850b57cec5SDimitry Andric // postfix-expression: p-e '.' template[opt] id-expression 20860b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 20870b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 20880b57cec5SDimitry Andric 20890b57cec5SDimitry Andric CXXScopeSpec SS; 20900b57cec5SDimitry Andric ParsedType ObjectType; 20910b57cec5SDimitry Andric bool MayBePseudoDestructor = false; 20920b57cec5SDimitry Andric Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; 20930b57cec5SDimitry Andric 20940b57cec5SDimitry Andric PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS); 20950b57cec5SDimitry Andric 20960b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { 20970b57cec5SDimitry Andric Expr *Base = OrigLHS; 20980b57cec5SDimitry Andric const Type* BaseType = Base->getType().getTypePtrOrNull(); 20990b57cec5SDimitry Andric if (BaseType && Tok.is(tok::l_paren) && 21000b57cec5SDimitry Andric (BaseType->isFunctionType() || 21010b57cec5SDimitry Andric BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { 21020b57cec5SDimitry Andric Diag(OpLoc, diag::err_function_is_not_record) 21030b57cec5SDimitry Andric << OpKind << Base->getSourceRange() 21040b57cec5SDimitry Andric << FixItHint::CreateRemoval(OpLoc); 21050b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Base); 21060b57cec5SDimitry Andric } 21070b57cec5SDimitry Andric 21085ffd83dbSDimitry Andric LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, 21095ffd83dbSDimitry Andric OpKind, ObjectType, 21100b57cec5SDimitry Andric MayBePseudoDestructor); 21115ffd83dbSDimitry Andric if (LHS.isInvalid()) { 21125ffd83dbSDimitry Andric // Clang will try to perform expression based completion as a 21135ffd83dbSDimitry Andric // fallback, which is confusing in case of member references. So we 21145ffd83dbSDimitry Andric // stop here without any completions. 21155ffd83dbSDimitry Andric if (Tok.is(tok::code_completion)) { 21165ffd83dbSDimitry Andric cutOffParsing(); 21175ffd83dbSDimitry Andric return ExprError(); 21185ffd83dbSDimitry Andric } 21190b57cec5SDimitry Andric break; 21205ffd83dbSDimitry Andric } 21215ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier( 21225ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 21235ffd83dbSDimitry Andric /*EnteringContext=*/false, &MayBePseudoDestructor); 21240b57cec5SDimitry Andric if (SS.isNotEmpty()) 21250b57cec5SDimitry Andric ObjectType = nullptr; 21260b57cec5SDimitry Andric } 21270b57cec5SDimitry Andric 21280b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 21290b57cec5SDimitry Andric tok::TokenKind CorrectedOpKind = 21300b57cec5SDimitry Andric OpKind == tok::arrow ? tok::period : tok::arrow; 21310b57cec5SDimitry Andric ExprResult CorrectedLHS(/*Invalid=*/true); 21320b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && OrigLHS) { 2133a7dea167SDimitry Andric // FIXME: Creating a TentativeAnalysisScope from outside Sema is a 2134a7dea167SDimitry Andric // hack. 2135a7dea167SDimitry Andric Sema::TentativeAnalysisScope Trap(Actions); 21360b57cec5SDimitry Andric CorrectedLHS = Actions.ActOnStartCXXMemberReference( 21370b57cec5SDimitry Andric getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType, 21380b57cec5SDimitry Andric MayBePseudoDestructor); 21390b57cec5SDimitry Andric } 21400b57cec5SDimitry Andric 21410b57cec5SDimitry Andric Expr *Base = LHS.get(); 21420b57cec5SDimitry Andric Expr *CorrectedBase = CorrectedLHS.get(); 21430b57cec5SDimitry Andric if (!CorrectedBase && !getLangOpts().CPlusPlus) 21440b57cec5SDimitry Andric CorrectedBase = Base; 21450b57cec5SDimitry Andric 21460b57cec5SDimitry Andric // Code completion for a member access expression. 2147fe6060f1SDimitry Andric cutOffParsing(); 21480b57cec5SDimitry Andric Actions.CodeCompleteMemberReferenceExpr( 21490b57cec5SDimitry Andric getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, 21500b57cec5SDimitry Andric Base && ExprStatementTokLoc == Base->getBeginLoc(), 21510b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 21520b57cec5SDimitry Andric 21530b57cec5SDimitry Andric return ExprError(); 21540b57cec5SDimitry Andric } 21550b57cec5SDimitry Andric 21560b57cec5SDimitry Andric if (MayBePseudoDestructor && !LHS.isInvalid()) { 21570b57cec5SDimitry Andric LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 21580b57cec5SDimitry Andric ObjectType); 21590b57cec5SDimitry Andric break; 21600b57cec5SDimitry Andric } 21610b57cec5SDimitry Andric 21620b57cec5SDimitry Andric // Either the action has told us that this cannot be a 21630b57cec5SDimitry Andric // pseudo-destructor expression (based on the type of base 21640b57cec5SDimitry Andric // expression), or we didn't see a '~' in the right place. We 21650b57cec5SDimitry Andric // can still parse a destructor name here, but in that case it 21660b57cec5SDimitry Andric // names a real destructor. 21670b57cec5SDimitry Andric // Allow explicit constructor calls in Microsoft mode. 21680b57cec5SDimitry Andric // FIXME: Add support for explicit call of template constructor. 21690b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 21700b57cec5SDimitry Andric UnqualifiedId Name; 21710b57cec5SDimitry Andric if (getLangOpts().ObjC && OpKind == tok::period && 21720b57cec5SDimitry Andric Tok.is(tok::kw_class)) { 21730b57cec5SDimitry Andric // Objective-C++: 21740b57cec5SDimitry Andric // After a '.' in a member access expression, treat the keyword 21750b57cec5SDimitry Andric // 'class' as if it were an identifier. 21760b57cec5SDimitry Andric // 21770b57cec5SDimitry Andric // This hack allows property access to the 'class' method because it is 21780b57cec5SDimitry Andric // such a common method name. For other C++ keywords that are 21790b57cec5SDimitry Andric // Objective-C method names, one must use the message send syntax. 21800b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 21810b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 21820b57cec5SDimitry Andric Name.setIdentifier(Id, Loc); 21835ffd83dbSDimitry Andric } else if (ParseUnqualifiedId( 21845ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 21850b57cec5SDimitry Andric /*EnteringContext=*/false, 21860b57cec5SDimitry Andric /*AllowDestructorName=*/true, 21870b57cec5SDimitry Andric /*AllowConstructorName=*/ 21885ffd83dbSDimitry Andric getLangOpts().MicrosoftExt && SS.isNotEmpty(), 21895ffd83dbSDimitry Andric /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) { 21900b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 21910b57cec5SDimitry Andric LHS = ExprError(); 21920b57cec5SDimitry Andric } 21930b57cec5SDimitry Andric 21940b57cec5SDimitry Andric if (!LHS.isInvalid()) 21950b57cec5SDimitry Andric LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 21960b57cec5SDimitry Andric OpKind, SS, TemplateKWLoc, Name, 21970b57cec5SDimitry Andric CurParsedObjCImpl ? CurParsedObjCImpl->Dcl 21980b57cec5SDimitry Andric : nullptr); 21995ffd83dbSDimitry Andric if (!LHS.isInvalid()) { 22005ffd83dbSDimitry Andric if (Tok.is(tok::less)) 22010b57cec5SDimitry Andric checkPotentialAngleBracket(LHS); 22025ffd83dbSDimitry Andric } else if (OrigLHS && Name.isValid()) { 22035ffd83dbSDimitry Andric // Preserve the LHS if the RHS is an invalid member. 22045ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), 22055ffd83dbSDimitry Andric Name.getEndLoc(), {OrigLHS}); 22065ffd83dbSDimitry Andric } 22070b57cec5SDimitry Andric break; 22080b57cec5SDimitry Andric } 22090b57cec5SDimitry Andric case tok::plusplus: // postfix-expression: postfix-expression '++' 22100b57cec5SDimitry Andric case tok::minusminus: // postfix-expression: postfix-expression '--' 22110b57cec5SDimitry Andric if (!LHS.isInvalid()) { 22125ffd83dbSDimitry Andric Expr *Arg = LHS.get(); 22130b57cec5SDimitry Andric LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), 22145ffd83dbSDimitry Andric Tok.getKind(), Arg); 22155ffd83dbSDimitry Andric if (LHS.isInvalid()) 22165ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(), 22175ffd83dbSDimitry Andric Tok.getLocation(), Arg); 22180b57cec5SDimitry Andric } 22190b57cec5SDimitry Andric ConsumeToken(); 22200b57cec5SDimitry Andric break; 22210b57cec5SDimitry Andric } 22220b57cec5SDimitry Andric } 22230b57cec5SDimitry Andric } 22240b57cec5SDimitry Andric 22250b57cec5SDimitry Andric /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/ 22260b57cec5SDimitry Andric /// vec_step and we are at the start of an expression or a parenthesized 22270b57cec5SDimitry Andric /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the 22280b57cec5SDimitry Andric /// expression (isCastExpr == false) or the type (isCastExpr == true). 22290b57cec5SDimitry Andric /// 22300b57cec5SDimitry Andric /// \verbatim 22310b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 22320b57cec5SDimitry Andric /// 'sizeof' unary-expression 22330b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 22340b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 22350b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 22360b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 22370b57cec5SDimitry Andric /// [C++0x] 'alignof' '(' type-id ')' 22380b57cec5SDimitry Andric /// 22390b57cec5SDimitry Andric /// [GNU] typeof-specifier: 22400b57cec5SDimitry Andric /// typeof ( expressions ) 22410b57cec5SDimitry Andric /// typeof ( type-name ) 22420b57cec5SDimitry Andric /// [GNU/C++] typeof unary-expression 22430b57cec5SDimitry Andric /// 22440b57cec5SDimitry Andric /// [OpenCL 1.1 6.11.12] vec_step built-in function: 22450b57cec5SDimitry Andric /// vec_step ( expressions ) 22460b57cec5SDimitry Andric /// vec_step ( type-name ) 22470b57cec5SDimitry Andric /// \endverbatim 22480b57cec5SDimitry Andric ExprResult 22490b57cec5SDimitry Andric Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, 22500b57cec5SDimitry Andric bool &isCastExpr, 22510b57cec5SDimitry Andric ParsedType &CastTy, 22520b57cec5SDimitry Andric SourceRange &CastRange) { 22530b57cec5SDimitry Andric 22540b57cec5SDimitry Andric assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, 22550b57cec5SDimitry Andric tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, 22560b57cec5SDimitry Andric tok::kw___builtin_omp_required_simd_align) && 22570b57cec5SDimitry Andric "Not a typeof/sizeof/alignof/vec_step expression!"); 22580b57cec5SDimitry Andric 22590b57cec5SDimitry Andric ExprResult Operand; 22600b57cec5SDimitry Andric 22610b57cec5SDimitry Andric // If the operand doesn't start with an '(', it must be an expression. 22620b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) { 22630b57cec5SDimitry Andric // If construct allows a form without parenthesis, user may forget to put 22640b57cec5SDimitry Andric // pathenthesis around type name. 22650b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, 22660b57cec5SDimitry Andric tok::kw__Alignof)) { 22670b57cec5SDimitry Andric if (isTypeIdUnambiguously()) { 22680b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 22690b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 2270e8d8bef9SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); 22710b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); 22740b57cec5SDimitry Andric SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); 2275e8d8bef9SDimitry Andric if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) { 2276e8d8bef9SDimitry Andric Diag(OpTok.getLocation(), 2277e8d8bef9SDimitry Andric diag::err_expected_parentheses_around_typename) 2278e8d8bef9SDimitry Andric << OpTok.getName(); 2279e8d8bef9SDimitry Andric } else { 22800b57cec5SDimitry Andric Diag(LParenLoc, diag::err_expected_parentheses_around_typename) 2281e8d8bef9SDimitry Andric << OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(") 22820b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 2283e8d8bef9SDimitry Andric } 22840b57cec5SDimitry Andric isCastExpr = true; 22850b57cec5SDimitry Andric return ExprEmpty(); 22860b57cec5SDimitry Andric } 22870b57cec5SDimitry Andric } 22880b57cec5SDimitry Andric 22890b57cec5SDimitry Andric isCastExpr = false; 22900b57cec5SDimitry Andric if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) { 22910b57cec5SDimitry Andric Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo() 22920b57cec5SDimitry Andric << tok::l_paren; 22930b57cec5SDimitry Andric return ExprError(); 22940b57cec5SDimitry Andric } 22950b57cec5SDimitry Andric 2296480093f4SDimitry Andric Operand = ParseCastExpression(UnaryExprOnly); 22970b57cec5SDimitry Andric } else { 22980b57cec5SDimitry Andric // If it starts with a '(', we know that it is either a parenthesized 22990b57cec5SDimitry Andric // type-name, or it is a unary-expression that starts with a compound 23000b57cec5SDimitry Andric // literal, or starts with a primary-expression that is a parenthesized 23010b57cec5SDimitry Andric // expression. 23020b57cec5SDimitry Andric ParenParseOption ExprType = CastExpr; 23030b57cec5SDimitry Andric SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 23040b57cec5SDimitry Andric 23050b57cec5SDimitry Andric Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 23060b57cec5SDimitry Andric false, CastTy, RParenLoc); 23070b57cec5SDimitry Andric CastRange = SourceRange(LParenLoc, RParenLoc); 23080b57cec5SDimitry Andric 23090b57cec5SDimitry Andric // If ParseParenExpression parsed a '(typename)' sequence only, then this is 23100b57cec5SDimitry Andric // a type. 23110b57cec5SDimitry Andric if (ExprType == CastExpr) { 23120b57cec5SDimitry Andric isCastExpr = true; 23130b57cec5SDimitry Andric return ExprEmpty(); 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { 23170b57cec5SDimitry Andric // GNU typeof in C requires the expression to be parenthesized. Not so for 23180b57cec5SDimitry Andric // sizeof/alignof or in C++. Therefore, the parenthesized expression is 23190b57cec5SDimitry Andric // the start of a unary-expression, but doesn't include any postfix 23200b57cec5SDimitry Andric // pieces. Parse these now if present. 23210b57cec5SDimitry Andric if (!Operand.isInvalid()) 23220b57cec5SDimitry Andric Operand = ParsePostfixExpressionSuffix(Operand.get()); 23230b57cec5SDimitry Andric } 23240b57cec5SDimitry Andric } 23250b57cec5SDimitry Andric 23260b57cec5SDimitry Andric // If we get here, the operand to the typeof/sizeof/alignof was an expression. 23270b57cec5SDimitry Andric isCastExpr = false; 23280b57cec5SDimitry Andric return Operand; 23290b57cec5SDimitry Andric } 23300b57cec5SDimitry Andric 2331fe6060f1SDimitry Andric /// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as 2332fe6060f1SDimitry Andric /// a parameter. 2333fe6060f1SDimitry Andric ExprResult Parser::ParseSYCLUniqueStableNameExpression() { 2334fe6060f1SDimitry Andric assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) && 2335*349cc55cSDimitry Andric "Not __builtin_sycl_unique_stable_name"); 2336fe6060f1SDimitry Andric 2337fe6060f1SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 2338fe6060f1SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 2339fe6060f1SDimitry Andric 2340fe6060f1SDimitry Andric // __builtin_sycl_unique_stable_name expressions are always parenthesized. 2341fe6060f1SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, 2342fe6060f1SDimitry Andric "__builtin_sycl_unique_stable_name")) 2343fe6060f1SDimitry Andric return ExprError(); 2344fe6060f1SDimitry Andric 2345fe6060f1SDimitry Andric TypeResult Ty = ParseTypeName(); 2346fe6060f1SDimitry Andric 2347fe6060f1SDimitry Andric if (Ty.isInvalid()) { 2348fe6060f1SDimitry Andric T.skipToEnd(); 2349fe6060f1SDimitry Andric return ExprError(); 2350fe6060f1SDimitry Andric } 2351fe6060f1SDimitry Andric 2352fe6060f1SDimitry Andric if (T.consumeClose()) 2353fe6060f1SDimitry Andric return ExprError(); 2354fe6060f1SDimitry Andric 2355fe6060f1SDimitry Andric return Actions.ActOnSYCLUniqueStableNameExpr(OpLoc, T.getOpenLocation(), 2356fe6060f1SDimitry Andric T.getCloseLocation(), Ty.get()); 2357fe6060f1SDimitry Andric } 23580b57cec5SDimitry Andric 23590b57cec5SDimitry Andric /// Parse a sizeof or alignof expression. 23600b57cec5SDimitry Andric /// 23610b57cec5SDimitry Andric /// \verbatim 23620b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 23630b57cec5SDimitry Andric /// 'sizeof' unary-expression 23640b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 23650b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 23660b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 23670b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 23680b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 23690b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 23700b57cec5SDimitry Andric /// \endverbatim 23710b57cec5SDimitry Andric ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { 23720b57cec5SDimitry Andric assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, 23730b57cec5SDimitry Andric tok::kw__Alignof, tok::kw_vec_step, 23740b57cec5SDimitry Andric tok::kw___builtin_omp_required_simd_align) && 23750b57cec5SDimitry Andric "Not a sizeof/alignof/vec_step expression!"); 23760b57cec5SDimitry Andric Token OpTok = Tok; 23770b57cec5SDimitry Andric ConsumeToken(); 23780b57cec5SDimitry Andric 23790b57cec5SDimitry Andric // [C++11] 'sizeof' '...' '(' identifier ')' 23800b57cec5SDimitry Andric if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { 23810b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 23820b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 23830b57cec5SDimitry Andric IdentifierInfo *Name = nullptr; 23840b57cec5SDimitry Andric SourceLocation NameLoc; 23850b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 23860b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 23870b57cec5SDimitry Andric T.consumeOpen(); 23880b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 23890b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 23900b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 23910b57cec5SDimitry Andric NameLoc = ConsumeToken(); 23920b57cec5SDimitry Andric T.consumeClose(); 23930b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 23940b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 23950b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 23960b57cec5SDimitry Andric } else { 23970b57cec5SDimitry Andric Diag(Tok, diag::err_expected_parameter_pack); 23980b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 23990b57cec5SDimitry Andric } 24000b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 24010b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 24020b57cec5SDimitry Andric NameLoc = ConsumeToken(); 24030b57cec5SDimitry Andric LParenLoc = PP.getLocForEndOfToken(EllipsisLoc); 24040b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 24050b57cec5SDimitry Andric Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack) 24060b57cec5SDimitry Andric << Name 24070b57cec5SDimitry Andric << FixItHint::CreateInsertion(LParenLoc, "(") 24080b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 24090b57cec5SDimitry Andric } else { 24100b57cec5SDimitry Andric Diag(Tok, diag::err_sizeof_parameter_pack); 24110b57cec5SDimitry Andric } 24120b57cec5SDimitry Andric 24130b57cec5SDimitry Andric if (!Name) 24140b57cec5SDimitry Andric return ExprError(); 24150b57cec5SDimitry Andric 24160b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 24170b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 24180b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 24190b57cec5SDimitry Andric 24200b57cec5SDimitry Andric return Actions.ActOnSizeofParameterPackExpr(getCurScope(), 24210b57cec5SDimitry Andric OpTok.getLocation(), 24220b57cec5SDimitry Andric *Name, NameLoc, 24230b57cec5SDimitry Andric RParenLoc); 24240b57cec5SDimitry Andric } 24250b57cec5SDimitry Andric 24260b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 24270b57cec5SDimitry Andric Diag(OpTok, diag::warn_cxx98_compat_alignof); 24280b57cec5SDimitry Andric 24290b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 24300b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 24310b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 24320b57cec5SDimitry Andric 24330b57cec5SDimitry Andric bool isCastExpr; 24340b57cec5SDimitry Andric ParsedType CastTy; 24350b57cec5SDimitry Andric SourceRange CastRange; 24360b57cec5SDimitry Andric ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, 24370b57cec5SDimitry Andric isCastExpr, 24380b57cec5SDimitry Andric CastTy, 24390b57cec5SDimitry Andric CastRange); 24400b57cec5SDimitry Andric 24410b57cec5SDimitry Andric UnaryExprOrTypeTrait ExprKind = UETT_SizeOf; 24420b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 24430b57cec5SDimitry Andric ExprKind = UETT_AlignOf; 24440b57cec5SDimitry Andric else if (OpTok.is(tok::kw___alignof)) 24450b57cec5SDimitry Andric ExprKind = UETT_PreferredAlignOf; 24460b57cec5SDimitry Andric else if (OpTok.is(tok::kw_vec_step)) 24470b57cec5SDimitry Andric ExprKind = UETT_VecStep; 24480b57cec5SDimitry Andric else if (OpTok.is(tok::kw___builtin_omp_required_simd_align)) 24490b57cec5SDimitry Andric ExprKind = UETT_OpenMPRequiredSimdAlign; 24500b57cec5SDimitry Andric 24510b57cec5SDimitry Andric if (isCastExpr) 24520b57cec5SDimitry Andric return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 24530b57cec5SDimitry Andric ExprKind, 24540b57cec5SDimitry Andric /*IsType=*/true, 24550b57cec5SDimitry Andric CastTy.getAsOpaquePtr(), 24560b57cec5SDimitry Andric CastRange); 24570b57cec5SDimitry Andric 24580b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 24590b57cec5SDimitry Andric Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); 24600b57cec5SDimitry Andric 24610b57cec5SDimitry Andric // If we get here, the operand to the sizeof/alignof was an expression. 24620b57cec5SDimitry Andric if (!Operand.isInvalid()) 24630b57cec5SDimitry Andric Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 24640b57cec5SDimitry Andric ExprKind, 24650b57cec5SDimitry Andric /*IsType=*/false, 24660b57cec5SDimitry Andric Operand.get(), 24670b57cec5SDimitry Andric CastRange); 24680b57cec5SDimitry Andric return Operand; 24690b57cec5SDimitry Andric } 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andric /// ParseBuiltinPrimaryExpression 24720b57cec5SDimitry Andric /// 24730b57cec5SDimitry Andric /// \verbatim 24740b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 24750b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 24760b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 24770b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 24780b57cec5SDimitry Andric /// assign-expr ')' 24790b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 24800b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 24810b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 24820b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 24830b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 24840b57cec5SDimitry Andric /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' 24850b57cec5SDimitry Andric /// 24860b57cec5SDimitry Andric /// [GNU] offsetof-member-designator: 24870b57cec5SDimitry Andric /// [GNU] identifier 24880b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '.' identifier 24890b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '[' expression ']' 24900b57cec5SDimitry Andric /// \endverbatim 24910b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinPrimaryExpression() { 24920b57cec5SDimitry Andric ExprResult Res; 24930b57cec5SDimitry Andric const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 24940b57cec5SDimitry Andric 24950b57cec5SDimitry Andric tok::TokenKind T = Tok.getKind(); 24960b57cec5SDimitry Andric SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 24970b57cec5SDimitry Andric 24980b57cec5SDimitry Andric // All of these start with an open paren. 24990b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) 25000b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII 25010b57cec5SDimitry Andric << tok::l_paren); 25020b57cec5SDimitry Andric 25030b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 25040b57cec5SDimitry Andric PT.consumeOpen(); 25050b57cec5SDimitry Andric 25060b57cec5SDimitry Andric // TODO: Build AST. 25070b57cec5SDimitry Andric 25080b57cec5SDimitry Andric switch (T) { 25090b57cec5SDimitry Andric default: llvm_unreachable("Not a builtin primary expression!"); 25100b57cec5SDimitry Andric case tok::kw___builtin_va_arg: { 25110b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 25120b57cec5SDimitry Andric 25130b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 25140b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25150b57cec5SDimitry Andric Expr = ExprError(); 25160b57cec5SDimitry Andric } 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 25190b57cec5SDimitry Andric 25200b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 25210b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 25220b57cec5SDimitry Andric Expr = ExprError(); 25230b57cec5SDimitry Andric } 25240b57cec5SDimitry Andric 25250b57cec5SDimitry Andric if (Expr.isInvalid() || Ty.isInvalid()) 25260b57cec5SDimitry Andric Res = ExprError(); 25270b57cec5SDimitry Andric else 25280b57cec5SDimitry Andric Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen()); 25290b57cec5SDimitry Andric break; 25300b57cec5SDimitry Andric } 25310b57cec5SDimitry Andric case tok::kw___builtin_offsetof: { 25320b57cec5SDimitry Andric SourceLocation TypeLoc = Tok.getLocation(); 25330b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 25340b57cec5SDimitry Andric if (Ty.isInvalid()) { 25350b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25360b57cec5SDimitry Andric return ExprError(); 25370b57cec5SDimitry Andric } 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 25400b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25410b57cec5SDimitry Andric return ExprError(); 25420b57cec5SDimitry Andric } 25430b57cec5SDimitry Andric 25440b57cec5SDimitry Andric // We must have at least one identifier here. 25450b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 25460b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 25470b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25480b57cec5SDimitry Andric return ExprError(); 25490b57cec5SDimitry Andric } 25500b57cec5SDimitry Andric 25510b57cec5SDimitry Andric // Keep track of the various subcomponents we see. 25520b57cec5SDimitry Andric SmallVector<Sema::OffsetOfComponent, 4> Comps; 25530b57cec5SDimitry Andric 25540b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 25550b57cec5SDimitry Andric Comps.back().isBrackets = false; 25560b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 25570b57cec5SDimitry Andric Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 25580b57cec5SDimitry Andric 25590b57cec5SDimitry Andric // FIXME: This loop leaks the index expressions on error. 25600b57cec5SDimitry Andric while (1) { 25610b57cec5SDimitry Andric if (Tok.is(tok::period)) { 25620b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-designator '.' identifier 25630b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 25640b57cec5SDimitry Andric Comps.back().isBrackets = false; 25650b57cec5SDimitry Andric Comps.back().LocStart = ConsumeToken(); 25660b57cec5SDimitry Andric 25670b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 25680b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 25690b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25700b57cec5SDimitry Andric return ExprError(); 25710b57cec5SDimitry Andric } 25720b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 25730b57cec5SDimitry Andric Comps.back().LocEnd = ConsumeToken(); 25740b57cec5SDimitry Andric 25750b57cec5SDimitry Andric } else if (Tok.is(tok::l_square)) { 25760b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 25770b57cec5SDimitry Andric return ExprError(); 25780b57cec5SDimitry Andric 25790b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-design '[' expression ']' 25800b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 25810b57cec5SDimitry Andric Comps.back().isBrackets = true; 25820b57cec5SDimitry Andric BalancedDelimiterTracker ST(*this, tok::l_square); 25830b57cec5SDimitry Andric ST.consumeOpen(); 25840b57cec5SDimitry Andric Comps.back().LocStart = ST.getOpenLocation(); 25850b57cec5SDimitry Andric Res = ParseExpression(); 25860b57cec5SDimitry Andric if (Res.isInvalid()) { 25870b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25880b57cec5SDimitry Andric return Res; 25890b57cec5SDimitry Andric } 25900b57cec5SDimitry Andric Comps.back().U.E = Res.get(); 25910b57cec5SDimitry Andric 25920b57cec5SDimitry Andric ST.consumeClose(); 25930b57cec5SDimitry Andric Comps.back().LocEnd = ST.getCloseLocation(); 25940b57cec5SDimitry Andric } else { 25950b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 25960b57cec5SDimitry Andric PT.consumeClose(); 25970b57cec5SDimitry Andric Res = ExprError(); 25980b57cec5SDimitry Andric } else if (Ty.isInvalid()) { 25990b57cec5SDimitry Andric Res = ExprError(); 26000b57cec5SDimitry Andric } else { 26010b57cec5SDimitry Andric PT.consumeClose(); 26020b57cec5SDimitry Andric Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc, 26030b57cec5SDimitry Andric Ty.get(), Comps, 26040b57cec5SDimitry Andric PT.getCloseLocation()); 26050b57cec5SDimitry Andric } 26060b57cec5SDimitry Andric break; 26070b57cec5SDimitry Andric } 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric break; 26100b57cec5SDimitry Andric } 26110b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: { 26120b57cec5SDimitry Andric ExprResult Cond(ParseAssignmentExpression()); 26130b57cec5SDimitry Andric if (Cond.isInvalid()) { 26140b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26150b57cec5SDimitry Andric return Cond; 26160b57cec5SDimitry Andric } 26170b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26180b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26190b57cec5SDimitry Andric return ExprError(); 26200b57cec5SDimitry Andric } 26210b57cec5SDimitry Andric 26220b57cec5SDimitry Andric ExprResult Expr1(ParseAssignmentExpression()); 26230b57cec5SDimitry Andric if (Expr1.isInvalid()) { 26240b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26250b57cec5SDimitry Andric return Expr1; 26260b57cec5SDimitry Andric } 26270b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26280b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26290b57cec5SDimitry Andric return ExprError(); 26300b57cec5SDimitry Andric } 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric ExprResult Expr2(ParseAssignmentExpression()); 26330b57cec5SDimitry Andric if (Expr2.isInvalid()) { 26340b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26350b57cec5SDimitry Andric return Expr2; 26360b57cec5SDimitry Andric } 26370b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 26380b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 26390b57cec5SDimitry Andric return ExprError(); 26400b57cec5SDimitry Andric } 26410b57cec5SDimitry Andric Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(), 26420b57cec5SDimitry Andric Expr2.get(), ConsumeParen()); 26430b57cec5SDimitry Andric break; 26440b57cec5SDimitry Andric } 26450b57cec5SDimitry Andric case tok::kw___builtin_astype: { 26460b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 26470b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 26480b57cec5SDimitry Andric if (Expr.isInvalid()) { 26490b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26500b57cec5SDimitry Andric return ExprError(); 26510b57cec5SDimitry Andric } 26520b57cec5SDimitry Andric 26530b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26540b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26550b57cec5SDimitry Andric return ExprError(); 26560b57cec5SDimitry Andric } 26570b57cec5SDimitry Andric 26580b57cec5SDimitry Andric // Second argument is the type to bitcast to. 26590b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 26600b57cec5SDimitry Andric if (DestTy.isInvalid()) 26610b57cec5SDimitry Andric return ExprError(); 26620b57cec5SDimitry Andric 26630b57cec5SDimitry Andric // Attempt to consume the r-paren. 26640b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 26650b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 26660b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26670b57cec5SDimitry Andric return ExprError(); 26680b57cec5SDimitry Andric } 26690b57cec5SDimitry Andric 26700b57cec5SDimitry Andric Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 26710b57cec5SDimitry Andric ConsumeParen()); 26720b57cec5SDimitry Andric break; 26730b57cec5SDimitry Andric } 26740b57cec5SDimitry Andric case tok::kw___builtin_convertvector: { 26750b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 26760b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 26770b57cec5SDimitry Andric if (Expr.isInvalid()) { 26780b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26790b57cec5SDimitry Andric return ExprError(); 26800b57cec5SDimitry Andric } 26810b57cec5SDimitry Andric 26820b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26830b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26840b57cec5SDimitry Andric return ExprError(); 26850b57cec5SDimitry Andric } 26860b57cec5SDimitry Andric 26870b57cec5SDimitry Andric // Second argument is the type to bitcast to. 26880b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 26890b57cec5SDimitry Andric if (DestTy.isInvalid()) 26900b57cec5SDimitry Andric return ExprError(); 26910b57cec5SDimitry Andric 26920b57cec5SDimitry Andric // Attempt to consume the r-paren. 26930b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 26940b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 26950b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26960b57cec5SDimitry Andric return ExprError(); 26970b57cec5SDimitry Andric } 26980b57cec5SDimitry Andric 26990b57cec5SDimitry Andric Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 27000b57cec5SDimitry Andric ConsumeParen()); 27010b57cec5SDimitry Andric break; 27020b57cec5SDimitry Andric } 27030b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 27040b57cec5SDimitry Andric case tok::kw___builtin_FILE: 27050b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 27060b57cec5SDimitry Andric case tok::kw___builtin_LINE: { 27070b57cec5SDimitry Andric // Attempt to consume the r-paren. 27080b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27090b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27100b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27110b57cec5SDimitry Andric return ExprError(); 27120b57cec5SDimitry Andric } 27130b57cec5SDimitry Andric SourceLocExpr::IdentKind Kind = [&] { 27140b57cec5SDimitry Andric switch (T) { 27150b57cec5SDimitry Andric case tok::kw___builtin_FILE: 27160b57cec5SDimitry Andric return SourceLocExpr::File; 27170b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 27180b57cec5SDimitry Andric return SourceLocExpr::Function; 27190b57cec5SDimitry Andric case tok::kw___builtin_LINE: 27200b57cec5SDimitry Andric return SourceLocExpr::Line; 27210b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 27220b57cec5SDimitry Andric return SourceLocExpr::Column; 27230b57cec5SDimitry Andric default: 27240b57cec5SDimitry Andric llvm_unreachable("invalid keyword"); 27250b57cec5SDimitry Andric } 27260b57cec5SDimitry Andric }(); 27270b57cec5SDimitry Andric Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen()); 27280b57cec5SDimitry Andric break; 27290b57cec5SDimitry Andric } 27300b57cec5SDimitry Andric } 27310b57cec5SDimitry Andric 27320b57cec5SDimitry Andric if (Res.isInvalid()) 27330b57cec5SDimitry Andric return ExprError(); 27340b57cec5SDimitry Andric 27350b57cec5SDimitry Andric // These can be followed by postfix-expr pieces because they are 27360b57cec5SDimitry Andric // primary-expressions. 27370b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Res.get()); 27380b57cec5SDimitry Andric } 27390b57cec5SDimitry Andric 27405ffd83dbSDimitry Andric bool Parser::tryParseOpenMPArrayShapingCastPart() { 27415ffd83dbSDimitry Andric assert(Tok.is(tok::l_square) && "Expected open bracket"); 27425ffd83dbSDimitry Andric bool ErrorFound = true; 27435ffd83dbSDimitry Andric TentativeParsingAction TPA(*this); 27445ffd83dbSDimitry Andric do { 27455ffd83dbSDimitry Andric if (Tok.isNot(tok::l_square)) 27465ffd83dbSDimitry Andric break; 27475ffd83dbSDimitry Andric // Consume '[' 27485ffd83dbSDimitry Andric ConsumeBracket(); 27495ffd83dbSDimitry Andric // Skip inner expression. 27505ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end, 27515ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 27525ffd83dbSDimitry Andric ; 27535ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) 27545ffd83dbSDimitry Andric break; 27555ffd83dbSDimitry Andric // Consume ']' 27565ffd83dbSDimitry Andric ConsumeBracket(); 27575ffd83dbSDimitry Andric // Found ')' - done. 27585ffd83dbSDimitry Andric if (Tok.is(tok::r_paren)) { 27595ffd83dbSDimitry Andric ErrorFound = false; 27605ffd83dbSDimitry Andric break; 27615ffd83dbSDimitry Andric } 27625ffd83dbSDimitry Andric } while (Tok.isNot(tok::annot_pragma_openmp_end)); 27635ffd83dbSDimitry Andric TPA.Revert(); 27645ffd83dbSDimitry Andric return !ErrorFound; 27655ffd83dbSDimitry Andric } 27665ffd83dbSDimitry Andric 27670b57cec5SDimitry Andric /// ParseParenExpression - This parses the unit that starts with a '(' token, 27680b57cec5SDimitry Andric /// based on what is allowed by ExprType. The actual thing parsed is returned 27690b57cec5SDimitry Andric /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 27700b57cec5SDimitry Andric /// not the parsed cast-expression. 27710b57cec5SDimitry Andric /// 27720b57cec5SDimitry Andric /// \verbatim 27730b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 27740b57cec5SDimitry Andric /// '(' expression ')' 27750b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 27760b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 27770b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 27780b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 27790b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 27800b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 27810b57cec5SDimitry Andric /// [ARC] bridged-cast-expression 27820b57cec5SDimitry Andric /// [ARC] bridged-cast-expression: 27830b57cec5SDimitry Andric /// (__bridge type-name) cast-expression 27840b57cec5SDimitry Andric /// (__bridge_transfer type-name) cast-expression 27850b57cec5SDimitry Andric /// (__bridge_retained type-name) cast-expression 27860b57cec5SDimitry Andric /// fold-expression: [C++1z] 27870b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' ')' 27880b57cec5SDimitry Andric /// '(' '...' fold-operator cast-expression ')' 27890b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' 27900b57cec5SDimitry Andric /// fold-operator cast-expression ')' 27915ffd83dbSDimitry Andric /// [OPENMP] Array shaping operation 27925ffd83dbSDimitry Andric /// '(' '[' expression ']' { '[' expression ']' } cast-expression 27930b57cec5SDimitry Andric /// \endverbatim 27940b57cec5SDimitry Andric ExprResult 27950b57cec5SDimitry Andric Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 27960b57cec5SDimitry Andric bool isTypeCast, ParsedType &CastTy, 27970b57cec5SDimitry Andric SourceLocation &RParenLoc) { 27980b57cec5SDimitry Andric assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 27990b57cec5SDimitry Andric ColonProtectionRAIIObject ColonProtection(*this, false); 28000b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 28010b57cec5SDimitry Andric if (T.consumeOpen()) 28020b57cec5SDimitry Andric return ExprError(); 28030b57cec5SDimitry Andric SourceLocation OpenLoc = T.getOpenLocation(); 28040b57cec5SDimitry Andric 28050b57cec5SDimitry Andric PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc); 28060b57cec5SDimitry Andric 28070b57cec5SDimitry Andric ExprResult Result(true); 28080b57cec5SDimitry Andric bool isAmbiguousTypeId; 28090b57cec5SDimitry Andric CastTy = nullptr; 28100b57cec5SDimitry Andric 28110b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 2812fe6060f1SDimitry Andric cutOffParsing(); 28130b57cec5SDimitry Andric Actions.CodeCompleteExpression( 28140b57cec5SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation()), 28150b57cec5SDimitry Andric /*IsParenthesized=*/ExprType >= CompoundLiteral); 28160b57cec5SDimitry Andric return ExprError(); 28170b57cec5SDimitry Andric } 28180b57cec5SDimitry Andric 28190b57cec5SDimitry Andric // Diagnose use of bridge casts in non-arc mode. 28200b57cec5SDimitry Andric bool BridgeCast = (getLangOpts().ObjC && 28210b57cec5SDimitry Andric Tok.isOneOf(tok::kw___bridge, 28220b57cec5SDimitry Andric tok::kw___bridge_transfer, 28230b57cec5SDimitry Andric tok::kw___bridge_retained, 28240b57cec5SDimitry Andric tok::kw___bridge_retain)); 28250b57cec5SDimitry Andric if (BridgeCast && !getLangOpts().ObjCAutoRefCount) { 28260b57cec5SDimitry Andric if (!TryConsumeToken(tok::kw___bridge)) { 28270b57cec5SDimitry Andric StringRef BridgeCastName = Tok.getName(); 28280b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 28290b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 28300b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc) 28310b57cec5SDimitry Andric << BridgeCastName 28320b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, ""); 28330b57cec5SDimitry Andric } 28340b57cec5SDimitry Andric BridgeCast = false; 28350b57cec5SDimitry Andric } 28360b57cec5SDimitry Andric 28370b57cec5SDimitry Andric // None of these cases should fall through with an invalid Result 28380b57cec5SDimitry Andric // unless they've already reported an error. 28390b57cec5SDimitry Andric if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 28400b57cec5SDimitry Andric Diag(Tok, diag::ext_gnu_statement_expr); 28410b57cec5SDimitry Andric 2842e8d8bef9SDimitry Andric checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin); 2843e8d8bef9SDimitry Andric 28440b57cec5SDimitry Andric if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) { 28450b57cec5SDimitry Andric Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope)); 28460b57cec5SDimitry Andric } else { 28470b57cec5SDimitry Andric // Find the nearest non-record decl context. Variables declared in a 28480b57cec5SDimitry Andric // statement expression behave as if they were declared in the enclosing 28490b57cec5SDimitry Andric // function, block, or other code construct. 28500b57cec5SDimitry Andric DeclContext *CodeDC = Actions.CurContext; 28510b57cec5SDimitry Andric while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) { 28520b57cec5SDimitry Andric CodeDC = CodeDC->getParent(); 28530b57cec5SDimitry Andric assert(CodeDC && !CodeDC->isFileContext() && 28540b57cec5SDimitry Andric "statement expr not in code context"); 28550b57cec5SDimitry Andric } 28560b57cec5SDimitry Andric Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false); 28570b57cec5SDimitry Andric 28580b57cec5SDimitry Andric Actions.ActOnStartStmtExpr(); 28590b57cec5SDimitry Andric 28600b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatement(true)); 28610b57cec5SDimitry Andric ExprType = CompoundStmt; 28620b57cec5SDimitry Andric 28630b57cec5SDimitry Andric // If the substmt parsed correctly, build the AST node. 28640b57cec5SDimitry Andric if (!Stmt.isInvalid()) { 28658c27c554SDimitry Andric Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(), 28668c27c554SDimitry Andric Tok.getLocation()); 28670b57cec5SDimitry Andric } else { 28680b57cec5SDimitry Andric Actions.ActOnStmtExprError(); 28690b57cec5SDimitry Andric } 28700b57cec5SDimitry Andric } 28710b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && BridgeCast) { 28720b57cec5SDimitry Andric tok::TokenKind tokenKind = Tok.getKind(); 28730b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 28740b57cec5SDimitry Andric 28750b57cec5SDimitry Andric // Parse an Objective-C ARC ownership cast expression. 28760b57cec5SDimitry Andric ObjCBridgeCastKind Kind; 28770b57cec5SDimitry Andric if (tokenKind == tok::kw___bridge) 28780b57cec5SDimitry Andric Kind = OBC_Bridge; 28790b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_transfer) 28800b57cec5SDimitry Andric Kind = OBC_BridgeTransfer; 28810b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_retained) 28820b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 28830b57cec5SDimitry Andric else { 28840b57cec5SDimitry Andric // As a hopefully temporary workaround, allow __bridge_retain as 28850b57cec5SDimitry Andric // a synonym for __bridge_retained, but only in system headers. 28860b57cec5SDimitry Andric assert(tokenKind == tok::kw___bridge_retain); 28870b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 28880b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 28890b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain) 28900b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, 28910b57cec5SDimitry Andric "__bridge_retained"); 28920b57cec5SDimitry Andric } 28930b57cec5SDimitry Andric 28940b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 28950b57cec5SDimitry Andric T.consumeClose(); 28960b57cec5SDimitry Andric ColonProtection.restore(); 28970b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 28980b57cec5SDimitry Andric 28990b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); 2900480093f4SDimitry Andric ExprResult SubExpr = ParseCastExpression(AnyCastExpr); 29010b57cec5SDimitry Andric 29020b57cec5SDimitry Andric if (Ty.isInvalid() || SubExpr.isInvalid()) 29030b57cec5SDimitry Andric return ExprError(); 29040b57cec5SDimitry Andric 29050b57cec5SDimitry Andric return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, 29060b57cec5SDimitry Andric BridgeKeywordLoc, Ty.get(), 29070b57cec5SDimitry Andric RParenLoc, SubExpr.get()); 29080b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && 29090b57cec5SDimitry Andric isTypeIdInParens(isAmbiguousTypeId)) { 29100b57cec5SDimitry Andric 29110b57cec5SDimitry Andric // Otherwise, this is a compound literal expression or cast expression. 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andric // In C++, if the type-id is ambiguous we disambiguate based on context. 29140b57cec5SDimitry Andric // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 29150b57cec5SDimitry Andric // in which case we should treat it as type-id. 29160b57cec5SDimitry Andric // if stopIfCastExpr is false, we need to determine the context past the 29170b57cec5SDimitry Andric // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 29180b57cec5SDimitry Andric if (isAmbiguousTypeId && !stopIfCastExpr) { 29190b57cec5SDimitry Andric ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T, 29200b57cec5SDimitry Andric ColonProtection); 29210b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 29220b57cec5SDimitry Andric return res; 29230b57cec5SDimitry Andric } 29240b57cec5SDimitry Andric 29250b57cec5SDimitry Andric // Parse the type declarator. 29260b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 29270b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 2928e8d8bef9SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); 29290b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 29300b57cec5SDimitry Andric 29310b57cec5SDimitry Andric // If our type is followed by an identifier and either ':' or ']', then 29320b57cec5SDimitry Andric // this is probably an Objective-C message send where the leading '[' is 29330b57cec5SDimitry Andric // missing. Recover as if that were the case. 29340b57cec5SDimitry Andric if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && 29350b57cec5SDimitry Andric !InMessageExpression && getLangOpts().ObjC && 29360b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 29370b57cec5SDimitry Andric TypeResult Ty; 29380b57cec5SDimitry Andric { 29390b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 29400b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 29410b57cec5SDimitry Andric } 29420b57cec5SDimitry Andric Result = ParseObjCMessageExpressionBody(SourceLocation(), 29430b57cec5SDimitry Andric SourceLocation(), 29440b57cec5SDimitry Andric Ty.get(), nullptr); 29450b57cec5SDimitry Andric } else { 29460b57cec5SDimitry Andric // Match the ')'. 29470b57cec5SDimitry Andric T.consumeClose(); 29480b57cec5SDimitry Andric ColonProtection.restore(); 29490b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 29500b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 29510b57cec5SDimitry Andric ExprType = CompoundLiteral; 29520b57cec5SDimitry Andric TypeResult Ty; 29530b57cec5SDimitry Andric { 29540b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 29550b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 29560b57cec5SDimitry Andric } 29570b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 29580b57cec5SDimitry Andric } 29590b57cec5SDimitry Andric 29600b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 29610b57cec5SDimitry Andric // This could be OpenCL vector Literals 29620b57cec5SDimitry Andric if (getLangOpts().OpenCL) 29630b57cec5SDimitry Andric { 29640b57cec5SDimitry Andric TypeResult Ty; 29650b57cec5SDimitry Andric { 29660b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 29670b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 29680b57cec5SDimitry Andric } 29690b57cec5SDimitry Andric if(Ty.isInvalid()) 29700b57cec5SDimitry Andric { 29710b57cec5SDimitry Andric return ExprError(); 29720b57cec5SDimitry Andric } 29730b57cec5SDimitry Andric QualType QT = Ty.get().get().getCanonicalType(); 29740b57cec5SDimitry Andric if (QT->isVectorType()) 29750b57cec5SDimitry Andric { 29760b57cec5SDimitry Andric // We parsed '(' vector-type-name ')' followed by '(' 29770b57cec5SDimitry Andric 29780b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 29790b57cec5SDimitry Andric // isVectorLiteral = true will make sure we don't parse any 29800b57cec5SDimitry Andric // Postfix expression yet 2981480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 29820b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 29830b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast, 29840b57cec5SDimitry Andric /*isVectorLiteral=*/true); 29850b57cec5SDimitry Andric 29860b57cec5SDimitry Andric if (!Result.isInvalid()) { 29870b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 29880b57cec5SDimitry Andric DeclaratorInfo, CastTy, 29890b57cec5SDimitry Andric RParenLoc, Result.get()); 29900b57cec5SDimitry Andric } 29910b57cec5SDimitry Andric 29920b57cec5SDimitry Andric // After we performed the cast we can check for postfix-expr pieces. 29930b57cec5SDimitry Andric if (!Result.isInvalid()) { 29940b57cec5SDimitry Andric Result = ParsePostfixExpressionSuffix(Result); 29950b57cec5SDimitry Andric } 29960b57cec5SDimitry Andric 29970b57cec5SDimitry Andric return Result; 29980b57cec5SDimitry Andric } 29990b57cec5SDimitry Andric } 30000b57cec5SDimitry Andric } 30010b57cec5SDimitry Andric 30020b57cec5SDimitry Andric if (ExprType == CastExpr) { 30030b57cec5SDimitry Andric // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 30040b57cec5SDimitry Andric 30050b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 30060b57cec5SDimitry Andric return ExprError(); 30070b57cec5SDimitry Andric 30080b57cec5SDimitry Andric // Note that this doesn't parse the subsequent cast-expression, it just 30090b57cec5SDimitry Andric // returns the parsed type to the callee. 30100b57cec5SDimitry Andric if (stopIfCastExpr) { 30110b57cec5SDimitry Andric TypeResult Ty; 30120b57cec5SDimitry Andric { 30130b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 30140b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 30150b57cec5SDimitry Andric } 30160b57cec5SDimitry Andric CastTy = Ty.get(); 30170b57cec5SDimitry Andric return ExprResult(); 30180b57cec5SDimitry Andric } 30190b57cec5SDimitry Andric 30200b57cec5SDimitry Andric // Reject the cast of super idiom in ObjC. 30210b57cec5SDimitry Andric if (Tok.is(tok::identifier) && getLangOpts().ObjC && 30220b57cec5SDimitry Andric Tok.getIdentifierInfo() == Ident_super && 30230b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 30240b57cec5SDimitry Andric GetLookAheadToken(1).isNot(tok::period)) { 30250b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_illegal_super_cast) 30260b57cec5SDimitry Andric << SourceRange(OpenLoc, RParenLoc); 30270b57cec5SDimitry Andric return ExprError(); 30280b57cec5SDimitry Andric } 30290b57cec5SDimitry Andric 30300b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get()); 30310b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 30320b57cec5SDimitry Andric // TODO: For cast expression with CastTy. 3033480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 30340b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 30350b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast); 30360b57cec5SDimitry Andric if (!Result.isInvalid()) { 30370b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 30380b57cec5SDimitry Andric DeclaratorInfo, CastTy, 30390b57cec5SDimitry Andric RParenLoc, Result.get()); 30400b57cec5SDimitry Andric } 30410b57cec5SDimitry Andric return Result; 30420b57cec5SDimitry Andric } 30430b57cec5SDimitry Andric 30440b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 30450b57cec5SDimitry Andric return ExprError(); 30460b57cec5SDimitry Andric } 30470b57cec5SDimitry Andric } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && 30480b57cec5SDimitry Andric isFoldOperator(NextToken().getKind())) { 30490b57cec5SDimitry Andric ExprType = FoldExpr; 30500b57cec5SDimitry Andric return ParseFoldExpression(ExprResult(), T); 30510b57cec5SDimitry Andric } else if (isTypeCast) { 30520b57cec5SDimitry Andric // Parse the expression-list. 30530b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 30540b57cec5SDimitry Andric 30550b57cec5SDimitry Andric ExprVector ArgExprs; 30560b57cec5SDimitry Andric CommaLocsTy CommaLocs; 30570b57cec5SDimitry Andric 30580b57cec5SDimitry Andric if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { 30590b57cec5SDimitry Andric // FIXME: If we ever support comma expressions as operands to 30600b57cec5SDimitry Andric // fold-expressions, we'll need to allow multiple ArgExprs here. 30610b57cec5SDimitry Andric if (ExprType >= FoldExpr && ArgExprs.size() == 1 && 30620b57cec5SDimitry Andric isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { 30630b57cec5SDimitry Andric ExprType = FoldExpr; 30640b57cec5SDimitry Andric return ParseFoldExpression(ArgExprs[0], T); 30650b57cec5SDimitry Andric } 30660b57cec5SDimitry Andric 30670b57cec5SDimitry Andric ExprType = SimpleExpr; 30680b57cec5SDimitry Andric Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), 30690b57cec5SDimitry Andric ArgExprs); 30700b57cec5SDimitry Andric } 30715ffd83dbSDimitry Andric } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing && 30725ffd83dbSDimitry Andric ExprType == CastExpr && Tok.is(tok::l_square) && 30735ffd83dbSDimitry Andric tryParseOpenMPArrayShapingCastPart()) { 30745ffd83dbSDimitry Andric bool ErrorFound = false; 30755ffd83dbSDimitry Andric SmallVector<Expr *, 4> OMPDimensions; 30765ffd83dbSDimitry Andric SmallVector<SourceRange, 4> OMPBracketsRanges; 30775ffd83dbSDimitry Andric do { 30785ffd83dbSDimitry Andric BalancedDelimiterTracker TS(*this, tok::l_square); 30795ffd83dbSDimitry Andric TS.consumeOpen(); 30805ffd83dbSDimitry Andric ExprResult NumElements = 30815ffd83dbSDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 30825ffd83dbSDimitry Andric if (!NumElements.isUsable()) { 30835ffd83dbSDimitry Andric ErrorFound = true; 30845ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::r_paren, 30855ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 30865ffd83dbSDimitry Andric ; 30875ffd83dbSDimitry Andric } 30885ffd83dbSDimitry Andric TS.consumeClose(); 30895ffd83dbSDimitry Andric OMPDimensions.push_back(NumElements.get()); 30905ffd83dbSDimitry Andric OMPBracketsRanges.push_back(TS.getRange()); 30915ffd83dbSDimitry Andric } while (Tok.isNot(tok::r_paren)); 30925ffd83dbSDimitry Andric // Match the ')'. 30935ffd83dbSDimitry Andric T.consumeClose(); 30945ffd83dbSDimitry Andric RParenLoc = T.getCloseLocation(); 30955ffd83dbSDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 30965ffd83dbSDimitry Andric if (ErrorFound) { 30975ffd83dbSDimitry Andric Result = ExprError(); 30985ffd83dbSDimitry Andric } else if (!Result.isInvalid()) { 30995ffd83dbSDimitry Andric Result = Actions.ActOnOMPArrayShapingExpr( 31005ffd83dbSDimitry Andric Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges); 31015ffd83dbSDimitry Andric } 31025ffd83dbSDimitry Andric return Result; 31030b57cec5SDimitry Andric } else { 31040b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31050b57cec5SDimitry Andric 31060b57cec5SDimitry Andric Result = ParseExpression(MaybeTypeCast); 31070b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus && MaybeTypeCast && Result.isUsable()) { 31080b57cec5SDimitry Andric // Correct typos in non-C++ code earlier so that implicit-cast-like 31090b57cec5SDimitry Andric // expressions are parsed correctly. 31100b57cec5SDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(Result); 31110b57cec5SDimitry Andric } 31120b57cec5SDimitry Andric 31130b57cec5SDimitry Andric if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && 31140b57cec5SDimitry Andric NextToken().is(tok::ellipsis)) { 31150b57cec5SDimitry Andric ExprType = FoldExpr; 31160b57cec5SDimitry Andric return ParseFoldExpression(Result, T); 31170b57cec5SDimitry Andric } 31180b57cec5SDimitry Andric ExprType = SimpleExpr; 31190b57cec5SDimitry Andric 31200b57cec5SDimitry Andric // Don't build a paren expression unless we actually match a ')'. 31210b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 31220b57cec5SDimitry Andric Result = 31230b57cec5SDimitry Andric Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get()); 31240b57cec5SDimitry Andric } 31250b57cec5SDimitry Andric 31260b57cec5SDimitry Andric // Match the ')'. 31270b57cec5SDimitry Andric if (Result.isInvalid()) { 31280b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 31290b57cec5SDimitry Andric return ExprError(); 31300b57cec5SDimitry Andric } 31310b57cec5SDimitry Andric 31320b57cec5SDimitry Andric T.consumeClose(); 31330b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 31340b57cec5SDimitry Andric return Result; 31350b57cec5SDimitry Andric } 31360b57cec5SDimitry Andric 31370b57cec5SDimitry Andric /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 31380b57cec5SDimitry Andric /// and we are at the left brace. 31390b57cec5SDimitry Andric /// 31400b57cec5SDimitry Andric /// \verbatim 31410b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 31420b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 31430b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 31440b57cec5SDimitry Andric /// \endverbatim 31450b57cec5SDimitry Andric ExprResult 31460b57cec5SDimitry Andric Parser::ParseCompoundLiteralExpression(ParsedType Ty, 31470b57cec5SDimitry Andric SourceLocation LParenLoc, 31480b57cec5SDimitry Andric SourceLocation RParenLoc) { 31490b57cec5SDimitry Andric assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 31500b57cec5SDimitry Andric if (!getLangOpts().C99) // Compound literals don't exist in C90. 31510b57cec5SDimitry Andric Diag(LParenLoc, diag::ext_c99_compound_literal); 3152e8d8bef9SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get()); 31530b57cec5SDimitry Andric ExprResult Result = ParseInitializer(); 31540b57cec5SDimitry Andric if (!Result.isInvalid() && Ty) 31550b57cec5SDimitry Andric return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get()); 31560b57cec5SDimitry Andric return Result; 31570b57cec5SDimitry Andric } 31580b57cec5SDimitry Andric 31590b57cec5SDimitry Andric /// ParseStringLiteralExpression - This handles the various token types that 31600b57cec5SDimitry Andric /// form string literals, and also handles string concatenation [C99 5.1.1.2, 31610b57cec5SDimitry Andric /// translation phase #6]. 31620b57cec5SDimitry Andric /// 31630b57cec5SDimitry Andric /// \verbatim 31640b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 31650b57cec5SDimitry Andric /// string-literal 31660b57cec5SDimitry Andric /// \verbatim 31670b57cec5SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) { 31680b57cec5SDimitry Andric assert(isTokenStringLiteral() && "Not a string literal!"); 31690b57cec5SDimitry Andric 31700b57cec5SDimitry Andric // String concat. Note that keywords like __func__ and __FUNCTION__ are not 31710b57cec5SDimitry Andric // considered to be strings for concatenation purposes. 31720b57cec5SDimitry Andric SmallVector<Token, 4> StringToks; 31730b57cec5SDimitry Andric 31740b57cec5SDimitry Andric do { 31750b57cec5SDimitry Andric StringToks.push_back(Tok); 31760b57cec5SDimitry Andric ConsumeStringToken(); 31770b57cec5SDimitry Andric } while (isTokenStringLiteral()); 31780b57cec5SDimitry Andric 31790b57cec5SDimitry Andric // Pass the set of string tokens, ready for concatenation, to the actions. 31800b57cec5SDimitry Andric return Actions.ActOnStringLiteral(StringToks, 31810b57cec5SDimitry Andric AllowUserDefinedLiteral ? getCurScope() 31820b57cec5SDimitry Andric : nullptr); 31830b57cec5SDimitry Andric } 31840b57cec5SDimitry Andric 31850b57cec5SDimitry Andric /// ParseGenericSelectionExpression - Parse a C11 generic-selection 31860b57cec5SDimitry Andric /// [C11 6.5.1.1]. 31870b57cec5SDimitry Andric /// 31880b57cec5SDimitry Andric /// \verbatim 31890b57cec5SDimitry Andric /// generic-selection: 31900b57cec5SDimitry Andric /// _Generic ( assignment-expression , generic-assoc-list ) 31910b57cec5SDimitry Andric /// generic-assoc-list: 31920b57cec5SDimitry Andric /// generic-association 31930b57cec5SDimitry Andric /// generic-assoc-list , generic-association 31940b57cec5SDimitry Andric /// generic-association: 31950b57cec5SDimitry Andric /// type-name : assignment-expression 31960b57cec5SDimitry Andric /// default : assignment-expression 31970b57cec5SDimitry Andric /// \endverbatim 31980b57cec5SDimitry Andric ExprResult Parser::ParseGenericSelectionExpression() { 31990b57cec5SDimitry Andric assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected"); 32000b57cec5SDimitry Andric if (!getLangOpts().C11) 3201a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 32020b57cec5SDimitry Andric 3203a7dea167SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 32040b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 32050b57cec5SDimitry Andric if (T.expectAndConsume()) 32060b57cec5SDimitry Andric return ExprError(); 32070b57cec5SDimitry Andric 32080b57cec5SDimitry Andric ExprResult ControllingExpr; 32090b57cec5SDimitry Andric { 32100b57cec5SDimitry Andric // C11 6.5.1.1p3 "The controlling expression of a generic selection is 32110b57cec5SDimitry Andric // not evaluated." 32120b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 32130b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 32140b57cec5SDimitry Andric ControllingExpr = 32150b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 32160b57cec5SDimitry Andric if (ControllingExpr.isInvalid()) { 32170b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32180b57cec5SDimitry Andric return ExprError(); 32190b57cec5SDimitry Andric } 32200b57cec5SDimitry Andric } 32210b57cec5SDimitry Andric 32220b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 32230b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32240b57cec5SDimitry Andric return ExprError(); 32250b57cec5SDimitry Andric } 32260b57cec5SDimitry Andric 32270b57cec5SDimitry Andric SourceLocation DefaultLoc; 32280b57cec5SDimitry Andric TypeVector Types; 32290b57cec5SDimitry Andric ExprVector Exprs; 32300b57cec5SDimitry Andric do { 32310b57cec5SDimitry Andric ParsedType Ty; 32320b57cec5SDimitry Andric if (Tok.is(tok::kw_default)) { 32330b57cec5SDimitry Andric // C11 6.5.1.1p2 "A generic selection shall have no more than one default 32340b57cec5SDimitry Andric // generic association." 32350b57cec5SDimitry Andric if (!DefaultLoc.isInvalid()) { 32360b57cec5SDimitry Andric Diag(Tok, diag::err_duplicate_default_assoc); 32370b57cec5SDimitry Andric Diag(DefaultLoc, diag::note_previous_default_assoc); 32380b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32390b57cec5SDimitry Andric return ExprError(); 32400b57cec5SDimitry Andric } 32410b57cec5SDimitry Andric DefaultLoc = ConsumeToken(); 32420b57cec5SDimitry Andric Ty = nullptr; 32430b57cec5SDimitry Andric } else { 32440b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 32450b57cec5SDimitry Andric TypeResult TR = ParseTypeName(); 32460b57cec5SDimitry Andric if (TR.isInvalid()) { 32470b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32480b57cec5SDimitry Andric return ExprError(); 32490b57cec5SDimitry Andric } 32500b57cec5SDimitry Andric Ty = TR.get(); 32510b57cec5SDimitry Andric } 32520b57cec5SDimitry Andric Types.push_back(Ty); 32530b57cec5SDimitry Andric 32540b57cec5SDimitry Andric if (ExpectAndConsume(tok::colon)) { 32550b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32560b57cec5SDimitry Andric return ExprError(); 32570b57cec5SDimitry Andric } 32580b57cec5SDimitry Andric 32590b57cec5SDimitry Andric // FIXME: These expressions should be parsed in a potentially potentially 32600b57cec5SDimitry Andric // evaluated context. 32610b57cec5SDimitry Andric ExprResult ER( 32620b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); 32630b57cec5SDimitry Andric if (ER.isInvalid()) { 32640b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32650b57cec5SDimitry Andric return ExprError(); 32660b57cec5SDimitry Andric } 32670b57cec5SDimitry Andric Exprs.push_back(ER.get()); 32680b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 32690b57cec5SDimitry Andric 32700b57cec5SDimitry Andric T.consumeClose(); 32710b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 32720b57cec5SDimitry Andric return ExprError(); 32730b57cec5SDimitry Andric 32740b57cec5SDimitry Andric return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, 32750b57cec5SDimitry Andric T.getCloseLocation(), 32760b57cec5SDimitry Andric ControllingExpr.get(), 32770b57cec5SDimitry Andric Types, Exprs); 32780b57cec5SDimitry Andric } 32790b57cec5SDimitry Andric 32800b57cec5SDimitry Andric /// Parse A C++1z fold-expression after the opening paren and optional 32810b57cec5SDimitry Andric /// left-hand-side expression. 32820b57cec5SDimitry Andric /// 32830b57cec5SDimitry Andric /// \verbatim 32840b57cec5SDimitry Andric /// fold-expression: 32850b57cec5SDimitry Andric /// ( cast-expression fold-operator ... ) 32860b57cec5SDimitry Andric /// ( ... fold-operator cast-expression ) 32870b57cec5SDimitry Andric /// ( cast-expression fold-operator ... fold-operator cast-expression ) 32880b57cec5SDimitry Andric ExprResult Parser::ParseFoldExpression(ExprResult LHS, 32890b57cec5SDimitry Andric BalancedDelimiterTracker &T) { 32900b57cec5SDimitry Andric if (LHS.isInvalid()) { 32910b57cec5SDimitry Andric T.skipToEnd(); 32920b57cec5SDimitry Andric return true; 32930b57cec5SDimitry Andric } 32940b57cec5SDimitry Andric 32950b57cec5SDimitry Andric tok::TokenKind Kind = tok::unknown; 32960b57cec5SDimitry Andric SourceLocation FirstOpLoc; 32970b57cec5SDimitry Andric if (LHS.isUsable()) { 32980b57cec5SDimitry Andric Kind = Tok.getKind(); 32990b57cec5SDimitry Andric assert(isFoldOperator(Kind) && "missing fold-operator"); 33000b57cec5SDimitry Andric FirstOpLoc = ConsumeToken(); 33010b57cec5SDimitry Andric } 33020b57cec5SDimitry Andric 33030b57cec5SDimitry Andric assert(Tok.is(tok::ellipsis) && "not a fold-expression"); 33040b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 33050b57cec5SDimitry Andric 33060b57cec5SDimitry Andric ExprResult RHS; 33070b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 33080b57cec5SDimitry Andric if (!isFoldOperator(Tok.getKind())) 33090b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_fold_operator); 33100b57cec5SDimitry Andric 33110b57cec5SDimitry Andric if (Kind != tok::unknown && Tok.getKind() != Kind) 33120b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_fold_operator_mismatch) 33130b57cec5SDimitry Andric << SourceRange(FirstOpLoc); 33140b57cec5SDimitry Andric Kind = Tok.getKind(); 33150b57cec5SDimitry Andric ConsumeToken(); 33160b57cec5SDimitry Andric 33170b57cec5SDimitry Andric RHS = ParseExpression(); 33180b57cec5SDimitry Andric if (RHS.isInvalid()) { 33190b57cec5SDimitry Andric T.skipToEnd(); 33200b57cec5SDimitry Andric return true; 33210b57cec5SDimitry Andric } 33220b57cec5SDimitry Andric } 33230b57cec5SDimitry Andric 33240b57cec5SDimitry Andric Diag(EllipsisLoc, getLangOpts().CPlusPlus17 33250b57cec5SDimitry Andric ? diag::warn_cxx14_compat_fold_expression 33260b57cec5SDimitry Andric : diag::ext_fold_expression); 33270b57cec5SDimitry Andric 33280b57cec5SDimitry Andric T.consumeClose(); 3329e8d8bef9SDimitry Andric return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(), 3330e8d8bef9SDimitry Andric Kind, EllipsisLoc, RHS.get(), 3331e8d8bef9SDimitry Andric T.getCloseLocation()); 33320b57cec5SDimitry Andric } 33330b57cec5SDimitry Andric 33340b57cec5SDimitry Andric /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 33350b57cec5SDimitry Andric /// 33360b57cec5SDimitry Andric /// \verbatim 33370b57cec5SDimitry Andric /// argument-expression-list: 33380b57cec5SDimitry Andric /// assignment-expression 33390b57cec5SDimitry Andric /// argument-expression-list , assignment-expression 33400b57cec5SDimitry Andric /// 33410b57cec5SDimitry Andric /// [C++] expression-list: 33420b57cec5SDimitry Andric /// [C++] assignment-expression 33430b57cec5SDimitry Andric /// [C++] expression-list , assignment-expression 33440b57cec5SDimitry Andric /// 33450b57cec5SDimitry Andric /// [C++0x] expression-list: 33460b57cec5SDimitry Andric /// [C++0x] initializer-list 33470b57cec5SDimitry Andric /// 33480b57cec5SDimitry Andric /// [C++0x] initializer-list 33490b57cec5SDimitry Andric /// [C++0x] initializer-clause ...[opt] 33500b57cec5SDimitry Andric /// [C++0x] initializer-list , initializer-clause ...[opt] 33510b57cec5SDimitry Andric /// 33520b57cec5SDimitry Andric /// [C++0x] initializer-clause: 33530b57cec5SDimitry Andric /// [C++0x] assignment-expression 33540b57cec5SDimitry Andric /// [C++0x] braced-init-list 33550b57cec5SDimitry Andric /// \endverbatim 33560b57cec5SDimitry Andric bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, 33570b57cec5SDimitry Andric SmallVectorImpl<SourceLocation> &CommaLocs, 33580b57cec5SDimitry Andric llvm::function_ref<void()> ExpressionStarts) { 33590b57cec5SDimitry Andric bool SawError = false; 33600b57cec5SDimitry Andric while (1) { 33610b57cec5SDimitry Andric if (ExpressionStarts) 33620b57cec5SDimitry Andric ExpressionStarts(); 33630b57cec5SDimitry Andric 33640b57cec5SDimitry Andric ExprResult Expr; 33650b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 33660b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 33670b57cec5SDimitry Andric Expr = ParseBraceInitializer(); 33680b57cec5SDimitry Andric } else 33690b57cec5SDimitry Andric Expr = ParseAssignmentExpression(); 33700b57cec5SDimitry Andric 33710b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) 33720b57cec5SDimitry Andric Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); 33735ffd83dbSDimitry Andric else if (Tok.is(tok::code_completion)) { 33745ffd83dbSDimitry Andric // There's nothing to suggest in here as we parsed a full expression. 33755ffd83dbSDimitry Andric // Instead fail and propogate the error since caller might have something 33765ffd83dbSDimitry Andric // the suggest, e.g. signature help in function call. Note that this is 33775ffd83dbSDimitry Andric // performed before pushing the \p Expr, so that signature help can report 33785ffd83dbSDimitry Andric // current argument correctly. 33795ffd83dbSDimitry Andric SawError = true; 33805ffd83dbSDimitry Andric cutOffParsing(); 33815ffd83dbSDimitry Andric break; 33825ffd83dbSDimitry Andric } 33830b57cec5SDimitry Andric if (Expr.isInvalid()) { 33840b57cec5SDimitry Andric SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); 33850b57cec5SDimitry Andric SawError = true; 33860b57cec5SDimitry Andric } else { 33870b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 33880b57cec5SDimitry Andric } 33890b57cec5SDimitry Andric 33900b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 33910b57cec5SDimitry Andric break; 33920b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 33930b57cec5SDimitry Andric Token Comma = Tok; 33940b57cec5SDimitry Andric CommaLocs.push_back(ConsumeToken()); 33950b57cec5SDimitry Andric 33960b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 33970b57cec5SDimitry Andric } 33980b57cec5SDimitry Andric if (SawError) { 33990b57cec5SDimitry Andric // Ensure typos get diagnosed when errors were encountered while parsing the 34000b57cec5SDimitry Andric // expression list. 34010b57cec5SDimitry Andric for (auto &E : Exprs) { 34020b57cec5SDimitry Andric ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); 34030b57cec5SDimitry Andric if (Expr.isUsable()) E = Expr.get(); 34040b57cec5SDimitry Andric } 34050b57cec5SDimitry Andric } 34060b57cec5SDimitry Andric return SawError; 34070b57cec5SDimitry Andric } 34080b57cec5SDimitry Andric 34090b57cec5SDimitry Andric /// ParseSimpleExpressionList - A simple comma-separated list of expressions, 34100b57cec5SDimitry Andric /// used for misc language extensions. 34110b57cec5SDimitry Andric /// 34120b57cec5SDimitry Andric /// \verbatim 34130b57cec5SDimitry Andric /// simple-expression-list: 34140b57cec5SDimitry Andric /// assignment-expression 34150b57cec5SDimitry Andric /// simple-expression-list , assignment-expression 34160b57cec5SDimitry Andric /// \endverbatim 34170b57cec5SDimitry Andric bool 34180b57cec5SDimitry Andric Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, 34190b57cec5SDimitry Andric SmallVectorImpl<SourceLocation> &CommaLocs) { 34200b57cec5SDimitry Andric while (1) { 34210b57cec5SDimitry Andric ExprResult Expr = ParseAssignmentExpression(); 34220b57cec5SDimitry Andric if (Expr.isInvalid()) 34230b57cec5SDimitry Andric return true; 34240b57cec5SDimitry Andric 34250b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 34260b57cec5SDimitry Andric 34270b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 34280b57cec5SDimitry Andric return false; 34290b57cec5SDimitry Andric 34300b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 34310b57cec5SDimitry Andric Token Comma = Tok; 34320b57cec5SDimitry Andric CommaLocs.push_back(ConsumeToken()); 34330b57cec5SDimitry Andric 34340b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 34350b57cec5SDimitry Andric } 34360b57cec5SDimitry Andric } 34370b57cec5SDimitry Andric 34380b57cec5SDimitry Andric /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 34390b57cec5SDimitry Andric /// 34400b57cec5SDimitry Andric /// \verbatim 34410b57cec5SDimitry Andric /// [clang] block-id: 34420b57cec5SDimitry Andric /// [clang] specifier-qualifier-list block-declarator 34430b57cec5SDimitry Andric /// \endverbatim 34440b57cec5SDimitry Andric void Parser::ParseBlockId(SourceLocation CaretLoc) { 34450b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 3446fe6060f1SDimitry Andric cutOffParsing(); 34470b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); 3448fe6060f1SDimitry Andric return; 34490b57cec5SDimitry Andric } 34500b57cec5SDimitry Andric 34510b57cec5SDimitry Andric // Parse the specifier-qualifier-list piece. 34520b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 34530b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 34540b57cec5SDimitry Andric 34550b57cec5SDimitry Andric // Parse the block-declarator. 3456e8d8bef9SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteral); 3457e8d8bef9SDimitry Andric DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 34580b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 34590b57cec5SDimitry Andric 34600b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 34610b57cec5SDimitry Andric 34620b57cec5SDimitry Andric // Inform sema that we are starting a block. 34630b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope()); 34640b57cec5SDimitry Andric } 34650b57cec5SDimitry Andric 34660b57cec5SDimitry Andric /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 34670b57cec5SDimitry Andric /// like ^(int x){ return x+1; } 34680b57cec5SDimitry Andric /// 34690b57cec5SDimitry Andric /// \verbatim 34700b57cec5SDimitry Andric /// block-literal: 34710b57cec5SDimitry Andric /// [clang] '^' block-args[opt] compound-statement 34720b57cec5SDimitry Andric /// [clang] '^' block-id compound-statement 34730b57cec5SDimitry Andric /// [clang] block-args: 34740b57cec5SDimitry Andric /// [clang] '(' parameter-list ')' 34750b57cec5SDimitry Andric /// \endverbatim 34760b57cec5SDimitry Andric ExprResult Parser::ParseBlockLiteralExpression() { 34770b57cec5SDimitry Andric assert(Tok.is(tok::caret) && "block literal starts with ^"); 34780b57cec5SDimitry Andric SourceLocation CaretLoc = ConsumeToken(); 34790b57cec5SDimitry Andric 34800b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 34810b57cec5SDimitry Andric "block literal parsing"); 34820b57cec5SDimitry Andric 34830b57cec5SDimitry Andric // Enter a scope to hold everything within the block. This includes the 34840b57cec5SDimitry Andric // argument decls, decls within the compound expression, etc. This also 34850b57cec5SDimitry Andric // allows determining whether a variable reference inside the block is 34860b57cec5SDimitry Andric // within or outside of the block. 34870b57cec5SDimitry Andric ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 34880b57cec5SDimitry Andric Scope::CompoundStmtScope | Scope::DeclScope); 34890b57cec5SDimitry Andric 34900b57cec5SDimitry Andric // Inform sema that we are starting a block. 34910b57cec5SDimitry Andric Actions.ActOnBlockStart(CaretLoc, getCurScope()); 34920b57cec5SDimitry Andric 34930b57cec5SDimitry Andric // Parse the return type if present. 34940b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 3495e8d8bef9SDimitry Andric Declarator ParamInfo(DS, DeclaratorContext::BlockLiteral); 3496e8d8bef9SDimitry Andric ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 34970b57cec5SDimitry Andric // FIXME: Since the return type isn't actually parsed, it can't be used to 34980b57cec5SDimitry Andric // fill ParamInfo with an initial valid range, so do it manually. 34990b57cec5SDimitry Andric ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 35000b57cec5SDimitry Andric 35010b57cec5SDimitry Andric // If this block has arguments, parse them. There is no ambiguity here with 35020b57cec5SDimitry Andric // the expression case, because the expression case requires a parameter list. 35030b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 35040b57cec5SDimitry Andric ParseParenDeclarator(ParamInfo); 35050b57cec5SDimitry Andric // Parse the pieces after the identifier as if we had "int(...)". 35060b57cec5SDimitry Andric // SetIdentifier sets the source range end, but in this case we're past 35070b57cec5SDimitry Andric // that location. 35080b57cec5SDimitry Andric SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 35090b57cec5SDimitry Andric ParamInfo.SetIdentifier(nullptr, CaretLoc); 35100b57cec5SDimitry Andric ParamInfo.SetRangeEnd(Tmp); 35110b57cec5SDimitry Andric if (ParamInfo.isInvalidType()) { 35120b57cec5SDimitry Andric // If there was an error parsing the arguments, they may have 35130b57cec5SDimitry Andric // tried to use ^(x+y) which requires an argument list. Just 35140b57cec5SDimitry Andric // skip the whole block literal. 35150b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 35160b57cec5SDimitry Andric return ExprError(); 35170b57cec5SDimitry Andric } 35180b57cec5SDimitry Andric 35190b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 35200b57cec5SDimitry Andric 35210b57cec5SDimitry Andric // Inform sema that we are starting a block. 35220b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 35230b57cec5SDimitry Andric } else if (!Tok.is(tok::l_brace)) { 35240b57cec5SDimitry Andric ParseBlockId(CaretLoc); 35250b57cec5SDimitry Andric } else { 35260b57cec5SDimitry Andric // Otherwise, pretend we saw (void). 35270b57cec5SDimitry Andric SourceLocation NoLoc; 35280b57cec5SDimitry Andric ParamInfo.AddTypeInfo( 35290b57cec5SDimitry Andric DeclaratorChunk::getFunction(/*HasProto=*/true, 35300b57cec5SDimitry Andric /*IsAmbiguous=*/false, 35310b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 35320b57cec5SDimitry Andric /*ArgInfo=*/nullptr, 35330b57cec5SDimitry Andric /*NumParams=*/0, 35340b57cec5SDimitry Andric /*EllipsisLoc=*/NoLoc, 35350b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 35360b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 35370b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, 35380b57cec5SDimitry Andric /*MutableLoc=*/NoLoc, EST_None, 35390b57cec5SDimitry Andric /*ESpecRange=*/SourceRange(), 35400b57cec5SDimitry Andric /*Exceptions=*/nullptr, 35410b57cec5SDimitry Andric /*ExceptionRanges=*/nullptr, 35420b57cec5SDimitry Andric /*NumExceptions=*/0, 35430b57cec5SDimitry Andric /*NoexceptExpr=*/nullptr, 35440b57cec5SDimitry Andric /*ExceptionSpecTokens=*/nullptr, 35450b57cec5SDimitry Andric /*DeclsInPrototype=*/None, CaretLoc, 35460b57cec5SDimitry Andric CaretLoc, ParamInfo), 35470b57cec5SDimitry Andric CaretLoc); 35480b57cec5SDimitry Andric 35490b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 35500b57cec5SDimitry Andric 35510b57cec5SDimitry Andric // Inform sema that we are starting a block. 35520b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 35530b57cec5SDimitry Andric } 35540b57cec5SDimitry Andric 35550b57cec5SDimitry Andric 35560b57cec5SDimitry Andric ExprResult Result(true); 35570b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 35580b57cec5SDimitry Andric // Saw something like: ^expr 35590b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 35600b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 35610b57cec5SDimitry Andric return ExprError(); 35620b57cec5SDimitry Andric } 35630b57cec5SDimitry Andric 35640b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 35650b57cec5SDimitry Andric BlockScope.Exit(); 35660b57cec5SDimitry Andric if (!Stmt.isInvalid()) 35670b57cec5SDimitry Andric Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope()); 35680b57cec5SDimitry Andric else 35690b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 35700b57cec5SDimitry Andric return Result; 35710b57cec5SDimitry Andric } 35720b57cec5SDimitry Andric 35730b57cec5SDimitry Andric /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals. 35740b57cec5SDimitry Andric /// 35750b57cec5SDimitry Andric /// '__objc_yes' 35760b57cec5SDimitry Andric /// '__objc_no' 35770b57cec5SDimitry Andric ExprResult Parser::ParseObjCBoolLiteral() { 35780b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 35790b57cec5SDimitry Andric return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind); 35800b57cec5SDimitry Andric } 35810b57cec5SDimitry Andric 35820b57cec5SDimitry Andric /// Validate availability spec list, emitting diagnostics if necessary. Returns 35830b57cec5SDimitry Andric /// true if invalid. 35840b57cec5SDimitry Andric static bool CheckAvailabilitySpecList(Parser &P, 35850b57cec5SDimitry Andric ArrayRef<AvailabilitySpec> AvailSpecs) { 35860b57cec5SDimitry Andric llvm::SmallSet<StringRef, 4> Platforms; 35870b57cec5SDimitry Andric bool HasOtherPlatformSpec = false; 35880b57cec5SDimitry Andric bool Valid = true; 35890b57cec5SDimitry Andric for (const auto &Spec : AvailSpecs) { 35900b57cec5SDimitry Andric if (Spec.isOtherPlatformSpec()) { 35910b57cec5SDimitry Andric if (HasOtherPlatformSpec) { 35920b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star); 35930b57cec5SDimitry Andric Valid = false; 35940b57cec5SDimitry Andric } 35950b57cec5SDimitry Andric 35960b57cec5SDimitry Andric HasOtherPlatformSpec = true; 35970b57cec5SDimitry Andric continue; 35980b57cec5SDimitry Andric } 35990b57cec5SDimitry Andric 36000b57cec5SDimitry Andric bool Inserted = Platforms.insert(Spec.getPlatform()).second; 36010b57cec5SDimitry Andric if (!Inserted) { 36020b57cec5SDimitry Andric // Rule out multiple version specs referring to the same platform. 36030b57cec5SDimitry Andric // For example, we emit an error for: 36040b57cec5SDimitry Andric // @available(macos 10.10, macos 10.11, *) 36050b57cec5SDimitry Andric StringRef Platform = Spec.getPlatform(); 36060b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform) 36070b57cec5SDimitry Andric << Spec.getEndLoc() << Platform; 36080b57cec5SDimitry Andric Valid = false; 36090b57cec5SDimitry Andric } 36100b57cec5SDimitry Andric } 36110b57cec5SDimitry Andric 36120b57cec5SDimitry Andric if (!HasOtherPlatformSpec) { 36130b57cec5SDimitry Andric SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc(); 36140b57cec5SDimitry Andric P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required) 36150b57cec5SDimitry Andric << FixItHint::CreateInsertion(InsertWildcardLoc, ", *"); 36160b57cec5SDimitry Andric return true; 36170b57cec5SDimitry Andric } 36180b57cec5SDimitry Andric 36190b57cec5SDimitry Andric return !Valid; 36200b57cec5SDimitry Andric } 36210b57cec5SDimitry Andric 36220b57cec5SDimitry Andric /// Parse availability query specification. 36230b57cec5SDimitry Andric /// 36240b57cec5SDimitry Andric /// availability-spec: 36250b57cec5SDimitry Andric /// '*' 36260b57cec5SDimitry Andric /// identifier version-tuple 36270b57cec5SDimitry Andric Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() { 36280b57cec5SDimitry Andric if (Tok.is(tok::star)) { 36290b57cec5SDimitry Andric return AvailabilitySpec(ConsumeToken()); 36300b57cec5SDimitry Andric } else { 36310b57cec5SDimitry Andric // Parse the platform name. 36320b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 36330b57cec5SDimitry Andric cutOffParsing(); 3634fe6060f1SDimitry Andric Actions.CodeCompleteAvailabilityPlatformName(); 36350b57cec5SDimitry Andric return None; 36360b57cec5SDimitry Andric } 36370b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 36380b57cec5SDimitry Andric Diag(Tok, diag::err_avail_query_expected_platform_name); 36390b57cec5SDimitry Andric return None; 36400b57cec5SDimitry Andric } 36410b57cec5SDimitry Andric 36420b57cec5SDimitry Andric IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc(); 36430b57cec5SDimitry Andric SourceRange VersionRange; 36440b57cec5SDimitry Andric VersionTuple Version = ParseVersionTuple(VersionRange); 36450b57cec5SDimitry Andric 36460b57cec5SDimitry Andric if (Version.empty()) 36470b57cec5SDimitry Andric return None; 36480b57cec5SDimitry Andric 36490b57cec5SDimitry Andric StringRef GivenPlatform = PlatformIdentifier->Ident->getName(); 36500b57cec5SDimitry Andric StringRef Platform = 36510b57cec5SDimitry Andric AvailabilityAttr::canonicalizePlatformName(GivenPlatform); 36520b57cec5SDimitry Andric 36530b57cec5SDimitry Andric if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) { 36540b57cec5SDimitry Andric Diag(PlatformIdentifier->Loc, 36550b57cec5SDimitry Andric diag::err_avail_query_unrecognized_platform_name) 36560b57cec5SDimitry Andric << GivenPlatform; 36570b57cec5SDimitry Andric return None; 36580b57cec5SDimitry Andric } 36590b57cec5SDimitry Andric 36600b57cec5SDimitry Andric return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc, 36610b57cec5SDimitry Andric VersionRange.getEnd()); 36620b57cec5SDimitry Andric } 36630b57cec5SDimitry Andric } 36640b57cec5SDimitry Andric 36650b57cec5SDimitry Andric ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { 36660b57cec5SDimitry Andric assert(Tok.is(tok::kw___builtin_available) || 36670b57cec5SDimitry Andric Tok.isObjCAtKeyword(tok::objc_available)); 36680b57cec5SDimitry Andric 36690b57cec5SDimitry Andric // Eat the available or __builtin_available. 36700b57cec5SDimitry Andric ConsumeToken(); 36710b57cec5SDimitry Andric 36720b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 36730b57cec5SDimitry Andric if (Parens.expectAndConsume()) 36740b57cec5SDimitry Andric return ExprError(); 36750b57cec5SDimitry Andric 36760b57cec5SDimitry Andric SmallVector<AvailabilitySpec, 4> AvailSpecs; 36770b57cec5SDimitry Andric bool HasError = false; 36780b57cec5SDimitry Andric while (true) { 36790b57cec5SDimitry Andric Optional<AvailabilitySpec> Spec = ParseAvailabilitySpec(); 36800b57cec5SDimitry Andric if (!Spec) 36810b57cec5SDimitry Andric HasError = true; 36820b57cec5SDimitry Andric else 36830b57cec5SDimitry Andric AvailSpecs.push_back(*Spec); 36840b57cec5SDimitry Andric 36850b57cec5SDimitry Andric if (!TryConsumeToken(tok::comma)) 36860b57cec5SDimitry Andric break; 36870b57cec5SDimitry Andric } 36880b57cec5SDimitry Andric 36890b57cec5SDimitry Andric if (HasError) { 36900b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 36910b57cec5SDimitry Andric return ExprError(); 36920b57cec5SDimitry Andric } 36930b57cec5SDimitry Andric 36940b57cec5SDimitry Andric CheckAvailabilitySpecList(*this, AvailSpecs); 36950b57cec5SDimitry Andric 36960b57cec5SDimitry Andric if (Parens.consumeClose()) 36970b57cec5SDimitry Andric return ExprError(); 36980b57cec5SDimitry Andric 36990b57cec5SDimitry Andric return Actions.ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, 37000b57cec5SDimitry Andric Parens.getCloseLocation()); 37010b57cec5SDimitry Andric } 3702