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" 25*480093f4SDimitry 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 149*480093f4SDimitry 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)) { 1620b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 1630b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 1640b57cec5SDimitry Andric cutOffParsing(); 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 173*480093f4SDimitry 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"); 206*480093f4SDimitry 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); 224*480093f4SDimitry 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( 237a7dea167SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 238*480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr)); 2390b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); 240*480093f4SDimitry Andric if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) { 241*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(Res); 242a7dea167SDimitry Andric return ExprError(); 243*480093f4SDimitry Andric } 2440b57cec5SDimitry Andric return Res; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 247*480093f4SDimitry Andric /// \brief Parse a constraint-logical-and-expression. 248*480093f4SDimitry Andric /// 249*480093f4SDimitry Andric /// \verbatim 250*480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 251*480093f4SDimitry Andric /// constraint-logical-and-expression: 252*480093f4SDimitry Andric /// primary-expression 253*480093f4SDimitry Andric /// constraint-logical-and-expression '&&' primary-expression 254*480093f4SDimitry Andric /// 255*480093f4SDimitry Andric /// \endverbatim 256*480093f4SDimitry Andric ExprResult 257*480093f4SDimitry Andric Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { 258*480093f4SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 259*480093f4SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 260*480093f4SDimitry Andric bool NotPrimaryExpression = false; 261*480093f4SDimitry Andric auto ParsePrimary = [&] () { 262*480093f4SDimitry Andric ExprResult E = ParseCastExpression(PrimaryExprOnly, 263*480093f4SDimitry Andric /*isAddressOfOperand=*/false, 264*480093f4SDimitry Andric /*isTypeCast=*/NotTypeCast, 265*480093f4SDimitry Andric /*isVectorLiteral=*/false, 266*480093f4SDimitry Andric &NotPrimaryExpression); 267*480093f4SDimitry Andric if (E.isInvalid()) 268*480093f4SDimitry Andric return ExprError(); 269*480093f4SDimitry Andric auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) { 270*480093f4SDimitry Andric E = ParsePostfixExpressionSuffix(E); 271*480093f4SDimitry Andric // Use InclusiveOr, the precedence just after '&&' to not parse the 272*480093f4SDimitry Andric // next arguments to the logical and. 273*480093f4SDimitry Andric E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr); 274*480093f4SDimitry Andric if (!E.isInvalid()) 275*480093f4SDimitry Andric Diag(E.get()->getExprLoc(), 276*480093f4SDimitry Andric Note 277*480093f4SDimitry Andric ? diag::note_unparenthesized_non_primary_expr_in_requires_clause 278*480093f4SDimitry Andric : diag::err_unparenthesized_non_primary_expr_in_requires_clause) 279*480093f4SDimitry Andric << FixItHint::CreateInsertion(E.get()->getBeginLoc(), "(") 280*480093f4SDimitry Andric << FixItHint::CreateInsertion( 281*480093f4SDimitry Andric PP.getLocForEndOfToken(E.get()->getEndLoc()), ")") 282*480093f4SDimitry Andric << E.get()->getSourceRange(); 283*480093f4SDimitry Andric return E; 284*480093f4SDimitry Andric }; 285*480093f4SDimitry Andric 286*480093f4SDimitry Andric if (NotPrimaryExpression || 287*480093f4SDimitry Andric // Check if the following tokens must be a part of a non-primary 288*480093f4SDimitry Andric // expression 289*480093f4SDimitry Andric getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 290*480093f4SDimitry Andric /*CPlusPlus11=*/true) > prec::LogicalAnd || 291*480093f4SDimitry Andric // Postfix operators other than '(' (which will be checked for in 292*480093f4SDimitry Andric // CheckConstraintExpression). 293*480093f4SDimitry Andric Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) || 294*480093f4SDimitry Andric (Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) { 295*480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/false); 296*480093f4SDimitry Andric if (E.isInvalid()) 297*480093f4SDimitry Andric return ExprError(); 298*480093f4SDimitry Andric NotPrimaryExpression = false; 299*480093f4SDimitry Andric } 300*480093f4SDimitry Andric bool PossibleNonPrimary; 301*480093f4SDimitry Andric bool IsConstraintExpr = 302*480093f4SDimitry Andric Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary, 303*480093f4SDimitry Andric IsTrailingRequiresClause); 304*480093f4SDimitry Andric if (!IsConstraintExpr || PossibleNonPrimary) { 305*480093f4SDimitry Andric // Atomic constraint might be an unparenthesized non-primary expression 306*480093f4SDimitry Andric // (such as a binary operator), in which case we might get here (e.g. in 307*480093f4SDimitry Andric // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore 308*480093f4SDimitry Andric // the rest of the addition expression). Try to parse the rest of it here. 309*480093f4SDimitry Andric if (PossibleNonPrimary) 310*480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr); 311*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 312*480093f4SDimitry Andric return ExprError(); 313*480093f4SDimitry Andric } 314*480093f4SDimitry Andric return E; 315*480093f4SDimitry Andric }; 316*480093f4SDimitry Andric ExprResult LHS = ParsePrimary(); 317*480093f4SDimitry Andric if (LHS.isInvalid()) 318*480093f4SDimitry Andric return ExprError(); 319*480093f4SDimitry Andric while (Tok.is(tok::ampamp)) { 320*480093f4SDimitry Andric SourceLocation LogicalAndLoc = ConsumeToken(); 321*480093f4SDimitry Andric ExprResult RHS = ParsePrimary(); 322*480093f4SDimitry Andric if (RHS.isInvalid()) { 323*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 324*480093f4SDimitry Andric return ExprError(); 325*480093f4SDimitry Andric } 326*480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc, 327*480093f4SDimitry Andric tok::ampamp, LHS.get(), RHS.get()); 328*480093f4SDimitry Andric if (!Op.isUsable()) { 329*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 330*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 331*480093f4SDimitry Andric return ExprError(); 332*480093f4SDimitry Andric } 333*480093f4SDimitry Andric LHS = Op; 334*480093f4SDimitry Andric } 335*480093f4SDimitry Andric return LHS; 336*480093f4SDimitry Andric } 337*480093f4SDimitry Andric 338*480093f4SDimitry Andric /// \brief Parse a constraint-logical-or-expression. 339*480093f4SDimitry Andric /// 340*480093f4SDimitry Andric /// \verbatim 341*480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 342*480093f4SDimitry Andric /// constraint-logical-or-expression: 343*480093f4SDimitry Andric /// constraint-logical-and-expression 344*480093f4SDimitry Andric /// constraint-logical-or-expression '||' 345*480093f4SDimitry Andric /// constraint-logical-and-expression 346*480093f4SDimitry Andric /// 347*480093f4SDimitry Andric /// \endverbatim 348*480093f4SDimitry Andric ExprResult 349*480093f4SDimitry Andric Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) { 350*480093f4SDimitry Andric ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause)); 351*480093f4SDimitry Andric if (!LHS.isUsable()) 352*480093f4SDimitry Andric return ExprError(); 353*480093f4SDimitry Andric while (Tok.is(tok::pipepipe)) { 354*480093f4SDimitry Andric SourceLocation LogicalOrLoc = ConsumeToken(); 355*480093f4SDimitry Andric ExprResult RHS = 356*480093f4SDimitry Andric ParseConstraintLogicalAndExpression(IsTrailingRequiresClause); 357*480093f4SDimitry Andric if (!RHS.isUsable()) { 358*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 359*480093f4SDimitry Andric return ExprError(); 360*480093f4SDimitry Andric } 361*480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc, 362*480093f4SDimitry Andric tok::pipepipe, LHS.get(), RHS.get()); 363*480093f4SDimitry Andric if (!Op.isUsable()) { 364*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 365*480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 366*480093f4SDimitry Andric return ExprError(); 367*480093f4SDimitry Andric } 368*480093f4SDimitry Andric LHS = Op; 369*480093f4SDimitry Andric } 370*480093f4SDimitry Andric return LHS; 371*480093f4SDimitry Andric } 372*480093f4SDimitry 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 546*480093f4SDimitry 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 6280b57cec5SDimitry Andric LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), 6290b57cec5SDimitry Andric OpToken.getKind(), LHS.get(), RHS.get()); 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric } else { 6320b57cec5SDimitry Andric LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, 6330b57cec5SDimitry Andric LHS.get(), TernaryMiddle.get(), 6340b57cec5SDimitry Andric RHS.get()); 6350b57cec5SDimitry Andric } 6360b57cec5SDimitry Andric // In this case, ActOnBinOp or ActOnConditionalOp performed the 6370b57cec5SDimitry Andric // CorrectDelayedTyposInExpr check. 6380b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 6390b57cec5SDimitry Andric continue; 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric // Ensure potential typos aren't left undiagnosed. 6430b57cec5SDimitry Andric if (LHS.isInvalid()) { 6440b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(OrigLHS); 6450b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6460b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric } 6490b57cec5SDimitry Andric } 6500b57cec5SDimitry Andric 651*480093f4SDimitry Andric /// Parse a cast-expression, unary-expression or primary-expression, based 652*480093f4SDimitry Andric /// on \p ExprType. 6530b57cec5SDimitry Andric /// 6540b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the 6550b57cec5SDimitry Andric /// operand of address-of gets special treatment due to member pointers. 6560b57cec5SDimitry Andric /// 657*480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 6580b57cec5SDimitry Andric bool isAddressOfOperand, 6590b57cec5SDimitry Andric TypeCastState isTypeCast, 660*480093f4SDimitry Andric bool isVectorLiteral, 661*480093f4SDimitry Andric bool *NotPrimaryExpression) { 6620b57cec5SDimitry Andric bool NotCastExpr; 663*480093f4SDimitry Andric ExprResult Res = ParseCastExpression(ParseKind, 6640b57cec5SDimitry Andric isAddressOfOperand, 6650b57cec5SDimitry Andric NotCastExpr, 6660b57cec5SDimitry Andric isTypeCast, 667*480093f4SDimitry Andric isVectorLiteral, 668*480093f4SDimitry Andric NotPrimaryExpression); 6690b57cec5SDimitry Andric if (NotCastExpr) 6700b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 6710b57cec5SDimitry Andric return Res; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric namespace { 6750b57cec5SDimitry Andric class CastExpressionIdValidator final : public CorrectionCandidateCallback { 6760b57cec5SDimitry Andric public: 6770b57cec5SDimitry Andric CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes) 6780b57cec5SDimitry Andric : NextToken(Next), AllowNonTypes(AllowNonTypes) { 6790b57cec5SDimitry Andric WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes; 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric bool ValidateCandidate(const TypoCorrection &candidate) override { 6830b57cec5SDimitry Andric NamedDecl *ND = candidate.getCorrectionDecl(); 6840b57cec5SDimitry Andric if (!ND) 6850b57cec5SDimitry Andric return candidate.isKeyword(); 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric if (isa<TypeDecl>(ND)) 6880b57cec5SDimitry Andric return WantTypeSpecifiers; 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate)) 6910b57cec5SDimitry Andric return false; 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period)) 6940b57cec5SDimitry Andric return true; 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric for (auto *C : candidate) { 6970b57cec5SDimitry Andric NamedDecl *ND = C->getUnderlyingDecl(); 6980b57cec5SDimitry Andric if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND)) 6990b57cec5SDimitry Andric return true; 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric return false; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric std::unique_ptr<CorrectionCandidateCallback> clone() override { 705a7dea167SDimitry Andric return std::make_unique<CastExpressionIdValidator>(*this); 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric private: 7090b57cec5SDimitry Andric Token NextToken; 7100b57cec5SDimitry Andric bool AllowNonTypes; 7110b57cec5SDimitry Andric }; 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse 7150b57cec5SDimitry Andric /// a unary-expression. 7160b57cec5SDimitry Andric /// 7170b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the operand 7180b57cec5SDimitry Andric /// of address-of gets special treatment due to member pointers. NotCastExpr 7190b57cec5SDimitry Andric /// is set to true if the token is not the start of a cast-expression, and no 7200b57cec5SDimitry Andric /// diagnostic is emitted in this case and no tokens are consumed. 7210b57cec5SDimitry Andric /// 7220b57cec5SDimitry Andric /// \verbatim 7230b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 7240b57cec5SDimitry Andric /// unary-expression 7250b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 7260b57cec5SDimitry Andric /// 7270b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 7280b57cec5SDimitry Andric /// postfix-expression 7290b57cec5SDimitry Andric /// '++' unary-expression 7300b57cec5SDimitry Andric /// '--' unary-expression 7310b57cec5SDimitry Andric /// [Coro] 'co_await' cast-expression 7320b57cec5SDimitry Andric /// unary-operator cast-expression 7330b57cec5SDimitry Andric /// 'sizeof' unary-expression 7340b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 7350b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 7360b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 7370b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 7380b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 7390b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 7400b57cec5SDimitry Andric /// [GNU] '&&' identifier 7410b57cec5SDimitry Andric /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7] 7420b57cec5SDimitry Andric /// [C++] new-expression 7430b57cec5SDimitry Andric /// [C++] delete-expression 7440b57cec5SDimitry Andric /// 7450b57cec5SDimitry Andric /// unary-operator: one of 7460b57cec5SDimitry Andric /// '&' '*' '+' '-' '~' '!' 7470b57cec5SDimitry Andric /// [GNU] '__extension__' '__real' '__imag' 7480b57cec5SDimitry Andric /// 7490b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 7500b57cec5SDimitry Andric /// [C99] identifier 7510b57cec5SDimitry Andric /// [C++] id-expression 7520b57cec5SDimitry Andric /// constant 7530b57cec5SDimitry Andric /// string-literal 7540b57cec5SDimitry Andric /// [C++] boolean-literal [C++ 2.13.5] 7550b57cec5SDimitry Andric /// [C++11] 'nullptr' [C++11 2.14.7] 7560b57cec5SDimitry Andric /// [C++11] user-defined-literal 7570b57cec5SDimitry Andric /// '(' expression ')' 7580b57cec5SDimitry Andric /// [C11] generic-selection 7590b57cec5SDimitry Andric /// '__func__' [C99 6.4.2.2] 7600b57cec5SDimitry Andric /// [GNU] '__FUNCTION__' 7610b57cec5SDimitry Andric /// [MS] '__FUNCDNAME__' 7620b57cec5SDimitry Andric /// [MS] 'L__FUNCTION__' 7630b57cec5SDimitry Andric /// [MS] '__FUNCSIG__' 7640b57cec5SDimitry Andric /// [MS] 'L__FUNCSIG__' 7650b57cec5SDimitry Andric /// [GNU] '__PRETTY_FUNCTION__' 7660b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' 7670b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 7680b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 7690b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 7700b57cec5SDimitry Andric /// assign-expr ')' 7710b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 7720b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 7730b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 7740b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 7750b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 7760b57cec5SDimitry Andric /// [GNU] '__null' 7770b57cec5SDimitry Andric /// [OBJC] '[' objc-message-expr ']' 7780b57cec5SDimitry Andric /// [OBJC] '\@selector' '(' objc-selector-arg ')' 7790b57cec5SDimitry Andric /// [OBJC] '\@protocol' '(' identifier ')' 7800b57cec5SDimitry Andric /// [OBJC] '\@encode' '(' type-name ')' 7810b57cec5SDimitry Andric /// [OBJC] objc-string-literal 7820b57cec5SDimitry Andric /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 7830b57cec5SDimitry Andric /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] 7840b57cec5SDimitry Andric /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 7850b57cec5SDimitry Andric /// [C++11] typename-specifier braced-init-list [C++11 5.2.3] 7860b57cec5SDimitry Andric /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 7870b57cec5SDimitry Andric /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 7880b57cec5SDimitry Andric /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 7890b57cec5SDimitry Andric /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 7900b57cec5SDimitry Andric /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 7910b57cec5SDimitry Andric /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 7920b57cec5SDimitry Andric /// [C++] 'this' [C++ 9.3.2] 7930b57cec5SDimitry Andric /// [G++] unary-type-trait '(' type-id ')' 7940b57cec5SDimitry Andric /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 7950b57cec5SDimitry Andric /// [EMBT] array-type-trait '(' type-id ',' integer ')' 7960b57cec5SDimitry Andric /// [clang] '^' block-literal 7970b57cec5SDimitry Andric /// 7980b57cec5SDimitry Andric /// constant: [C99 6.4.4] 7990b57cec5SDimitry Andric /// integer-constant 8000b57cec5SDimitry Andric /// floating-constant 8010b57cec5SDimitry Andric /// enumeration-constant -> identifier 8020b57cec5SDimitry Andric /// character-constant 8030b57cec5SDimitry Andric /// 8040b57cec5SDimitry Andric /// id-expression: [C++ 5.1] 8050b57cec5SDimitry Andric /// unqualified-id 8060b57cec5SDimitry Andric /// qualified-id 8070b57cec5SDimitry Andric /// 8080b57cec5SDimitry Andric /// unqualified-id: [C++ 5.1] 8090b57cec5SDimitry Andric /// identifier 8100b57cec5SDimitry Andric /// operator-function-id 8110b57cec5SDimitry Andric /// conversion-function-id 8120b57cec5SDimitry Andric /// '~' class-name 8130b57cec5SDimitry Andric /// template-id 8140b57cec5SDimitry Andric /// 8150b57cec5SDimitry Andric /// new-expression: [C++ 5.3.4] 8160b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 8170b57cec5SDimitry Andric /// new-initializer[opt] 8180b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8190b57cec5SDimitry Andric /// new-initializer[opt] 8200b57cec5SDimitry Andric /// 8210b57cec5SDimitry Andric /// delete-expression: [C++ 5.3.5] 8220b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 8230b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 8240b57cec5SDimitry Andric /// 8250b57cec5SDimitry Andric /// [GNU/Embarcadero] unary-type-trait: 8260b57cec5SDimitry Andric /// '__is_arithmetic' 8270b57cec5SDimitry Andric /// '__is_floating_point' 8280b57cec5SDimitry Andric /// '__is_integral' 8290b57cec5SDimitry Andric /// '__is_lvalue_expr' 8300b57cec5SDimitry Andric /// '__is_rvalue_expr' 8310b57cec5SDimitry Andric /// '__is_complete_type' 8320b57cec5SDimitry Andric /// '__is_void' 8330b57cec5SDimitry Andric /// '__is_array' 8340b57cec5SDimitry Andric /// '__is_function' 8350b57cec5SDimitry Andric /// '__is_reference' 8360b57cec5SDimitry Andric /// '__is_lvalue_reference' 8370b57cec5SDimitry Andric /// '__is_rvalue_reference' 8380b57cec5SDimitry Andric /// '__is_fundamental' 8390b57cec5SDimitry Andric /// '__is_object' 8400b57cec5SDimitry Andric /// '__is_scalar' 8410b57cec5SDimitry Andric /// '__is_compound' 8420b57cec5SDimitry Andric /// '__is_pointer' 8430b57cec5SDimitry Andric /// '__is_member_object_pointer' 8440b57cec5SDimitry Andric /// '__is_member_function_pointer' 8450b57cec5SDimitry Andric /// '__is_member_pointer' 8460b57cec5SDimitry Andric /// '__is_const' 8470b57cec5SDimitry Andric /// '__is_volatile' 8480b57cec5SDimitry Andric /// '__is_trivial' 8490b57cec5SDimitry Andric /// '__is_standard_layout' 8500b57cec5SDimitry Andric /// '__is_signed' 8510b57cec5SDimitry Andric /// '__is_unsigned' 8520b57cec5SDimitry Andric /// 8530b57cec5SDimitry Andric /// [GNU] unary-type-trait: 8540b57cec5SDimitry Andric /// '__has_nothrow_assign' 8550b57cec5SDimitry Andric /// '__has_nothrow_copy' 8560b57cec5SDimitry Andric /// '__has_nothrow_constructor' 8570b57cec5SDimitry Andric /// '__has_trivial_assign' [TODO] 8580b57cec5SDimitry Andric /// '__has_trivial_copy' [TODO] 8590b57cec5SDimitry Andric /// '__has_trivial_constructor' 8600b57cec5SDimitry Andric /// '__has_trivial_destructor' 8610b57cec5SDimitry Andric /// '__has_virtual_destructor' 8620b57cec5SDimitry Andric /// '__is_abstract' [TODO] 8630b57cec5SDimitry Andric /// '__is_class' 8640b57cec5SDimitry Andric /// '__is_empty' [TODO] 8650b57cec5SDimitry Andric /// '__is_enum' 8660b57cec5SDimitry Andric /// '__is_final' 8670b57cec5SDimitry Andric /// '__is_pod' 8680b57cec5SDimitry Andric /// '__is_polymorphic' 8690b57cec5SDimitry Andric /// '__is_sealed' [MS] 8700b57cec5SDimitry Andric /// '__is_trivial' 8710b57cec5SDimitry Andric /// '__is_union' 8720b57cec5SDimitry Andric /// '__has_unique_object_representations' 8730b57cec5SDimitry Andric /// 8740b57cec5SDimitry Andric /// [Clang] unary-type-trait: 8750b57cec5SDimitry Andric /// '__is_aggregate' 8760b57cec5SDimitry Andric /// '__trivially_copyable' 8770b57cec5SDimitry Andric /// 8780b57cec5SDimitry Andric /// binary-type-trait: 8790b57cec5SDimitry Andric /// [GNU] '__is_base_of' 8800b57cec5SDimitry Andric /// [MS] '__is_convertible_to' 8810b57cec5SDimitry Andric /// '__is_convertible' 8820b57cec5SDimitry Andric /// '__is_same' 8830b57cec5SDimitry Andric /// 8840b57cec5SDimitry Andric /// [Embarcadero] array-type-trait: 8850b57cec5SDimitry Andric /// '__array_rank' 8860b57cec5SDimitry Andric /// '__array_extent' 8870b57cec5SDimitry Andric /// 8880b57cec5SDimitry Andric /// [Embarcadero] expression-trait: 8890b57cec5SDimitry Andric /// '__is_lvalue_expr' 8900b57cec5SDimitry Andric /// '__is_rvalue_expr' 8910b57cec5SDimitry Andric /// \endverbatim 8920b57cec5SDimitry Andric /// 893*480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 8940b57cec5SDimitry Andric bool isAddressOfOperand, 8950b57cec5SDimitry Andric bool &NotCastExpr, 8960b57cec5SDimitry Andric TypeCastState isTypeCast, 897*480093f4SDimitry Andric bool isVectorLiteral, 898*480093f4SDimitry Andric bool *NotPrimaryExpression) { 8990b57cec5SDimitry Andric ExprResult Res; 9000b57cec5SDimitry Andric tok::TokenKind SavedKind = Tok.getKind(); 9010b57cec5SDimitry Andric auto SavedType = PreferredType; 9020b57cec5SDimitry Andric NotCastExpr = false; 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric // This handles all of cast-expression, unary-expression, postfix-expression, 9050b57cec5SDimitry Andric // and primary-expression. We handle them together like this for efficiency 9060b57cec5SDimitry Andric // and to simplify handling of an expression starting with a '(' token: which 9070b57cec5SDimitry Andric // may be one of a parenthesized expression, cast-expression, compound literal 9080b57cec5SDimitry Andric // expression, or statement expression. 9090b57cec5SDimitry Andric // 9100b57cec5SDimitry Andric // If the parsed tokens consist of a primary-expression, the cases below 9110b57cec5SDimitry Andric // break out of the switch; at the end we call ParsePostfixExpressionSuffix 9120b57cec5SDimitry Andric // to handle the postfix expression suffixes. Cases that cannot be followed 9130b57cec5SDimitry Andric // by postfix exprs should return without invoking 9140b57cec5SDimitry Andric // ParsePostfixExpressionSuffix. 9150b57cec5SDimitry Andric switch (SavedKind) { 9160b57cec5SDimitry Andric case tok::l_paren: { 917*480093f4SDimitry Andric // If this expression is limited to being a unary-expression, the paren can 9180b57cec5SDimitry Andric // not start a cast expression. 919*480093f4SDimitry Andric ParenParseOption ParenExprType; 920*480093f4SDimitry Andric switch (ParseKind) { 921*480093f4SDimitry Andric case CastParseKind::UnaryExprOnly: 922*480093f4SDimitry Andric if (!getLangOpts().CPlusPlus) 923*480093f4SDimitry Andric ParenExprType = CompoundLiteral; 924*480093f4SDimitry Andric LLVM_FALLTHROUGH; 925*480093f4SDimitry Andric case CastParseKind::AnyCastExpr: 926*480093f4SDimitry Andric ParenExprType = ParenParseOption::CastExpr; 927*480093f4SDimitry Andric break; 928*480093f4SDimitry Andric case CastParseKind::PrimaryExprOnly: 929*480093f4SDimitry Andric ParenExprType = FoldExpr; 930*480093f4SDimitry Andric break; 931*480093f4SDimitry Andric } 9320b57cec5SDimitry Andric ParsedType CastTy; 9330b57cec5SDimitry Andric SourceLocation RParenLoc; 9340b57cec5SDimitry Andric Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 9350b57cec5SDimitry Andric isTypeCast == IsTypeCast, CastTy, RParenLoc); 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric if (isVectorLiteral) 9380b57cec5SDimitry Andric return Res; 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andric switch (ParenExprType) { 9410b57cec5SDimitry Andric case SimpleExpr: break; // Nothing else to do. 9420b57cec5SDimitry Andric case CompoundStmt: break; // Nothing else to do. 9430b57cec5SDimitry Andric case CompoundLiteral: 9440b57cec5SDimitry Andric // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 9450b57cec5SDimitry Andric // postfix-expression exist, parse them now. 9460b57cec5SDimitry Andric break; 9470b57cec5SDimitry Andric case CastExpr: 9480b57cec5SDimitry Andric // We have parsed the cast-expression and no postfix-expr pieces are 9490b57cec5SDimitry Andric // following. 9500b57cec5SDimitry Andric return Res; 9510b57cec5SDimitry Andric case FoldExpr: 9520b57cec5SDimitry Andric // We only parsed a fold-expression. There might be postfix-expr pieces 9530b57cec5SDimitry Andric // afterwards; parse them now. 9540b57cec5SDimitry Andric break; 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric break; 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric // primary-expression 9610b57cec5SDimitry Andric case tok::numeric_constant: 9620b57cec5SDimitry Andric // constant: integer-constant 9630b57cec5SDimitry Andric // constant: floating-constant 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andric Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope()); 9660b57cec5SDimitry Andric ConsumeToken(); 9670b57cec5SDimitry Andric break; 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andric case tok::kw_true: 9700b57cec5SDimitry Andric case tok::kw_false: 9710b57cec5SDimitry Andric Res = ParseCXXBoolLiteral(); 9720b57cec5SDimitry Andric break; 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric case tok::kw___objc_yes: 9750b57cec5SDimitry Andric case tok::kw___objc_no: 9760b57cec5SDimitry Andric return ParseObjCBoolLiteral(); 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric case tok::kw_nullptr: 9790b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_nullptr); 9800b57cec5SDimitry Andric return Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 9810b57cec5SDimitry Andric 9820b57cec5SDimitry Andric case tok::annot_primary_expr: 9830b57cec5SDimitry Andric Res = getExprAnnotation(Tok); 9840b57cec5SDimitry Andric ConsumeAnnotationToken(); 9850b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 9860b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 9870b57cec5SDimitry Andric break; 9880b57cec5SDimitry Andric 989a7dea167SDimitry Andric case tok::annot_non_type: 990a7dea167SDimitry Andric case tok::annot_non_type_dependent: 991a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 992a7dea167SDimitry Andric CXXScopeSpec SS; 993a7dea167SDimitry Andric Token Replacement; 994a7dea167SDimitry Andric Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 995a7dea167SDimitry Andric assert(!Res.isUnset() && 996a7dea167SDimitry Andric "should not perform typo correction on annotation token"); 997a7dea167SDimitry Andric break; 998a7dea167SDimitry Andric } 999a7dea167SDimitry Andric 10000b57cec5SDimitry Andric case tok::kw___super: 10010b57cec5SDimitry Andric case tok::kw_decltype: 10020b57cec5SDimitry Andric // Annotate the token and tail recurse. 10030b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 10040b57cec5SDimitry Andric return ExprError(); 10050b57cec5SDimitry Andric assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); 1006*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1007*480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric case tok::identifier: { // primary-expression: identifier 10100b57cec5SDimitry Andric // unqualified-id: identifier 10110b57cec5SDimitry Andric // constant: enumeration-constant 10120b57cec5SDimitry Andric // Turn a potentially qualified name into a annot_typename or 10130b57cec5SDimitry Andric // annot_cxxscope if it would be valid. This handles things like x::y, etc. 10140b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) { 10150b57cec5SDimitry Andric // Avoid the unnecessary parse-time lookup in the common case 10160b57cec5SDimitry Andric // where the syntax forbids a type. 10170b57cec5SDimitry Andric const Token &Next = NextToken(); 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric // If this identifier was reverted from a token ID, and the next token 10200b57cec5SDimitry Andric // is a parenthesis, this is likely to be a use of a type trait. Check 10210b57cec5SDimitry Andric // those tokens. 10220b57cec5SDimitry Andric if (Next.is(tok::l_paren) && 10230b57cec5SDimitry Andric Tok.is(tok::identifier) && 10240b57cec5SDimitry Andric Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { 10250b57cec5SDimitry Andric IdentifierInfo *II = Tok.getIdentifierInfo(); 10260b57cec5SDimitry Andric // Build up the mapping of revertible type traits, for future use. 10270b57cec5SDimitry Andric if (RevertibleTypeTraits.empty()) { 10280b57cec5SDimitry Andric #define RTT_JOIN(X,Y) X##Y 10290b57cec5SDimitry Andric #define REVERTIBLE_TYPE_TRAIT(Name) \ 10300b57cec5SDimitry Andric RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ 10310b57cec5SDimitry Andric = RTT_JOIN(tok::kw_,Name) 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_abstract); 10340b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_aggregate); 10350b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_arithmetic); 10360b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_array); 10370b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_assignable); 10380b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_base_of); 10390b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_class); 10400b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_complete_type); 10410b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_compound); 10420b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_const); 10430b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_constructible); 10440b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible); 10450b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible_to); 10460b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_destructible); 10470b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_empty); 10480b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_enum); 10490b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_floating_point); 10500b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_final); 10510b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_function); 10520b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_fundamental); 10530b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_integral); 10540b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_interface_class); 10550b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_literal); 10560b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); 10570b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); 10580b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); 10590b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); 10600b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_pointer); 10610b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); 10620b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); 10630b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); 10640b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_object); 10650b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pod); 10660b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pointer); 10670b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_polymorphic); 10680b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_reference); 10690b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); 10700b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); 10710b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_same); 10720b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scalar); 10730b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_sealed); 10740b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_signed); 10750b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_standard_layout); 10760b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivial); 10770b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); 10780b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); 10790b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); 10800b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_union); 10810b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unsigned); 10820b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_void); 10830b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_volatile); 10840b57cec5SDimitry Andric #undef REVERTIBLE_TYPE_TRAIT 10850b57cec5SDimitry Andric #undef RTT_JOIN 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric // If we find that this is in fact the name of a type trait, 10890b57cec5SDimitry Andric // update the token kind in place and parse again to treat it as 10900b57cec5SDimitry Andric // the appropriate kind of type trait. 10910b57cec5SDimitry Andric llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known 10920b57cec5SDimitry Andric = RevertibleTypeTraits.find(II); 10930b57cec5SDimitry Andric if (Known != RevertibleTypeTraits.end()) { 10940b57cec5SDimitry Andric Tok.setKind(Known->second); 1095*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1096*480093f4SDimitry Andric NotCastExpr, isTypeCast, 1097*480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 10980b57cec5SDimitry Andric } 10990b57cec5SDimitry Andric } 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric if ((!ColonIsSacred && Next.is(tok::colon)) || 11020b57cec5SDimitry Andric Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren, 11030b57cec5SDimitry Andric tok::l_brace)) { 11040b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 11050b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 11060b57cec5SDimitry Andric return ExprError(); 11070b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) 1108*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1109*480093f4SDimitry Andric NotCastExpr, isTypeCast, 1110*480093f4SDimitry Andric isVectorLiteral, 1111*480093f4SDimitry Andric NotPrimaryExpression); 11120b57cec5SDimitry Andric } 11130b57cec5SDimitry Andric } 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric // Consume the identifier so that we can see if it is followed by a '(' or 11160b57cec5SDimitry Andric // '.'. 11170b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 11180b57cec5SDimitry Andric SourceLocation ILoc = ConsumeToken(); 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric // Support 'Class.property' and 'super.property' notation. 11210b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.is(tok::period) && 11220b57cec5SDimitry Andric (Actions.getTypeName(II, ILoc, getCurScope()) || 11230b57cec5SDimitry Andric // Allow the base to be 'super' if in an objc-method. 11240b57cec5SDimitry Andric (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { 11250b57cec5SDimitry Andric ConsumeToken(); 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && &II != Ident_super) { 11280b57cec5SDimitry Andric Actions.CodeCompleteObjCClassPropertyRefExpr( 11290b57cec5SDimitry Andric getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); 11300b57cec5SDimitry Andric cutOffParsing(); 11310b57cec5SDimitry Andric return ExprError(); 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric // Allow either an identifier or the keyword 'class' (in C++). 11340b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) && 11350b57cec5SDimitry Andric !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { 11360b57cec5SDimitry Andric Diag(Tok, diag::err_expected_property_name); 11370b57cec5SDimitry Andric return ExprError(); 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 11400b57cec5SDimitry Andric SourceLocation PropertyLoc = ConsumeToken(); 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, 11430b57cec5SDimitry Andric ILoc, PropertyLoc); 11440b57cec5SDimitry Andric break; 11450b57cec5SDimitry Andric } 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric // In an Objective-C method, if we have "super" followed by an identifier, 11480b57cec5SDimitry Andric // the token sequence is ill-formed. However, if there's a ':' or ']' after 11490b57cec5SDimitry Andric // that identifier, this is probably a message send with a missing open 11500b57cec5SDimitry Andric // bracket. Treat it as such. 11510b57cec5SDimitry Andric if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression && 11520b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 11530b57cec5SDimitry Andric ((Tok.is(tok::identifier) && 11540b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || 11550b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 11560b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr, 11570b57cec5SDimitry Andric nullptr); 11580b57cec5SDimitry Andric break; 11590b57cec5SDimitry Andric } 11600b57cec5SDimitry Andric 11610b57cec5SDimitry Andric // If we have an Objective-C class name followed by an identifier 11620b57cec5SDimitry Andric // and either ':' or ']', this is an Objective-C class message 11630b57cec5SDimitry Andric // send that's missing the opening '['. Recovery 11640b57cec5SDimitry Andric // appropriately. Also take this path if we're performing code 11650b57cec5SDimitry Andric // completion after an Objective-C class name. 11660b57cec5SDimitry Andric if (getLangOpts().ObjC && 11670b57cec5SDimitry Andric ((Tok.is(tok::identifier) && !InMessageExpression) || 11680b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 11690b57cec5SDimitry Andric const Token& Next = NextToken(); 11700b57cec5SDimitry Andric if (Tok.is(tok::code_completion) || 11710b57cec5SDimitry Andric Next.is(tok::colon) || Next.is(tok::r_square)) 11720b57cec5SDimitry Andric if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) 11730b57cec5SDimitry Andric if (Typ.get()->isObjCObjectOrInterfaceType()) { 11740b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 11750b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 11760b57cec5SDimitry Andric DS.SetRangeStart(ILoc); 11770b57cec5SDimitry Andric DS.SetRangeEnd(ILoc); 11780b57cec5SDimitry Andric const char *PrevSpec = nullptr; 11790b57cec5SDimitry Andric unsigned DiagID; 11800b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, 11810b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 11840b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), 11850b57cec5SDimitry Andric DeclaratorInfo); 11860b57cec5SDimitry Andric if (Ty.isInvalid()) 11870b57cec5SDimitry Andric break; 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), 11900b57cec5SDimitry Andric SourceLocation(), 11910b57cec5SDimitry Andric Ty.get(), nullptr); 11920b57cec5SDimitry Andric break; 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric // Make sure to pass down the right value for isAddressOfOperand. 11970b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 11980b57cec5SDimitry Andric isAddressOfOperand = false; 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 12010b57cec5SDimitry Andric // need to know whether or not this identifier is a function designator or 12020b57cec5SDimitry Andric // not. 12030b57cec5SDimitry Andric UnqualifiedId Name; 12040b57cec5SDimitry Andric CXXScopeSpec ScopeSpec; 12050b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 12060b57cec5SDimitry Andric Token Replacement; 12070b57cec5SDimitry Andric CastExpressionIdValidator Validator( 12080b57cec5SDimitry Andric /*Next=*/Tok, 12090b57cec5SDimitry Andric /*AllowTypes=*/isTypeCast != NotTypeCast, 12100b57cec5SDimitry Andric /*AllowNonTypes=*/isTypeCast != IsTypeCast); 12110b57cec5SDimitry Andric Validator.IsAddressOfOperand = isAddressOfOperand; 12120b57cec5SDimitry Andric if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) { 12130b57cec5SDimitry Andric Validator.WantExpressionKeywords = false; 12140b57cec5SDimitry Andric Validator.WantRemainingKeywords = false; 12150b57cec5SDimitry Andric } else { 12160b57cec5SDimitry Andric Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren); 12170b57cec5SDimitry Andric } 12180b57cec5SDimitry Andric Name.setIdentifier(&II, ILoc); 12190b57cec5SDimitry Andric Res = Actions.ActOnIdExpression( 12200b57cec5SDimitry Andric getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), 12210b57cec5SDimitry Andric isAddressOfOperand, &Validator, 12220b57cec5SDimitry Andric /*IsInlineAsmIdentifier=*/false, 12230b57cec5SDimitry Andric Tok.is(tok::r_paren) ? nullptr : &Replacement); 12240b57cec5SDimitry Andric if (!Res.isInvalid() && Res.isUnset()) { 12250b57cec5SDimitry Andric UnconsumeToken(Replacement); 1226*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1227*480093f4SDimitry Andric NotCastExpr, isTypeCast, 1228*480093f4SDimitry Andric /*isVectorLiteral=*/false, 1229*480093f4SDimitry Andric NotPrimaryExpression); 12300b57cec5SDimitry Andric } 12310b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 12320b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 12330b57cec5SDimitry Andric break; 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric case tok::char_constant: // constant: character-constant 12360b57cec5SDimitry Andric case tok::wide_char_constant: 12370b57cec5SDimitry Andric case tok::utf8_char_constant: 12380b57cec5SDimitry Andric case tok::utf16_char_constant: 12390b57cec5SDimitry Andric case tok::utf32_char_constant: 12400b57cec5SDimitry Andric Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope()); 12410b57cec5SDimitry Andric ConsumeToken(); 12420b57cec5SDimitry Andric break; 12430b57cec5SDimitry Andric case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 12440b57cec5SDimitry Andric case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 12450b57cec5SDimitry Andric case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] 12460b57cec5SDimitry Andric case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS] 12470b57cec5SDimitry Andric case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] 12480b57cec5SDimitry Andric case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] 12490b57cec5SDimitry Andric case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 12500b57cec5SDimitry Andric Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 12510b57cec5SDimitry Andric ConsumeToken(); 12520b57cec5SDimitry Andric break; 12530b57cec5SDimitry Andric case tok::string_literal: // primary-expression: string-literal 12540b57cec5SDimitry Andric case tok::wide_string_literal: 12550b57cec5SDimitry Andric case tok::utf8_string_literal: 12560b57cec5SDimitry Andric case tok::utf16_string_literal: 12570b57cec5SDimitry Andric case tok::utf32_string_literal: 12580b57cec5SDimitry Andric Res = ParseStringLiteralExpression(true); 12590b57cec5SDimitry Andric break; 12600b57cec5SDimitry Andric case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1] 12610b57cec5SDimitry Andric Res = ParseGenericSelectionExpression(); 12620b57cec5SDimitry Andric break; 12630b57cec5SDimitry Andric case tok::kw___builtin_available: 12640b57cec5SDimitry Andric return ParseAvailabilityCheckExpr(Tok.getLocation()); 12650b57cec5SDimitry Andric case tok::kw___builtin_va_arg: 12660b57cec5SDimitry Andric case tok::kw___builtin_offsetof: 12670b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: 12680b57cec5SDimitry Andric case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() 12690b57cec5SDimitry Andric case tok::kw___builtin_convertvector: 12700b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 12710b57cec5SDimitry Andric case tok::kw___builtin_FILE: 12720b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 12730b57cec5SDimitry Andric case tok::kw___builtin_LINE: 1274*480093f4SDimitry Andric if (NotPrimaryExpression) 1275*480093f4SDimitry Andric *NotPrimaryExpression = true; 12760b57cec5SDimitry Andric return ParseBuiltinPrimaryExpression(); 12770b57cec5SDimitry Andric case tok::kw___null: 12780b57cec5SDimitry Andric return Actions.ActOnGNUNullExpr(ConsumeToken()); 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric case tok::plusplus: // unary-expression: '++' unary-expression [C99] 12810b57cec5SDimitry Andric case tok::minusminus: { // unary-expression: '--' unary-expression [C99] 1282*480093f4SDimitry Andric if (NotPrimaryExpression) 1283*480093f4SDimitry Andric *NotPrimaryExpression = true; 12840b57cec5SDimitry Andric // C++ [expr.unary] has: 12850b57cec5SDimitry Andric // unary-expression: 12860b57cec5SDimitry Andric // ++ cast-expression 12870b57cec5SDimitry Andric // -- cast-expression 12880b57cec5SDimitry Andric Token SavedTok = Tok; 12890b57cec5SDimitry Andric ConsumeToken(); 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(), 12920b57cec5SDimitry Andric SavedTok.getLocation()); 12930b57cec5SDimitry Andric // One special case is implicitly handled here: if the preceding tokens are 12940b57cec5SDimitry Andric // an ambiguous cast expression, such as "(T())++", then we recurse to 12950b57cec5SDimitry Andric // determine whether the '++' is prefix or postfix. 1296*480093f4SDimitry Andric Res = ParseCastExpression(getLangOpts().CPlusPlus ? 1297*480093f4SDimitry Andric UnaryExprOnly : AnyCastExpr, 12980b57cec5SDimitry Andric /*isAddressOfOperand*/false, NotCastExpr, 12990b57cec5SDimitry Andric NotTypeCast); 13000b57cec5SDimitry Andric if (NotCastExpr) { 13010b57cec5SDimitry Andric // If we return with NotCastExpr = true, we must not consume any tokens, 13020b57cec5SDimitry Andric // so put the token back where we found it. 13030b57cec5SDimitry Andric assert(Res.isInvalid()); 13040b57cec5SDimitry Andric UnconsumeToken(SavedTok); 13050b57cec5SDimitry Andric return ExprError(); 13060b57cec5SDimitry Andric } 13070b57cec5SDimitry Andric if (!Res.isInvalid()) 13080b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(), 13090b57cec5SDimitry Andric SavedKind, Res.get()); 13100b57cec5SDimitry Andric return Res; 13110b57cec5SDimitry Andric } 13120b57cec5SDimitry Andric case tok::amp: { // unary-expression: '&' cast-expression 1313*480093f4SDimitry Andric if (NotPrimaryExpression) 1314*480093f4SDimitry Andric *NotPrimaryExpression = true; 13150b57cec5SDimitry Andric // Special treatment because of member pointers 13160b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 13170b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); 1318*480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr, true); 13190b57cec5SDimitry Andric if (!Res.isInvalid()) 13200b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 13210b57cec5SDimitry Andric return Res; 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric case tok::star: // unary-expression: '*' cast-expression 13250b57cec5SDimitry Andric case tok::plus: // unary-expression: '+' cast-expression 13260b57cec5SDimitry Andric case tok::minus: // unary-expression: '-' cast-expression 13270b57cec5SDimitry Andric case tok::tilde: // unary-expression: '~' cast-expression 13280b57cec5SDimitry Andric case tok::exclaim: // unary-expression: '!' cast-expression 13290b57cec5SDimitry Andric case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 13300b57cec5SDimitry Andric case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 1331*480093f4SDimitry Andric if (NotPrimaryExpression) 1332*480093f4SDimitry Andric *NotPrimaryExpression = true; 13330b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 13340b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); 1335*480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 13360b57cec5SDimitry Andric if (!Res.isInvalid()) 13370b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 13380b57cec5SDimitry Andric return Res; 13390b57cec5SDimitry Andric } 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andric case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression 1342*480093f4SDimitry Andric if (NotPrimaryExpression) 1343*480093f4SDimitry Andric *NotPrimaryExpression = true; 13440b57cec5SDimitry Andric SourceLocation CoawaitLoc = ConsumeToken(); 1345*480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 13460b57cec5SDimitry Andric if (!Res.isInvalid()) 13470b57cec5SDimitry Andric Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get()); 13480b57cec5SDimitry Andric return Res; 13490b57cec5SDimitry Andric } 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 13520b57cec5SDimitry Andric // __extension__ silences extension warnings in the subexpression. 1353*480093f4SDimitry Andric if (NotPrimaryExpression) 1354*480093f4SDimitry Andric *NotPrimaryExpression = true; 13550b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); // Use RAII to do this. 13560b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 1357*480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 13580b57cec5SDimitry Andric if (!Res.isInvalid()) 13590b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 13600b57cec5SDimitry Andric return Res; 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' 13630b57cec5SDimitry Andric if (!getLangOpts().C11) 1364a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 13650b57cec5SDimitry Andric LLVM_FALLTHROUGH; 13660b57cec5SDimitry Andric case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' 13670b57cec5SDimitry Andric case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 13680b57cec5SDimitry Andric // unary-expression: '__alignof' '(' type-name ')' 13690b57cec5SDimitry Andric case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 13700b57cec5SDimitry Andric // unary-expression: 'sizeof' '(' type-name ')' 13710b57cec5SDimitry Andric case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression 13720b57cec5SDimitry Andric // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' 13730b57cec5SDimitry Andric case tok::kw___builtin_omp_required_simd_align: 1374*480093f4SDimitry Andric if (NotPrimaryExpression) 1375*480093f4SDimitry Andric *NotPrimaryExpression = true; 13760b57cec5SDimitry Andric return ParseUnaryExprOrTypeTraitExpression(); 13770b57cec5SDimitry Andric case tok::ampamp: { // unary-expression: '&&' identifier 1378*480093f4SDimitry Andric if (NotPrimaryExpression) 1379*480093f4SDimitry Andric *NotPrimaryExpression = true; 13800b57cec5SDimitry Andric SourceLocation AmpAmpLoc = ConsumeToken(); 13810b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 13820b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric if (getCurScope()->getFnParent() == nullptr) 13850b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 13880b57cec5SDimitry Andric LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 13890b57cec5SDimitry Andric Tok.getLocation()); 13900b57cec5SDimitry Andric Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); 13910b57cec5SDimitry Andric ConsumeToken(); 13920b57cec5SDimitry Andric return Res; 13930b57cec5SDimitry Andric } 13940b57cec5SDimitry Andric case tok::kw_const_cast: 13950b57cec5SDimitry Andric case tok::kw_dynamic_cast: 13960b57cec5SDimitry Andric case tok::kw_reinterpret_cast: 13970b57cec5SDimitry Andric case tok::kw_static_cast: 1398*480093f4SDimitry Andric if (NotPrimaryExpression) 1399*480093f4SDimitry Andric *NotPrimaryExpression = true; 14000b57cec5SDimitry Andric Res = ParseCXXCasts(); 14010b57cec5SDimitry Andric break; 14020b57cec5SDimitry Andric case tok::kw___builtin_bit_cast: 1403*480093f4SDimitry Andric if (NotPrimaryExpression) 1404*480093f4SDimitry Andric *NotPrimaryExpression = true; 14050b57cec5SDimitry Andric Res = ParseBuiltinBitCast(); 14060b57cec5SDimitry Andric break; 14070b57cec5SDimitry Andric case tok::kw_typeid: 1408*480093f4SDimitry Andric if (NotPrimaryExpression) 1409*480093f4SDimitry Andric *NotPrimaryExpression = true; 14100b57cec5SDimitry Andric Res = ParseCXXTypeid(); 14110b57cec5SDimitry Andric break; 14120b57cec5SDimitry Andric case tok::kw___uuidof: 1413*480093f4SDimitry Andric if (NotPrimaryExpression) 1414*480093f4SDimitry Andric *NotPrimaryExpression = true; 14150b57cec5SDimitry Andric Res = ParseCXXUuidof(); 14160b57cec5SDimitry Andric break; 14170b57cec5SDimitry Andric case tok::kw_this: 14180b57cec5SDimitry Andric Res = ParseCXXThis(); 14190b57cec5SDimitry Andric break; 14200b57cec5SDimitry Andric 14210b57cec5SDimitry Andric case tok::annot_typename: 14220b57cec5SDimitry Andric if (isStartOfObjCClassMessageMissingOpenBracket()) { 14230b57cec5SDimitry Andric ParsedType Type = getTypeAnnotation(Tok); 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 14260b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 14270b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 14280b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getLastLoc()); 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric const char *PrevSpec = nullptr; 14310b57cec5SDimitry Andric unsigned DiagID; 14320b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(), 14330b57cec5SDimitry Andric PrevSpec, DiagID, Type, 14340b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 14350b57cec5SDimitry Andric 14360b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 14370b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 14380b57cec5SDimitry Andric if (Ty.isInvalid()) 14390b57cec5SDimitry Andric break; 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric ConsumeAnnotationToken(); 14420b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 14430b57cec5SDimitry Andric Ty.get(), nullptr); 14440b57cec5SDimitry Andric break; 14450b57cec5SDimitry Andric } 14460b57cec5SDimitry Andric LLVM_FALLTHROUGH; 14470b57cec5SDimitry Andric 14480b57cec5SDimitry Andric case tok::annot_decltype: 14490b57cec5SDimitry Andric case tok::kw_char: 14500b57cec5SDimitry Andric case tok::kw_wchar_t: 14510b57cec5SDimitry Andric case tok::kw_char8_t: 14520b57cec5SDimitry Andric case tok::kw_char16_t: 14530b57cec5SDimitry Andric case tok::kw_char32_t: 14540b57cec5SDimitry Andric case tok::kw_bool: 14550b57cec5SDimitry Andric case tok::kw_short: 14560b57cec5SDimitry Andric case tok::kw_int: 14570b57cec5SDimitry Andric case tok::kw_long: 14580b57cec5SDimitry Andric case tok::kw___int64: 14590b57cec5SDimitry Andric case tok::kw___int128: 14600b57cec5SDimitry Andric case tok::kw_signed: 14610b57cec5SDimitry Andric case tok::kw_unsigned: 14620b57cec5SDimitry Andric case tok::kw_half: 14630b57cec5SDimitry Andric case tok::kw_float: 14640b57cec5SDimitry Andric case tok::kw_double: 14650b57cec5SDimitry Andric case tok::kw__Float16: 14660b57cec5SDimitry Andric case tok::kw___float128: 14670b57cec5SDimitry Andric case tok::kw_void: 14680b57cec5SDimitry Andric case tok::kw_typename: 14690b57cec5SDimitry Andric case tok::kw_typeof: 14700b57cec5SDimitry Andric case tok::kw___vector: 14710b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 14720b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 14730b57cec5SDimitry Andric { 14740b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 14750b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 14760b57cec5SDimitry Andric return ExprError(); 14770b57cec5SDimitry Andric } 14780b57cec5SDimitry Andric 1479*480093f4SDimitry Andric // Everything henceforth is a postfix-expression. 1480*480093f4SDimitry Andric if (NotPrimaryExpression) 1481*480093f4SDimitry Andric *NotPrimaryExpression = true; 1482*480093f4SDimitry Andric 14830b57cec5SDimitry Andric if (SavedKind == tok::kw_typename) { 14840b57cec5SDimitry Andric // postfix-expression: typename-specifier '(' expression-list[opt] ')' 14850b57cec5SDimitry Andric // typename-specifier braced-init-list 14860b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 14870b57cec5SDimitry Andric return ExprError(); 14880b57cec5SDimitry Andric 14890b57cec5SDimitry Andric if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) 14900b57cec5SDimitry Andric // We are trying to parse a simple-type-specifier but might not get such 14910b57cec5SDimitry Andric // a token after error recovery. 14920b57cec5SDimitry Andric return ExprError(); 14930b57cec5SDimitry Andric } 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 14960b57cec5SDimitry Andric // simple-type-specifier braced-init-list 14970b57cec5SDimitry Andric // 14980b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 14990b57cec5SDimitry Andric 15000b57cec5SDimitry Andric ParseCXXSimpleTypeSpecifier(DS); 15010b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren) && 15020b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) 15030b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 15040b57cec5SDimitry Andric << DS.getSourceRange()); 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) 15070b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 15080b57cec5SDimitry Andric 15090b57cec5SDimitry Andric Res = ParseCXXTypeConstructExpression(DS); 15100b57cec5SDimitry Andric break; 15110b57cec5SDimitry Andric } 15120b57cec5SDimitry Andric 15130b57cec5SDimitry Andric case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 15140b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 15150b57cec5SDimitry Andric // (We can end up in this situation after tentative parsing.) 15160b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 15170b57cec5SDimitry Andric return ExprError(); 15180b57cec5SDimitry Andric if (!Tok.is(tok::annot_cxxscope)) 1519*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1520*480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1521*480093f4SDimitry Andric NotPrimaryExpression); 15220b57cec5SDimitry Andric 15230b57cec5SDimitry Andric Token Next = NextToken(); 15240b57cec5SDimitry Andric if (Next.is(tok::annot_template_id)) { 15250b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 15260b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 15270b57cec5SDimitry Andric // We have a qualified template-id that we know refers to a 15280b57cec5SDimitry Andric // type, translate it into a type and continue parsing as a 15290b57cec5SDimitry Andric // cast expression. 15300b57cec5SDimitry Andric CXXScopeSpec SS; 15310b57cec5SDimitry Andric ParseOptionalCXXScopeSpecifier(SS, nullptr, 15320b57cec5SDimitry Andric /*EnteringContext=*/false); 15330b57cec5SDimitry Andric AnnotateTemplateIdTokenAsType(); 1534*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1535*480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1536*480093f4SDimitry Andric NotPrimaryExpression); 15370b57cec5SDimitry Andric } 15380b57cec5SDimitry Andric } 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andric // Parse as an id-expression. 15410b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 15420b57cec5SDimitry Andric break; 15430b57cec5SDimitry Andric } 15440b57cec5SDimitry Andric 15450b57cec5SDimitry Andric case tok::annot_template_id: { // [C++] template-id 15460b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 15470b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 15480b57cec5SDimitry Andric // We have a template-id that we know refers to a type, 15490b57cec5SDimitry Andric // translate it into a type and continue parsing as a cast 15500b57cec5SDimitry Andric // expression. 15510b57cec5SDimitry Andric AnnotateTemplateIdTokenAsType(); 1552*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1553*480093f4SDimitry Andric NotCastExpr, isTypeCast, isVectorLiteral, 1554*480093f4SDimitry Andric NotPrimaryExpression); 15550b57cec5SDimitry Andric } 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric // Fall through to treat the template-id as an id-expression. 15580b57cec5SDimitry Andric LLVM_FALLTHROUGH; 15590b57cec5SDimitry Andric } 15600b57cec5SDimitry Andric 15610b57cec5SDimitry Andric case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 15620b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 15630b57cec5SDimitry Andric break; 15640b57cec5SDimitry Andric 15650b57cec5SDimitry Andric case tok::coloncolon: { 15660b57cec5SDimitry Andric // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 15670b57cec5SDimitry Andric // annotates the token, tail recurse. 15680b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 15690b57cec5SDimitry Andric return ExprError(); 15700b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) 1571*480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1572*480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric // ::new -> [C++] new-expression 15750b57cec5SDimitry Andric // ::delete -> [C++] delete-expression 15760b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 1577*480093f4SDimitry Andric if (Tok.is(tok::kw_new)) { 1578*480093f4SDimitry Andric if (NotPrimaryExpression) 1579*480093f4SDimitry Andric *NotPrimaryExpression = true; 15800b57cec5SDimitry Andric return ParseCXXNewExpression(true, CCLoc); 1581*480093f4SDimitry Andric } 1582*480093f4SDimitry Andric if (Tok.is(tok::kw_delete)) { 1583*480093f4SDimitry Andric if (NotPrimaryExpression) 1584*480093f4SDimitry Andric *NotPrimaryExpression = true; 15850b57cec5SDimitry Andric return ParseCXXDeleteExpression(true, CCLoc); 1586*480093f4SDimitry Andric } 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric // This is not a type name or scope specifier, it is an invalid expression. 15890b57cec5SDimitry Andric Diag(CCLoc, diag::err_expected_expression); 15900b57cec5SDimitry Andric return ExprError(); 15910b57cec5SDimitry Andric } 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric case tok::kw_new: // [C++] new-expression 1594*480093f4SDimitry Andric if (NotPrimaryExpression) 1595*480093f4SDimitry Andric *NotPrimaryExpression = true; 15960b57cec5SDimitry Andric return ParseCXXNewExpression(false, Tok.getLocation()); 15970b57cec5SDimitry Andric 15980b57cec5SDimitry Andric case tok::kw_delete: // [C++] delete-expression 1599*480093f4SDimitry Andric if (NotPrimaryExpression) 1600*480093f4SDimitry Andric *NotPrimaryExpression = true; 16010b57cec5SDimitry Andric return ParseCXXDeleteExpression(false, Tok.getLocation()); 16020b57cec5SDimitry Andric 16030b57cec5SDimitry Andric case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' 1604*480093f4SDimitry Andric if (NotPrimaryExpression) 1605*480093f4SDimitry Andric *NotPrimaryExpression = true; 16060b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_noexcept_expr); 16070b57cec5SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 16080b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 16090b57cec5SDimitry Andric 16100b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept")) 16110b57cec5SDimitry Andric return ExprError(); 16120b57cec5SDimitry Andric // C++11 [expr.unary.noexcept]p1: 16130b57cec5SDimitry Andric // The noexcept operator determines whether the evaluation of its operand, 16140b57cec5SDimitry Andric // which is an unevaluated operand, can throw an exception. 16150b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 16160b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 16170b57cec5SDimitry Andric ExprResult Result = ParseExpression(); 16180b57cec5SDimitry Andric 16190b57cec5SDimitry Andric T.consumeClose(); 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric if (!Result.isInvalid()) 16220b57cec5SDimitry Andric Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), 16230b57cec5SDimitry Andric Result.get(), T.getCloseLocation()); 16240b57cec5SDimitry Andric return Result; 16250b57cec5SDimitry Andric } 16260b57cec5SDimitry Andric 16270b57cec5SDimitry Andric #define TYPE_TRAIT(N,Spelling,K) \ 16280b57cec5SDimitry Andric case tok::kw_##Spelling: 16290b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 16300b57cec5SDimitry Andric return ParseTypeTrait(); 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric case tok::kw___array_rank: 16330b57cec5SDimitry Andric case tok::kw___array_extent: 1634*480093f4SDimitry Andric if (NotPrimaryExpression) 1635*480093f4SDimitry Andric *NotPrimaryExpression = true; 16360b57cec5SDimitry Andric return ParseArrayTypeTrait(); 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric case tok::kw___is_lvalue_expr: 16390b57cec5SDimitry Andric case tok::kw___is_rvalue_expr: 1640*480093f4SDimitry Andric if (NotPrimaryExpression) 1641*480093f4SDimitry Andric *NotPrimaryExpression = true; 16420b57cec5SDimitry Andric return ParseExpressionTrait(); 16430b57cec5SDimitry Andric 16440b57cec5SDimitry Andric case tok::at: { 1645*480093f4SDimitry Andric if (NotPrimaryExpression) 1646*480093f4SDimitry Andric *NotPrimaryExpression = true; 16470b57cec5SDimitry Andric SourceLocation AtLoc = ConsumeToken(); 16480b57cec5SDimitry Andric return ParseObjCAtExpression(AtLoc); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric case tok::caret: 16510b57cec5SDimitry Andric Res = ParseBlockLiteralExpression(); 16520b57cec5SDimitry Andric break; 16530b57cec5SDimitry Andric case tok::code_completion: { 16540b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 16550b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 16560b57cec5SDimitry Andric cutOffParsing(); 16570b57cec5SDimitry Andric return ExprError(); 16580b57cec5SDimitry Andric } 16590b57cec5SDimitry Andric case tok::l_square: 16600b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11) { 16610b57cec5SDimitry Andric if (getLangOpts().ObjC) { 16620b57cec5SDimitry Andric // C++11 lambda expressions and Objective-C message sends both start with a 16630b57cec5SDimitry Andric // square bracket. There are three possibilities here: 16640b57cec5SDimitry Andric // we have a valid lambda expression, we have an invalid lambda 16650b57cec5SDimitry Andric // expression, or we have something that doesn't appear to be a lambda. 16660b57cec5SDimitry Andric // If we're in the last case, we fall back to ParseObjCMessageExpression. 16670b57cec5SDimitry Andric Res = TryParseLambdaExpression(); 1668*480093f4SDimitry Andric if (!Res.isInvalid() && !Res.get()) { 1669*480093f4SDimitry Andric // We assume Objective-C++ message expressions are not 1670*480093f4SDimitry Andric // primary-expressions. 1671*480093f4SDimitry Andric if (NotPrimaryExpression) 1672*480093f4SDimitry Andric *NotPrimaryExpression = true; 16730b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 1674*480093f4SDimitry Andric } 16750b57cec5SDimitry Andric break; 16760b57cec5SDimitry Andric } 16770b57cec5SDimitry Andric Res = ParseLambdaExpression(); 16780b57cec5SDimitry Andric break; 16790b57cec5SDimitry Andric } 16800b57cec5SDimitry Andric if (getLangOpts().ObjC) { 16810b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 16820b57cec5SDimitry Andric break; 16830b57cec5SDimitry Andric } 16840b57cec5SDimitry Andric LLVM_FALLTHROUGH; 16850b57cec5SDimitry Andric default: 16860b57cec5SDimitry Andric NotCastExpr = true; 16870b57cec5SDimitry Andric return ExprError(); 16880b57cec5SDimitry Andric } 16890b57cec5SDimitry Andric 16900b57cec5SDimitry Andric // Check to see whether Res is a function designator only. If it is and we 16910b57cec5SDimitry Andric // are compiling for OpenCL, we need to return an error as this implies 16920b57cec5SDimitry Andric // that the address of the function is being taken, which is illegal in CL. 16930b57cec5SDimitry Andric 1694*480093f4SDimitry Andric if (ParseKind == PrimaryExprOnly) 1695*480093f4SDimitry Andric // This is strictly a primary-expression - no postfix-expr pieces should be 1696*480093f4SDimitry Andric // parsed. 1697*480093f4SDimitry Andric return Res; 1698*480093f4SDimitry Andric 16990b57cec5SDimitry Andric // These can be followed by postfix-expr pieces. 17000b57cec5SDimitry Andric PreferredType = SavedType; 17010b57cec5SDimitry Andric Res = ParsePostfixExpressionSuffix(Res); 17020b57cec5SDimitry Andric if (getLangOpts().OpenCL) 17030b57cec5SDimitry Andric if (Expr *PostfixExpr = Res.get()) { 17040b57cec5SDimitry Andric QualType Ty = PostfixExpr->getType(); 17050b57cec5SDimitry Andric if (!Ty.isNull() && Ty->isFunctionType()) { 17060b57cec5SDimitry Andric Diag(PostfixExpr->getExprLoc(), 17070b57cec5SDimitry Andric diag::err_opencl_taking_function_address_parser); 17080b57cec5SDimitry Andric return ExprError(); 17090b57cec5SDimitry Andric } 17100b57cec5SDimitry Andric } 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andric return Res; 17130b57cec5SDimitry Andric } 17140b57cec5SDimitry Andric 17150b57cec5SDimitry Andric /// Once the leading part of a postfix-expression is parsed, this 17160b57cec5SDimitry Andric /// method parses any suffixes that apply. 17170b57cec5SDimitry Andric /// 17180b57cec5SDimitry Andric /// \verbatim 17190b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 17200b57cec5SDimitry Andric /// primary-expression 17210b57cec5SDimitry Andric /// postfix-expression '[' expression ']' 17220b57cec5SDimitry Andric /// postfix-expression '[' braced-init-list ']' 17230b57cec5SDimitry Andric /// postfix-expression '(' argument-expression-list[opt] ')' 17240b57cec5SDimitry Andric /// postfix-expression '.' identifier 17250b57cec5SDimitry Andric /// postfix-expression '->' identifier 17260b57cec5SDimitry Andric /// postfix-expression '++' 17270b57cec5SDimitry Andric /// postfix-expression '--' 17280b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 17290b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 17300b57cec5SDimitry Andric /// 17310b57cec5SDimitry Andric /// argument-expression-list: [C99 6.5.2] 17320b57cec5SDimitry Andric /// argument-expression ...[opt] 17330b57cec5SDimitry Andric /// argument-expression-list ',' assignment-expression ...[opt] 17340b57cec5SDimitry Andric /// \endverbatim 17350b57cec5SDimitry Andric ExprResult 17360b57cec5SDimitry Andric Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { 17370b57cec5SDimitry Andric // Now that the primary-expression piece of the postfix-expression has been 17380b57cec5SDimitry Andric // parsed, see if there are any postfix-expression pieces here. 17390b57cec5SDimitry Andric SourceLocation Loc; 17400b57cec5SDimitry Andric auto SavedType = PreferredType; 17410b57cec5SDimitry Andric while (1) { 17420b57cec5SDimitry Andric // Each iteration relies on preferred type for the whole expression. 17430b57cec5SDimitry Andric PreferredType = SavedType; 17440b57cec5SDimitry Andric switch (Tok.getKind()) { 17450b57cec5SDimitry Andric case tok::code_completion: 17460b57cec5SDimitry Andric if (InMessageExpression) 17470b57cec5SDimitry Andric return LHS; 17480b57cec5SDimitry Andric 17490b57cec5SDimitry Andric Actions.CodeCompletePostfixExpression( 17500b57cec5SDimitry Andric getCurScope(), LHS, PreferredType.get(Tok.getLocation())); 17510b57cec5SDimitry Andric cutOffParsing(); 17520b57cec5SDimitry Andric return ExprError(); 17530b57cec5SDimitry Andric 17540b57cec5SDimitry Andric case tok::identifier: 17550b57cec5SDimitry Andric // If we see identifier: after an expression, and we're not already in a 17560b57cec5SDimitry Andric // message send, then this is probably a message send with a missing 17570b57cec5SDimitry Andric // opening bracket '['. 17580b57cec5SDimitry Andric if (getLangOpts().ObjC && !InMessageExpression && 17590b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 17600b57cec5SDimitry Andric LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 17610b57cec5SDimitry Andric nullptr, LHS.get()); 17620b57cec5SDimitry Andric break; 17630b57cec5SDimitry Andric } 17640b57cec5SDimitry Andric // Fall through; this isn't a message send. 17650b57cec5SDimitry Andric LLVM_FALLTHROUGH; 17660b57cec5SDimitry Andric 17670b57cec5SDimitry Andric default: // Not a postfix-expression suffix. 17680b57cec5SDimitry Andric return LHS; 17690b57cec5SDimitry Andric case tok::l_square: { // postfix-expression: p-e '[' expression ']' 17700b57cec5SDimitry Andric // If we have a array postfix expression that starts on a new line and 17710b57cec5SDimitry Andric // Objective-C is enabled, it is highly likely that the user forgot a 17720b57cec5SDimitry Andric // semicolon after the base expression and that the array postfix-expr is 17730b57cec5SDimitry Andric // actually another message send. In this case, do some look-ahead to see 17740b57cec5SDimitry Andric // if the contents of the square brackets are obviously not a valid 17750b57cec5SDimitry Andric // expression and recover by pretending there is no suffix. 17760b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.isAtStartOfLine() && 17770b57cec5SDimitry Andric isSimpleObjCMessageExpression()) 17780b57cec5SDimitry Andric return LHS; 17790b57cec5SDimitry Andric 17800b57cec5SDimitry Andric // Reject array indices starting with a lambda-expression. '[[' is 17810b57cec5SDimitry Andric // reserved for attributes. 17820b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) { 17830b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 17840b57cec5SDimitry Andric return ExprError(); 17850b57cec5SDimitry Andric } 17860b57cec5SDimitry Andric 17870b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 17880b57cec5SDimitry Andric T.consumeOpen(); 17890b57cec5SDimitry Andric Loc = T.getOpenLocation(); 17900b57cec5SDimitry Andric ExprResult Idx, Length; 17910b57cec5SDimitry Andric SourceLocation ColonLoc; 17920b57cec5SDimitry Andric PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); 17930b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 17940b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 17950b57cec5SDimitry Andric Idx = ParseBraceInitializer(); 17960b57cec5SDimitry Andric } else if (getLangOpts().OpenMP) { 17970b57cec5SDimitry Andric ColonProtectionRAIIObject RAII(*this); 17980b57cec5SDimitry Andric // Parse [: or [ expr or [ expr : 17990b57cec5SDimitry Andric if (!Tok.is(tok::colon)) { 18000b57cec5SDimitry Andric // [ expr 18010b57cec5SDimitry Andric Idx = ParseExpression(); 18020b57cec5SDimitry Andric } 18030b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 18040b57cec5SDimitry Andric // Consume ':' 18050b57cec5SDimitry Andric ColonLoc = ConsumeToken(); 18060b57cec5SDimitry Andric if (Tok.isNot(tok::r_square)) 18070b57cec5SDimitry Andric Length = ParseExpression(); 18080b57cec5SDimitry Andric } 18090b57cec5SDimitry Andric } else 18100b57cec5SDimitry Andric Idx = ParseExpression(); 18110b57cec5SDimitry Andric 18120b57cec5SDimitry Andric SourceLocation RLoc = Tok.getLocation(); 18130b57cec5SDimitry Andric 18140b57cec5SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 18150b57cec5SDimitry Andric Idx = Actions.CorrectDelayedTyposInExpr(Idx); 18160b57cec5SDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(Length); 18170b57cec5SDimitry Andric if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() && 18180b57cec5SDimitry Andric Tok.is(tok::r_square)) { 18190b57cec5SDimitry Andric if (ColonLoc.isValid()) { 18200b57cec5SDimitry Andric LHS = Actions.ActOnOMPArraySectionExpr(LHS.get(), Loc, Idx.get(), 18210b57cec5SDimitry Andric ColonLoc, Length.get(), RLoc); 18220b57cec5SDimitry Andric } else { 18230b57cec5SDimitry Andric LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, 18240b57cec5SDimitry Andric Idx.get(), RLoc); 18250b57cec5SDimitry Andric } 18260b57cec5SDimitry Andric } else { 18270b57cec5SDimitry Andric LHS = ExprError(); 18280b57cec5SDimitry Andric Idx = ExprError(); 18290b57cec5SDimitry Andric } 18300b57cec5SDimitry Andric 18310b57cec5SDimitry Andric // Match the ']'. 18320b57cec5SDimitry Andric T.consumeClose(); 18330b57cec5SDimitry Andric break; 18340b57cec5SDimitry Andric } 18350b57cec5SDimitry Andric 18360b57cec5SDimitry Andric case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' 18370b57cec5SDimitry Andric case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>' 18380b57cec5SDimitry Andric // '(' argument-expression-list[opt] ')' 18390b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 18400b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 18410b57cec5SDimitry Andric 18420b57cec5SDimitry Andric Expr *ExecConfig = nullptr; 18430b57cec5SDimitry Andric 18440b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 18450b57cec5SDimitry Andric 18460b57cec5SDimitry Andric if (OpKind == tok::lesslessless) { 18470b57cec5SDimitry Andric ExprVector ExecConfigExprs; 18480b57cec5SDimitry Andric CommaLocsTy ExecConfigCommaLocs; 18490b57cec5SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { 18520b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 18530b57cec5SDimitry Andric LHS = ExprError(); 18540b57cec5SDimitry Andric } 18550b57cec5SDimitry Andric 18560b57cec5SDimitry Andric SourceLocation CloseLoc; 18570b57cec5SDimitry Andric if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) { 18580b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 18590b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 18600b57cec5SDimitry Andric } else { 18610b57cec5SDimitry Andric // There was an error closing the brackets 18620b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::greatergreatergreater; 18630b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::lesslessless; 18640b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 18650b57cec5SDimitry Andric LHS = ExprError(); 18660b57cec5SDimitry Andric } 18670b57cec5SDimitry Andric 18680b57cec5SDimitry Andric if (!LHS.isInvalid()) { 18690b57cec5SDimitry Andric if (ExpectAndConsume(tok::l_paren)) 18700b57cec5SDimitry Andric LHS = ExprError(); 18710b57cec5SDimitry Andric else 18720b57cec5SDimitry Andric Loc = PrevTokLocation; 18730b57cec5SDimitry Andric } 18740b57cec5SDimitry Andric 18750b57cec5SDimitry Andric if (!LHS.isInvalid()) { 18760b57cec5SDimitry Andric ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), 18770b57cec5SDimitry Andric OpenLoc, 18780b57cec5SDimitry Andric ExecConfigExprs, 18790b57cec5SDimitry Andric CloseLoc); 18800b57cec5SDimitry Andric if (ECResult.isInvalid()) 18810b57cec5SDimitry Andric LHS = ExprError(); 18820b57cec5SDimitry Andric else 18830b57cec5SDimitry Andric ExecConfig = ECResult.get(); 18840b57cec5SDimitry Andric } 18850b57cec5SDimitry Andric } else { 18860b57cec5SDimitry Andric PT.consumeOpen(); 18870b57cec5SDimitry Andric Loc = PT.getOpenLocation(); 18880b57cec5SDimitry Andric } 18890b57cec5SDimitry Andric 18900b57cec5SDimitry Andric ExprVector ArgExprs; 18910b57cec5SDimitry Andric CommaLocsTy CommaLocs; 18920b57cec5SDimitry Andric auto RunSignatureHelp = [&]() -> QualType { 18930b57cec5SDimitry Andric QualType PreferredType = Actions.ProduceCallSignatureHelp( 18940b57cec5SDimitry Andric getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation()); 18950b57cec5SDimitry Andric CalledSignatureHelp = true; 18960b57cec5SDimitry Andric return PreferredType; 18970b57cec5SDimitry Andric }; 18980b57cec5SDimitry Andric if (OpKind == tok::l_paren || !LHS.isInvalid()) { 18990b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 19000b57cec5SDimitry Andric if (ParseExpressionList(ArgExprs, CommaLocs, [&] { 19010b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 19020b57cec5SDimitry Andric RunSignatureHelp); 19030b57cec5SDimitry Andric })) { 19040b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 19050b57cec5SDimitry Andric // If we got an error when parsing expression list, we don't call 19060b57cec5SDimitry Andric // the CodeCompleteCall handler inside the parser. So call it here 19070b57cec5SDimitry Andric // to make sure we get overload suggestions even when we are in the 19080b57cec5SDimitry Andric // middle of a parameter. 19090b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 19100b57cec5SDimitry Andric RunSignatureHelp(); 19110b57cec5SDimitry Andric LHS = ExprError(); 19120b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 19130b57cec5SDimitry Andric for (auto &E : ArgExprs) 19140b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 19150b57cec5SDimitry Andric } 19160b57cec5SDimitry Andric } 19170b57cec5SDimitry Andric } 19180b57cec5SDimitry Andric 19190b57cec5SDimitry Andric // Match the ')'. 19200b57cec5SDimitry Andric if (LHS.isInvalid()) { 19210b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 19220b57cec5SDimitry Andric } else if (Tok.isNot(tok::r_paren)) { 19230b57cec5SDimitry Andric bool HadDelayedTypo = false; 19240b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get()) 19250b57cec5SDimitry Andric HadDelayedTypo = true; 19260b57cec5SDimitry Andric for (auto &E : ArgExprs) 19270b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(E).get() != E) 19280b57cec5SDimitry Andric HadDelayedTypo = true; 19290b57cec5SDimitry Andric // If there were delayed typos in the LHS or ArgExprs, call SkipUntil 19300b57cec5SDimitry Andric // instead of PT.consumeClose() to avoid emitting extra diagnostics for 19310b57cec5SDimitry Andric // the unmatched l_paren. 19320b57cec5SDimitry Andric if (HadDelayedTypo) 19330b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 19340b57cec5SDimitry Andric else 19350b57cec5SDimitry Andric PT.consumeClose(); 19360b57cec5SDimitry Andric LHS = ExprError(); 19370b57cec5SDimitry Andric } else { 19380b57cec5SDimitry Andric assert((ArgExprs.size() == 0 || 19390b57cec5SDimitry Andric ArgExprs.size()-1 == CommaLocs.size())&& 19400b57cec5SDimitry Andric "Unexpected number of commas!"); 19410b57cec5SDimitry Andric LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc, 19420b57cec5SDimitry Andric ArgExprs, Tok.getLocation(), 19430b57cec5SDimitry Andric ExecConfig); 19440b57cec5SDimitry Andric PT.consumeClose(); 19450b57cec5SDimitry Andric } 19460b57cec5SDimitry Andric 19470b57cec5SDimitry Andric break; 19480b57cec5SDimitry Andric } 19490b57cec5SDimitry Andric case tok::arrow: 19500b57cec5SDimitry Andric case tok::period: { 19510b57cec5SDimitry Andric // postfix-expression: p-e '->' template[opt] id-expression 19520b57cec5SDimitry Andric // postfix-expression: p-e '.' template[opt] id-expression 19530b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 19540b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 19550b57cec5SDimitry Andric 19560b57cec5SDimitry Andric CXXScopeSpec SS; 19570b57cec5SDimitry Andric ParsedType ObjectType; 19580b57cec5SDimitry Andric bool MayBePseudoDestructor = false; 19590b57cec5SDimitry Andric Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; 19600b57cec5SDimitry Andric 19610b57cec5SDimitry Andric PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS); 19620b57cec5SDimitry Andric 19630b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { 19640b57cec5SDimitry Andric Expr *Base = OrigLHS; 19650b57cec5SDimitry Andric const Type* BaseType = Base->getType().getTypePtrOrNull(); 19660b57cec5SDimitry Andric if (BaseType && Tok.is(tok::l_paren) && 19670b57cec5SDimitry Andric (BaseType->isFunctionType() || 19680b57cec5SDimitry Andric BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { 19690b57cec5SDimitry Andric Diag(OpLoc, diag::err_function_is_not_record) 19700b57cec5SDimitry Andric << OpKind << Base->getSourceRange() 19710b57cec5SDimitry Andric << FixItHint::CreateRemoval(OpLoc); 19720b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Base); 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andric LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, 19760b57cec5SDimitry Andric OpLoc, OpKind, ObjectType, 19770b57cec5SDimitry Andric MayBePseudoDestructor); 19780b57cec5SDimitry Andric if (LHS.isInvalid()) 19790b57cec5SDimitry Andric break; 19800b57cec5SDimitry Andric 19810b57cec5SDimitry Andric ParseOptionalCXXScopeSpecifier(SS, ObjectType, 19820b57cec5SDimitry Andric /*EnteringContext=*/false, 19830b57cec5SDimitry Andric &MayBePseudoDestructor); 19840b57cec5SDimitry Andric if (SS.isNotEmpty()) 19850b57cec5SDimitry Andric ObjectType = nullptr; 19860b57cec5SDimitry Andric } 19870b57cec5SDimitry Andric 19880b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 19890b57cec5SDimitry Andric tok::TokenKind CorrectedOpKind = 19900b57cec5SDimitry Andric OpKind == tok::arrow ? tok::period : tok::arrow; 19910b57cec5SDimitry Andric ExprResult CorrectedLHS(/*Invalid=*/true); 19920b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && OrigLHS) { 1993a7dea167SDimitry Andric // FIXME: Creating a TentativeAnalysisScope from outside Sema is a 1994a7dea167SDimitry Andric // hack. 1995a7dea167SDimitry Andric Sema::TentativeAnalysisScope Trap(Actions); 19960b57cec5SDimitry Andric CorrectedLHS = Actions.ActOnStartCXXMemberReference( 19970b57cec5SDimitry Andric getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType, 19980b57cec5SDimitry Andric MayBePseudoDestructor); 19990b57cec5SDimitry Andric } 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andric Expr *Base = LHS.get(); 20020b57cec5SDimitry Andric Expr *CorrectedBase = CorrectedLHS.get(); 20030b57cec5SDimitry Andric if (!CorrectedBase && !getLangOpts().CPlusPlus) 20040b57cec5SDimitry Andric CorrectedBase = Base; 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric // Code completion for a member access expression. 20070b57cec5SDimitry Andric Actions.CodeCompleteMemberReferenceExpr( 20080b57cec5SDimitry Andric getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, 20090b57cec5SDimitry Andric Base && ExprStatementTokLoc == Base->getBeginLoc(), 20100b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 20110b57cec5SDimitry Andric 20120b57cec5SDimitry Andric cutOffParsing(); 20130b57cec5SDimitry Andric return ExprError(); 20140b57cec5SDimitry Andric } 20150b57cec5SDimitry Andric 20160b57cec5SDimitry Andric if (MayBePseudoDestructor && !LHS.isInvalid()) { 20170b57cec5SDimitry Andric LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 20180b57cec5SDimitry Andric ObjectType); 20190b57cec5SDimitry Andric break; 20200b57cec5SDimitry Andric } 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andric // Either the action has told us that this cannot be a 20230b57cec5SDimitry Andric // pseudo-destructor expression (based on the type of base 20240b57cec5SDimitry Andric // expression), or we didn't see a '~' in the right place. We 20250b57cec5SDimitry Andric // can still parse a destructor name here, but in that case it 20260b57cec5SDimitry Andric // names a real destructor. 20270b57cec5SDimitry Andric // Allow explicit constructor calls in Microsoft mode. 20280b57cec5SDimitry Andric // FIXME: Add support for explicit call of template constructor. 20290b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 20300b57cec5SDimitry Andric UnqualifiedId Name; 20310b57cec5SDimitry Andric if (getLangOpts().ObjC && OpKind == tok::period && 20320b57cec5SDimitry Andric Tok.is(tok::kw_class)) { 20330b57cec5SDimitry Andric // Objective-C++: 20340b57cec5SDimitry Andric // After a '.' in a member access expression, treat the keyword 20350b57cec5SDimitry Andric // 'class' as if it were an identifier. 20360b57cec5SDimitry Andric // 20370b57cec5SDimitry Andric // This hack allows property access to the 'class' method because it is 20380b57cec5SDimitry Andric // such a common method name. For other C++ keywords that are 20390b57cec5SDimitry Andric // Objective-C method names, one must use the message send syntax. 20400b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 20410b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 20420b57cec5SDimitry Andric Name.setIdentifier(Id, Loc); 20430b57cec5SDimitry Andric } else if (ParseUnqualifiedId(SS, 20440b57cec5SDimitry Andric /*EnteringContext=*/false, 20450b57cec5SDimitry Andric /*AllowDestructorName=*/true, 20460b57cec5SDimitry Andric /*AllowConstructorName=*/ 20470b57cec5SDimitry Andric getLangOpts().MicrosoftExt && 20480b57cec5SDimitry Andric SS.isNotEmpty(), 20490b57cec5SDimitry Andric /*AllowDeductionGuide=*/false, 20500b57cec5SDimitry Andric ObjectType, &TemplateKWLoc, Name)) { 20510b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 20520b57cec5SDimitry Andric LHS = ExprError(); 20530b57cec5SDimitry Andric } 20540b57cec5SDimitry Andric 20550b57cec5SDimitry Andric if (!LHS.isInvalid()) 20560b57cec5SDimitry Andric LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 20570b57cec5SDimitry Andric OpKind, SS, TemplateKWLoc, Name, 20580b57cec5SDimitry Andric CurParsedObjCImpl ? CurParsedObjCImpl->Dcl 20590b57cec5SDimitry Andric : nullptr); 20600b57cec5SDimitry Andric if (!LHS.isInvalid() && Tok.is(tok::less)) 20610b57cec5SDimitry Andric checkPotentialAngleBracket(LHS); 20620b57cec5SDimitry Andric break; 20630b57cec5SDimitry Andric } 20640b57cec5SDimitry Andric case tok::plusplus: // postfix-expression: postfix-expression '++' 20650b57cec5SDimitry Andric case tok::minusminus: // postfix-expression: postfix-expression '--' 20660b57cec5SDimitry Andric if (!LHS.isInvalid()) { 20670b57cec5SDimitry Andric LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), 20680b57cec5SDimitry Andric Tok.getKind(), LHS.get()); 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric ConsumeToken(); 20710b57cec5SDimitry Andric break; 20720b57cec5SDimitry Andric } 20730b57cec5SDimitry Andric } 20740b57cec5SDimitry Andric } 20750b57cec5SDimitry Andric 20760b57cec5SDimitry Andric /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/ 20770b57cec5SDimitry Andric /// vec_step and we are at the start of an expression or a parenthesized 20780b57cec5SDimitry Andric /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the 20790b57cec5SDimitry Andric /// expression (isCastExpr == false) or the type (isCastExpr == true). 20800b57cec5SDimitry Andric /// 20810b57cec5SDimitry Andric /// \verbatim 20820b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 20830b57cec5SDimitry Andric /// 'sizeof' unary-expression 20840b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 20850b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 20860b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 20870b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 20880b57cec5SDimitry Andric /// [C++0x] 'alignof' '(' type-id ')' 20890b57cec5SDimitry Andric /// 20900b57cec5SDimitry Andric /// [GNU] typeof-specifier: 20910b57cec5SDimitry Andric /// typeof ( expressions ) 20920b57cec5SDimitry Andric /// typeof ( type-name ) 20930b57cec5SDimitry Andric /// [GNU/C++] typeof unary-expression 20940b57cec5SDimitry Andric /// 20950b57cec5SDimitry Andric /// [OpenCL 1.1 6.11.12] vec_step built-in function: 20960b57cec5SDimitry Andric /// vec_step ( expressions ) 20970b57cec5SDimitry Andric /// vec_step ( type-name ) 20980b57cec5SDimitry Andric /// \endverbatim 20990b57cec5SDimitry Andric ExprResult 21000b57cec5SDimitry Andric Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, 21010b57cec5SDimitry Andric bool &isCastExpr, 21020b57cec5SDimitry Andric ParsedType &CastTy, 21030b57cec5SDimitry Andric SourceRange &CastRange) { 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, 21060b57cec5SDimitry Andric tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, 21070b57cec5SDimitry Andric tok::kw___builtin_omp_required_simd_align) && 21080b57cec5SDimitry Andric "Not a typeof/sizeof/alignof/vec_step expression!"); 21090b57cec5SDimitry Andric 21100b57cec5SDimitry Andric ExprResult Operand; 21110b57cec5SDimitry Andric 21120b57cec5SDimitry Andric // If the operand doesn't start with an '(', it must be an expression. 21130b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) { 21140b57cec5SDimitry Andric // If construct allows a form without parenthesis, user may forget to put 21150b57cec5SDimitry Andric // pathenthesis around type name. 21160b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, 21170b57cec5SDimitry Andric tok::kw__Alignof)) { 21180b57cec5SDimitry Andric if (isTypeIdUnambiguously()) { 21190b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 21200b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 21210b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 21220b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 21230b57cec5SDimitry Andric 21240b57cec5SDimitry Andric SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); 21250b57cec5SDimitry Andric SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); 21260b57cec5SDimitry Andric Diag(LParenLoc, diag::err_expected_parentheses_around_typename) 21270b57cec5SDimitry Andric << OpTok.getName() 21280b57cec5SDimitry Andric << FixItHint::CreateInsertion(LParenLoc, "(") 21290b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 21300b57cec5SDimitry Andric isCastExpr = true; 21310b57cec5SDimitry Andric return ExprEmpty(); 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric } 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric isCastExpr = false; 21360b57cec5SDimitry Andric if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) { 21370b57cec5SDimitry Andric Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo() 21380b57cec5SDimitry Andric << tok::l_paren; 21390b57cec5SDimitry Andric return ExprError(); 21400b57cec5SDimitry Andric } 21410b57cec5SDimitry Andric 2142*480093f4SDimitry Andric Operand = ParseCastExpression(UnaryExprOnly); 21430b57cec5SDimitry Andric } else { 21440b57cec5SDimitry Andric // If it starts with a '(', we know that it is either a parenthesized 21450b57cec5SDimitry Andric // type-name, or it is a unary-expression that starts with a compound 21460b57cec5SDimitry Andric // literal, or starts with a primary-expression that is a parenthesized 21470b57cec5SDimitry Andric // expression. 21480b57cec5SDimitry Andric ParenParseOption ExprType = CastExpr; 21490b57cec5SDimitry Andric SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 21520b57cec5SDimitry Andric false, CastTy, RParenLoc); 21530b57cec5SDimitry Andric CastRange = SourceRange(LParenLoc, RParenLoc); 21540b57cec5SDimitry Andric 21550b57cec5SDimitry Andric // If ParseParenExpression parsed a '(typename)' sequence only, then this is 21560b57cec5SDimitry Andric // a type. 21570b57cec5SDimitry Andric if (ExprType == CastExpr) { 21580b57cec5SDimitry Andric isCastExpr = true; 21590b57cec5SDimitry Andric return ExprEmpty(); 21600b57cec5SDimitry Andric } 21610b57cec5SDimitry Andric 21620b57cec5SDimitry Andric if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { 21630b57cec5SDimitry Andric // GNU typeof in C requires the expression to be parenthesized. Not so for 21640b57cec5SDimitry Andric // sizeof/alignof or in C++. Therefore, the parenthesized expression is 21650b57cec5SDimitry Andric // the start of a unary-expression, but doesn't include any postfix 21660b57cec5SDimitry Andric // pieces. Parse these now if present. 21670b57cec5SDimitry Andric if (!Operand.isInvalid()) 21680b57cec5SDimitry Andric Operand = ParsePostfixExpressionSuffix(Operand.get()); 21690b57cec5SDimitry Andric } 21700b57cec5SDimitry Andric } 21710b57cec5SDimitry Andric 21720b57cec5SDimitry Andric // If we get here, the operand to the typeof/sizeof/alignof was an expression. 21730b57cec5SDimitry Andric isCastExpr = false; 21740b57cec5SDimitry Andric return Operand; 21750b57cec5SDimitry Andric } 21760b57cec5SDimitry Andric 21770b57cec5SDimitry Andric 21780b57cec5SDimitry Andric /// Parse a sizeof or alignof expression. 21790b57cec5SDimitry Andric /// 21800b57cec5SDimitry Andric /// \verbatim 21810b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 21820b57cec5SDimitry Andric /// 'sizeof' unary-expression 21830b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 21840b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 21850b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 21860b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 21870b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 21880b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 21890b57cec5SDimitry Andric /// \endverbatim 21900b57cec5SDimitry Andric ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { 21910b57cec5SDimitry Andric assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, 21920b57cec5SDimitry Andric tok::kw__Alignof, tok::kw_vec_step, 21930b57cec5SDimitry Andric tok::kw___builtin_omp_required_simd_align) && 21940b57cec5SDimitry Andric "Not a sizeof/alignof/vec_step expression!"); 21950b57cec5SDimitry Andric Token OpTok = Tok; 21960b57cec5SDimitry Andric ConsumeToken(); 21970b57cec5SDimitry Andric 21980b57cec5SDimitry Andric // [C++11] 'sizeof' '...' '(' identifier ')' 21990b57cec5SDimitry Andric if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { 22000b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 22010b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 22020b57cec5SDimitry Andric IdentifierInfo *Name = nullptr; 22030b57cec5SDimitry Andric SourceLocation NameLoc; 22040b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 22050b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 22060b57cec5SDimitry Andric T.consumeOpen(); 22070b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 22080b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 22090b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 22100b57cec5SDimitry Andric NameLoc = ConsumeToken(); 22110b57cec5SDimitry Andric T.consumeClose(); 22120b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 22130b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 22140b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 22150b57cec5SDimitry Andric } else { 22160b57cec5SDimitry Andric Diag(Tok, diag::err_expected_parameter_pack); 22170b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 22180b57cec5SDimitry Andric } 22190b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 22200b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 22210b57cec5SDimitry Andric NameLoc = ConsumeToken(); 22220b57cec5SDimitry Andric LParenLoc = PP.getLocForEndOfToken(EllipsisLoc); 22230b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 22240b57cec5SDimitry Andric Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack) 22250b57cec5SDimitry Andric << Name 22260b57cec5SDimitry Andric << FixItHint::CreateInsertion(LParenLoc, "(") 22270b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 22280b57cec5SDimitry Andric } else { 22290b57cec5SDimitry Andric Diag(Tok, diag::err_sizeof_parameter_pack); 22300b57cec5SDimitry Andric } 22310b57cec5SDimitry Andric 22320b57cec5SDimitry Andric if (!Name) 22330b57cec5SDimitry Andric return ExprError(); 22340b57cec5SDimitry Andric 22350b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 22360b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 22370b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric return Actions.ActOnSizeofParameterPackExpr(getCurScope(), 22400b57cec5SDimitry Andric OpTok.getLocation(), 22410b57cec5SDimitry Andric *Name, NameLoc, 22420b57cec5SDimitry Andric RParenLoc); 22430b57cec5SDimitry Andric } 22440b57cec5SDimitry Andric 22450b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 22460b57cec5SDimitry Andric Diag(OpTok, diag::warn_cxx98_compat_alignof); 22470b57cec5SDimitry Andric 22480b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 22490b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 22500b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 22510b57cec5SDimitry Andric 22520b57cec5SDimitry Andric bool isCastExpr; 22530b57cec5SDimitry Andric ParsedType CastTy; 22540b57cec5SDimitry Andric SourceRange CastRange; 22550b57cec5SDimitry Andric ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, 22560b57cec5SDimitry Andric isCastExpr, 22570b57cec5SDimitry Andric CastTy, 22580b57cec5SDimitry Andric CastRange); 22590b57cec5SDimitry Andric 22600b57cec5SDimitry Andric UnaryExprOrTypeTrait ExprKind = UETT_SizeOf; 22610b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 22620b57cec5SDimitry Andric ExprKind = UETT_AlignOf; 22630b57cec5SDimitry Andric else if (OpTok.is(tok::kw___alignof)) 22640b57cec5SDimitry Andric ExprKind = UETT_PreferredAlignOf; 22650b57cec5SDimitry Andric else if (OpTok.is(tok::kw_vec_step)) 22660b57cec5SDimitry Andric ExprKind = UETT_VecStep; 22670b57cec5SDimitry Andric else if (OpTok.is(tok::kw___builtin_omp_required_simd_align)) 22680b57cec5SDimitry Andric ExprKind = UETT_OpenMPRequiredSimdAlign; 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric if (isCastExpr) 22710b57cec5SDimitry Andric return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 22720b57cec5SDimitry Andric ExprKind, 22730b57cec5SDimitry Andric /*IsType=*/true, 22740b57cec5SDimitry Andric CastTy.getAsOpaquePtr(), 22750b57cec5SDimitry Andric CastRange); 22760b57cec5SDimitry Andric 22770b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 22780b57cec5SDimitry Andric Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); 22790b57cec5SDimitry Andric 22800b57cec5SDimitry Andric // If we get here, the operand to the sizeof/alignof was an expression. 22810b57cec5SDimitry Andric if (!Operand.isInvalid()) 22820b57cec5SDimitry Andric Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 22830b57cec5SDimitry Andric ExprKind, 22840b57cec5SDimitry Andric /*IsType=*/false, 22850b57cec5SDimitry Andric Operand.get(), 22860b57cec5SDimitry Andric CastRange); 22870b57cec5SDimitry Andric return Operand; 22880b57cec5SDimitry Andric } 22890b57cec5SDimitry Andric 22900b57cec5SDimitry Andric /// ParseBuiltinPrimaryExpression 22910b57cec5SDimitry Andric /// 22920b57cec5SDimitry Andric /// \verbatim 22930b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 22940b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 22950b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 22960b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 22970b57cec5SDimitry Andric /// assign-expr ')' 22980b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 22990b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 23000b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 23010b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 23020b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 23030b57cec5SDimitry Andric /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' 23040b57cec5SDimitry Andric /// 23050b57cec5SDimitry Andric /// [GNU] offsetof-member-designator: 23060b57cec5SDimitry Andric /// [GNU] identifier 23070b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '.' identifier 23080b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '[' expression ']' 23090b57cec5SDimitry Andric /// \endverbatim 23100b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinPrimaryExpression() { 23110b57cec5SDimitry Andric ExprResult Res; 23120b57cec5SDimitry Andric const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 23130b57cec5SDimitry Andric 23140b57cec5SDimitry Andric tok::TokenKind T = Tok.getKind(); 23150b57cec5SDimitry Andric SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 23160b57cec5SDimitry Andric 23170b57cec5SDimitry Andric // All of these start with an open paren. 23180b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) 23190b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII 23200b57cec5SDimitry Andric << tok::l_paren); 23210b57cec5SDimitry Andric 23220b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 23230b57cec5SDimitry Andric PT.consumeOpen(); 23240b57cec5SDimitry Andric 23250b57cec5SDimitry Andric // TODO: Build AST. 23260b57cec5SDimitry Andric 23270b57cec5SDimitry Andric switch (T) { 23280b57cec5SDimitry Andric default: llvm_unreachable("Not a builtin primary expression!"); 23290b57cec5SDimitry Andric case tok::kw___builtin_va_arg: { 23300b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 23330b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 23340b57cec5SDimitry Andric Expr = ExprError(); 23350b57cec5SDimitry Andric } 23360b57cec5SDimitry Andric 23370b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 23380b57cec5SDimitry Andric 23390b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 23400b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 23410b57cec5SDimitry Andric Expr = ExprError(); 23420b57cec5SDimitry Andric } 23430b57cec5SDimitry Andric 23440b57cec5SDimitry Andric if (Expr.isInvalid() || Ty.isInvalid()) 23450b57cec5SDimitry Andric Res = ExprError(); 23460b57cec5SDimitry Andric else 23470b57cec5SDimitry Andric Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen()); 23480b57cec5SDimitry Andric break; 23490b57cec5SDimitry Andric } 23500b57cec5SDimitry Andric case tok::kw___builtin_offsetof: { 23510b57cec5SDimitry Andric SourceLocation TypeLoc = Tok.getLocation(); 23520b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 23530b57cec5SDimitry Andric if (Ty.isInvalid()) { 23540b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 23550b57cec5SDimitry Andric return ExprError(); 23560b57cec5SDimitry Andric } 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 23590b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 23600b57cec5SDimitry Andric return ExprError(); 23610b57cec5SDimitry Andric } 23620b57cec5SDimitry Andric 23630b57cec5SDimitry Andric // We must have at least one identifier here. 23640b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 23650b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 23660b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 23670b57cec5SDimitry Andric return ExprError(); 23680b57cec5SDimitry Andric } 23690b57cec5SDimitry Andric 23700b57cec5SDimitry Andric // Keep track of the various subcomponents we see. 23710b57cec5SDimitry Andric SmallVector<Sema::OffsetOfComponent, 4> Comps; 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 23740b57cec5SDimitry Andric Comps.back().isBrackets = false; 23750b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 23760b57cec5SDimitry Andric Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 23770b57cec5SDimitry Andric 23780b57cec5SDimitry Andric // FIXME: This loop leaks the index expressions on error. 23790b57cec5SDimitry Andric while (1) { 23800b57cec5SDimitry Andric if (Tok.is(tok::period)) { 23810b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-designator '.' identifier 23820b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 23830b57cec5SDimitry Andric Comps.back().isBrackets = false; 23840b57cec5SDimitry Andric Comps.back().LocStart = ConsumeToken(); 23850b57cec5SDimitry Andric 23860b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 23870b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 23880b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 23890b57cec5SDimitry Andric return ExprError(); 23900b57cec5SDimitry Andric } 23910b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 23920b57cec5SDimitry Andric Comps.back().LocEnd = ConsumeToken(); 23930b57cec5SDimitry Andric 23940b57cec5SDimitry Andric } else if (Tok.is(tok::l_square)) { 23950b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 23960b57cec5SDimitry Andric return ExprError(); 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-design '[' expression ']' 23990b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 24000b57cec5SDimitry Andric Comps.back().isBrackets = true; 24010b57cec5SDimitry Andric BalancedDelimiterTracker ST(*this, tok::l_square); 24020b57cec5SDimitry Andric ST.consumeOpen(); 24030b57cec5SDimitry Andric Comps.back().LocStart = ST.getOpenLocation(); 24040b57cec5SDimitry Andric Res = ParseExpression(); 24050b57cec5SDimitry Andric if (Res.isInvalid()) { 24060b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24070b57cec5SDimitry Andric return Res; 24080b57cec5SDimitry Andric } 24090b57cec5SDimitry Andric Comps.back().U.E = Res.get(); 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andric ST.consumeClose(); 24120b57cec5SDimitry Andric Comps.back().LocEnd = ST.getCloseLocation(); 24130b57cec5SDimitry Andric } else { 24140b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 24150b57cec5SDimitry Andric PT.consumeClose(); 24160b57cec5SDimitry Andric Res = ExprError(); 24170b57cec5SDimitry Andric } else if (Ty.isInvalid()) { 24180b57cec5SDimitry Andric Res = ExprError(); 24190b57cec5SDimitry Andric } else { 24200b57cec5SDimitry Andric PT.consumeClose(); 24210b57cec5SDimitry Andric Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc, 24220b57cec5SDimitry Andric Ty.get(), Comps, 24230b57cec5SDimitry Andric PT.getCloseLocation()); 24240b57cec5SDimitry Andric } 24250b57cec5SDimitry Andric break; 24260b57cec5SDimitry Andric } 24270b57cec5SDimitry Andric } 24280b57cec5SDimitry Andric break; 24290b57cec5SDimitry Andric } 24300b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: { 24310b57cec5SDimitry Andric ExprResult Cond(ParseAssignmentExpression()); 24320b57cec5SDimitry Andric if (Cond.isInvalid()) { 24330b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24340b57cec5SDimitry Andric return Cond; 24350b57cec5SDimitry Andric } 24360b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 24370b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24380b57cec5SDimitry Andric return ExprError(); 24390b57cec5SDimitry Andric } 24400b57cec5SDimitry Andric 24410b57cec5SDimitry Andric ExprResult Expr1(ParseAssignmentExpression()); 24420b57cec5SDimitry Andric if (Expr1.isInvalid()) { 24430b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24440b57cec5SDimitry Andric return Expr1; 24450b57cec5SDimitry Andric } 24460b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 24470b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24480b57cec5SDimitry Andric return ExprError(); 24490b57cec5SDimitry Andric } 24500b57cec5SDimitry Andric 24510b57cec5SDimitry Andric ExprResult Expr2(ParseAssignmentExpression()); 24520b57cec5SDimitry Andric if (Expr2.isInvalid()) { 24530b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24540b57cec5SDimitry Andric return Expr2; 24550b57cec5SDimitry Andric } 24560b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 24570b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 24580b57cec5SDimitry Andric return ExprError(); 24590b57cec5SDimitry Andric } 24600b57cec5SDimitry Andric Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(), 24610b57cec5SDimitry Andric Expr2.get(), ConsumeParen()); 24620b57cec5SDimitry Andric break; 24630b57cec5SDimitry Andric } 24640b57cec5SDimitry Andric case tok::kw___builtin_astype: { 24650b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 24660b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 24670b57cec5SDimitry Andric if (Expr.isInvalid()) { 24680b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24690b57cec5SDimitry Andric return ExprError(); 24700b57cec5SDimitry Andric } 24710b57cec5SDimitry Andric 24720b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 24730b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24740b57cec5SDimitry Andric return ExprError(); 24750b57cec5SDimitry Andric } 24760b57cec5SDimitry Andric 24770b57cec5SDimitry Andric // Second argument is the type to bitcast to. 24780b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 24790b57cec5SDimitry Andric if (DestTy.isInvalid()) 24800b57cec5SDimitry Andric return ExprError(); 24810b57cec5SDimitry Andric 24820b57cec5SDimitry Andric // Attempt to consume the r-paren. 24830b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 24840b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 24850b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24860b57cec5SDimitry Andric return ExprError(); 24870b57cec5SDimitry Andric } 24880b57cec5SDimitry Andric 24890b57cec5SDimitry Andric Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 24900b57cec5SDimitry Andric ConsumeParen()); 24910b57cec5SDimitry Andric break; 24920b57cec5SDimitry Andric } 24930b57cec5SDimitry Andric case tok::kw___builtin_convertvector: { 24940b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 24950b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 24960b57cec5SDimitry Andric if (Expr.isInvalid()) { 24970b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24980b57cec5SDimitry Andric return ExprError(); 24990b57cec5SDimitry Andric } 25000b57cec5SDimitry Andric 25010b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 25020b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25030b57cec5SDimitry Andric return ExprError(); 25040b57cec5SDimitry Andric } 25050b57cec5SDimitry Andric 25060b57cec5SDimitry Andric // Second argument is the type to bitcast to. 25070b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 25080b57cec5SDimitry Andric if (DestTy.isInvalid()) 25090b57cec5SDimitry Andric return ExprError(); 25100b57cec5SDimitry Andric 25110b57cec5SDimitry Andric // Attempt to consume the r-paren. 25120b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 25130b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 25140b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25150b57cec5SDimitry Andric return ExprError(); 25160b57cec5SDimitry Andric } 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andric Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 25190b57cec5SDimitry Andric ConsumeParen()); 25200b57cec5SDimitry Andric break; 25210b57cec5SDimitry Andric } 25220b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 25230b57cec5SDimitry Andric case tok::kw___builtin_FILE: 25240b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 25250b57cec5SDimitry Andric case tok::kw___builtin_LINE: { 25260b57cec5SDimitry Andric // Attempt to consume the r-paren. 25270b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 25280b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 25290b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25300b57cec5SDimitry Andric return ExprError(); 25310b57cec5SDimitry Andric } 25320b57cec5SDimitry Andric SourceLocExpr::IdentKind Kind = [&] { 25330b57cec5SDimitry Andric switch (T) { 25340b57cec5SDimitry Andric case tok::kw___builtin_FILE: 25350b57cec5SDimitry Andric return SourceLocExpr::File; 25360b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 25370b57cec5SDimitry Andric return SourceLocExpr::Function; 25380b57cec5SDimitry Andric case tok::kw___builtin_LINE: 25390b57cec5SDimitry Andric return SourceLocExpr::Line; 25400b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 25410b57cec5SDimitry Andric return SourceLocExpr::Column; 25420b57cec5SDimitry Andric default: 25430b57cec5SDimitry Andric llvm_unreachable("invalid keyword"); 25440b57cec5SDimitry Andric } 25450b57cec5SDimitry Andric }(); 25460b57cec5SDimitry Andric Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen()); 25470b57cec5SDimitry Andric break; 25480b57cec5SDimitry Andric } 25490b57cec5SDimitry Andric } 25500b57cec5SDimitry Andric 25510b57cec5SDimitry Andric if (Res.isInvalid()) 25520b57cec5SDimitry Andric return ExprError(); 25530b57cec5SDimitry Andric 25540b57cec5SDimitry Andric // These can be followed by postfix-expr pieces because they are 25550b57cec5SDimitry Andric // primary-expressions. 25560b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Res.get()); 25570b57cec5SDimitry Andric } 25580b57cec5SDimitry Andric 25590b57cec5SDimitry Andric /// ParseParenExpression - This parses the unit that starts with a '(' token, 25600b57cec5SDimitry Andric /// based on what is allowed by ExprType. The actual thing parsed is returned 25610b57cec5SDimitry Andric /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 25620b57cec5SDimitry Andric /// not the parsed cast-expression. 25630b57cec5SDimitry Andric /// 25640b57cec5SDimitry Andric /// \verbatim 25650b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 25660b57cec5SDimitry Andric /// '(' expression ')' 25670b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 25680b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 25690b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 25700b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 25710b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 25720b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 25730b57cec5SDimitry Andric /// [ARC] bridged-cast-expression 25740b57cec5SDimitry Andric /// [ARC] bridged-cast-expression: 25750b57cec5SDimitry Andric /// (__bridge type-name) cast-expression 25760b57cec5SDimitry Andric /// (__bridge_transfer type-name) cast-expression 25770b57cec5SDimitry Andric /// (__bridge_retained type-name) cast-expression 25780b57cec5SDimitry Andric /// fold-expression: [C++1z] 25790b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' ')' 25800b57cec5SDimitry Andric /// '(' '...' fold-operator cast-expression ')' 25810b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' 25820b57cec5SDimitry Andric /// fold-operator cast-expression ')' 25830b57cec5SDimitry Andric /// \endverbatim 25840b57cec5SDimitry Andric ExprResult 25850b57cec5SDimitry Andric Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 25860b57cec5SDimitry Andric bool isTypeCast, ParsedType &CastTy, 25870b57cec5SDimitry Andric SourceLocation &RParenLoc) { 25880b57cec5SDimitry Andric assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 25890b57cec5SDimitry Andric ColonProtectionRAIIObject ColonProtection(*this, false); 25900b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 25910b57cec5SDimitry Andric if (T.consumeOpen()) 25920b57cec5SDimitry Andric return ExprError(); 25930b57cec5SDimitry Andric SourceLocation OpenLoc = T.getOpenLocation(); 25940b57cec5SDimitry Andric 25950b57cec5SDimitry Andric PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc); 25960b57cec5SDimitry Andric 25970b57cec5SDimitry Andric ExprResult Result(true); 25980b57cec5SDimitry Andric bool isAmbiguousTypeId; 25990b57cec5SDimitry Andric CastTy = nullptr; 26000b57cec5SDimitry Andric 26010b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 26020b57cec5SDimitry Andric Actions.CodeCompleteExpression( 26030b57cec5SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation()), 26040b57cec5SDimitry Andric /*IsParenthesized=*/ExprType >= CompoundLiteral); 26050b57cec5SDimitry Andric cutOffParsing(); 26060b57cec5SDimitry Andric return ExprError(); 26070b57cec5SDimitry Andric } 26080b57cec5SDimitry Andric 26090b57cec5SDimitry Andric // Diagnose use of bridge casts in non-arc mode. 26100b57cec5SDimitry Andric bool BridgeCast = (getLangOpts().ObjC && 26110b57cec5SDimitry Andric Tok.isOneOf(tok::kw___bridge, 26120b57cec5SDimitry Andric tok::kw___bridge_transfer, 26130b57cec5SDimitry Andric tok::kw___bridge_retained, 26140b57cec5SDimitry Andric tok::kw___bridge_retain)); 26150b57cec5SDimitry Andric if (BridgeCast && !getLangOpts().ObjCAutoRefCount) { 26160b57cec5SDimitry Andric if (!TryConsumeToken(tok::kw___bridge)) { 26170b57cec5SDimitry Andric StringRef BridgeCastName = Tok.getName(); 26180b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 26190b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 26200b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc) 26210b57cec5SDimitry Andric << BridgeCastName 26220b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, ""); 26230b57cec5SDimitry Andric } 26240b57cec5SDimitry Andric BridgeCast = false; 26250b57cec5SDimitry Andric } 26260b57cec5SDimitry Andric 26270b57cec5SDimitry Andric // None of these cases should fall through with an invalid Result 26280b57cec5SDimitry Andric // unless they've already reported an error. 26290b57cec5SDimitry Andric if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 26300b57cec5SDimitry Andric Diag(Tok, diag::ext_gnu_statement_expr); 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) { 26330b57cec5SDimitry Andric Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope)); 26340b57cec5SDimitry Andric } else { 26350b57cec5SDimitry Andric // Find the nearest non-record decl context. Variables declared in a 26360b57cec5SDimitry Andric // statement expression behave as if they were declared in the enclosing 26370b57cec5SDimitry Andric // function, block, or other code construct. 26380b57cec5SDimitry Andric DeclContext *CodeDC = Actions.CurContext; 26390b57cec5SDimitry Andric while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) { 26400b57cec5SDimitry Andric CodeDC = CodeDC->getParent(); 26410b57cec5SDimitry Andric assert(CodeDC && !CodeDC->isFileContext() && 26420b57cec5SDimitry Andric "statement expr not in code context"); 26430b57cec5SDimitry Andric } 26440b57cec5SDimitry Andric Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false); 26450b57cec5SDimitry Andric 26460b57cec5SDimitry Andric Actions.ActOnStartStmtExpr(); 26470b57cec5SDimitry Andric 26480b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatement(true)); 26490b57cec5SDimitry Andric ExprType = CompoundStmt; 26500b57cec5SDimitry Andric 26510b57cec5SDimitry Andric // If the substmt parsed correctly, build the AST node. 26520b57cec5SDimitry Andric if (!Stmt.isInvalid()) { 26530b57cec5SDimitry Andric Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation()); 26540b57cec5SDimitry Andric } else { 26550b57cec5SDimitry Andric Actions.ActOnStmtExprError(); 26560b57cec5SDimitry Andric } 26570b57cec5SDimitry Andric } 26580b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && BridgeCast) { 26590b57cec5SDimitry Andric tok::TokenKind tokenKind = Tok.getKind(); 26600b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 26610b57cec5SDimitry Andric 26620b57cec5SDimitry Andric // Parse an Objective-C ARC ownership cast expression. 26630b57cec5SDimitry Andric ObjCBridgeCastKind Kind; 26640b57cec5SDimitry Andric if (tokenKind == tok::kw___bridge) 26650b57cec5SDimitry Andric Kind = OBC_Bridge; 26660b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_transfer) 26670b57cec5SDimitry Andric Kind = OBC_BridgeTransfer; 26680b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_retained) 26690b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 26700b57cec5SDimitry Andric else { 26710b57cec5SDimitry Andric // As a hopefully temporary workaround, allow __bridge_retain as 26720b57cec5SDimitry Andric // a synonym for __bridge_retained, but only in system headers. 26730b57cec5SDimitry Andric assert(tokenKind == tok::kw___bridge_retain); 26740b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 26750b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 26760b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain) 26770b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, 26780b57cec5SDimitry Andric "__bridge_retained"); 26790b57cec5SDimitry Andric } 26800b57cec5SDimitry Andric 26810b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 26820b57cec5SDimitry Andric T.consumeClose(); 26830b57cec5SDimitry Andric ColonProtection.restore(); 26840b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 26850b57cec5SDimitry Andric 26860b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); 2687*480093f4SDimitry Andric ExprResult SubExpr = ParseCastExpression(AnyCastExpr); 26880b57cec5SDimitry Andric 26890b57cec5SDimitry Andric if (Ty.isInvalid() || SubExpr.isInvalid()) 26900b57cec5SDimitry Andric return ExprError(); 26910b57cec5SDimitry Andric 26920b57cec5SDimitry Andric return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, 26930b57cec5SDimitry Andric BridgeKeywordLoc, Ty.get(), 26940b57cec5SDimitry Andric RParenLoc, SubExpr.get()); 26950b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && 26960b57cec5SDimitry Andric isTypeIdInParens(isAmbiguousTypeId)) { 26970b57cec5SDimitry Andric 26980b57cec5SDimitry Andric // Otherwise, this is a compound literal expression or cast expression. 26990b57cec5SDimitry Andric 27000b57cec5SDimitry Andric // In C++, if the type-id is ambiguous we disambiguate based on context. 27010b57cec5SDimitry Andric // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 27020b57cec5SDimitry Andric // in which case we should treat it as type-id. 27030b57cec5SDimitry Andric // if stopIfCastExpr is false, we need to determine the context past the 27040b57cec5SDimitry Andric // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 27050b57cec5SDimitry Andric if (isAmbiguousTypeId && !stopIfCastExpr) { 27060b57cec5SDimitry Andric ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T, 27070b57cec5SDimitry Andric ColonProtection); 27080b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 27090b57cec5SDimitry Andric return res; 27100b57cec5SDimitry Andric } 27110b57cec5SDimitry Andric 27120b57cec5SDimitry Andric // Parse the type declarator. 27130b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 27140b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 27150b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); 27160b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 27170b57cec5SDimitry Andric 27180b57cec5SDimitry Andric // If our type is followed by an identifier and either ':' or ']', then 27190b57cec5SDimitry Andric // this is probably an Objective-C message send where the leading '[' is 27200b57cec5SDimitry Andric // missing. Recover as if that were the case. 27210b57cec5SDimitry Andric if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && 27220b57cec5SDimitry Andric !InMessageExpression && getLangOpts().ObjC && 27230b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 27240b57cec5SDimitry Andric TypeResult Ty; 27250b57cec5SDimitry Andric { 27260b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 27270b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric Result = ParseObjCMessageExpressionBody(SourceLocation(), 27300b57cec5SDimitry Andric SourceLocation(), 27310b57cec5SDimitry Andric Ty.get(), nullptr); 27320b57cec5SDimitry Andric } else { 27330b57cec5SDimitry Andric // Match the ')'. 27340b57cec5SDimitry Andric T.consumeClose(); 27350b57cec5SDimitry Andric ColonProtection.restore(); 27360b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 27370b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 27380b57cec5SDimitry Andric ExprType = CompoundLiteral; 27390b57cec5SDimitry Andric TypeResult Ty; 27400b57cec5SDimitry Andric { 27410b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 27420b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 27430b57cec5SDimitry Andric } 27440b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 27450b57cec5SDimitry Andric } 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 27480b57cec5SDimitry Andric // This could be OpenCL vector Literals 27490b57cec5SDimitry Andric if (getLangOpts().OpenCL) 27500b57cec5SDimitry Andric { 27510b57cec5SDimitry Andric TypeResult Ty; 27520b57cec5SDimitry Andric { 27530b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 27540b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 27550b57cec5SDimitry Andric } 27560b57cec5SDimitry Andric if(Ty.isInvalid()) 27570b57cec5SDimitry Andric { 27580b57cec5SDimitry Andric return ExprError(); 27590b57cec5SDimitry Andric } 27600b57cec5SDimitry Andric QualType QT = Ty.get().get().getCanonicalType(); 27610b57cec5SDimitry Andric if (QT->isVectorType()) 27620b57cec5SDimitry Andric { 27630b57cec5SDimitry Andric // We parsed '(' vector-type-name ')' followed by '(' 27640b57cec5SDimitry Andric 27650b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 27660b57cec5SDimitry Andric // isVectorLiteral = true will make sure we don't parse any 27670b57cec5SDimitry Andric // Postfix expression yet 2768*480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 27690b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 27700b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast, 27710b57cec5SDimitry Andric /*isVectorLiteral=*/true); 27720b57cec5SDimitry Andric 27730b57cec5SDimitry Andric if (!Result.isInvalid()) { 27740b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 27750b57cec5SDimitry Andric DeclaratorInfo, CastTy, 27760b57cec5SDimitry Andric RParenLoc, Result.get()); 27770b57cec5SDimitry Andric } 27780b57cec5SDimitry Andric 27790b57cec5SDimitry Andric // After we performed the cast we can check for postfix-expr pieces. 27800b57cec5SDimitry Andric if (!Result.isInvalid()) { 27810b57cec5SDimitry Andric Result = ParsePostfixExpressionSuffix(Result); 27820b57cec5SDimitry Andric } 27830b57cec5SDimitry Andric 27840b57cec5SDimitry Andric return Result; 27850b57cec5SDimitry Andric } 27860b57cec5SDimitry Andric } 27870b57cec5SDimitry Andric } 27880b57cec5SDimitry Andric 27890b57cec5SDimitry Andric if (ExprType == CastExpr) { 27900b57cec5SDimitry Andric // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 27910b57cec5SDimitry Andric 27920b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 27930b57cec5SDimitry Andric return ExprError(); 27940b57cec5SDimitry Andric 27950b57cec5SDimitry Andric // Note that this doesn't parse the subsequent cast-expression, it just 27960b57cec5SDimitry Andric // returns the parsed type to the callee. 27970b57cec5SDimitry Andric if (stopIfCastExpr) { 27980b57cec5SDimitry Andric TypeResult Ty; 27990b57cec5SDimitry Andric { 28000b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 28010b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 28020b57cec5SDimitry Andric } 28030b57cec5SDimitry Andric CastTy = Ty.get(); 28040b57cec5SDimitry Andric return ExprResult(); 28050b57cec5SDimitry Andric } 28060b57cec5SDimitry Andric 28070b57cec5SDimitry Andric // Reject the cast of super idiom in ObjC. 28080b57cec5SDimitry Andric if (Tok.is(tok::identifier) && getLangOpts().ObjC && 28090b57cec5SDimitry Andric Tok.getIdentifierInfo() == Ident_super && 28100b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 28110b57cec5SDimitry Andric GetLookAheadToken(1).isNot(tok::period)) { 28120b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_illegal_super_cast) 28130b57cec5SDimitry Andric << SourceRange(OpenLoc, RParenLoc); 28140b57cec5SDimitry Andric return ExprError(); 28150b57cec5SDimitry Andric } 28160b57cec5SDimitry Andric 28170b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get()); 28180b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 28190b57cec5SDimitry Andric // TODO: For cast expression with CastTy. 2820*480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 28210b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 28220b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast); 28230b57cec5SDimitry Andric if (!Result.isInvalid()) { 28240b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 28250b57cec5SDimitry Andric DeclaratorInfo, CastTy, 28260b57cec5SDimitry Andric RParenLoc, Result.get()); 28270b57cec5SDimitry Andric } 28280b57cec5SDimitry Andric return Result; 28290b57cec5SDimitry Andric } 28300b57cec5SDimitry Andric 28310b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 28320b57cec5SDimitry Andric return ExprError(); 28330b57cec5SDimitry Andric } 28340b57cec5SDimitry Andric } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && 28350b57cec5SDimitry Andric isFoldOperator(NextToken().getKind())) { 28360b57cec5SDimitry Andric ExprType = FoldExpr; 28370b57cec5SDimitry Andric return ParseFoldExpression(ExprResult(), T); 28380b57cec5SDimitry Andric } else if (isTypeCast) { 28390b57cec5SDimitry Andric // Parse the expression-list. 28400b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 28410b57cec5SDimitry Andric 28420b57cec5SDimitry Andric ExprVector ArgExprs; 28430b57cec5SDimitry Andric CommaLocsTy CommaLocs; 28440b57cec5SDimitry Andric 28450b57cec5SDimitry Andric if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { 28460b57cec5SDimitry Andric // FIXME: If we ever support comma expressions as operands to 28470b57cec5SDimitry Andric // fold-expressions, we'll need to allow multiple ArgExprs here. 28480b57cec5SDimitry Andric if (ExprType >= FoldExpr && ArgExprs.size() == 1 && 28490b57cec5SDimitry Andric isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { 28500b57cec5SDimitry Andric ExprType = FoldExpr; 28510b57cec5SDimitry Andric return ParseFoldExpression(ArgExprs[0], T); 28520b57cec5SDimitry Andric } 28530b57cec5SDimitry Andric 28540b57cec5SDimitry Andric ExprType = SimpleExpr; 28550b57cec5SDimitry Andric Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), 28560b57cec5SDimitry Andric ArgExprs); 28570b57cec5SDimitry Andric } 28580b57cec5SDimitry Andric } else { 28590b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 28600b57cec5SDimitry Andric 28610b57cec5SDimitry Andric Result = ParseExpression(MaybeTypeCast); 28620b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus && MaybeTypeCast && Result.isUsable()) { 28630b57cec5SDimitry Andric // Correct typos in non-C++ code earlier so that implicit-cast-like 28640b57cec5SDimitry Andric // expressions are parsed correctly. 28650b57cec5SDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(Result); 28660b57cec5SDimitry Andric } 28670b57cec5SDimitry Andric 28680b57cec5SDimitry Andric if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && 28690b57cec5SDimitry Andric NextToken().is(tok::ellipsis)) { 28700b57cec5SDimitry Andric ExprType = FoldExpr; 28710b57cec5SDimitry Andric return ParseFoldExpression(Result, T); 28720b57cec5SDimitry Andric } 28730b57cec5SDimitry Andric ExprType = SimpleExpr; 28740b57cec5SDimitry Andric 28750b57cec5SDimitry Andric // Don't build a paren expression unless we actually match a ')'. 28760b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 28770b57cec5SDimitry Andric Result = 28780b57cec5SDimitry Andric Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get()); 28790b57cec5SDimitry Andric } 28800b57cec5SDimitry Andric 28810b57cec5SDimitry Andric // Match the ')'. 28820b57cec5SDimitry Andric if (Result.isInvalid()) { 28830b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 28840b57cec5SDimitry Andric return ExprError(); 28850b57cec5SDimitry Andric } 28860b57cec5SDimitry Andric 28870b57cec5SDimitry Andric T.consumeClose(); 28880b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 28890b57cec5SDimitry Andric return Result; 28900b57cec5SDimitry Andric } 28910b57cec5SDimitry Andric 28920b57cec5SDimitry Andric /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 28930b57cec5SDimitry Andric /// and we are at the left brace. 28940b57cec5SDimitry Andric /// 28950b57cec5SDimitry Andric /// \verbatim 28960b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 28970b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 28980b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 28990b57cec5SDimitry Andric /// \endverbatim 29000b57cec5SDimitry Andric ExprResult 29010b57cec5SDimitry Andric Parser::ParseCompoundLiteralExpression(ParsedType Ty, 29020b57cec5SDimitry Andric SourceLocation LParenLoc, 29030b57cec5SDimitry Andric SourceLocation RParenLoc) { 29040b57cec5SDimitry Andric assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 29050b57cec5SDimitry Andric if (!getLangOpts().C99) // Compound literals don't exist in C90. 29060b57cec5SDimitry Andric Diag(LParenLoc, diag::ext_c99_compound_literal); 29070b57cec5SDimitry Andric ExprResult Result = ParseInitializer(); 29080b57cec5SDimitry Andric if (!Result.isInvalid() && Ty) 29090b57cec5SDimitry Andric return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get()); 29100b57cec5SDimitry Andric return Result; 29110b57cec5SDimitry Andric } 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andric /// ParseStringLiteralExpression - This handles the various token types that 29140b57cec5SDimitry Andric /// form string literals, and also handles string concatenation [C99 5.1.1.2, 29150b57cec5SDimitry Andric /// translation phase #6]. 29160b57cec5SDimitry Andric /// 29170b57cec5SDimitry Andric /// \verbatim 29180b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 29190b57cec5SDimitry Andric /// string-literal 29200b57cec5SDimitry Andric /// \verbatim 29210b57cec5SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) { 29220b57cec5SDimitry Andric assert(isTokenStringLiteral() && "Not a string literal!"); 29230b57cec5SDimitry Andric 29240b57cec5SDimitry Andric // String concat. Note that keywords like __func__ and __FUNCTION__ are not 29250b57cec5SDimitry Andric // considered to be strings for concatenation purposes. 29260b57cec5SDimitry Andric SmallVector<Token, 4> StringToks; 29270b57cec5SDimitry Andric 29280b57cec5SDimitry Andric do { 29290b57cec5SDimitry Andric StringToks.push_back(Tok); 29300b57cec5SDimitry Andric ConsumeStringToken(); 29310b57cec5SDimitry Andric } while (isTokenStringLiteral()); 29320b57cec5SDimitry Andric 29330b57cec5SDimitry Andric // Pass the set of string tokens, ready for concatenation, to the actions. 29340b57cec5SDimitry Andric return Actions.ActOnStringLiteral(StringToks, 29350b57cec5SDimitry Andric AllowUserDefinedLiteral ? getCurScope() 29360b57cec5SDimitry Andric : nullptr); 29370b57cec5SDimitry Andric } 29380b57cec5SDimitry Andric 29390b57cec5SDimitry Andric /// ParseGenericSelectionExpression - Parse a C11 generic-selection 29400b57cec5SDimitry Andric /// [C11 6.5.1.1]. 29410b57cec5SDimitry Andric /// 29420b57cec5SDimitry Andric /// \verbatim 29430b57cec5SDimitry Andric /// generic-selection: 29440b57cec5SDimitry Andric /// _Generic ( assignment-expression , generic-assoc-list ) 29450b57cec5SDimitry Andric /// generic-assoc-list: 29460b57cec5SDimitry Andric /// generic-association 29470b57cec5SDimitry Andric /// generic-assoc-list , generic-association 29480b57cec5SDimitry Andric /// generic-association: 29490b57cec5SDimitry Andric /// type-name : assignment-expression 29500b57cec5SDimitry Andric /// default : assignment-expression 29510b57cec5SDimitry Andric /// \endverbatim 29520b57cec5SDimitry Andric ExprResult Parser::ParseGenericSelectionExpression() { 29530b57cec5SDimitry Andric assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected"); 29540b57cec5SDimitry Andric if (!getLangOpts().C11) 2955a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 29560b57cec5SDimitry Andric 2957a7dea167SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 29580b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 29590b57cec5SDimitry Andric if (T.expectAndConsume()) 29600b57cec5SDimitry Andric return ExprError(); 29610b57cec5SDimitry Andric 29620b57cec5SDimitry Andric ExprResult ControllingExpr; 29630b57cec5SDimitry Andric { 29640b57cec5SDimitry Andric // C11 6.5.1.1p3 "The controlling expression of a generic selection is 29650b57cec5SDimitry Andric // not evaluated." 29660b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 29670b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 29680b57cec5SDimitry Andric ControllingExpr = 29690b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 29700b57cec5SDimitry Andric if (ControllingExpr.isInvalid()) { 29710b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29720b57cec5SDimitry Andric return ExprError(); 29730b57cec5SDimitry Andric } 29740b57cec5SDimitry Andric } 29750b57cec5SDimitry Andric 29760b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 29770b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29780b57cec5SDimitry Andric return ExprError(); 29790b57cec5SDimitry Andric } 29800b57cec5SDimitry Andric 29810b57cec5SDimitry Andric SourceLocation DefaultLoc; 29820b57cec5SDimitry Andric TypeVector Types; 29830b57cec5SDimitry Andric ExprVector Exprs; 29840b57cec5SDimitry Andric do { 29850b57cec5SDimitry Andric ParsedType Ty; 29860b57cec5SDimitry Andric if (Tok.is(tok::kw_default)) { 29870b57cec5SDimitry Andric // C11 6.5.1.1p2 "A generic selection shall have no more than one default 29880b57cec5SDimitry Andric // generic association." 29890b57cec5SDimitry Andric if (!DefaultLoc.isInvalid()) { 29900b57cec5SDimitry Andric Diag(Tok, diag::err_duplicate_default_assoc); 29910b57cec5SDimitry Andric Diag(DefaultLoc, diag::note_previous_default_assoc); 29920b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 29930b57cec5SDimitry Andric return ExprError(); 29940b57cec5SDimitry Andric } 29950b57cec5SDimitry Andric DefaultLoc = ConsumeToken(); 29960b57cec5SDimitry Andric Ty = nullptr; 29970b57cec5SDimitry Andric } else { 29980b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 29990b57cec5SDimitry Andric TypeResult TR = ParseTypeName(); 30000b57cec5SDimitry Andric if (TR.isInvalid()) { 30010b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 30020b57cec5SDimitry Andric return ExprError(); 30030b57cec5SDimitry Andric } 30040b57cec5SDimitry Andric Ty = TR.get(); 30050b57cec5SDimitry Andric } 30060b57cec5SDimitry Andric Types.push_back(Ty); 30070b57cec5SDimitry Andric 30080b57cec5SDimitry Andric if (ExpectAndConsume(tok::colon)) { 30090b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 30100b57cec5SDimitry Andric return ExprError(); 30110b57cec5SDimitry Andric } 30120b57cec5SDimitry Andric 30130b57cec5SDimitry Andric // FIXME: These expressions should be parsed in a potentially potentially 30140b57cec5SDimitry Andric // evaluated context. 30150b57cec5SDimitry Andric ExprResult ER( 30160b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); 30170b57cec5SDimitry Andric if (ER.isInvalid()) { 30180b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 30190b57cec5SDimitry Andric return ExprError(); 30200b57cec5SDimitry Andric } 30210b57cec5SDimitry Andric Exprs.push_back(ER.get()); 30220b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 30230b57cec5SDimitry Andric 30240b57cec5SDimitry Andric T.consumeClose(); 30250b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 30260b57cec5SDimitry Andric return ExprError(); 30270b57cec5SDimitry Andric 30280b57cec5SDimitry Andric return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, 30290b57cec5SDimitry Andric T.getCloseLocation(), 30300b57cec5SDimitry Andric ControllingExpr.get(), 30310b57cec5SDimitry Andric Types, Exprs); 30320b57cec5SDimitry Andric } 30330b57cec5SDimitry Andric 30340b57cec5SDimitry Andric /// Parse A C++1z fold-expression after the opening paren and optional 30350b57cec5SDimitry Andric /// left-hand-side expression. 30360b57cec5SDimitry Andric /// 30370b57cec5SDimitry Andric /// \verbatim 30380b57cec5SDimitry Andric /// fold-expression: 30390b57cec5SDimitry Andric /// ( cast-expression fold-operator ... ) 30400b57cec5SDimitry Andric /// ( ... fold-operator cast-expression ) 30410b57cec5SDimitry Andric /// ( cast-expression fold-operator ... fold-operator cast-expression ) 30420b57cec5SDimitry Andric ExprResult Parser::ParseFoldExpression(ExprResult LHS, 30430b57cec5SDimitry Andric BalancedDelimiterTracker &T) { 30440b57cec5SDimitry Andric if (LHS.isInvalid()) { 30450b57cec5SDimitry Andric T.skipToEnd(); 30460b57cec5SDimitry Andric return true; 30470b57cec5SDimitry Andric } 30480b57cec5SDimitry Andric 30490b57cec5SDimitry Andric tok::TokenKind Kind = tok::unknown; 30500b57cec5SDimitry Andric SourceLocation FirstOpLoc; 30510b57cec5SDimitry Andric if (LHS.isUsable()) { 30520b57cec5SDimitry Andric Kind = Tok.getKind(); 30530b57cec5SDimitry Andric assert(isFoldOperator(Kind) && "missing fold-operator"); 30540b57cec5SDimitry Andric FirstOpLoc = ConsumeToken(); 30550b57cec5SDimitry Andric } 30560b57cec5SDimitry Andric 30570b57cec5SDimitry Andric assert(Tok.is(tok::ellipsis) && "not a fold-expression"); 30580b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 30590b57cec5SDimitry Andric 30600b57cec5SDimitry Andric ExprResult RHS; 30610b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 30620b57cec5SDimitry Andric if (!isFoldOperator(Tok.getKind())) 30630b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_fold_operator); 30640b57cec5SDimitry Andric 30650b57cec5SDimitry Andric if (Kind != tok::unknown && Tok.getKind() != Kind) 30660b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_fold_operator_mismatch) 30670b57cec5SDimitry Andric << SourceRange(FirstOpLoc); 30680b57cec5SDimitry Andric Kind = Tok.getKind(); 30690b57cec5SDimitry Andric ConsumeToken(); 30700b57cec5SDimitry Andric 30710b57cec5SDimitry Andric RHS = ParseExpression(); 30720b57cec5SDimitry Andric if (RHS.isInvalid()) { 30730b57cec5SDimitry Andric T.skipToEnd(); 30740b57cec5SDimitry Andric return true; 30750b57cec5SDimitry Andric } 30760b57cec5SDimitry Andric } 30770b57cec5SDimitry Andric 30780b57cec5SDimitry Andric Diag(EllipsisLoc, getLangOpts().CPlusPlus17 30790b57cec5SDimitry Andric ? diag::warn_cxx14_compat_fold_expression 30800b57cec5SDimitry Andric : diag::ext_fold_expression); 30810b57cec5SDimitry Andric 30820b57cec5SDimitry Andric T.consumeClose(); 30830b57cec5SDimitry Andric return Actions.ActOnCXXFoldExpr(T.getOpenLocation(), LHS.get(), Kind, 30840b57cec5SDimitry Andric EllipsisLoc, RHS.get(), T.getCloseLocation()); 30850b57cec5SDimitry Andric } 30860b57cec5SDimitry Andric 30870b57cec5SDimitry Andric /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 30880b57cec5SDimitry Andric /// 30890b57cec5SDimitry Andric /// \verbatim 30900b57cec5SDimitry Andric /// argument-expression-list: 30910b57cec5SDimitry Andric /// assignment-expression 30920b57cec5SDimitry Andric /// argument-expression-list , assignment-expression 30930b57cec5SDimitry Andric /// 30940b57cec5SDimitry Andric /// [C++] expression-list: 30950b57cec5SDimitry Andric /// [C++] assignment-expression 30960b57cec5SDimitry Andric /// [C++] expression-list , assignment-expression 30970b57cec5SDimitry Andric /// 30980b57cec5SDimitry Andric /// [C++0x] expression-list: 30990b57cec5SDimitry Andric /// [C++0x] initializer-list 31000b57cec5SDimitry Andric /// 31010b57cec5SDimitry Andric /// [C++0x] initializer-list 31020b57cec5SDimitry Andric /// [C++0x] initializer-clause ...[opt] 31030b57cec5SDimitry Andric /// [C++0x] initializer-list , initializer-clause ...[opt] 31040b57cec5SDimitry Andric /// 31050b57cec5SDimitry Andric /// [C++0x] initializer-clause: 31060b57cec5SDimitry Andric /// [C++0x] assignment-expression 31070b57cec5SDimitry Andric /// [C++0x] braced-init-list 31080b57cec5SDimitry Andric /// \endverbatim 31090b57cec5SDimitry Andric bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, 31100b57cec5SDimitry Andric SmallVectorImpl<SourceLocation> &CommaLocs, 31110b57cec5SDimitry Andric llvm::function_ref<void()> ExpressionStarts) { 31120b57cec5SDimitry Andric bool SawError = false; 31130b57cec5SDimitry Andric while (1) { 31140b57cec5SDimitry Andric if (ExpressionStarts) 31150b57cec5SDimitry Andric ExpressionStarts(); 31160b57cec5SDimitry Andric 31170b57cec5SDimitry Andric ExprResult Expr; 31180b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 31190b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 31200b57cec5SDimitry Andric Expr = ParseBraceInitializer(); 31210b57cec5SDimitry Andric } else 31220b57cec5SDimitry Andric Expr = ParseAssignmentExpression(); 31230b57cec5SDimitry Andric 31240b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) 31250b57cec5SDimitry Andric Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); 31260b57cec5SDimitry Andric if (Expr.isInvalid()) { 31270b57cec5SDimitry Andric SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); 31280b57cec5SDimitry Andric SawError = true; 31290b57cec5SDimitry Andric } else { 31300b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 31310b57cec5SDimitry Andric } 31320b57cec5SDimitry Andric 31330b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 31340b57cec5SDimitry Andric break; 31350b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 31360b57cec5SDimitry Andric Token Comma = Tok; 31370b57cec5SDimitry Andric CommaLocs.push_back(ConsumeToken()); 31380b57cec5SDimitry Andric 31390b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 31400b57cec5SDimitry Andric } 31410b57cec5SDimitry Andric if (SawError) { 31420b57cec5SDimitry Andric // Ensure typos get diagnosed when errors were encountered while parsing the 31430b57cec5SDimitry Andric // expression list. 31440b57cec5SDimitry Andric for (auto &E : Exprs) { 31450b57cec5SDimitry Andric ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); 31460b57cec5SDimitry Andric if (Expr.isUsable()) E = Expr.get(); 31470b57cec5SDimitry Andric } 31480b57cec5SDimitry Andric } 31490b57cec5SDimitry Andric return SawError; 31500b57cec5SDimitry Andric } 31510b57cec5SDimitry Andric 31520b57cec5SDimitry Andric /// ParseSimpleExpressionList - A simple comma-separated list of expressions, 31530b57cec5SDimitry Andric /// used for misc language extensions. 31540b57cec5SDimitry Andric /// 31550b57cec5SDimitry Andric /// \verbatim 31560b57cec5SDimitry Andric /// simple-expression-list: 31570b57cec5SDimitry Andric /// assignment-expression 31580b57cec5SDimitry Andric /// simple-expression-list , assignment-expression 31590b57cec5SDimitry Andric /// \endverbatim 31600b57cec5SDimitry Andric bool 31610b57cec5SDimitry Andric Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, 31620b57cec5SDimitry Andric SmallVectorImpl<SourceLocation> &CommaLocs) { 31630b57cec5SDimitry Andric while (1) { 31640b57cec5SDimitry Andric ExprResult Expr = ParseAssignmentExpression(); 31650b57cec5SDimitry Andric if (Expr.isInvalid()) 31660b57cec5SDimitry Andric return true; 31670b57cec5SDimitry Andric 31680b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 31690b57cec5SDimitry Andric 31700b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 31710b57cec5SDimitry Andric return false; 31720b57cec5SDimitry Andric 31730b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 31740b57cec5SDimitry Andric Token Comma = Tok; 31750b57cec5SDimitry Andric CommaLocs.push_back(ConsumeToken()); 31760b57cec5SDimitry Andric 31770b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 31780b57cec5SDimitry Andric } 31790b57cec5SDimitry Andric } 31800b57cec5SDimitry Andric 31810b57cec5SDimitry Andric /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 31820b57cec5SDimitry Andric /// 31830b57cec5SDimitry Andric /// \verbatim 31840b57cec5SDimitry Andric /// [clang] block-id: 31850b57cec5SDimitry Andric /// [clang] specifier-qualifier-list block-declarator 31860b57cec5SDimitry Andric /// \endverbatim 31870b57cec5SDimitry Andric void Parser::ParseBlockId(SourceLocation CaretLoc) { 31880b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 31890b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); 31900b57cec5SDimitry Andric return cutOffParsing(); 31910b57cec5SDimitry Andric } 31920b57cec5SDimitry Andric 31930b57cec5SDimitry Andric // Parse the specifier-qualifier-list piece. 31940b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 31950b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 31960b57cec5SDimitry Andric 31970b57cec5SDimitry Andric // Parse the block-declarator. 31980b57cec5SDimitry Andric Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteralContext); 31990b57cec5SDimitry Andric DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition); 32000b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 32010b57cec5SDimitry Andric 32020b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 32030b57cec5SDimitry Andric 32040b57cec5SDimitry Andric // Inform sema that we are starting a block. 32050b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope()); 32060b57cec5SDimitry Andric } 32070b57cec5SDimitry Andric 32080b57cec5SDimitry Andric /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 32090b57cec5SDimitry Andric /// like ^(int x){ return x+1; } 32100b57cec5SDimitry Andric /// 32110b57cec5SDimitry Andric /// \verbatim 32120b57cec5SDimitry Andric /// block-literal: 32130b57cec5SDimitry Andric /// [clang] '^' block-args[opt] compound-statement 32140b57cec5SDimitry Andric /// [clang] '^' block-id compound-statement 32150b57cec5SDimitry Andric /// [clang] block-args: 32160b57cec5SDimitry Andric /// [clang] '(' parameter-list ')' 32170b57cec5SDimitry Andric /// \endverbatim 32180b57cec5SDimitry Andric ExprResult Parser::ParseBlockLiteralExpression() { 32190b57cec5SDimitry Andric assert(Tok.is(tok::caret) && "block literal starts with ^"); 32200b57cec5SDimitry Andric SourceLocation CaretLoc = ConsumeToken(); 32210b57cec5SDimitry Andric 32220b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 32230b57cec5SDimitry Andric "block literal parsing"); 32240b57cec5SDimitry Andric 32250b57cec5SDimitry Andric // Enter a scope to hold everything within the block. This includes the 32260b57cec5SDimitry Andric // argument decls, decls within the compound expression, etc. This also 32270b57cec5SDimitry Andric // allows determining whether a variable reference inside the block is 32280b57cec5SDimitry Andric // within or outside of the block. 32290b57cec5SDimitry Andric ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 32300b57cec5SDimitry Andric Scope::CompoundStmtScope | Scope::DeclScope); 32310b57cec5SDimitry Andric 32320b57cec5SDimitry Andric // Inform sema that we are starting a block. 32330b57cec5SDimitry Andric Actions.ActOnBlockStart(CaretLoc, getCurScope()); 32340b57cec5SDimitry Andric 32350b57cec5SDimitry Andric // Parse the return type if present. 32360b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 32370b57cec5SDimitry Andric Declarator ParamInfo(DS, DeclaratorContext::BlockLiteralContext); 32380b57cec5SDimitry Andric ParamInfo.setFunctionDefinitionKind(FDK_Definition); 32390b57cec5SDimitry Andric // FIXME: Since the return type isn't actually parsed, it can't be used to 32400b57cec5SDimitry Andric // fill ParamInfo with an initial valid range, so do it manually. 32410b57cec5SDimitry Andric ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 32420b57cec5SDimitry Andric 32430b57cec5SDimitry Andric // If this block has arguments, parse them. There is no ambiguity here with 32440b57cec5SDimitry Andric // the expression case, because the expression case requires a parameter list. 32450b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 32460b57cec5SDimitry Andric ParseParenDeclarator(ParamInfo); 32470b57cec5SDimitry Andric // Parse the pieces after the identifier as if we had "int(...)". 32480b57cec5SDimitry Andric // SetIdentifier sets the source range end, but in this case we're past 32490b57cec5SDimitry Andric // that location. 32500b57cec5SDimitry Andric SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 32510b57cec5SDimitry Andric ParamInfo.SetIdentifier(nullptr, CaretLoc); 32520b57cec5SDimitry Andric ParamInfo.SetRangeEnd(Tmp); 32530b57cec5SDimitry Andric if (ParamInfo.isInvalidType()) { 32540b57cec5SDimitry Andric // If there was an error parsing the arguments, they may have 32550b57cec5SDimitry Andric // tried to use ^(x+y) which requires an argument list. Just 32560b57cec5SDimitry Andric // skip the whole block literal. 32570b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 32580b57cec5SDimitry Andric return ExprError(); 32590b57cec5SDimitry Andric } 32600b57cec5SDimitry Andric 32610b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 32620b57cec5SDimitry Andric 32630b57cec5SDimitry Andric // Inform sema that we are starting a block. 32640b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 32650b57cec5SDimitry Andric } else if (!Tok.is(tok::l_brace)) { 32660b57cec5SDimitry Andric ParseBlockId(CaretLoc); 32670b57cec5SDimitry Andric } else { 32680b57cec5SDimitry Andric // Otherwise, pretend we saw (void). 32690b57cec5SDimitry Andric SourceLocation NoLoc; 32700b57cec5SDimitry Andric ParamInfo.AddTypeInfo( 32710b57cec5SDimitry Andric DeclaratorChunk::getFunction(/*HasProto=*/true, 32720b57cec5SDimitry Andric /*IsAmbiguous=*/false, 32730b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 32740b57cec5SDimitry Andric /*ArgInfo=*/nullptr, 32750b57cec5SDimitry Andric /*NumParams=*/0, 32760b57cec5SDimitry Andric /*EllipsisLoc=*/NoLoc, 32770b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 32780b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 32790b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, 32800b57cec5SDimitry Andric /*MutableLoc=*/NoLoc, EST_None, 32810b57cec5SDimitry Andric /*ESpecRange=*/SourceRange(), 32820b57cec5SDimitry Andric /*Exceptions=*/nullptr, 32830b57cec5SDimitry Andric /*ExceptionRanges=*/nullptr, 32840b57cec5SDimitry Andric /*NumExceptions=*/0, 32850b57cec5SDimitry Andric /*NoexceptExpr=*/nullptr, 32860b57cec5SDimitry Andric /*ExceptionSpecTokens=*/nullptr, 32870b57cec5SDimitry Andric /*DeclsInPrototype=*/None, CaretLoc, 32880b57cec5SDimitry Andric CaretLoc, ParamInfo), 32890b57cec5SDimitry Andric CaretLoc); 32900b57cec5SDimitry Andric 32910b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andric // Inform sema that we are starting a block. 32940b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 32950b57cec5SDimitry Andric } 32960b57cec5SDimitry Andric 32970b57cec5SDimitry Andric 32980b57cec5SDimitry Andric ExprResult Result(true); 32990b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 33000b57cec5SDimitry Andric // Saw something like: ^expr 33010b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 33020b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 33030b57cec5SDimitry Andric return ExprError(); 33040b57cec5SDimitry Andric } 33050b57cec5SDimitry Andric 33060b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 33070b57cec5SDimitry Andric BlockScope.Exit(); 33080b57cec5SDimitry Andric if (!Stmt.isInvalid()) 33090b57cec5SDimitry Andric Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope()); 33100b57cec5SDimitry Andric else 33110b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 33120b57cec5SDimitry Andric return Result; 33130b57cec5SDimitry Andric } 33140b57cec5SDimitry Andric 33150b57cec5SDimitry Andric /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals. 33160b57cec5SDimitry Andric /// 33170b57cec5SDimitry Andric /// '__objc_yes' 33180b57cec5SDimitry Andric /// '__objc_no' 33190b57cec5SDimitry Andric ExprResult Parser::ParseObjCBoolLiteral() { 33200b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 33210b57cec5SDimitry Andric return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind); 33220b57cec5SDimitry Andric } 33230b57cec5SDimitry Andric 33240b57cec5SDimitry Andric /// Validate availability spec list, emitting diagnostics if necessary. Returns 33250b57cec5SDimitry Andric /// true if invalid. 33260b57cec5SDimitry Andric static bool CheckAvailabilitySpecList(Parser &P, 33270b57cec5SDimitry Andric ArrayRef<AvailabilitySpec> AvailSpecs) { 33280b57cec5SDimitry Andric llvm::SmallSet<StringRef, 4> Platforms; 33290b57cec5SDimitry Andric bool HasOtherPlatformSpec = false; 33300b57cec5SDimitry Andric bool Valid = true; 33310b57cec5SDimitry Andric for (const auto &Spec : AvailSpecs) { 33320b57cec5SDimitry Andric if (Spec.isOtherPlatformSpec()) { 33330b57cec5SDimitry Andric if (HasOtherPlatformSpec) { 33340b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star); 33350b57cec5SDimitry Andric Valid = false; 33360b57cec5SDimitry Andric } 33370b57cec5SDimitry Andric 33380b57cec5SDimitry Andric HasOtherPlatformSpec = true; 33390b57cec5SDimitry Andric continue; 33400b57cec5SDimitry Andric } 33410b57cec5SDimitry Andric 33420b57cec5SDimitry Andric bool Inserted = Platforms.insert(Spec.getPlatform()).second; 33430b57cec5SDimitry Andric if (!Inserted) { 33440b57cec5SDimitry Andric // Rule out multiple version specs referring to the same platform. 33450b57cec5SDimitry Andric // For example, we emit an error for: 33460b57cec5SDimitry Andric // @available(macos 10.10, macos 10.11, *) 33470b57cec5SDimitry Andric StringRef Platform = Spec.getPlatform(); 33480b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform) 33490b57cec5SDimitry Andric << Spec.getEndLoc() << Platform; 33500b57cec5SDimitry Andric Valid = false; 33510b57cec5SDimitry Andric } 33520b57cec5SDimitry Andric } 33530b57cec5SDimitry Andric 33540b57cec5SDimitry Andric if (!HasOtherPlatformSpec) { 33550b57cec5SDimitry Andric SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc(); 33560b57cec5SDimitry Andric P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required) 33570b57cec5SDimitry Andric << FixItHint::CreateInsertion(InsertWildcardLoc, ", *"); 33580b57cec5SDimitry Andric return true; 33590b57cec5SDimitry Andric } 33600b57cec5SDimitry Andric 33610b57cec5SDimitry Andric return !Valid; 33620b57cec5SDimitry Andric } 33630b57cec5SDimitry Andric 33640b57cec5SDimitry Andric /// Parse availability query specification. 33650b57cec5SDimitry Andric /// 33660b57cec5SDimitry Andric /// availability-spec: 33670b57cec5SDimitry Andric /// '*' 33680b57cec5SDimitry Andric /// identifier version-tuple 33690b57cec5SDimitry Andric Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() { 33700b57cec5SDimitry Andric if (Tok.is(tok::star)) { 33710b57cec5SDimitry Andric return AvailabilitySpec(ConsumeToken()); 33720b57cec5SDimitry Andric } else { 33730b57cec5SDimitry Andric // Parse the platform name. 33740b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 33750b57cec5SDimitry Andric Actions.CodeCompleteAvailabilityPlatformName(); 33760b57cec5SDimitry Andric cutOffParsing(); 33770b57cec5SDimitry Andric return None; 33780b57cec5SDimitry Andric } 33790b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 33800b57cec5SDimitry Andric Diag(Tok, diag::err_avail_query_expected_platform_name); 33810b57cec5SDimitry Andric return None; 33820b57cec5SDimitry Andric } 33830b57cec5SDimitry Andric 33840b57cec5SDimitry Andric IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc(); 33850b57cec5SDimitry Andric SourceRange VersionRange; 33860b57cec5SDimitry Andric VersionTuple Version = ParseVersionTuple(VersionRange); 33870b57cec5SDimitry Andric 33880b57cec5SDimitry Andric if (Version.empty()) 33890b57cec5SDimitry Andric return None; 33900b57cec5SDimitry Andric 33910b57cec5SDimitry Andric StringRef GivenPlatform = PlatformIdentifier->Ident->getName(); 33920b57cec5SDimitry Andric StringRef Platform = 33930b57cec5SDimitry Andric AvailabilityAttr::canonicalizePlatformName(GivenPlatform); 33940b57cec5SDimitry Andric 33950b57cec5SDimitry Andric if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) { 33960b57cec5SDimitry Andric Diag(PlatformIdentifier->Loc, 33970b57cec5SDimitry Andric diag::err_avail_query_unrecognized_platform_name) 33980b57cec5SDimitry Andric << GivenPlatform; 33990b57cec5SDimitry Andric return None; 34000b57cec5SDimitry Andric } 34010b57cec5SDimitry Andric 34020b57cec5SDimitry Andric return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc, 34030b57cec5SDimitry Andric VersionRange.getEnd()); 34040b57cec5SDimitry Andric } 34050b57cec5SDimitry Andric } 34060b57cec5SDimitry Andric 34070b57cec5SDimitry Andric ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { 34080b57cec5SDimitry Andric assert(Tok.is(tok::kw___builtin_available) || 34090b57cec5SDimitry Andric Tok.isObjCAtKeyword(tok::objc_available)); 34100b57cec5SDimitry Andric 34110b57cec5SDimitry Andric // Eat the available or __builtin_available. 34120b57cec5SDimitry Andric ConsumeToken(); 34130b57cec5SDimitry Andric 34140b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 34150b57cec5SDimitry Andric if (Parens.expectAndConsume()) 34160b57cec5SDimitry Andric return ExprError(); 34170b57cec5SDimitry Andric 34180b57cec5SDimitry Andric SmallVector<AvailabilitySpec, 4> AvailSpecs; 34190b57cec5SDimitry Andric bool HasError = false; 34200b57cec5SDimitry Andric while (true) { 34210b57cec5SDimitry Andric Optional<AvailabilitySpec> Spec = ParseAvailabilitySpec(); 34220b57cec5SDimitry Andric if (!Spec) 34230b57cec5SDimitry Andric HasError = true; 34240b57cec5SDimitry Andric else 34250b57cec5SDimitry Andric AvailSpecs.push_back(*Spec); 34260b57cec5SDimitry Andric 34270b57cec5SDimitry Andric if (!TryConsumeToken(tok::comma)) 34280b57cec5SDimitry Andric break; 34290b57cec5SDimitry Andric } 34300b57cec5SDimitry Andric 34310b57cec5SDimitry Andric if (HasError) { 34320b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 34330b57cec5SDimitry Andric return ExprError(); 34340b57cec5SDimitry Andric } 34350b57cec5SDimitry Andric 34360b57cec5SDimitry Andric CheckAvailabilitySpecList(*this, AvailSpecs); 34370b57cec5SDimitry Andric 34380b57cec5SDimitry Andric if (Parens.consumeClose()) 34390b57cec5SDimitry Andric return ExprError(); 34400b57cec5SDimitry Andric 34410b57cec5SDimitry Andric return Actions.ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, 34420b57cec5SDimitry Andric Parens.getCloseLocation()); 34430b57cec5SDimitry Andric } 3444