10b57cec5SDimitry Andric //===--- ParseExpr.cpp - Expression Parsing -------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Provides the Expression parsing implementation. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric /// Expressions in C99 basically consist of a bunch of binary operators with 130b57cec5SDimitry Andric /// unary operators and other random stuff at the leaves. 140b57cec5SDimitry Andric /// 150b57cec5SDimitry Andric /// In the C99 grammar, these unary operators bind tightest and are represented 160b57cec5SDimitry Andric /// as the 'cast-expression' production. Everything else is either a binary 170b57cec5SDimitry Andric /// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are 180b57cec5SDimitry Andric /// handled by ParseCastExpression, the higher level pieces are handled by 190b57cec5SDimitry Andric /// ParseBinaryExpression. 200b57cec5SDimitry Andric /// 210b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 24480093f4SDimitry Andric #include "clang/AST/ExprCXX.h" 250b57cec5SDimitry Andric #include "clang/Basic/PrettyStackTrace.h" 26*06c3fb27SDimitry Andric #include "clang/Parse/Parser.h" 270b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 280b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 29*06c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h" 300b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 310b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 320b57cec5SDimitry Andric #include "clang/Sema/TypoCorrection.h" 330b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 34bdd1243dSDimitry Andric #include <optional> 350b57cec5SDimitry Andric using namespace clang; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// Simple precedence-based parser for binary/ternary operators. 380b57cec5SDimitry Andric /// 390b57cec5SDimitry Andric /// Note: we diverge from the C99 grammar when parsing the assignment-expression 400b57cec5SDimitry Andric /// production. C99 specifies that the LHS of an assignment operator should be 410b57cec5SDimitry Andric /// parsed as a unary-expression, but consistency dictates that it be a 420b57cec5SDimitry Andric /// conditional-expession. In practice, the important thing here is that the 430b57cec5SDimitry Andric /// LHS of an assignment has to be an l-value, which productions between 440b57cec5SDimitry Andric /// unary-expression and conditional-expression don't produce. Because we want 450b57cec5SDimitry Andric /// consistency, we parse the LHS as a conditional-expression, then check for 460b57cec5SDimitry Andric /// l-value-ness in semantic analysis stages. 470b57cec5SDimitry Andric /// 480b57cec5SDimitry Andric /// \verbatim 490b57cec5SDimitry Andric /// pm-expression: [C++ 5.5] 500b57cec5SDimitry Andric /// cast-expression 510b57cec5SDimitry Andric /// pm-expression '.*' cast-expression 520b57cec5SDimitry Andric /// pm-expression '->*' cast-expression 530b57cec5SDimitry Andric /// 540b57cec5SDimitry Andric /// multiplicative-expression: [C99 6.5.5] 550b57cec5SDimitry Andric /// Note: in C++, apply pm-expression instead of cast-expression 560b57cec5SDimitry Andric /// cast-expression 570b57cec5SDimitry Andric /// multiplicative-expression '*' cast-expression 580b57cec5SDimitry Andric /// multiplicative-expression '/' cast-expression 590b57cec5SDimitry Andric /// multiplicative-expression '%' cast-expression 600b57cec5SDimitry Andric /// 610b57cec5SDimitry Andric /// additive-expression: [C99 6.5.6] 620b57cec5SDimitry Andric /// multiplicative-expression 630b57cec5SDimitry Andric /// additive-expression '+' multiplicative-expression 640b57cec5SDimitry Andric /// additive-expression '-' multiplicative-expression 650b57cec5SDimitry Andric /// 660b57cec5SDimitry Andric /// shift-expression: [C99 6.5.7] 670b57cec5SDimitry Andric /// additive-expression 680b57cec5SDimitry Andric /// shift-expression '<<' additive-expression 690b57cec5SDimitry Andric /// shift-expression '>>' additive-expression 700b57cec5SDimitry Andric /// 710b57cec5SDimitry Andric /// compare-expression: [C++20 expr.spaceship] 720b57cec5SDimitry Andric /// shift-expression 730b57cec5SDimitry Andric /// compare-expression '<=>' shift-expression 740b57cec5SDimitry Andric /// 750b57cec5SDimitry Andric /// relational-expression: [C99 6.5.8] 760b57cec5SDimitry Andric /// compare-expression 770b57cec5SDimitry Andric /// relational-expression '<' compare-expression 780b57cec5SDimitry Andric /// relational-expression '>' compare-expression 790b57cec5SDimitry Andric /// relational-expression '<=' compare-expression 800b57cec5SDimitry Andric /// relational-expression '>=' compare-expression 810b57cec5SDimitry Andric /// 820b57cec5SDimitry Andric /// equality-expression: [C99 6.5.9] 830b57cec5SDimitry Andric /// relational-expression 840b57cec5SDimitry Andric /// equality-expression '==' relational-expression 850b57cec5SDimitry Andric /// equality-expression '!=' relational-expression 860b57cec5SDimitry Andric /// 870b57cec5SDimitry Andric /// AND-expression: [C99 6.5.10] 880b57cec5SDimitry Andric /// equality-expression 890b57cec5SDimitry Andric /// AND-expression '&' equality-expression 900b57cec5SDimitry Andric /// 910b57cec5SDimitry Andric /// exclusive-OR-expression: [C99 6.5.11] 920b57cec5SDimitry Andric /// AND-expression 930b57cec5SDimitry Andric /// exclusive-OR-expression '^' AND-expression 940b57cec5SDimitry Andric /// 950b57cec5SDimitry Andric /// inclusive-OR-expression: [C99 6.5.12] 960b57cec5SDimitry Andric /// exclusive-OR-expression 970b57cec5SDimitry Andric /// inclusive-OR-expression '|' exclusive-OR-expression 980b57cec5SDimitry Andric /// 990b57cec5SDimitry Andric /// logical-AND-expression: [C99 6.5.13] 1000b57cec5SDimitry Andric /// inclusive-OR-expression 1010b57cec5SDimitry Andric /// logical-AND-expression '&&' inclusive-OR-expression 1020b57cec5SDimitry Andric /// 1030b57cec5SDimitry Andric /// logical-OR-expression: [C99 6.5.14] 1040b57cec5SDimitry Andric /// logical-AND-expression 1050b57cec5SDimitry Andric /// logical-OR-expression '||' logical-AND-expression 1060b57cec5SDimitry Andric /// 1070b57cec5SDimitry Andric /// conditional-expression: [C99 6.5.15] 1080b57cec5SDimitry Andric /// logical-OR-expression 1090b57cec5SDimitry Andric /// logical-OR-expression '?' expression ':' conditional-expression 1100b57cec5SDimitry Andric /// [GNU] logical-OR-expression '?' ':' conditional-expression 1110b57cec5SDimitry Andric /// [C++] the third operand is an assignment-expression 1120b57cec5SDimitry Andric /// 1130b57cec5SDimitry Andric /// assignment-expression: [C99 6.5.16] 1140b57cec5SDimitry Andric /// conditional-expression 1150b57cec5SDimitry Andric /// unary-expression assignment-operator assignment-expression 1160b57cec5SDimitry Andric /// [C++] throw-expression [C++ 15] 1170b57cec5SDimitry Andric /// 1180b57cec5SDimitry Andric /// assignment-operator: one of 1190b57cec5SDimitry Andric /// = *= /= %= += -= <<= >>= &= ^= |= 1200b57cec5SDimitry Andric /// 1210b57cec5SDimitry Andric /// expression: [C99 6.5.17] 1220b57cec5SDimitry Andric /// assignment-expression ...[opt] 1230b57cec5SDimitry Andric /// expression ',' assignment-expression ...[opt] 1240b57cec5SDimitry Andric /// \endverbatim 1250b57cec5SDimitry Andric ExprResult Parser::ParseExpression(TypeCastState isTypeCast) { 1260b57cec5SDimitry Andric ExprResult LHS(ParseAssignmentExpression(isTypeCast)); 1270b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric /// This routine is called when the '@' is seen and consumed. 1310b57cec5SDimitry Andric /// Current token is an Identifier and is not a 'try'. This 1320b57cec5SDimitry Andric /// routine is necessary to disambiguate \@try-statement from, 1330b57cec5SDimitry Andric /// for example, \@encode-expression. 1340b57cec5SDimitry Andric /// 1350b57cec5SDimitry Andric ExprResult 1360b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { 1370b57cec5SDimitry Andric ExprResult LHS(ParseObjCAtExpression(AtLoc)); 1380b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric /// This routine is called when a leading '__extension__' is seen and 1420b57cec5SDimitry Andric /// consumed. This is necessary because the token gets consumed in the 1430b57cec5SDimitry Andric /// process of disambiguating between an expression and a declaration. 1440b57cec5SDimitry Andric ExprResult 1450b57cec5SDimitry Andric Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { 1460b57cec5SDimitry Andric ExprResult LHS(true); 1470b57cec5SDimitry Andric { 1480b57cec5SDimitry Andric // Silence extension warnings in the sub-expression 1490b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); 1500b57cec5SDimitry Andric 151480093f4SDimitry Andric LHS = ParseCastExpression(AnyCastExpr); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric if (!LHS.isInvalid()) 1550b57cec5SDimitry Andric LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__, 1560b57cec5SDimitry Andric LHS.get()); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Comma); 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric /// Parse an expr that doesn't include (top-level) commas. 1620b57cec5SDimitry Andric ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { 1630b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 164fe6060f1SDimitry Andric cutOffParsing(); 1650b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 1660b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 1670b57cec5SDimitry Andric return ExprError(); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric if (Tok.is(tok::kw_throw)) 1710b57cec5SDimitry Andric return ParseThrowExpression(); 1720b57cec5SDimitry Andric if (Tok.is(tok::kw_co_yield)) 1730b57cec5SDimitry Andric return ParseCoyieldExpression(); 1740b57cec5SDimitry Andric 175480093f4SDimitry Andric ExprResult LHS = ParseCastExpression(AnyCastExpr, 1760b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 1770b57cec5SDimitry Andric isTypeCast); 1780b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(LHS, prec::Assignment); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric /// Parse an assignment expression where part of an Objective-C message 1820b57cec5SDimitry Andric /// send has already been parsed. 1830b57cec5SDimitry Andric /// 1840b57cec5SDimitry Andric /// In this case \p LBracLoc indicates the location of the '[' of the message 1850b57cec5SDimitry Andric /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating 1860b57cec5SDimitry Andric /// the receiver of the message. 1870b57cec5SDimitry Andric /// 1880b57cec5SDimitry Andric /// Since this handles full assignment-expression's, it handles postfix 1890b57cec5SDimitry Andric /// expressions and other binary operators for these expressions as well. 1900b57cec5SDimitry Andric ExprResult 1910b57cec5SDimitry Andric Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, 1920b57cec5SDimitry Andric SourceLocation SuperLoc, 1930b57cec5SDimitry Andric ParsedType ReceiverType, 1940b57cec5SDimitry Andric Expr *ReceiverExpr) { 1950b57cec5SDimitry Andric ExprResult R 1960b57cec5SDimitry Andric = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, 1970b57cec5SDimitry Andric ReceiverType, ReceiverExpr); 1980b57cec5SDimitry Andric R = ParsePostfixExpressionSuffix(R); 1990b57cec5SDimitry Andric return ParseRHSOfBinaryExpression(R, prec::Assignment); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric ExprResult 2030b57cec5SDimitry Andric Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) { 2040b57cec5SDimitry Andric assert(Actions.ExprEvalContexts.back().Context == 2050b57cec5SDimitry Andric Sema::ExpressionEvaluationContext::ConstantEvaluated && 2060b57cec5SDimitry Andric "Call this function only if your ExpressionEvaluationContext is " 2070b57cec5SDimitry Andric "already ConstantEvaluated"); 208480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, isTypeCast)); 2090b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2100b57cec5SDimitry Andric return Actions.ActOnConstantExpression(Res); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 213bdd1243dSDimitry Andric ExprResult Parser::ParseConstantExpression() { 2140b57cec5SDimitry Andric // C++03 [basic.def.odr]p2: 2150b57cec5SDimitry Andric // An expression is potentially evaluated unless it appears where an 2160b57cec5SDimitry Andric // integral constant expression is required (see 5.19) [...]. 2170b57cec5SDimitry Andric // C++98 and C++11 have no such rule, but this is only a defect in C++98. 2180b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2190b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 220bdd1243dSDimitry Andric return ParseConstantExpressionInExprEvalContext(NotTypeCast); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) { 2240b57cec5SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 2250b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); 226480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); 2270b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2280b57cec5SDimitry Andric return Actions.ActOnCaseExpr(CaseLoc, Res); 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric /// Parse a constraint-expression. 2320b57cec5SDimitry Andric /// 2330b57cec5SDimitry Andric /// \verbatim 234a7dea167SDimitry Andric /// constraint-expression: C++2a[temp.constr.decl]p1 2350b57cec5SDimitry Andric /// logical-or-expression 2360b57cec5SDimitry Andric /// \endverbatim 2370b57cec5SDimitry Andric ExprResult Parser::ParseConstraintExpression() { 238a7dea167SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 23955e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 240480093f4SDimitry Andric ExprResult LHS(ParseCastExpression(AnyCastExpr)); 2410b57cec5SDimitry Andric ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); 242480093f4SDimitry Andric if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) { 243480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(Res); 244a7dea167SDimitry Andric return ExprError(); 245480093f4SDimitry Andric } 2460b57cec5SDimitry Andric return Res; 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 249480093f4SDimitry Andric /// \brief Parse a constraint-logical-and-expression. 250480093f4SDimitry Andric /// 251480093f4SDimitry Andric /// \verbatim 252480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 253480093f4SDimitry Andric /// constraint-logical-and-expression: 254480093f4SDimitry Andric /// primary-expression 255480093f4SDimitry Andric /// constraint-logical-and-expression '&&' primary-expression 256480093f4SDimitry Andric /// 257480093f4SDimitry Andric /// \endverbatim 258480093f4SDimitry Andric ExprResult 259480093f4SDimitry Andric Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { 260480093f4SDimitry Andric EnterExpressionEvaluationContext ConstantEvaluated( 26155e4f9d5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 262480093f4SDimitry Andric bool NotPrimaryExpression = false; 263480093f4SDimitry Andric auto ParsePrimary = [&] () { 264480093f4SDimitry Andric ExprResult E = ParseCastExpression(PrimaryExprOnly, 265480093f4SDimitry Andric /*isAddressOfOperand=*/false, 266480093f4SDimitry Andric /*isTypeCast=*/NotTypeCast, 267480093f4SDimitry Andric /*isVectorLiteral=*/false, 268480093f4SDimitry Andric &NotPrimaryExpression); 269480093f4SDimitry Andric if (E.isInvalid()) 270480093f4SDimitry Andric return ExprError(); 271480093f4SDimitry Andric auto RecoverFromNonPrimary = [&] (ExprResult E, bool Note) { 272480093f4SDimitry Andric E = ParsePostfixExpressionSuffix(E); 273480093f4SDimitry Andric // Use InclusiveOr, the precedence just after '&&' to not parse the 274480093f4SDimitry Andric // next arguments to the logical and. 275480093f4SDimitry Andric E = ParseRHSOfBinaryExpression(E, prec::InclusiveOr); 276480093f4SDimitry Andric if (!E.isInvalid()) 277480093f4SDimitry Andric Diag(E.get()->getExprLoc(), 278480093f4SDimitry Andric Note 279480093f4SDimitry Andric ? diag::note_unparenthesized_non_primary_expr_in_requires_clause 280480093f4SDimitry Andric : diag::err_unparenthesized_non_primary_expr_in_requires_clause) 281480093f4SDimitry Andric << FixItHint::CreateInsertion(E.get()->getBeginLoc(), "(") 282480093f4SDimitry Andric << FixItHint::CreateInsertion( 283480093f4SDimitry Andric PP.getLocForEndOfToken(E.get()->getEndLoc()), ")") 284480093f4SDimitry Andric << E.get()->getSourceRange(); 285480093f4SDimitry Andric return E; 286480093f4SDimitry Andric }; 287480093f4SDimitry Andric 288480093f4SDimitry Andric if (NotPrimaryExpression || 289480093f4SDimitry Andric // Check if the following tokens must be a part of a non-primary 290480093f4SDimitry Andric // expression 291480093f4SDimitry Andric getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 292480093f4SDimitry Andric /*CPlusPlus11=*/true) > prec::LogicalAnd || 293480093f4SDimitry Andric // Postfix operators other than '(' (which will be checked for in 294480093f4SDimitry Andric // CheckConstraintExpression). 295480093f4SDimitry Andric Tok.isOneOf(tok::period, tok::plusplus, tok::minusminus) || 296480093f4SDimitry Andric (Tok.is(tok::l_square) && !NextToken().is(tok::l_square))) { 297480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/false); 298480093f4SDimitry Andric if (E.isInvalid()) 299480093f4SDimitry Andric return ExprError(); 300480093f4SDimitry Andric NotPrimaryExpression = false; 301480093f4SDimitry Andric } 302480093f4SDimitry Andric bool PossibleNonPrimary; 303480093f4SDimitry Andric bool IsConstraintExpr = 304480093f4SDimitry Andric Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary, 305480093f4SDimitry Andric IsTrailingRequiresClause); 306480093f4SDimitry Andric if (!IsConstraintExpr || PossibleNonPrimary) { 307480093f4SDimitry Andric // Atomic constraint might be an unparenthesized non-primary expression 308480093f4SDimitry Andric // (such as a binary operator), in which case we might get here (e.g. in 309480093f4SDimitry Andric // 'requires 0 + 1 && true' we would now be at '+', and parse and ignore 310480093f4SDimitry Andric // the rest of the addition expression). Try to parse the rest of it here. 311480093f4SDimitry Andric if (PossibleNonPrimary) 312480093f4SDimitry Andric E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr); 313480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 314480093f4SDimitry Andric return ExprError(); 315480093f4SDimitry Andric } 316480093f4SDimitry Andric return E; 317480093f4SDimitry Andric }; 318480093f4SDimitry Andric ExprResult LHS = ParsePrimary(); 319480093f4SDimitry Andric if (LHS.isInvalid()) 320480093f4SDimitry Andric return ExprError(); 321480093f4SDimitry Andric while (Tok.is(tok::ampamp)) { 322480093f4SDimitry Andric SourceLocation LogicalAndLoc = ConsumeToken(); 323480093f4SDimitry Andric ExprResult RHS = ParsePrimary(); 324480093f4SDimitry Andric if (RHS.isInvalid()) { 325480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 326480093f4SDimitry Andric return ExprError(); 327480093f4SDimitry Andric } 328480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc, 329480093f4SDimitry Andric tok::ampamp, LHS.get(), RHS.get()); 330480093f4SDimitry Andric if (!Op.isUsable()) { 331480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 332480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 333480093f4SDimitry Andric return ExprError(); 334480093f4SDimitry Andric } 335480093f4SDimitry Andric LHS = Op; 336480093f4SDimitry Andric } 337480093f4SDimitry Andric return LHS; 338480093f4SDimitry Andric } 339480093f4SDimitry Andric 340480093f4SDimitry Andric /// \brief Parse a constraint-logical-or-expression. 341480093f4SDimitry Andric /// 342480093f4SDimitry Andric /// \verbatim 343480093f4SDimitry Andric /// C++2a[temp.constr.decl]p1 344480093f4SDimitry Andric /// constraint-logical-or-expression: 345480093f4SDimitry Andric /// constraint-logical-and-expression 346480093f4SDimitry Andric /// constraint-logical-or-expression '||' 347480093f4SDimitry Andric /// constraint-logical-and-expression 348480093f4SDimitry Andric /// 349480093f4SDimitry Andric /// \endverbatim 350480093f4SDimitry Andric ExprResult 351480093f4SDimitry Andric Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) { 352480093f4SDimitry Andric ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause)); 353480093f4SDimitry Andric if (!LHS.isUsable()) 354480093f4SDimitry Andric return ExprError(); 355480093f4SDimitry Andric while (Tok.is(tok::pipepipe)) { 356480093f4SDimitry Andric SourceLocation LogicalOrLoc = ConsumeToken(); 357480093f4SDimitry Andric ExprResult RHS = 358480093f4SDimitry Andric ParseConstraintLogicalAndExpression(IsTrailingRequiresClause); 359480093f4SDimitry Andric if (!RHS.isUsable()) { 360480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 361480093f4SDimitry Andric return ExprError(); 362480093f4SDimitry Andric } 363480093f4SDimitry Andric ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc, 364480093f4SDimitry Andric tok::pipepipe, LHS.get(), RHS.get()); 365480093f4SDimitry Andric if (!Op.isUsable()) { 366480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 367480093f4SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 368480093f4SDimitry Andric return ExprError(); 369480093f4SDimitry Andric } 370480093f4SDimitry Andric LHS = Op; 371480093f4SDimitry Andric } 372480093f4SDimitry Andric return LHS; 373480093f4SDimitry Andric } 374480093f4SDimitry Andric 3750b57cec5SDimitry Andric bool Parser::isNotExpressionStart() { 3760b57cec5SDimitry Andric tok::TokenKind K = Tok.getKind(); 3770b57cec5SDimitry Andric if (K == tok::l_brace || K == tok::r_brace || 3780b57cec5SDimitry Andric K == tok::kw_for || K == tok::kw_while || 3790b57cec5SDimitry Andric K == tok::kw_if || K == tok::kw_else || 3800b57cec5SDimitry Andric K == tok::kw_goto || K == tok::kw_try) 3810b57cec5SDimitry Andric return true; 3820b57cec5SDimitry Andric // If this is a decl-specifier, we can't be at the start of an expression. 3830b57cec5SDimitry Andric return isKnownToBeDeclarationSpecifier(); 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric bool Parser::isFoldOperator(prec::Level Level) const { 3870b57cec5SDimitry Andric return Level > prec::Unknown && Level != prec::Conditional && 3880b57cec5SDimitry Andric Level != prec::Spaceship; 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric bool Parser::isFoldOperator(tok::TokenKind Kind) const { 3920b57cec5SDimitry Andric return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric /// Parse a binary expression that starts with \p LHS and has a 3960b57cec5SDimitry Andric /// precedence of at least \p MinPrec. 3970b57cec5SDimitry Andric ExprResult 3980b57cec5SDimitry Andric Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { 3990b57cec5SDimitry Andric prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(), 4000b57cec5SDimitry Andric GreaterThanIsOperator, 4010b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 4020b57cec5SDimitry Andric SourceLocation ColonLoc; 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric auto SavedType = PreferredType; 40504eeddc0SDimitry Andric while (true) { 4060b57cec5SDimitry Andric // Every iteration may rely on a preferred type for the whole expression. 4070b57cec5SDimitry Andric PreferredType = SavedType; 4080b57cec5SDimitry Andric // If this token has a lower precedence than we are allowed to parse (e.g. 4090b57cec5SDimitry Andric // because we are called recursively, or because the token is not a binop), 4100b57cec5SDimitry Andric // then we are done! 4110b57cec5SDimitry Andric if (NextTokPrec < MinPrec) 4120b57cec5SDimitry Andric return LHS; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric // Consume the operator, saving the operator token for error reporting. 4150b57cec5SDimitry Andric Token OpToken = Tok; 4160b57cec5SDimitry Andric ConsumeToken(); 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric if (OpToken.is(tok::caretcaret)) { 4190b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or)); 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric // If we're potentially in a template-id, we may now be able to determine 4230b57cec5SDimitry Andric // whether we're actually in one or not. 4240b57cec5SDimitry Andric if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater, 4250b57cec5SDimitry Andric tok::greatergreatergreater) && 4260b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(OpToken)) 4270b57cec5SDimitry Andric return ExprError(); 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric // Bail out when encountering a comma followed by a token which can't 4300b57cec5SDimitry Andric // possibly be the start of an expression. For instance: 4310b57cec5SDimitry Andric // int f() { return 1, } 4320b57cec5SDimitry Andric // We can't do this before consuming the comma, because 4330b57cec5SDimitry Andric // isNotExpressionStart() looks at the token stream. 4340b57cec5SDimitry Andric if (OpToken.is(tok::comma) && isNotExpressionStart()) { 4350b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4360b57cec5SDimitry Andric Tok = OpToken; 4370b57cec5SDimitry Andric return LHS; 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric // If the next token is an ellipsis, then this is a fold-expression. Leave 4410b57cec5SDimitry Andric // it alone so we can handle it in the paren expression. 4420b57cec5SDimitry Andric if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) { 4430b57cec5SDimitry Andric // FIXME: We can't check this via lookahead before we consume the token 4440b57cec5SDimitry Andric // because that tickles a lexer bug. 4450b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4460b57cec5SDimitry Andric Tok = OpToken; 4470b57cec5SDimitry Andric return LHS; 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric // In Objective-C++, alternative operator tokens can be used as keyword args 4510b57cec5SDimitry Andric // in message expressions. Unconsume the token so that it can reinterpreted 4520b57cec5SDimitry Andric // as an identifier in ParseObjCMessageExpressionBody. i.e., we support: 4530b57cec5SDimitry Andric // [foo meth:0 and:0]; 4540b57cec5SDimitry Andric // [foo not_eq]; 4550b57cec5SDimitry Andric if (getLangOpts().ObjC && getLangOpts().CPlusPlus && 4560b57cec5SDimitry Andric Tok.isOneOf(tok::colon, tok::r_square) && 4570b57cec5SDimitry Andric OpToken.getIdentifierInfo() != nullptr) { 4580b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject*/true); 4590b57cec5SDimitry Andric Tok = OpToken; 4600b57cec5SDimitry Andric return LHS; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric // Special case handling for the ternary operator. 4640b57cec5SDimitry Andric ExprResult TernaryMiddle(true); 4650b57cec5SDimitry Andric if (NextTokPrec == prec::Conditional) { 4660b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 4670b57cec5SDimitry Andric // Parse a braced-init-list here for error recovery purposes. 4680b57cec5SDimitry Andric SourceLocation BraceLoc = Tok.getLocation(); 4690b57cec5SDimitry Andric TernaryMiddle = ParseBraceInitializer(); 4700b57cec5SDimitry Andric if (!TernaryMiddle.isInvalid()) { 4710b57cec5SDimitry Andric Diag(BraceLoc, diag::err_init_list_bin_op) 4720b57cec5SDimitry Andric << /*RHS*/ 1 << PP.getSpelling(OpToken) 4730b57cec5SDimitry Andric << Actions.getExprRange(TernaryMiddle.get()); 4740b57cec5SDimitry Andric TernaryMiddle = ExprError(); 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric } else if (Tok.isNot(tok::colon)) { 4770b57cec5SDimitry Andric // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 4780b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric // Handle this production specially: 4810b57cec5SDimitry Andric // logical-OR-expression '?' expression ':' conditional-expression 4820b57cec5SDimitry Andric // In particular, the RHS of the '?' is 'expression', not 4830b57cec5SDimitry Andric // 'logical-OR-expression' as we might expect. 4840b57cec5SDimitry Andric TernaryMiddle = ParseExpression(); 4850b57cec5SDimitry Andric } else { 4860b57cec5SDimitry Andric // Special case handling of "X ? Y : Z" where Y is empty: 4870b57cec5SDimitry Andric // logical-OR-expression '?' ':' conditional-expression [GNU] 4880b57cec5SDimitry Andric TernaryMiddle = nullptr; 4890b57cec5SDimitry Andric Diag(Tok, diag::ext_gnu_conditional_expr); 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 4930b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 4940b57cec5SDimitry Andric LHS = ExprError(); 4950b57cec5SDimitry Andric TernaryMiddle = nullptr; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric if (!TryConsumeToken(tok::colon, ColonLoc)) { 4990b57cec5SDimitry Andric // Otherwise, we're missing a ':'. Assume that this was a typo that 5000b57cec5SDimitry Andric // the user forgot. If we're not in a macro expansion, we can suggest 5010b57cec5SDimitry Andric // a fixit hint. If there were two spaces before the current token, 5020b57cec5SDimitry Andric // suggest inserting the colon in between them, otherwise insert ": ". 5030b57cec5SDimitry Andric SourceLocation FILoc = Tok.getLocation(); 5040b57cec5SDimitry Andric const char *FIText = ": "; 5050b57cec5SDimitry Andric const SourceManager &SM = PP.getSourceManager(); 5060b57cec5SDimitry Andric if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) { 5070b57cec5SDimitry Andric assert(FILoc.isFileID()); 5080b57cec5SDimitry Andric bool IsInvalid = false; 5090b57cec5SDimitry Andric const char *SourcePtr = 5100b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid); 5110b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5120b57cec5SDimitry Andric SourcePtr = 5130b57cec5SDimitry Andric SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid); 5140b57cec5SDimitry Andric if (!IsInvalid && *SourcePtr == ' ') { 5150b57cec5SDimitry Andric FILoc = FILoc.getLocWithOffset(-1); 5160b57cec5SDimitry Andric FIText = ":"; 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric Diag(Tok, diag::err_expected) 5220b57cec5SDimitry Andric << tok::colon << FixItHint::CreateInsertion(FILoc, FIText); 5230b57cec5SDimitry Andric Diag(OpToken, diag::note_matching) << tok::question; 5240b57cec5SDimitry Andric ColonLoc = Tok.getLocation(); 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(), 5290b57cec5SDimitry Andric OpToken.getKind()); 5300b57cec5SDimitry Andric // Parse another leaf here for the RHS of the operator. 5310b57cec5SDimitry Andric // ParseCastExpression works here because all RHS expressions in C have it 5320b57cec5SDimitry Andric // as a prefix, at least. However, in C++, an assignment-expression could 5330b57cec5SDimitry Andric // be a throw-expression, which is not a valid cast-expression. 5340b57cec5SDimitry Andric // Therefore we need some special-casing here. 5350b57cec5SDimitry Andric // Also note that the third operand of the conditional operator is 5360b57cec5SDimitry Andric // an assignment-expression in C++, and in C++11, we can have a 5370b57cec5SDimitry Andric // braced-init-list on the RHS of an assignment. For better diagnostics, 5380b57cec5SDimitry Andric // parse as if we were allowed braced-init-lists everywhere, and check that 5390b57cec5SDimitry Andric // they only appear on the RHS of assignments later. 5400b57cec5SDimitry Andric ExprResult RHS; 5410b57cec5SDimitry Andric bool RHSIsInitList = false; 5420b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 5430b57cec5SDimitry Andric RHS = ParseBraceInitializer(); 5440b57cec5SDimitry Andric RHSIsInitList = true; 5450b57cec5SDimitry Andric } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional) 5460b57cec5SDimitry Andric RHS = ParseAssignmentExpression(); 5470b57cec5SDimitry Andric else 548480093f4SDimitry Andric RHS = ParseCastExpression(AnyCastExpr); 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric if (RHS.isInvalid()) { 5510b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5520b57cec5SDimitry Andric // printed before errors from parsing the RHS, not after. 5530b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5540b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 5550b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 5560b57cec5SDimitry Andric LHS = ExprError(); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric // Remember the precedence of this operator and get the precedence of the 5600b57cec5SDimitry Andric // operator immediately to the right of the RHS. 5610b57cec5SDimitry Andric prec::Level ThisPrec = NextTokPrec; 5620b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 5630b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric // Assignment and conditional expressions are right-associative. 5660b57cec5SDimitry Andric bool isRightAssoc = ThisPrec == prec::Conditional || 5670b57cec5SDimitry Andric ThisPrec == prec::Assignment; 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric // Get the precedence of the operator to the right of the RHS. If it binds 5700b57cec5SDimitry Andric // more tightly with RHS than we do, evaluate it completely first. 5710b57cec5SDimitry Andric if (ThisPrec < NextTokPrec || 5720b57cec5SDimitry Andric (ThisPrec == NextTokPrec && isRightAssoc)) { 5730b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 5740b57cec5SDimitry Andric Diag(Tok, diag::err_init_list_bin_op) 5750b57cec5SDimitry Andric << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get()); 5760b57cec5SDimitry Andric RHS = ExprError(); 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric // If this is left-associative, only parse things on the RHS that bind 5790b57cec5SDimitry Andric // more tightly than the current operator. If it is left-associative, it 5800b57cec5SDimitry Andric // is okay, to bind exactly as tightly. For example, compile A=B=C=D as 5810b57cec5SDimitry Andric // A=(B=(C=D)), where each paren is a level of recursion here. 5820b57cec5SDimitry Andric // The function takes ownership of the RHS. 5830b57cec5SDimitry Andric RHS = ParseRHSOfBinaryExpression(RHS, 5840b57cec5SDimitry Andric static_cast<prec::Level>(ThisPrec + !isRightAssoc)); 5850b57cec5SDimitry Andric RHSIsInitList = false; 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric if (RHS.isInvalid()) { 5880b57cec5SDimitry Andric // FIXME: Errors generated by the delayed typo correction should be 5890b57cec5SDimitry Andric // printed before errors from ParseRHSOfBinaryExpression, not after. 5900b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(LHS); 5910b57cec5SDimitry Andric if (TernaryMiddle.isUsable()) 5920b57cec5SDimitry Andric TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 5930b57cec5SDimitry Andric LHS = ExprError(); 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 5970b57cec5SDimitry Andric getLangOpts().CPlusPlus11); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric if (!RHS.isInvalid() && RHSIsInitList) { 6010b57cec5SDimitry Andric if (ThisPrec == prec::Assignment) { 6020b57cec5SDimitry Andric Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists) 6030b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6040b57cec5SDimitry Andric } else if (ColonLoc.isValid()) { 6050b57cec5SDimitry Andric Diag(ColonLoc, diag::err_init_list_bin_op) 6060b57cec5SDimitry Andric << /*RHS*/1 << ":" 6070b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6080b57cec5SDimitry Andric LHS = ExprError(); 6090b57cec5SDimitry Andric } else { 6100b57cec5SDimitry Andric Diag(OpToken, diag::err_init_list_bin_op) 6110b57cec5SDimitry Andric << /*RHS*/1 << PP.getSpelling(OpToken) 6120b57cec5SDimitry Andric << Actions.getExprRange(RHS.get()); 6130b57cec5SDimitry Andric LHS = ExprError(); 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric ExprResult OrigLHS = LHS; 6180b57cec5SDimitry Andric if (!LHS.isInvalid()) { 6190b57cec5SDimitry Andric // Combine the LHS and RHS into the LHS (e.g. build AST). 6200b57cec5SDimitry Andric if (TernaryMiddle.isInvalid()) { 6210b57cec5SDimitry Andric // If we're using '>>' as an operator within a template 6220b57cec5SDimitry Andric // argument list (in C++98), suggest the addition of 6230b57cec5SDimitry Andric // parentheses so that the code remains well-formed in C++0x. 6240b57cec5SDimitry Andric if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) 6250b57cec5SDimitry Andric SuggestParentheses(OpToken.getLocation(), 6260b57cec5SDimitry Andric diag::warn_cxx11_right_shift_in_template_arg, 6270b57cec5SDimitry Andric SourceRange(Actions.getExprRange(LHS.get()).getBegin(), 6280b57cec5SDimitry Andric Actions.getExprRange(RHS.get()).getEnd())); 6290b57cec5SDimitry Andric 6305ffd83dbSDimitry Andric ExprResult BinOp = 6315ffd83dbSDimitry Andric Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), 6320b57cec5SDimitry Andric OpToken.getKind(), LHS.get(), RHS.get()); 6335ffd83dbSDimitry Andric if (BinOp.isInvalid()) 6345ffd83dbSDimitry Andric BinOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6355ffd83dbSDimitry Andric RHS.get()->getEndLoc(), 6365ffd83dbSDimitry Andric {LHS.get(), RHS.get()}); 6370b57cec5SDimitry Andric 6385ffd83dbSDimitry Andric LHS = BinOp; 6390b57cec5SDimitry Andric } else { 6405ffd83dbSDimitry Andric ExprResult CondOp = Actions.ActOnConditionalOp( 6415ffd83dbSDimitry Andric OpToken.getLocation(), ColonLoc, LHS.get(), TernaryMiddle.get(), 6420b57cec5SDimitry Andric RHS.get()); 6435ffd83dbSDimitry Andric if (CondOp.isInvalid()) { 6445ffd83dbSDimitry Andric std::vector<clang::Expr *> Args; 6455ffd83dbSDimitry Andric // TernaryMiddle can be null for the GNU conditional expr extension. 6465ffd83dbSDimitry Andric if (TernaryMiddle.get()) 6475ffd83dbSDimitry Andric Args = {LHS.get(), TernaryMiddle.get(), RHS.get()}; 6485ffd83dbSDimitry Andric else 6495ffd83dbSDimitry Andric Args = {LHS.get(), RHS.get()}; 6505ffd83dbSDimitry Andric CondOp = Actions.CreateRecoveryExpr(LHS.get()->getBeginLoc(), 6515ffd83dbSDimitry Andric RHS.get()->getEndLoc(), Args); 6525ffd83dbSDimitry Andric } 6535ffd83dbSDimitry Andric 6545ffd83dbSDimitry Andric LHS = CondOp; 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric // In this case, ActOnBinOp or ActOnConditionalOp performed the 6570b57cec5SDimitry Andric // CorrectDelayedTyposInExpr check. 6580b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 6590b57cec5SDimitry Andric continue; 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric // Ensure potential typos aren't left undiagnosed. 6630b57cec5SDimitry Andric if (LHS.isInvalid()) { 6640b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(OrigLHS); 6650b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(TernaryMiddle); 6660b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(RHS); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric } 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 671480093f4SDimitry Andric /// Parse a cast-expression, unary-expression or primary-expression, based 672480093f4SDimitry Andric /// on \p ExprType. 6730b57cec5SDimitry Andric /// 6740b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the 6750b57cec5SDimitry Andric /// operand of address-of gets special treatment due to member pointers. 6760b57cec5SDimitry Andric /// 677480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 6780b57cec5SDimitry Andric bool isAddressOfOperand, 6790b57cec5SDimitry Andric TypeCastState isTypeCast, 680480093f4SDimitry Andric bool isVectorLiteral, 681480093f4SDimitry Andric bool *NotPrimaryExpression) { 6820b57cec5SDimitry Andric bool NotCastExpr; 683480093f4SDimitry Andric ExprResult Res = ParseCastExpression(ParseKind, 6840b57cec5SDimitry Andric isAddressOfOperand, 6850b57cec5SDimitry Andric NotCastExpr, 6860b57cec5SDimitry Andric isTypeCast, 687480093f4SDimitry Andric isVectorLiteral, 688480093f4SDimitry Andric NotPrimaryExpression); 6890b57cec5SDimitry Andric if (NotCastExpr) 6900b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 6910b57cec5SDimitry Andric return Res; 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric namespace { 6950b57cec5SDimitry Andric class CastExpressionIdValidator final : public CorrectionCandidateCallback { 6960b57cec5SDimitry Andric public: 6970b57cec5SDimitry Andric CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes) 6980b57cec5SDimitry Andric : NextToken(Next), AllowNonTypes(AllowNonTypes) { 6990b57cec5SDimitry Andric WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes; 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric bool ValidateCandidate(const TypoCorrection &candidate) override { 7030b57cec5SDimitry Andric NamedDecl *ND = candidate.getCorrectionDecl(); 7040b57cec5SDimitry Andric if (!ND) 7050b57cec5SDimitry Andric return candidate.isKeyword(); 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric if (isa<TypeDecl>(ND)) 7080b57cec5SDimitry Andric return WantTypeSpecifiers; 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate)) 7110b57cec5SDimitry Andric return false; 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period)) 7140b57cec5SDimitry Andric return true; 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric for (auto *C : candidate) { 7170b57cec5SDimitry Andric NamedDecl *ND = C->getUnderlyingDecl(); 7180b57cec5SDimitry Andric if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND)) 7190b57cec5SDimitry Andric return true; 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric return false; 7220b57cec5SDimitry Andric } 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric std::unique_ptr<CorrectionCandidateCallback> clone() override { 725a7dea167SDimitry Andric return std::make_unique<CastExpressionIdValidator>(*this); 7260b57cec5SDimitry Andric } 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric private: 7290b57cec5SDimitry Andric Token NextToken; 7300b57cec5SDimitry Andric bool AllowNonTypes; 7310b57cec5SDimitry Andric }; 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse 7350b57cec5SDimitry Andric /// a unary-expression. 7360b57cec5SDimitry Andric /// 7370b57cec5SDimitry Andric /// \p isAddressOfOperand exists because an id-expression that is the operand 7380b57cec5SDimitry Andric /// of address-of gets special treatment due to member pointers. NotCastExpr 7390b57cec5SDimitry Andric /// is set to true if the token is not the start of a cast-expression, and no 7400b57cec5SDimitry Andric /// diagnostic is emitted in this case and no tokens are consumed. 7410b57cec5SDimitry Andric /// 7420b57cec5SDimitry Andric /// \verbatim 7430b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 7440b57cec5SDimitry Andric /// unary-expression 7450b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 7460b57cec5SDimitry Andric /// 7470b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 7480b57cec5SDimitry Andric /// postfix-expression 7490b57cec5SDimitry Andric /// '++' unary-expression 7500b57cec5SDimitry Andric /// '--' unary-expression 7510b57cec5SDimitry Andric /// [Coro] 'co_await' cast-expression 7520b57cec5SDimitry Andric /// unary-operator cast-expression 7530b57cec5SDimitry Andric /// 'sizeof' unary-expression 7540b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 7550b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 7560b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 7570b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 7580b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 7590b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 7600b57cec5SDimitry Andric /// [GNU] '&&' identifier 7610b57cec5SDimitry Andric /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7] 7620b57cec5SDimitry Andric /// [C++] new-expression 7630b57cec5SDimitry Andric /// [C++] delete-expression 7640b57cec5SDimitry Andric /// 7650b57cec5SDimitry Andric /// unary-operator: one of 7660b57cec5SDimitry Andric /// '&' '*' '+' '-' '~' '!' 7670b57cec5SDimitry Andric /// [GNU] '__extension__' '__real' '__imag' 7680b57cec5SDimitry Andric /// 7690b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 7700b57cec5SDimitry Andric /// [C99] identifier 7710b57cec5SDimitry Andric /// [C++] id-expression 7720b57cec5SDimitry Andric /// constant 7730b57cec5SDimitry Andric /// string-literal 7740b57cec5SDimitry Andric /// [C++] boolean-literal [C++ 2.13.5] 7750b57cec5SDimitry Andric /// [C++11] 'nullptr' [C++11 2.14.7] 7760b57cec5SDimitry Andric /// [C++11] user-defined-literal 7770b57cec5SDimitry Andric /// '(' expression ')' 7780b57cec5SDimitry Andric /// [C11] generic-selection 77955e4f9d5SDimitry Andric /// [C++2a] requires-expression 7800b57cec5SDimitry Andric /// '__func__' [C99 6.4.2.2] 7810b57cec5SDimitry Andric /// [GNU] '__FUNCTION__' 7820b57cec5SDimitry Andric /// [MS] '__FUNCDNAME__' 7830b57cec5SDimitry Andric /// [MS] 'L__FUNCTION__' 7840b57cec5SDimitry Andric /// [MS] '__FUNCSIG__' 7850b57cec5SDimitry Andric /// [MS] 'L__FUNCSIG__' 7860b57cec5SDimitry Andric /// [GNU] '__PRETTY_FUNCTION__' 7870b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' 7880b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 7890b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 7900b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 7910b57cec5SDimitry Andric /// assign-expr ')' 7920b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 793*06c3fb27SDimitry Andric /// [CLANG] '__builtin_FILE_NAME' '(' ')' 7940b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 795*06c3fb27SDimitry Andric /// [MS] '__builtin_FUNCSIG' '(' ')' 7960b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 7970b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 79881ad6265SDimitry Andric /// [GNU] '__builtin_source_location' '(' ')' 7990b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 8000b57cec5SDimitry Andric /// [GNU] '__null' 8010b57cec5SDimitry Andric /// [OBJC] '[' objc-message-expr ']' 8020b57cec5SDimitry Andric /// [OBJC] '\@selector' '(' objc-selector-arg ')' 8030b57cec5SDimitry Andric /// [OBJC] '\@protocol' '(' identifier ')' 8040b57cec5SDimitry Andric /// [OBJC] '\@encode' '(' type-name ')' 8050b57cec5SDimitry Andric /// [OBJC] objc-string-literal 8060b57cec5SDimitry Andric /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 8070b57cec5SDimitry Andric /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] 8080b57cec5SDimitry Andric /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 8090b57cec5SDimitry Andric /// [C++11] typename-specifier braced-init-list [C++11 5.2.3] 8100b57cec5SDimitry Andric /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8110b57cec5SDimitry Andric /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8120b57cec5SDimitry Andric /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8130b57cec5SDimitry Andric /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 8140b57cec5SDimitry Andric /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 8150b57cec5SDimitry Andric /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 8160b57cec5SDimitry Andric /// [C++] 'this' [C++ 9.3.2] 8170b57cec5SDimitry Andric /// [G++] unary-type-trait '(' type-id ')' 8180b57cec5SDimitry Andric /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 8190b57cec5SDimitry Andric /// [EMBT] array-type-trait '(' type-id ',' integer ')' 8200b57cec5SDimitry Andric /// [clang] '^' block-literal 8210b57cec5SDimitry Andric /// 8220b57cec5SDimitry Andric /// constant: [C99 6.4.4] 8230b57cec5SDimitry Andric /// integer-constant 8240b57cec5SDimitry Andric /// floating-constant 8250b57cec5SDimitry Andric /// enumeration-constant -> identifier 8260b57cec5SDimitry Andric /// character-constant 8270b57cec5SDimitry Andric /// 8280b57cec5SDimitry Andric /// id-expression: [C++ 5.1] 8290b57cec5SDimitry Andric /// unqualified-id 8300b57cec5SDimitry Andric /// qualified-id 8310b57cec5SDimitry Andric /// 8320b57cec5SDimitry Andric /// unqualified-id: [C++ 5.1] 8330b57cec5SDimitry Andric /// identifier 8340b57cec5SDimitry Andric /// operator-function-id 8350b57cec5SDimitry Andric /// conversion-function-id 8360b57cec5SDimitry Andric /// '~' class-name 8370b57cec5SDimitry Andric /// template-id 8380b57cec5SDimitry Andric /// 8390b57cec5SDimitry Andric /// new-expression: [C++ 5.3.4] 8400b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] new-type-id 8410b57cec5SDimitry Andric /// new-initializer[opt] 8420b57cec5SDimitry Andric /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8430b57cec5SDimitry Andric /// new-initializer[opt] 8440b57cec5SDimitry Andric /// 8450b57cec5SDimitry Andric /// delete-expression: [C++ 5.3.5] 8460b57cec5SDimitry Andric /// '::'[opt] 'delete' cast-expression 8470b57cec5SDimitry Andric /// '::'[opt] 'delete' '[' ']' cast-expression 8480b57cec5SDimitry Andric /// 8490b57cec5SDimitry Andric /// [GNU/Embarcadero] unary-type-trait: 8500b57cec5SDimitry Andric /// '__is_arithmetic' 8510b57cec5SDimitry Andric /// '__is_floating_point' 8520b57cec5SDimitry Andric /// '__is_integral' 8530b57cec5SDimitry Andric /// '__is_lvalue_expr' 8540b57cec5SDimitry Andric /// '__is_rvalue_expr' 8550b57cec5SDimitry Andric /// '__is_complete_type' 8560b57cec5SDimitry Andric /// '__is_void' 8570b57cec5SDimitry Andric /// '__is_array' 8580b57cec5SDimitry Andric /// '__is_function' 8590b57cec5SDimitry Andric /// '__is_reference' 8600b57cec5SDimitry Andric /// '__is_lvalue_reference' 8610b57cec5SDimitry Andric /// '__is_rvalue_reference' 8620b57cec5SDimitry Andric /// '__is_fundamental' 8630b57cec5SDimitry Andric /// '__is_object' 8640b57cec5SDimitry Andric /// '__is_scalar' 8650b57cec5SDimitry Andric /// '__is_compound' 8660b57cec5SDimitry Andric /// '__is_pointer' 8670b57cec5SDimitry Andric /// '__is_member_object_pointer' 8680b57cec5SDimitry Andric /// '__is_member_function_pointer' 8690b57cec5SDimitry Andric /// '__is_member_pointer' 8700b57cec5SDimitry Andric /// '__is_const' 8710b57cec5SDimitry Andric /// '__is_volatile' 8720b57cec5SDimitry Andric /// '__is_trivial' 8730b57cec5SDimitry Andric /// '__is_standard_layout' 8740b57cec5SDimitry Andric /// '__is_signed' 8750b57cec5SDimitry Andric /// '__is_unsigned' 8760b57cec5SDimitry Andric /// 8770b57cec5SDimitry Andric /// [GNU] unary-type-trait: 8780b57cec5SDimitry Andric /// '__has_nothrow_assign' 8790b57cec5SDimitry Andric /// '__has_nothrow_copy' 8800b57cec5SDimitry Andric /// '__has_nothrow_constructor' 8810b57cec5SDimitry Andric /// '__has_trivial_assign' [TODO] 8820b57cec5SDimitry Andric /// '__has_trivial_copy' [TODO] 8830b57cec5SDimitry Andric /// '__has_trivial_constructor' 8840b57cec5SDimitry Andric /// '__has_trivial_destructor' 8850b57cec5SDimitry Andric /// '__has_virtual_destructor' 8860b57cec5SDimitry Andric /// '__is_abstract' [TODO] 8870b57cec5SDimitry Andric /// '__is_class' 8880b57cec5SDimitry Andric /// '__is_empty' [TODO] 8890b57cec5SDimitry Andric /// '__is_enum' 8900b57cec5SDimitry Andric /// '__is_final' 8910b57cec5SDimitry Andric /// '__is_pod' 8920b57cec5SDimitry Andric /// '__is_polymorphic' 8930b57cec5SDimitry Andric /// '__is_sealed' [MS] 8940b57cec5SDimitry Andric /// '__is_trivial' 8950b57cec5SDimitry Andric /// '__is_union' 8960b57cec5SDimitry Andric /// '__has_unique_object_representations' 8970b57cec5SDimitry Andric /// 8980b57cec5SDimitry Andric /// [Clang] unary-type-trait: 8990b57cec5SDimitry Andric /// '__is_aggregate' 9000b57cec5SDimitry Andric /// '__trivially_copyable' 9010b57cec5SDimitry Andric /// 9020b57cec5SDimitry Andric /// binary-type-trait: 9030b57cec5SDimitry Andric /// [GNU] '__is_base_of' 9040b57cec5SDimitry Andric /// [MS] '__is_convertible_to' 9050b57cec5SDimitry Andric /// '__is_convertible' 9060b57cec5SDimitry Andric /// '__is_same' 9070b57cec5SDimitry Andric /// 9080b57cec5SDimitry Andric /// [Embarcadero] array-type-trait: 9090b57cec5SDimitry Andric /// '__array_rank' 9100b57cec5SDimitry Andric /// '__array_extent' 9110b57cec5SDimitry Andric /// 9120b57cec5SDimitry Andric /// [Embarcadero] expression-trait: 9130b57cec5SDimitry Andric /// '__is_lvalue_expr' 9140b57cec5SDimitry Andric /// '__is_rvalue_expr' 9150b57cec5SDimitry Andric /// \endverbatim 9160b57cec5SDimitry Andric /// 917480093f4SDimitry Andric ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, 9180b57cec5SDimitry Andric bool isAddressOfOperand, 9190b57cec5SDimitry Andric bool &NotCastExpr, 9200b57cec5SDimitry Andric TypeCastState isTypeCast, 921480093f4SDimitry Andric bool isVectorLiteral, 922480093f4SDimitry Andric bool *NotPrimaryExpression) { 9230b57cec5SDimitry Andric ExprResult Res; 9240b57cec5SDimitry Andric tok::TokenKind SavedKind = Tok.getKind(); 9250b57cec5SDimitry Andric auto SavedType = PreferredType; 9260b57cec5SDimitry Andric NotCastExpr = false; 9270b57cec5SDimitry Andric 9285ffd83dbSDimitry Andric // Are postfix-expression suffix operators permitted after this 9295ffd83dbSDimitry Andric // cast-expression? If not, and we find some, we'll parse them anyway and 9305ffd83dbSDimitry Andric // diagnose them. 9315ffd83dbSDimitry Andric bool AllowSuffix = true; 9325ffd83dbSDimitry Andric 9330b57cec5SDimitry Andric // This handles all of cast-expression, unary-expression, postfix-expression, 9340b57cec5SDimitry Andric // and primary-expression. We handle them together like this for efficiency 9350b57cec5SDimitry Andric // and to simplify handling of an expression starting with a '(' token: which 9360b57cec5SDimitry Andric // may be one of a parenthesized expression, cast-expression, compound literal 9370b57cec5SDimitry Andric // expression, or statement expression. 9380b57cec5SDimitry Andric // 9390b57cec5SDimitry Andric // If the parsed tokens consist of a primary-expression, the cases below 9400b57cec5SDimitry Andric // break out of the switch; at the end we call ParsePostfixExpressionSuffix 9410b57cec5SDimitry Andric // to handle the postfix expression suffixes. Cases that cannot be followed 9425ffd83dbSDimitry Andric // by postfix exprs should set AllowSuffix to false. 9430b57cec5SDimitry Andric switch (SavedKind) { 9440b57cec5SDimitry Andric case tok::l_paren: { 945480093f4SDimitry Andric // If this expression is limited to being a unary-expression, the paren can 9460b57cec5SDimitry Andric // not start a cast expression. 947480093f4SDimitry Andric ParenParseOption ParenExprType; 948480093f4SDimitry Andric switch (ParseKind) { 949480093f4SDimitry Andric case CastParseKind::UnaryExprOnly: 950bdd1243dSDimitry Andric assert(getLangOpts().CPlusPlus && "not possible to get here in C"); 951bdd1243dSDimitry Andric [[fallthrough]]; 952480093f4SDimitry Andric case CastParseKind::AnyCastExpr: 953480093f4SDimitry Andric ParenExprType = ParenParseOption::CastExpr; 954480093f4SDimitry Andric break; 955480093f4SDimitry Andric case CastParseKind::PrimaryExprOnly: 956480093f4SDimitry Andric ParenExprType = FoldExpr; 957480093f4SDimitry Andric break; 958480093f4SDimitry Andric } 9590b57cec5SDimitry Andric ParsedType CastTy; 9600b57cec5SDimitry Andric SourceLocation RParenLoc; 9610b57cec5SDimitry Andric Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 9620b57cec5SDimitry Andric isTypeCast == IsTypeCast, CastTy, RParenLoc); 9630b57cec5SDimitry Andric 9645ffd83dbSDimitry Andric // FIXME: What should we do if a vector literal is followed by a 9655ffd83dbSDimitry Andric // postfix-expression suffix? Usually postfix operators are permitted on 9665ffd83dbSDimitry Andric // literals. 9670b57cec5SDimitry Andric if (isVectorLiteral) 9680b57cec5SDimitry Andric return Res; 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric switch (ParenExprType) { 9710b57cec5SDimitry Andric case SimpleExpr: break; // Nothing else to do. 9720b57cec5SDimitry Andric case CompoundStmt: break; // Nothing else to do. 9730b57cec5SDimitry Andric case CompoundLiteral: 9740b57cec5SDimitry Andric // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 9750b57cec5SDimitry Andric // postfix-expression exist, parse them now. 9760b57cec5SDimitry Andric break; 9770b57cec5SDimitry Andric case CastExpr: 9780b57cec5SDimitry Andric // We have parsed the cast-expression and no postfix-expr pieces are 9790b57cec5SDimitry Andric // following. 9800b57cec5SDimitry Andric return Res; 9810b57cec5SDimitry Andric case FoldExpr: 9820b57cec5SDimitry Andric // We only parsed a fold-expression. There might be postfix-expr pieces 9830b57cec5SDimitry Andric // afterwards; parse them now. 9840b57cec5SDimitry Andric break; 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric break; 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric // primary-expression 9910b57cec5SDimitry Andric case tok::numeric_constant: 9920b57cec5SDimitry Andric // constant: integer-constant 9930b57cec5SDimitry Andric // constant: floating-constant 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope()); 9960b57cec5SDimitry Andric ConsumeToken(); 9970b57cec5SDimitry Andric break; 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric case tok::kw_true: 10000b57cec5SDimitry Andric case tok::kw_false: 10010b57cec5SDimitry Andric Res = ParseCXXBoolLiteral(); 10020b57cec5SDimitry Andric break; 10030b57cec5SDimitry Andric 10040b57cec5SDimitry Andric case tok::kw___objc_yes: 10050b57cec5SDimitry Andric case tok::kw___objc_no: 10065ffd83dbSDimitry Andric Res = ParseObjCBoolLiteral(); 10075ffd83dbSDimitry Andric break; 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric case tok::kw_nullptr: 1010bdd1243dSDimitry Andric if (getLangOpts().CPlusPlus) 10110b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_nullptr); 1012bdd1243dSDimitry Andric else 1013*06c3fb27SDimitry Andric Diag(Tok, getLangOpts().C2x ? diag::warn_c2x_compat_keyword 1014*06c3fb27SDimitry Andric : diag::ext_c_nullptr) << Tok.getName(); 1015bdd1243dSDimitry Andric 10165ffd83dbSDimitry Andric Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 10175ffd83dbSDimitry Andric break; 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric case tok::annot_primary_expr: 1020e8d8bef9SDimitry Andric case tok::annot_overload_set: 10210b57cec5SDimitry Andric Res = getExprAnnotation(Tok); 1022e8d8bef9SDimitry Andric if (!Res.isInvalid() && Tok.getKind() == tok::annot_overload_set) 1023e8d8bef9SDimitry Andric Res = Actions.ActOnNameClassifiedAsOverloadSet(getCurScope(), Res.get()); 10240b57cec5SDimitry Andric ConsumeAnnotationToken(); 10250b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 10260b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 10270b57cec5SDimitry Andric break; 10280b57cec5SDimitry Andric 1029a7dea167SDimitry Andric case tok::annot_non_type: 1030a7dea167SDimitry Andric case tok::annot_non_type_dependent: 1031a7dea167SDimitry Andric case tok::annot_non_type_undeclared: { 1032a7dea167SDimitry Andric CXXScopeSpec SS; 1033a7dea167SDimitry Andric Token Replacement; 1034a7dea167SDimitry Andric Res = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement); 1035a7dea167SDimitry Andric assert(!Res.isUnset() && 1036a7dea167SDimitry Andric "should not perform typo correction on annotation token"); 1037a7dea167SDimitry Andric break; 1038a7dea167SDimitry Andric } 1039a7dea167SDimitry Andric 10400b57cec5SDimitry Andric case tok::kw___super: 10410b57cec5SDimitry Andric case tok::kw_decltype: 10420b57cec5SDimitry Andric // Annotate the token and tail recurse. 10430b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 10440b57cec5SDimitry Andric return ExprError(); 10450b57cec5SDimitry Andric assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); 1046480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1047480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 10480b57cec5SDimitry Andric 1049bdd1243dSDimitry Andric case tok::identifier: 1050bdd1243dSDimitry Andric ParseIdentifier: { // primary-expression: identifier 10510b57cec5SDimitry Andric // unqualified-id: identifier 10520b57cec5SDimitry Andric // constant: enumeration-constant 10530b57cec5SDimitry Andric // Turn a potentially qualified name into a annot_typename or 10540b57cec5SDimitry Andric // annot_cxxscope if it would be valid. This handles things like x::y, etc. 10550b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) { 10560b57cec5SDimitry Andric // Avoid the unnecessary parse-time lookup in the common case 10570b57cec5SDimitry Andric // where the syntax forbids a type. 10580b57cec5SDimitry Andric const Token &Next = NextToken(); 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // If this identifier was reverted from a token ID, and the next token 10610b57cec5SDimitry Andric // is a parenthesis, this is likely to be a use of a type trait. Check 10620b57cec5SDimitry Andric // those tokens. 10630b57cec5SDimitry Andric if (Next.is(tok::l_paren) && 10640b57cec5SDimitry Andric Tok.is(tok::identifier) && 10650b57cec5SDimitry Andric Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { 10660b57cec5SDimitry Andric IdentifierInfo *II = Tok.getIdentifierInfo(); 10670b57cec5SDimitry Andric // Build up the mapping of revertible type traits, for future use. 10680b57cec5SDimitry Andric if (RevertibleTypeTraits.empty()) { 10690b57cec5SDimitry Andric #define RTT_JOIN(X,Y) X##Y 10700b57cec5SDimitry Andric #define REVERTIBLE_TYPE_TRAIT(Name) \ 10710b57cec5SDimitry Andric RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ 10720b57cec5SDimitry Andric = RTT_JOIN(tok::kw_,Name) 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_abstract); 10750b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_aggregate); 10760b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_arithmetic); 10770b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_array); 10780b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_assignable); 10790b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_base_of); 1080bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_bounded_array); 10810b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_class); 10820b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_complete_type); 10830b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_compound); 10840b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_const); 10850b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_constructible); 10860b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible); 10870b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_convertible_to); 10880b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_destructible); 10890b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_empty); 10900b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_enum); 10910b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_floating_point); 10920b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_final); 10930b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_function); 10940b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_fundamental); 10950b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_integral); 10960b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_interface_class); 10970b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_literal); 10980b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); 10990b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); 11000b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); 11010b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); 11020b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_member_pointer); 11030b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); 11040b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); 11050b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); 1106bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_nullptr); 11070b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_object); 11080b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pod); 11090b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_pointer); 11100b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_polymorphic); 11110b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_reference); 1112bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_referenceable); 11130b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); 11140b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); 11150b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_same); 11160b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scalar); 1117bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); 11180b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_sealed); 11190b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_signed); 11200b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_standard_layout); 11210b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivial); 11220b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); 11230b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); 11240b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); 1125bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); 11260b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_union); 11270b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_unsigned); 11280b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_void); 11290b57cec5SDimitry Andric REVERTIBLE_TYPE_TRAIT(__is_volatile); 1130bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ 1131bdd1243dSDimitry Andric REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait)); 1132bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 11330b57cec5SDimitry Andric #undef REVERTIBLE_TYPE_TRAIT 11340b57cec5SDimitry Andric #undef RTT_JOIN 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric // If we find that this is in fact the name of a type trait, 11380b57cec5SDimitry Andric // update the token kind in place and parse again to treat it as 11390b57cec5SDimitry Andric // the appropriate kind of type trait. 11400b57cec5SDimitry Andric llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known 11410b57cec5SDimitry Andric = RevertibleTypeTraits.find(II); 11420b57cec5SDimitry Andric if (Known != RevertibleTypeTraits.end()) { 11430b57cec5SDimitry Andric Tok.setKind(Known->second); 1144480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1145480093f4SDimitry Andric NotCastExpr, isTypeCast, 1146480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric } 11490b57cec5SDimitry Andric 11500b57cec5SDimitry Andric if ((!ColonIsSacred && Next.is(tok::colon)) || 11510b57cec5SDimitry Andric Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren, 11520b57cec5SDimitry Andric tok::l_brace)) { 11530b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 11540b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 11550b57cec5SDimitry Andric return ExprError(); 11560b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) 1157480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1158480093f4SDimitry Andric NotCastExpr, isTypeCast, 1159480093f4SDimitry Andric isVectorLiteral, 1160480093f4SDimitry Andric NotPrimaryExpression); 11610b57cec5SDimitry Andric } 11620b57cec5SDimitry Andric } 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric // Consume the identifier so that we can see if it is followed by a '(' or 11650b57cec5SDimitry Andric // '.'. 11660b57cec5SDimitry Andric IdentifierInfo &II = *Tok.getIdentifierInfo(); 11670b57cec5SDimitry Andric SourceLocation ILoc = ConsumeToken(); 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric // Support 'Class.property' and 'super.property' notation. 11700b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.is(tok::period) && 11710b57cec5SDimitry Andric (Actions.getTypeName(II, ILoc, getCurScope()) || 11720b57cec5SDimitry Andric // Allow the base to be 'super' if in an objc-method. 11730b57cec5SDimitry Andric (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { 11740b57cec5SDimitry Andric ConsumeToken(); 11750b57cec5SDimitry Andric 11760b57cec5SDimitry Andric if (Tok.is(tok::code_completion) && &II != Ident_super) { 1177fe6060f1SDimitry Andric cutOffParsing(); 11780b57cec5SDimitry Andric Actions.CodeCompleteObjCClassPropertyRefExpr( 11790b57cec5SDimitry Andric getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc); 11800b57cec5SDimitry Andric return ExprError(); 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric // Allow either an identifier or the keyword 'class' (in C++). 11830b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) && 11840b57cec5SDimitry Andric !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { 11850b57cec5SDimitry Andric Diag(Tok, diag::err_expected_property_name); 11860b57cec5SDimitry Andric return ExprError(); 11870b57cec5SDimitry Andric } 11880b57cec5SDimitry Andric IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 11890b57cec5SDimitry Andric SourceLocation PropertyLoc = ConsumeToken(); 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, 11920b57cec5SDimitry Andric ILoc, PropertyLoc); 11930b57cec5SDimitry Andric break; 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric // In an Objective-C method, if we have "super" followed by an identifier, 11970b57cec5SDimitry Andric // the token sequence is ill-formed. However, if there's a ':' or ']' after 11980b57cec5SDimitry Andric // that identifier, this is probably a message send with a missing open 11990b57cec5SDimitry Andric // bracket. Treat it as such. 12000b57cec5SDimitry Andric if (getLangOpts().ObjC && &II == Ident_super && !InMessageExpression && 12010b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 12020b57cec5SDimitry Andric ((Tok.is(tok::identifier) && 12030b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || 12040b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12050b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, nullptr, 12060b57cec5SDimitry Andric nullptr); 12070b57cec5SDimitry Andric break; 12080b57cec5SDimitry Andric } 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric // If we have an Objective-C class name followed by an identifier 12110b57cec5SDimitry Andric // and either ':' or ']', this is an Objective-C class message 12120b57cec5SDimitry Andric // send that's missing the opening '['. Recovery 12130b57cec5SDimitry Andric // appropriately. Also take this path if we're performing code 12140b57cec5SDimitry Andric // completion after an Objective-C class name. 12150b57cec5SDimitry Andric if (getLangOpts().ObjC && 12160b57cec5SDimitry Andric ((Tok.is(tok::identifier) && !InMessageExpression) || 12170b57cec5SDimitry Andric Tok.is(tok::code_completion))) { 12180b57cec5SDimitry Andric const Token& Next = NextToken(); 12190b57cec5SDimitry Andric if (Tok.is(tok::code_completion) || 12200b57cec5SDimitry Andric Next.is(tok::colon) || Next.is(tok::r_square)) 12210b57cec5SDimitry Andric if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) 12220b57cec5SDimitry Andric if (Typ.get()->isObjCObjectOrInterfaceType()) { 12230b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 12240b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 12250b57cec5SDimitry Andric DS.SetRangeStart(ILoc); 12260b57cec5SDimitry Andric DS.SetRangeEnd(ILoc); 12270b57cec5SDimitry Andric const char *PrevSpec = nullptr; 12280b57cec5SDimitry Andric unsigned DiagID; 12290b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, 12300b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 12310b57cec5SDimitry Andric 123281ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 123381ad6265SDimitry Andric DeclaratorContext::TypeName); 12340b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), 12350b57cec5SDimitry Andric DeclaratorInfo); 12360b57cec5SDimitry Andric if (Ty.isInvalid()) 12370b57cec5SDimitry Andric break; 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), 12400b57cec5SDimitry Andric SourceLocation(), 12410b57cec5SDimitry Andric Ty.get(), nullptr); 12420b57cec5SDimitry Andric break; 12430b57cec5SDimitry Andric } 12440b57cec5SDimitry Andric } 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric // Make sure to pass down the right value for isAddressOfOperand. 12470b57cec5SDimitry Andric if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 12480b57cec5SDimitry Andric isAddressOfOperand = false; 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 12510b57cec5SDimitry Andric // need to know whether or not this identifier is a function designator or 12520b57cec5SDimitry Andric // not. 12530b57cec5SDimitry Andric UnqualifiedId Name; 12540b57cec5SDimitry Andric CXXScopeSpec ScopeSpec; 12550b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 12560b57cec5SDimitry Andric Token Replacement; 12570b57cec5SDimitry Andric CastExpressionIdValidator Validator( 12580b57cec5SDimitry Andric /*Next=*/Tok, 12590b57cec5SDimitry Andric /*AllowTypes=*/isTypeCast != NotTypeCast, 12600b57cec5SDimitry Andric /*AllowNonTypes=*/isTypeCast != IsTypeCast); 12610b57cec5SDimitry Andric Validator.IsAddressOfOperand = isAddressOfOperand; 12620b57cec5SDimitry Andric if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) { 12630b57cec5SDimitry Andric Validator.WantExpressionKeywords = false; 12640b57cec5SDimitry Andric Validator.WantRemainingKeywords = false; 12650b57cec5SDimitry Andric } else { 12660b57cec5SDimitry Andric Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren); 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric Name.setIdentifier(&II, ILoc); 12690b57cec5SDimitry Andric Res = Actions.ActOnIdExpression( 12700b57cec5SDimitry Andric getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), 12710b57cec5SDimitry Andric isAddressOfOperand, &Validator, 12720b57cec5SDimitry Andric /*IsInlineAsmIdentifier=*/false, 12730b57cec5SDimitry Andric Tok.is(tok::r_paren) ? nullptr : &Replacement); 12740b57cec5SDimitry Andric if (!Res.isInvalid() && Res.isUnset()) { 12750b57cec5SDimitry Andric UnconsumeToken(Replacement); 1276480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1277480093f4SDimitry Andric NotCastExpr, isTypeCast, 1278480093f4SDimitry Andric /*isVectorLiteral=*/false, 1279480093f4SDimitry Andric NotPrimaryExpression); 12800b57cec5SDimitry Andric } 12810b57cec5SDimitry Andric if (!Res.isInvalid() && Tok.is(tok::less)) 12820b57cec5SDimitry Andric checkPotentialAngleBracket(Res); 12830b57cec5SDimitry Andric break; 12840b57cec5SDimitry Andric } 12850b57cec5SDimitry Andric case tok::char_constant: // constant: character-constant 12860b57cec5SDimitry Andric case tok::wide_char_constant: 12870b57cec5SDimitry Andric case tok::utf8_char_constant: 12880b57cec5SDimitry Andric case tok::utf16_char_constant: 12890b57cec5SDimitry Andric case tok::utf32_char_constant: 12900b57cec5SDimitry Andric Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope()); 12910b57cec5SDimitry Andric ConsumeToken(); 12920b57cec5SDimitry Andric break; 12930b57cec5SDimitry Andric case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 12940b57cec5SDimitry Andric case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 12950b57cec5SDimitry Andric case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] 12960b57cec5SDimitry Andric case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS] 12970b57cec5SDimitry Andric case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] 12980b57cec5SDimitry Andric case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] 12990b57cec5SDimitry Andric case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 13000b57cec5SDimitry Andric Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 13010b57cec5SDimitry Andric ConsumeToken(); 13020b57cec5SDimitry Andric break; 13030b57cec5SDimitry Andric case tok::string_literal: // primary-expression: string-literal 13040b57cec5SDimitry Andric case tok::wide_string_literal: 13050b57cec5SDimitry Andric case tok::utf8_string_literal: 13060b57cec5SDimitry Andric case tok::utf16_string_literal: 13070b57cec5SDimitry Andric case tok::utf32_string_literal: 13080b57cec5SDimitry Andric Res = ParseStringLiteralExpression(true); 13090b57cec5SDimitry Andric break; 13100b57cec5SDimitry Andric case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1] 13110b57cec5SDimitry Andric Res = ParseGenericSelectionExpression(); 13120b57cec5SDimitry Andric break; 13130b57cec5SDimitry Andric case tok::kw___builtin_available: 13145ffd83dbSDimitry Andric Res = ParseAvailabilityCheckExpr(Tok.getLocation()); 13155ffd83dbSDimitry Andric break; 13160b57cec5SDimitry Andric case tok::kw___builtin_va_arg: 13170b57cec5SDimitry Andric case tok::kw___builtin_offsetof: 13180b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: 13190b57cec5SDimitry Andric case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() 13200b57cec5SDimitry Andric case tok::kw___builtin_convertvector: 13210b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 13220b57cec5SDimitry Andric case tok::kw___builtin_FILE: 1323*06c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 13240b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 1325*06c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 13260b57cec5SDimitry Andric case tok::kw___builtin_LINE: 132781ad6265SDimitry Andric case tok::kw___builtin_source_location: 1328480093f4SDimitry Andric if (NotPrimaryExpression) 1329480093f4SDimitry Andric *NotPrimaryExpression = true; 13305ffd83dbSDimitry Andric // This parses the complete suffix; we can return early. 13310b57cec5SDimitry Andric return ParseBuiltinPrimaryExpression(); 13320b57cec5SDimitry Andric case tok::kw___null: 13335ffd83dbSDimitry Andric Res = Actions.ActOnGNUNullExpr(ConsumeToken()); 13345ffd83dbSDimitry Andric break; 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andric case tok::plusplus: // unary-expression: '++' unary-expression [C99] 13370b57cec5SDimitry Andric case tok::minusminus: { // unary-expression: '--' unary-expression [C99] 1338480093f4SDimitry Andric if (NotPrimaryExpression) 1339480093f4SDimitry Andric *NotPrimaryExpression = true; 13400b57cec5SDimitry Andric // C++ [expr.unary] has: 13410b57cec5SDimitry Andric // unary-expression: 13420b57cec5SDimitry Andric // ++ cast-expression 13430b57cec5SDimitry Andric // -- cast-expression 13440b57cec5SDimitry Andric Token SavedTok = Tok; 13450b57cec5SDimitry Andric ConsumeToken(); 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(), 13480b57cec5SDimitry Andric SavedTok.getLocation()); 13490b57cec5SDimitry Andric // One special case is implicitly handled here: if the preceding tokens are 13500b57cec5SDimitry Andric // an ambiguous cast expression, such as "(T())++", then we recurse to 13510b57cec5SDimitry Andric // determine whether the '++' is prefix or postfix. 1352480093f4SDimitry Andric Res = ParseCastExpression(getLangOpts().CPlusPlus ? 1353480093f4SDimitry Andric UnaryExprOnly : AnyCastExpr, 13540b57cec5SDimitry Andric /*isAddressOfOperand*/false, NotCastExpr, 13550b57cec5SDimitry Andric NotTypeCast); 13560b57cec5SDimitry Andric if (NotCastExpr) { 13570b57cec5SDimitry Andric // If we return with NotCastExpr = true, we must not consume any tokens, 13580b57cec5SDimitry Andric // so put the token back where we found it. 13590b57cec5SDimitry Andric assert(Res.isInvalid()); 13600b57cec5SDimitry Andric UnconsumeToken(SavedTok); 13610b57cec5SDimitry Andric return ExprError(); 13620b57cec5SDimitry Andric } 13635ffd83dbSDimitry Andric if (!Res.isInvalid()) { 13645ffd83dbSDimitry Andric Expr *Arg = Res.get(); 13650b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(), 13665ffd83dbSDimitry Andric SavedKind, Arg); 13675ffd83dbSDimitry Andric if (Res.isInvalid()) 13685ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedTok.getLocation(), 13695ffd83dbSDimitry Andric Arg->getEndLoc(), Arg); 13705ffd83dbSDimitry Andric } 13710b57cec5SDimitry Andric return Res; 13720b57cec5SDimitry Andric } 13730b57cec5SDimitry Andric case tok::amp: { // unary-expression: '&' cast-expression 1374480093f4SDimitry Andric if (NotPrimaryExpression) 1375480093f4SDimitry Andric *NotPrimaryExpression = true; 13760b57cec5SDimitry Andric // Special treatment because of member pointers 13770b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 13780b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); 1379bdd1243dSDimitry Andric 1380bdd1243dSDimitry Andric Res = ParseCastExpression(AnyCastExpr, /*isAddressOfOperand=*/true); 13815ffd83dbSDimitry Andric if (!Res.isInvalid()) { 13825ffd83dbSDimitry Andric Expr *Arg = Res.get(); 13835ffd83dbSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); 13845ffd83dbSDimitry Andric if (Res.isInvalid()) 13855ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(Tok.getLocation(), Arg->getEndLoc(), 13865ffd83dbSDimitry Andric Arg); 13875ffd83dbSDimitry Andric } 13880b57cec5SDimitry Andric return Res; 13890b57cec5SDimitry Andric } 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric case tok::star: // unary-expression: '*' cast-expression 13920b57cec5SDimitry Andric case tok::plus: // unary-expression: '+' cast-expression 13930b57cec5SDimitry Andric case tok::minus: // unary-expression: '-' cast-expression 13940b57cec5SDimitry Andric case tok::tilde: // unary-expression: '~' cast-expression 13950b57cec5SDimitry Andric case tok::exclaim: // unary-expression: '!' cast-expression 13960b57cec5SDimitry Andric case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 13970b57cec5SDimitry Andric case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 1398480093f4SDimitry Andric if (NotPrimaryExpression) 1399480093f4SDimitry Andric *NotPrimaryExpression = true; 14000b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 14010b57cec5SDimitry Andric PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); 1402480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14035ffd83dbSDimitry Andric if (!Res.isInvalid()) { 14045ffd83dbSDimitry Andric Expr *Arg = Res.get(); 1405bdd1243dSDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg, 1406bdd1243dSDimitry Andric isAddressOfOperand); 14075ffd83dbSDimitry Andric if (Res.isInvalid()) 14085ffd83dbSDimitry Andric Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg); 14095ffd83dbSDimitry Andric } 14100b57cec5SDimitry Andric return Res; 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric 14130b57cec5SDimitry Andric case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression 1414480093f4SDimitry Andric if (NotPrimaryExpression) 1415480093f4SDimitry Andric *NotPrimaryExpression = true; 14160b57cec5SDimitry Andric SourceLocation CoawaitLoc = ConsumeToken(); 1417480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14180b57cec5SDimitry Andric if (!Res.isInvalid()) 14190b57cec5SDimitry Andric Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get()); 14200b57cec5SDimitry Andric return Res; 14210b57cec5SDimitry Andric } 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 14240b57cec5SDimitry Andric // __extension__ silences extension warnings in the subexpression. 1425480093f4SDimitry Andric if (NotPrimaryExpression) 1426480093f4SDimitry Andric *NotPrimaryExpression = true; 14270b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); // Use RAII to do this. 14280b57cec5SDimitry Andric SourceLocation SavedLoc = ConsumeToken(); 1429480093f4SDimitry Andric Res = ParseCastExpression(AnyCastExpr); 14300b57cec5SDimitry Andric if (!Res.isInvalid()) 14310b57cec5SDimitry Andric Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 14320b57cec5SDimitry Andric return Res; 14330b57cec5SDimitry Andric } 14340b57cec5SDimitry Andric case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' 14350b57cec5SDimitry Andric if (!getLangOpts().C11) 1436a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 1437bdd1243dSDimitry Andric [[fallthrough]]; 14380b57cec5SDimitry Andric case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' 14390b57cec5SDimitry Andric case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 14400b57cec5SDimitry Andric // unary-expression: '__alignof' '(' type-name ')' 14410b57cec5SDimitry Andric case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 14420b57cec5SDimitry Andric // unary-expression: 'sizeof' '(' type-name ')' 14430b57cec5SDimitry Andric case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression 14440b57cec5SDimitry Andric // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' 14450b57cec5SDimitry Andric case tok::kw___builtin_omp_required_simd_align: 1446480093f4SDimitry Andric if (NotPrimaryExpression) 1447480093f4SDimitry Andric *NotPrimaryExpression = true; 14485ffd83dbSDimitry Andric AllowSuffix = false; 14495ffd83dbSDimitry Andric Res = ParseUnaryExprOrTypeTraitExpression(); 14505ffd83dbSDimitry Andric break; 14510b57cec5SDimitry Andric case tok::ampamp: { // unary-expression: '&&' identifier 1452480093f4SDimitry Andric if (NotPrimaryExpression) 1453480093f4SDimitry Andric *NotPrimaryExpression = true; 14540b57cec5SDimitry Andric SourceLocation AmpAmpLoc = ConsumeToken(); 14550b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) 14560b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric if (getCurScope()->getFnParent() == nullptr) 14590b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andric Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 14620b57cec5SDimitry Andric LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 14630b57cec5SDimitry Andric Tok.getLocation()); 14640b57cec5SDimitry Andric Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); 14650b57cec5SDimitry Andric ConsumeToken(); 14665ffd83dbSDimitry Andric AllowSuffix = false; 14675ffd83dbSDimitry Andric break; 14680b57cec5SDimitry Andric } 14690b57cec5SDimitry Andric case tok::kw_const_cast: 14700b57cec5SDimitry Andric case tok::kw_dynamic_cast: 14710b57cec5SDimitry Andric case tok::kw_reinterpret_cast: 14720b57cec5SDimitry Andric case tok::kw_static_cast: 14735ffd83dbSDimitry Andric case tok::kw_addrspace_cast: 1474480093f4SDimitry Andric if (NotPrimaryExpression) 1475480093f4SDimitry Andric *NotPrimaryExpression = true; 14760b57cec5SDimitry Andric Res = ParseCXXCasts(); 14770b57cec5SDimitry Andric break; 14780b57cec5SDimitry Andric case tok::kw___builtin_bit_cast: 1479480093f4SDimitry Andric if (NotPrimaryExpression) 1480480093f4SDimitry Andric *NotPrimaryExpression = true; 14810b57cec5SDimitry Andric Res = ParseBuiltinBitCast(); 14820b57cec5SDimitry Andric break; 14830b57cec5SDimitry Andric case tok::kw_typeid: 1484480093f4SDimitry Andric if (NotPrimaryExpression) 1485480093f4SDimitry Andric *NotPrimaryExpression = true; 14860b57cec5SDimitry Andric Res = ParseCXXTypeid(); 14870b57cec5SDimitry Andric break; 14880b57cec5SDimitry Andric case tok::kw___uuidof: 1489480093f4SDimitry Andric if (NotPrimaryExpression) 1490480093f4SDimitry Andric *NotPrimaryExpression = true; 14910b57cec5SDimitry Andric Res = ParseCXXUuidof(); 14920b57cec5SDimitry Andric break; 14930b57cec5SDimitry Andric case tok::kw_this: 14940b57cec5SDimitry Andric Res = ParseCXXThis(); 14950b57cec5SDimitry Andric break; 1496fe6060f1SDimitry Andric case tok::kw___builtin_sycl_unique_stable_name: 1497fe6060f1SDimitry Andric Res = ParseSYCLUniqueStableNameExpression(); 1498fe6060f1SDimitry Andric break; 1499e8d8bef9SDimitry Andric 15000b57cec5SDimitry Andric case tok::annot_typename: 15010b57cec5SDimitry Andric if (isStartOfObjCClassMessageMissingOpenBracket()) { 15025ffd83dbSDimitry Andric TypeResult Type = getTypeAnnotation(Tok); 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andric // Fake up a Declarator to use with ActOnTypeName. 15050b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 15060b57cec5SDimitry Andric DS.SetRangeStart(Tok.getLocation()); 15070b57cec5SDimitry Andric DS.SetRangeEnd(Tok.getLastLoc()); 15080b57cec5SDimitry Andric 15090b57cec5SDimitry Andric const char *PrevSpec = nullptr; 15100b57cec5SDimitry Andric unsigned DiagID; 15110b57cec5SDimitry Andric DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(), 15120b57cec5SDimitry Andric PrevSpec, DiagID, Type, 15130b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()); 15140b57cec5SDimitry Andric 151581ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 151681ad6265SDimitry Andric DeclaratorContext::TypeName); 15170b57cec5SDimitry Andric TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 15180b57cec5SDimitry Andric if (Ty.isInvalid()) 15190b57cec5SDimitry Andric break; 15200b57cec5SDimitry Andric 15210b57cec5SDimitry Andric ConsumeAnnotationToken(); 15220b57cec5SDimitry Andric Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 15230b57cec5SDimitry Andric Ty.get(), nullptr); 15240b57cec5SDimitry Andric break; 15250b57cec5SDimitry Andric } 1526bdd1243dSDimitry Andric [[fallthrough]]; 15270b57cec5SDimitry Andric 15280b57cec5SDimitry Andric case tok::annot_decltype: 15290b57cec5SDimitry Andric case tok::kw_char: 15300b57cec5SDimitry Andric case tok::kw_wchar_t: 15310b57cec5SDimitry Andric case tok::kw_char8_t: 15320b57cec5SDimitry Andric case tok::kw_char16_t: 15330b57cec5SDimitry Andric case tok::kw_char32_t: 15340b57cec5SDimitry Andric case tok::kw_bool: 15350b57cec5SDimitry Andric case tok::kw_short: 15360b57cec5SDimitry Andric case tok::kw_int: 15370b57cec5SDimitry Andric case tok::kw_long: 15380b57cec5SDimitry Andric case tok::kw___int64: 15390b57cec5SDimitry Andric case tok::kw___int128: 15405ffd83dbSDimitry Andric case tok::kw__ExtInt: 15410eae32dcSDimitry Andric case tok::kw__BitInt: 15420b57cec5SDimitry Andric case tok::kw_signed: 15430b57cec5SDimitry Andric case tok::kw_unsigned: 15440b57cec5SDimitry Andric case tok::kw_half: 15450b57cec5SDimitry Andric case tok::kw_float: 15460b57cec5SDimitry Andric case tok::kw_double: 15475ffd83dbSDimitry Andric case tok::kw___bf16: 15480b57cec5SDimitry Andric case tok::kw__Float16: 15490b57cec5SDimitry Andric case tok::kw___float128: 1550349cc55cSDimitry Andric case tok::kw___ibm128: 15510b57cec5SDimitry Andric case tok::kw_void: 155281ad6265SDimitry Andric case tok::kw_auto: 15530b57cec5SDimitry Andric case tok::kw_typename: 15540b57cec5SDimitry Andric case tok::kw_typeof: 15550b57cec5SDimitry Andric case tok::kw___vector: 15560b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 15570b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 15580b57cec5SDimitry Andric { 15590b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 15600b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 15610b57cec5SDimitry Andric return ExprError(); 15620b57cec5SDimitry Andric } 15630b57cec5SDimitry Andric 1564480093f4SDimitry Andric // Everything henceforth is a postfix-expression. 1565480093f4SDimitry Andric if (NotPrimaryExpression) 1566480093f4SDimitry Andric *NotPrimaryExpression = true; 1567480093f4SDimitry Andric 15680b57cec5SDimitry Andric if (SavedKind == tok::kw_typename) { 15690b57cec5SDimitry Andric // postfix-expression: typename-specifier '(' expression-list[opt] ')' 15700b57cec5SDimitry Andric // typename-specifier braced-init-list 15710b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 15720b57cec5SDimitry Andric return ExprError(); 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) 15750b57cec5SDimitry Andric // We are trying to parse a simple-type-specifier but might not get such 15760b57cec5SDimitry Andric // a token after error recovery. 15770b57cec5SDimitry Andric return ExprError(); 15780b57cec5SDimitry Andric } 15790b57cec5SDimitry Andric 15800b57cec5SDimitry Andric // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 15810b57cec5SDimitry Andric // simple-type-specifier braced-init-list 15820b57cec5SDimitry Andric // 15830b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 15840b57cec5SDimitry Andric 15850b57cec5SDimitry Andric ParseCXXSimpleTypeSpecifier(DS); 15860b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren) && 15870b57cec5SDimitry Andric (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) 15880b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 15890b57cec5SDimitry Andric << DS.getSourceRange()); 15900b57cec5SDimitry Andric 15910b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) 15920b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 15930b57cec5SDimitry Andric 15940b57cec5SDimitry Andric Res = ParseCXXTypeConstructExpression(DS); 15950b57cec5SDimitry Andric break; 15960b57cec5SDimitry Andric } 15970b57cec5SDimitry Andric 15980b57cec5SDimitry Andric case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 15990b57cec5SDimitry Andric // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 16000b57cec5SDimitry Andric // (We can end up in this situation after tentative parsing.) 16010b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16020b57cec5SDimitry Andric return ExprError(); 16030b57cec5SDimitry Andric if (!Tok.is(tok::annot_cxxscope)) 1604480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1605480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1606480093f4SDimitry Andric NotPrimaryExpression); 16070b57cec5SDimitry Andric 16080b57cec5SDimitry Andric Token Next = NextToken(); 16090b57cec5SDimitry Andric if (Next.is(tok::annot_template_id)) { 16100b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 16110b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 16120b57cec5SDimitry Andric // We have a qualified template-id that we know refers to a 16130b57cec5SDimitry Andric // type, translate it into a type and continue parsing as a 16140b57cec5SDimitry Andric // cast expression. 16150b57cec5SDimitry Andric CXXScopeSpec SS; 16165ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 161704eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 16180b57cec5SDimitry Andric /*EnteringContext=*/false); 1619bdd1243dSDimitry Andric AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); 1620480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, 1621480093f4SDimitry Andric isTypeCast, isVectorLiteral, 1622480093f4SDimitry Andric NotPrimaryExpression); 16230b57cec5SDimitry Andric } 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric // Parse as an id-expression. 16270b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 16280b57cec5SDimitry Andric break; 16290b57cec5SDimitry Andric } 16300b57cec5SDimitry Andric 16310b57cec5SDimitry Andric case tok::annot_template_id: { // [C++] template-id 16320b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 16330b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 16340b57cec5SDimitry Andric // We have a template-id that we know refers to a type, 16350b57cec5SDimitry Andric // translate it into a type and continue parsing as a cast 16360b57cec5SDimitry Andric // expression. 163755e4f9d5SDimitry Andric CXXScopeSpec SS; 1638bdd1243dSDimitry Andric AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); 1639480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, 1640480093f4SDimitry Andric NotCastExpr, isTypeCast, isVectorLiteral, 1641480093f4SDimitry Andric NotPrimaryExpression); 16420b57cec5SDimitry Andric } 16430b57cec5SDimitry Andric 16440b57cec5SDimitry Andric // Fall through to treat the template-id as an id-expression. 1645bdd1243dSDimitry Andric [[fallthrough]]; 16460b57cec5SDimitry Andric } 16470b57cec5SDimitry Andric 16480b57cec5SDimitry Andric case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 16490b57cec5SDimitry Andric Res = ParseCXXIdExpression(isAddressOfOperand); 16500b57cec5SDimitry Andric break; 16510b57cec5SDimitry Andric 16520b57cec5SDimitry Andric case tok::coloncolon: { 16530b57cec5SDimitry Andric // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 16540b57cec5SDimitry Andric // annotates the token, tail recurse. 16550b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeToken()) 16560b57cec5SDimitry Andric return ExprError(); 16570b57cec5SDimitry Andric if (!Tok.is(tok::coloncolon)) 1658480093f4SDimitry Andric return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, 1659480093f4SDimitry Andric isVectorLiteral, NotPrimaryExpression); 16600b57cec5SDimitry Andric 16610b57cec5SDimitry Andric // ::new -> [C++] new-expression 16620b57cec5SDimitry Andric // ::delete -> [C++] delete-expression 16630b57cec5SDimitry Andric SourceLocation CCLoc = ConsumeToken(); 1664480093f4SDimitry Andric if (Tok.is(tok::kw_new)) { 1665480093f4SDimitry Andric if (NotPrimaryExpression) 1666480093f4SDimitry Andric *NotPrimaryExpression = true; 16675ffd83dbSDimitry Andric Res = ParseCXXNewExpression(true, CCLoc); 16685ffd83dbSDimitry Andric AllowSuffix = false; 16695ffd83dbSDimitry Andric break; 1670480093f4SDimitry Andric } 1671480093f4SDimitry Andric if (Tok.is(tok::kw_delete)) { 1672480093f4SDimitry Andric if (NotPrimaryExpression) 1673480093f4SDimitry Andric *NotPrimaryExpression = true; 16745ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(true, CCLoc); 16755ffd83dbSDimitry Andric AllowSuffix = false; 16765ffd83dbSDimitry Andric break; 1677480093f4SDimitry Andric } 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric // This is not a type name or scope specifier, it is an invalid expression. 16800b57cec5SDimitry Andric Diag(CCLoc, diag::err_expected_expression); 16810b57cec5SDimitry Andric return ExprError(); 16820b57cec5SDimitry Andric } 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric case tok::kw_new: // [C++] new-expression 1685480093f4SDimitry Andric if (NotPrimaryExpression) 1686480093f4SDimitry Andric *NotPrimaryExpression = true; 16875ffd83dbSDimitry Andric Res = ParseCXXNewExpression(false, Tok.getLocation()); 16885ffd83dbSDimitry Andric AllowSuffix = false; 16895ffd83dbSDimitry Andric break; 16900b57cec5SDimitry Andric 16910b57cec5SDimitry Andric case tok::kw_delete: // [C++] delete-expression 1692480093f4SDimitry Andric if (NotPrimaryExpression) 1693480093f4SDimitry Andric *NotPrimaryExpression = true; 16945ffd83dbSDimitry Andric Res = ParseCXXDeleteExpression(false, Tok.getLocation()); 16955ffd83dbSDimitry Andric AllowSuffix = false; 16965ffd83dbSDimitry Andric break; 16970b57cec5SDimitry Andric 169855e4f9d5SDimitry Andric case tok::kw_requires: // [C++2a] requires-expression 16995ffd83dbSDimitry Andric Res = ParseRequiresExpression(); 17005ffd83dbSDimitry Andric AllowSuffix = false; 17015ffd83dbSDimitry Andric break; 170255e4f9d5SDimitry Andric 17030b57cec5SDimitry Andric case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' 1704480093f4SDimitry Andric if (NotPrimaryExpression) 1705480093f4SDimitry Andric *NotPrimaryExpression = true; 17060b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_noexcept_expr); 17070b57cec5SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 17080b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 17090b57cec5SDimitry Andric 17100b57cec5SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept")) 17110b57cec5SDimitry Andric return ExprError(); 17120b57cec5SDimitry Andric // C++11 [expr.unary.noexcept]p1: 17130b57cec5SDimitry Andric // The noexcept operator determines whether the evaluation of its operand, 17140b57cec5SDimitry Andric // which is an unevaluated operand, can throw an exception. 17150b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 17160b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 17175ffd83dbSDimitry Andric Res = ParseExpression(); 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andric T.consumeClose(); 17200b57cec5SDimitry Andric 17215ffd83dbSDimitry Andric if (!Res.isInvalid()) 17225ffd83dbSDimitry Andric Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(), 17235ffd83dbSDimitry Andric T.getCloseLocation()); 17245ffd83dbSDimitry Andric AllowSuffix = false; 17255ffd83dbSDimitry Andric break; 17260b57cec5SDimitry Andric } 17270b57cec5SDimitry Andric 17280b57cec5SDimitry Andric #define TYPE_TRAIT(N,Spelling,K) \ 17290b57cec5SDimitry Andric case tok::kw_##Spelling: 17300b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 17315ffd83dbSDimitry Andric Res = ParseTypeTrait(); 17325ffd83dbSDimitry Andric break; 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andric case tok::kw___array_rank: 17350b57cec5SDimitry Andric case tok::kw___array_extent: 1736480093f4SDimitry Andric if (NotPrimaryExpression) 1737480093f4SDimitry Andric *NotPrimaryExpression = true; 17385ffd83dbSDimitry Andric Res = ParseArrayTypeTrait(); 17395ffd83dbSDimitry Andric break; 17400b57cec5SDimitry Andric 17410b57cec5SDimitry Andric case tok::kw___is_lvalue_expr: 17420b57cec5SDimitry Andric case tok::kw___is_rvalue_expr: 1743480093f4SDimitry Andric if (NotPrimaryExpression) 1744480093f4SDimitry Andric *NotPrimaryExpression = true; 17455ffd83dbSDimitry Andric Res = ParseExpressionTrait(); 17465ffd83dbSDimitry Andric break; 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric case tok::at: { 1749480093f4SDimitry Andric if (NotPrimaryExpression) 1750480093f4SDimitry Andric *NotPrimaryExpression = true; 17510b57cec5SDimitry Andric SourceLocation AtLoc = ConsumeToken(); 17520b57cec5SDimitry Andric return ParseObjCAtExpression(AtLoc); 17530b57cec5SDimitry Andric } 17540b57cec5SDimitry Andric case tok::caret: 17550b57cec5SDimitry Andric Res = ParseBlockLiteralExpression(); 17560b57cec5SDimitry Andric break; 17570b57cec5SDimitry Andric case tok::code_completion: { 1758fe6060f1SDimitry Andric cutOffParsing(); 17590b57cec5SDimitry Andric Actions.CodeCompleteExpression(getCurScope(), 17600b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 17610b57cec5SDimitry Andric return ExprError(); 17620b57cec5SDimitry Andric } 1763bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: 1764bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 1765bdd1243dSDimitry Andric // HACK: libstdc++ uses some of the transform-type-traits as alias 1766bdd1243dSDimitry Andric // templates, so we need to work around this. 1767bdd1243dSDimitry Andric if (!NextToken().is(tok::l_paren)) { 1768bdd1243dSDimitry Andric Tok.setKind(tok::identifier); 1769bdd1243dSDimitry Andric Diag(Tok, diag::ext_keyword_as_ident) 1770bdd1243dSDimitry Andric << Tok.getIdentifierInfo()->getName() << 0; 1771bdd1243dSDimitry Andric goto ParseIdentifier; 1772bdd1243dSDimitry Andric } 1773bdd1243dSDimitry Andric goto ExpectedExpression; 17740b57cec5SDimitry Andric case tok::l_square: 17750b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11) { 17760b57cec5SDimitry Andric if (getLangOpts().ObjC) { 17770b57cec5SDimitry Andric // C++11 lambda expressions and Objective-C message sends both start with a 17780b57cec5SDimitry Andric // square bracket. There are three possibilities here: 17790b57cec5SDimitry Andric // we have a valid lambda expression, we have an invalid lambda 17800b57cec5SDimitry Andric // expression, or we have something that doesn't appear to be a lambda. 17810b57cec5SDimitry Andric // If we're in the last case, we fall back to ParseObjCMessageExpression. 17820b57cec5SDimitry Andric Res = TryParseLambdaExpression(); 1783480093f4SDimitry Andric if (!Res.isInvalid() && !Res.get()) { 1784480093f4SDimitry Andric // We assume Objective-C++ message expressions are not 1785480093f4SDimitry Andric // primary-expressions. 1786480093f4SDimitry Andric if (NotPrimaryExpression) 1787480093f4SDimitry Andric *NotPrimaryExpression = true; 17880b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 1789480093f4SDimitry Andric } 17900b57cec5SDimitry Andric break; 17910b57cec5SDimitry Andric } 17920b57cec5SDimitry Andric Res = ParseLambdaExpression(); 17930b57cec5SDimitry Andric break; 17940b57cec5SDimitry Andric } 17950b57cec5SDimitry Andric if (getLangOpts().ObjC) { 17960b57cec5SDimitry Andric Res = ParseObjCMessageExpression(); 17970b57cec5SDimitry Andric break; 17980b57cec5SDimitry Andric } 1799bdd1243dSDimitry Andric [[fallthrough]]; 18000b57cec5SDimitry Andric default: 1801bdd1243dSDimitry Andric ExpectedExpression: 18020b57cec5SDimitry Andric NotCastExpr = true; 18030b57cec5SDimitry Andric return ExprError(); 18040b57cec5SDimitry Andric } 18050b57cec5SDimitry Andric 18060b57cec5SDimitry Andric // Check to see whether Res is a function designator only. If it is and we 18070b57cec5SDimitry Andric // are compiling for OpenCL, we need to return an error as this implies 18080b57cec5SDimitry Andric // that the address of the function is being taken, which is illegal in CL. 18090b57cec5SDimitry Andric 1810480093f4SDimitry Andric if (ParseKind == PrimaryExprOnly) 1811480093f4SDimitry Andric // This is strictly a primary-expression - no postfix-expr pieces should be 1812480093f4SDimitry Andric // parsed. 1813480093f4SDimitry Andric return Res; 1814480093f4SDimitry Andric 18155ffd83dbSDimitry Andric if (!AllowSuffix) { 18165ffd83dbSDimitry Andric // FIXME: Don't parse a primary-expression suffix if we encountered a parse 18175ffd83dbSDimitry Andric // error already. 18185ffd83dbSDimitry Andric if (Res.isInvalid()) 18195ffd83dbSDimitry Andric return Res; 18205ffd83dbSDimitry Andric 18215ffd83dbSDimitry Andric switch (Tok.getKind()) { 18225ffd83dbSDimitry Andric case tok::l_square: 18235ffd83dbSDimitry Andric case tok::l_paren: 18245ffd83dbSDimitry Andric case tok::plusplus: 18255ffd83dbSDimitry Andric case tok::minusminus: 18265ffd83dbSDimitry Andric // "expected ';'" or similar is probably the right diagnostic here. Let 18275ffd83dbSDimitry Andric // the caller decide what to do. 18285ffd83dbSDimitry Andric if (Tok.isAtStartOfLine()) 18295ffd83dbSDimitry Andric return Res; 18305ffd83dbSDimitry Andric 1831bdd1243dSDimitry Andric [[fallthrough]]; 18325ffd83dbSDimitry Andric case tok::period: 18335ffd83dbSDimitry Andric case tok::arrow: 18345ffd83dbSDimitry Andric break; 18355ffd83dbSDimitry Andric 18365ffd83dbSDimitry Andric default: 18375ffd83dbSDimitry Andric return Res; 18385ffd83dbSDimitry Andric } 18395ffd83dbSDimitry Andric 18405ffd83dbSDimitry Andric // This was a unary-expression for which a postfix-expression suffix is 18415ffd83dbSDimitry Andric // not permitted by the grammar (eg, a sizeof expression or 18425ffd83dbSDimitry Andric // new-expression or similar). Diagnose but parse the suffix anyway. 18435ffd83dbSDimitry Andric Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens) 18445ffd83dbSDimitry Andric << Tok.getKind() << Res.get()->getSourceRange() 18455ffd83dbSDimitry Andric << FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(") 18465ffd83dbSDimitry Andric << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation), 18475ffd83dbSDimitry Andric ")"); 18485ffd83dbSDimitry Andric } 18495ffd83dbSDimitry Andric 18500b57cec5SDimitry Andric // These can be followed by postfix-expr pieces. 18510b57cec5SDimitry Andric PreferredType = SavedType; 18520b57cec5SDimitry Andric Res = ParsePostfixExpressionSuffix(Res); 1853fe6060f1SDimitry Andric if (getLangOpts().OpenCL && 1854fe6060f1SDimitry Andric !getActions().getOpenCLOptions().isAvailableOption( 1855fe6060f1SDimitry Andric "__cl_clang_function_pointers", getLangOpts())) 18560b57cec5SDimitry Andric if (Expr *PostfixExpr = Res.get()) { 18570b57cec5SDimitry Andric QualType Ty = PostfixExpr->getType(); 18580b57cec5SDimitry Andric if (!Ty.isNull() && Ty->isFunctionType()) { 18590b57cec5SDimitry Andric Diag(PostfixExpr->getExprLoc(), 18600b57cec5SDimitry Andric diag::err_opencl_taking_function_address_parser); 18610b57cec5SDimitry Andric return ExprError(); 18620b57cec5SDimitry Andric } 18630b57cec5SDimitry Andric } 18640b57cec5SDimitry Andric 18650b57cec5SDimitry Andric return Res; 18660b57cec5SDimitry Andric } 18670b57cec5SDimitry Andric 18680b57cec5SDimitry Andric /// Once the leading part of a postfix-expression is parsed, this 18690b57cec5SDimitry Andric /// method parses any suffixes that apply. 18700b57cec5SDimitry Andric /// 18710b57cec5SDimitry Andric /// \verbatim 18720b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 18730b57cec5SDimitry Andric /// primary-expression 18740b57cec5SDimitry Andric /// postfix-expression '[' expression ']' 18750b57cec5SDimitry Andric /// postfix-expression '[' braced-init-list ']' 1876*06c3fb27SDimitry Andric /// postfix-expression '[' expression-list [opt] ']' [C++23 12.4.5] 18770b57cec5SDimitry Andric /// postfix-expression '(' argument-expression-list[opt] ')' 18780b57cec5SDimitry Andric /// postfix-expression '.' identifier 18790b57cec5SDimitry Andric /// postfix-expression '->' identifier 18800b57cec5SDimitry Andric /// postfix-expression '++' 18810b57cec5SDimitry Andric /// postfix-expression '--' 18820b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 18830b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 18840b57cec5SDimitry Andric /// 18850b57cec5SDimitry Andric /// argument-expression-list: [C99 6.5.2] 18860b57cec5SDimitry Andric /// argument-expression ...[opt] 18870b57cec5SDimitry Andric /// argument-expression-list ',' assignment-expression ...[opt] 18880b57cec5SDimitry Andric /// \endverbatim 18890b57cec5SDimitry Andric ExprResult 18900b57cec5SDimitry Andric Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { 18910b57cec5SDimitry Andric // Now that the primary-expression piece of the postfix-expression has been 18920b57cec5SDimitry Andric // parsed, see if there are any postfix-expression pieces here. 18930b57cec5SDimitry Andric SourceLocation Loc; 18940b57cec5SDimitry Andric auto SavedType = PreferredType; 189504eeddc0SDimitry Andric while (true) { 18960b57cec5SDimitry Andric // Each iteration relies on preferred type for the whole expression. 18970b57cec5SDimitry Andric PreferredType = SavedType; 18980b57cec5SDimitry Andric switch (Tok.getKind()) { 18990b57cec5SDimitry Andric case tok::code_completion: 19000b57cec5SDimitry Andric if (InMessageExpression) 19010b57cec5SDimitry Andric return LHS; 19020b57cec5SDimitry Andric 1903fe6060f1SDimitry Andric cutOffParsing(); 19040b57cec5SDimitry Andric Actions.CodeCompletePostfixExpression( 19050b57cec5SDimitry Andric getCurScope(), LHS, PreferredType.get(Tok.getLocation())); 19060b57cec5SDimitry Andric return ExprError(); 19070b57cec5SDimitry Andric 19080b57cec5SDimitry Andric case tok::identifier: 19090b57cec5SDimitry Andric // If we see identifier: after an expression, and we're not already in a 19100b57cec5SDimitry Andric // message send, then this is probably a message send with a missing 19110b57cec5SDimitry Andric // opening bracket '['. 19120b57cec5SDimitry Andric if (getLangOpts().ObjC && !InMessageExpression && 19130b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 19140b57cec5SDimitry Andric LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 19150b57cec5SDimitry Andric nullptr, LHS.get()); 19160b57cec5SDimitry Andric break; 19170b57cec5SDimitry Andric } 19180b57cec5SDimitry Andric // Fall through; this isn't a message send. 1919bdd1243dSDimitry Andric [[fallthrough]]; 19200b57cec5SDimitry Andric 19210b57cec5SDimitry Andric default: // Not a postfix-expression suffix. 19220b57cec5SDimitry Andric return LHS; 19230b57cec5SDimitry Andric case tok::l_square: { // postfix-expression: p-e '[' expression ']' 19240b57cec5SDimitry Andric // If we have a array postfix expression that starts on a new line and 19250b57cec5SDimitry Andric // Objective-C is enabled, it is highly likely that the user forgot a 19260b57cec5SDimitry Andric // semicolon after the base expression and that the array postfix-expr is 19270b57cec5SDimitry Andric // actually another message send. In this case, do some look-ahead to see 19280b57cec5SDimitry Andric // if the contents of the square brackets are obviously not a valid 19290b57cec5SDimitry Andric // expression and recover by pretending there is no suffix. 19300b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.isAtStartOfLine() && 19310b57cec5SDimitry Andric isSimpleObjCMessageExpression()) 19320b57cec5SDimitry Andric return LHS; 19330b57cec5SDimitry Andric 19340b57cec5SDimitry Andric // Reject array indices starting with a lambda-expression. '[[' is 19350b57cec5SDimitry Andric // reserved for attributes. 19360b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) { 19370b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 19380b57cec5SDimitry Andric return ExprError(); 19390b57cec5SDimitry Andric } 19400b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_square); 19410b57cec5SDimitry Andric T.consumeOpen(); 19420b57cec5SDimitry Andric Loc = T.getOpenLocation(); 194381ad6265SDimitry Andric ExprResult Length, Stride; 19445ffd83dbSDimitry Andric SourceLocation ColonLocFirst, ColonLocSecond; 194581ad6265SDimitry Andric ExprVector ArgExprs; 194681ad6265SDimitry Andric bool HasError = false; 19470b57cec5SDimitry Andric PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); 194881ad6265SDimitry Andric 194981ad6265SDimitry Andric // We try to parse a list of indexes in all language mode first 195081ad6265SDimitry Andric // and, in we find 0 or one index, we try to parse an OpenMP array 1951*06c3fb27SDimitry Andric // section. This allow us to support C++23 multi dimensional subscript and 195281ad6265SDimitry Andric // OpenMp sections in the same language mode. 195381ad6265SDimitry Andric if (!getLangOpts().OpenMP || Tok.isNot(tok::colon)) { 1954*06c3fb27SDimitry Andric if (!getLangOpts().CPlusPlus23) { 195581ad6265SDimitry Andric ExprResult Idx; 19560b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 19570b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 19580b57cec5SDimitry Andric Idx = ParseBraceInitializer(); 195981ad6265SDimitry Andric } else { 196081ad6265SDimitry Andric Idx = ParseExpression(); // May be a comma expression 19610b57cec5SDimitry Andric } 196281ad6265SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 196381ad6265SDimitry Andric Idx = Actions.CorrectDelayedTyposInExpr(Idx); 196481ad6265SDimitry Andric if (Idx.isInvalid()) { 196581ad6265SDimitry Andric HasError = true; 196681ad6265SDimitry Andric } else { 196781ad6265SDimitry Andric ArgExprs.push_back(Idx.get()); 196881ad6265SDimitry Andric } 196981ad6265SDimitry Andric } else if (Tok.isNot(tok::r_square)) { 1970bdd1243dSDimitry Andric if (ParseExpressionList(ArgExprs)) { 197181ad6265SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 197281ad6265SDimitry Andric HasError = true; 197381ad6265SDimitry Andric } 197481ad6265SDimitry Andric } 197581ad6265SDimitry Andric } 197681ad6265SDimitry Andric 197781ad6265SDimitry Andric if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { 197881ad6265SDimitry Andric ColonProtectionRAIIObject RAII(*this); 19790b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 19800b57cec5SDimitry Andric // Consume ':' 19815ffd83dbSDimitry Andric ColonLocFirst = ConsumeToken(); 19825ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square) && 19835ffd83dbSDimitry Andric (getLangOpts().OpenMP < 50 || 198481ad6265SDimitry Andric ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) { 19850b57cec5SDimitry Andric Length = ParseExpression(); 198681ad6265SDimitry Andric Length = Actions.CorrectDelayedTyposInExpr(Length); 198781ad6265SDimitry Andric } 19880b57cec5SDimitry Andric } 19895ffd83dbSDimitry Andric if (getLangOpts().OpenMP >= 50 && 19905ffd83dbSDimitry Andric (OMPClauseKind == llvm::omp::Clause::OMPC_to || 19915ffd83dbSDimitry Andric OMPClauseKind == llvm::omp::Clause::OMPC_from) && 19925ffd83dbSDimitry Andric Tok.is(tok::colon)) { 19935ffd83dbSDimitry Andric // Consume ':' 19945ffd83dbSDimitry Andric ColonLocSecond = ConsumeToken(); 19955ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) { 19965ffd83dbSDimitry Andric Stride = ParseExpression(); 19975ffd83dbSDimitry Andric } 19985ffd83dbSDimitry Andric } 199981ad6265SDimitry Andric } 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andric SourceLocation RLoc = Tok.getLocation(); 20020b57cec5SDimitry Andric LHS = Actions.CorrectDelayedTyposInExpr(LHS); 200381ad6265SDimitry Andric 200481ad6265SDimitry Andric if (!LHS.isInvalid() && !HasError && !Length.isInvalid() && 20055ffd83dbSDimitry Andric !Stride.isInvalid() && Tok.is(tok::r_square)) { 20065ffd83dbSDimitry Andric if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { 20075ffd83dbSDimitry Andric LHS = Actions.ActOnOMPArraySectionExpr( 200881ad6265SDimitry Andric LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], 200981ad6265SDimitry Andric ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), RLoc); 20100b57cec5SDimitry Andric } else { 20110b57cec5SDimitry Andric LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, 201281ad6265SDimitry Andric ArgExprs, RLoc); 20130b57cec5SDimitry Andric } 20140b57cec5SDimitry Andric } else { 20150b57cec5SDimitry Andric LHS = ExprError(); 20160b57cec5SDimitry Andric } 20170b57cec5SDimitry Andric 20180b57cec5SDimitry Andric // Match the ']'. 20190b57cec5SDimitry Andric T.consumeClose(); 20200b57cec5SDimitry Andric break; 20210b57cec5SDimitry Andric } 20220b57cec5SDimitry Andric 20230b57cec5SDimitry Andric case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' 20240b57cec5SDimitry Andric case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>' 20250b57cec5SDimitry Andric // '(' argument-expression-list[opt] ')' 20260b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 20270b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 20280b57cec5SDimitry Andric 20290b57cec5SDimitry Andric Expr *ExecConfig = nullptr; 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 20320b57cec5SDimitry Andric 20330b57cec5SDimitry Andric if (OpKind == tok::lesslessless) { 20340b57cec5SDimitry Andric ExprVector ExecConfigExprs; 20350b57cec5SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 20360b57cec5SDimitry Andric 2037bdd1243dSDimitry Andric if (ParseSimpleExpressionList(ExecConfigExprs)) { 20380b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 20390b57cec5SDimitry Andric LHS = ExprError(); 20400b57cec5SDimitry Andric } 20410b57cec5SDimitry Andric 20420b57cec5SDimitry Andric SourceLocation CloseLoc; 20430b57cec5SDimitry Andric if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) { 20440b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 20450b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 20460b57cec5SDimitry Andric } else { 20470b57cec5SDimitry Andric // There was an error closing the brackets 20480b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::greatergreatergreater; 20490b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::lesslessless; 20500b57cec5SDimitry Andric SkipUntil(tok::greatergreatergreater, StopAtSemi); 20510b57cec5SDimitry Andric LHS = ExprError(); 20520b57cec5SDimitry Andric } 20530b57cec5SDimitry Andric 20540b57cec5SDimitry Andric if (!LHS.isInvalid()) { 20550b57cec5SDimitry Andric if (ExpectAndConsume(tok::l_paren)) 20560b57cec5SDimitry Andric LHS = ExprError(); 20570b57cec5SDimitry Andric else 20580b57cec5SDimitry Andric Loc = PrevTokLocation; 20590b57cec5SDimitry Andric } 20600b57cec5SDimitry Andric 20610b57cec5SDimitry Andric if (!LHS.isInvalid()) { 20620b57cec5SDimitry Andric ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), 20630b57cec5SDimitry Andric OpenLoc, 20640b57cec5SDimitry Andric ExecConfigExprs, 20650b57cec5SDimitry Andric CloseLoc); 20660b57cec5SDimitry Andric if (ECResult.isInvalid()) 20670b57cec5SDimitry Andric LHS = ExprError(); 20680b57cec5SDimitry Andric else 20690b57cec5SDimitry Andric ExecConfig = ECResult.get(); 20700b57cec5SDimitry Andric } 20710b57cec5SDimitry Andric } else { 20720b57cec5SDimitry Andric PT.consumeOpen(); 20730b57cec5SDimitry Andric Loc = PT.getOpenLocation(); 20740b57cec5SDimitry Andric } 20750b57cec5SDimitry Andric 20760b57cec5SDimitry Andric ExprVector ArgExprs; 20770b57cec5SDimitry Andric auto RunSignatureHelp = [&]() -> QualType { 20780b57cec5SDimitry Andric QualType PreferredType = Actions.ProduceCallSignatureHelp( 207904eeddc0SDimitry Andric LHS.get(), ArgExprs, PT.getOpenLocation()); 20800b57cec5SDimitry Andric CalledSignatureHelp = true; 20810b57cec5SDimitry Andric return PreferredType; 20820b57cec5SDimitry Andric }; 20830b57cec5SDimitry Andric if (OpKind == tok::l_paren || !LHS.isInvalid()) { 20840b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 2085bdd1243dSDimitry Andric if (ParseExpressionList(ArgExprs, [&] { 20860b57cec5SDimitry Andric PreferredType.enterFunctionArgument(Tok.getLocation(), 20870b57cec5SDimitry Andric RunSignatureHelp); 20880b57cec5SDimitry Andric })) { 20890b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 20900b57cec5SDimitry Andric // If we got an error when parsing expression list, we don't call 20910b57cec5SDimitry Andric // the CodeCompleteCall handler inside the parser. So call it here 20920b57cec5SDimitry Andric // to make sure we get overload suggestions even when we are in the 20930b57cec5SDimitry Andric // middle of a parameter. 20940b57cec5SDimitry Andric if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 20950b57cec5SDimitry Andric RunSignatureHelp(); 20960b57cec5SDimitry Andric LHS = ExprError(); 20970b57cec5SDimitry Andric } else if (LHS.isInvalid()) { 20980b57cec5SDimitry Andric for (auto &E : ArgExprs) 20990b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(E); 21000b57cec5SDimitry Andric } 21010b57cec5SDimitry Andric } 21020b57cec5SDimitry Andric } 21030b57cec5SDimitry Andric 21040b57cec5SDimitry Andric // Match the ')'. 21050b57cec5SDimitry Andric if (LHS.isInvalid()) { 21060b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 21070b57cec5SDimitry Andric } else if (Tok.isNot(tok::r_paren)) { 21080b57cec5SDimitry Andric bool HadDelayedTypo = false; 21090b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get()) 21100b57cec5SDimitry Andric HadDelayedTypo = true; 21110b57cec5SDimitry Andric for (auto &E : ArgExprs) 21120b57cec5SDimitry Andric if (Actions.CorrectDelayedTyposInExpr(E).get() != E) 21130b57cec5SDimitry Andric HadDelayedTypo = true; 21140b57cec5SDimitry Andric // If there were delayed typos in the LHS or ArgExprs, call SkipUntil 21150b57cec5SDimitry Andric // instead of PT.consumeClose() to avoid emitting extra diagnostics for 21160b57cec5SDimitry Andric // the unmatched l_paren. 21170b57cec5SDimitry Andric if (HadDelayedTypo) 21180b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 21190b57cec5SDimitry Andric else 21200b57cec5SDimitry Andric PT.consumeClose(); 21210b57cec5SDimitry Andric LHS = ExprError(); 21220b57cec5SDimitry Andric } else { 21235ffd83dbSDimitry Andric Expr *Fn = LHS.get(); 21245ffd83dbSDimitry Andric SourceLocation RParLoc = Tok.getLocation(); 21255ffd83dbSDimitry Andric LHS = Actions.ActOnCallExpr(getCurScope(), Fn, Loc, ArgExprs, RParLoc, 21260b57cec5SDimitry Andric ExecConfig); 21275ffd83dbSDimitry Andric if (LHS.isInvalid()) { 21285ffd83dbSDimitry Andric ArgExprs.insert(ArgExprs.begin(), Fn); 21295ffd83dbSDimitry Andric LHS = 21305ffd83dbSDimitry Andric Actions.CreateRecoveryExpr(Fn->getBeginLoc(), RParLoc, ArgExprs); 21315ffd83dbSDimitry Andric } 21320b57cec5SDimitry Andric PT.consumeClose(); 21330b57cec5SDimitry Andric } 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric break; 21360b57cec5SDimitry Andric } 21370b57cec5SDimitry Andric case tok::arrow: 21380b57cec5SDimitry Andric case tok::period: { 21390b57cec5SDimitry Andric // postfix-expression: p-e '->' template[opt] id-expression 21400b57cec5SDimitry Andric // postfix-expression: p-e '.' template[opt] id-expression 21410b57cec5SDimitry Andric tok::TokenKind OpKind = Tok.getKind(); 21420b57cec5SDimitry Andric SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric CXXScopeSpec SS; 21450b57cec5SDimitry Andric ParsedType ObjectType; 21460b57cec5SDimitry Andric bool MayBePseudoDestructor = false; 21470b57cec5SDimitry Andric Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; 21480b57cec5SDimitry Andric 21490b57cec5SDimitry Andric PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS); 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { 21520b57cec5SDimitry Andric Expr *Base = OrigLHS; 21530b57cec5SDimitry Andric const Type* BaseType = Base->getType().getTypePtrOrNull(); 21540b57cec5SDimitry Andric if (BaseType && Tok.is(tok::l_paren) && 21550b57cec5SDimitry Andric (BaseType->isFunctionType() || 21560b57cec5SDimitry Andric BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { 21570b57cec5SDimitry Andric Diag(OpLoc, diag::err_function_is_not_record) 21580b57cec5SDimitry Andric << OpKind << Base->getSourceRange() 21590b57cec5SDimitry Andric << FixItHint::CreateRemoval(OpLoc); 21600b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Base); 21610b57cec5SDimitry Andric } 21620b57cec5SDimitry Andric 21635ffd83dbSDimitry Andric LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, 21645ffd83dbSDimitry Andric OpKind, ObjectType, 21650b57cec5SDimitry Andric MayBePseudoDestructor); 21665ffd83dbSDimitry Andric if (LHS.isInvalid()) { 21675ffd83dbSDimitry Andric // Clang will try to perform expression based completion as a 21685ffd83dbSDimitry Andric // fallback, which is confusing in case of member references. So we 21695ffd83dbSDimitry Andric // stop here without any completions. 21705ffd83dbSDimitry Andric if (Tok.is(tok::code_completion)) { 21715ffd83dbSDimitry Andric cutOffParsing(); 21725ffd83dbSDimitry Andric return ExprError(); 21735ffd83dbSDimitry Andric } 21740b57cec5SDimitry Andric break; 21755ffd83dbSDimitry Andric } 21765ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier( 21775ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 21785ffd83dbSDimitry Andric /*EnteringContext=*/false, &MayBePseudoDestructor); 21790b57cec5SDimitry Andric if (SS.isNotEmpty()) 21800b57cec5SDimitry Andric ObjectType = nullptr; 21810b57cec5SDimitry Andric } 21820b57cec5SDimitry Andric 21830b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 21840b57cec5SDimitry Andric tok::TokenKind CorrectedOpKind = 21850b57cec5SDimitry Andric OpKind == tok::arrow ? tok::period : tok::arrow; 21860b57cec5SDimitry Andric ExprResult CorrectedLHS(/*Invalid=*/true); 21870b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && OrigLHS) { 2188a7dea167SDimitry Andric // FIXME: Creating a TentativeAnalysisScope from outside Sema is a 2189a7dea167SDimitry Andric // hack. 2190a7dea167SDimitry Andric Sema::TentativeAnalysisScope Trap(Actions); 21910b57cec5SDimitry Andric CorrectedLHS = Actions.ActOnStartCXXMemberReference( 21920b57cec5SDimitry Andric getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType, 21930b57cec5SDimitry Andric MayBePseudoDestructor); 21940b57cec5SDimitry Andric } 21950b57cec5SDimitry Andric 21960b57cec5SDimitry Andric Expr *Base = LHS.get(); 21970b57cec5SDimitry Andric Expr *CorrectedBase = CorrectedLHS.get(); 21980b57cec5SDimitry Andric if (!CorrectedBase && !getLangOpts().CPlusPlus) 21990b57cec5SDimitry Andric CorrectedBase = Base; 22000b57cec5SDimitry Andric 22010b57cec5SDimitry Andric // Code completion for a member access expression. 2202fe6060f1SDimitry Andric cutOffParsing(); 22030b57cec5SDimitry Andric Actions.CodeCompleteMemberReferenceExpr( 22040b57cec5SDimitry Andric getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, 22050b57cec5SDimitry Andric Base && ExprStatementTokLoc == Base->getBeginLoc(), 22060b57cec5SDimitry Andric PreferredType.get(Tok.getLocation())); 22070b57cec5SDimitry Andric 22080b57cec5SDimitry Andric return ExprError(); 22090b57cec5SDimitry Andric } 22100b57cec5SDimitry Andric 22110b57cec5SDimitry Andric if (MayBePseudoDestructor && !LHS.isInvalid()) { 22120b57cec5SDimitry Andric LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 22130b57cec5SDimitry Andric ObjectType); 22140b57cec5SDimitry Andric break; 22150b57cec5SDimitry Andric } 22160b57cec5SDimitry Andric 22170b57cec5SDimitry Andric // Either the action has told us that this cannot be a 22180b57cec5SDimitry Andric // pseudo-destructor expression (based on the type of base 22190b57cec5SDimitry Andric // expression), or we didn't see a '~' in the right place. We 22200b57cec5SDimitry Andric // can still parse a destructor name here, but in that case it 22210b57cec5SDimitry Andric // names a real destructor. 22220b57cec5SDimitry Andric // Allow explicit constructor calls in Microsoft mode. 22230b57cec5SDimitry Andric // FIXME: Add support for explicit call of template constructor. 22240b57cec5SDimitry Andric SourceLocation TemplateKWLoc; 22250b57cec5SDimitry Andric UnqualifiedId Name; 22260b57cec5SDimitry Andric if (getLangOpts().ObjC && OpKind == tok::period && 22270b57cec5SDimitry Andric Tok.is(tok::kw_class)) { 22280b57cec5SDimitry Andric // Objective-C++: 22290b57cec5SDimitry Andric // After a '.' in a member access expression, treat the keyword 22300b57cec5SDimitry Andric // 'class' as if it were an identifier. 22310b57cec5SDimitry Andric // 22320b57cec5SDimitry Andric // This hack allows property access to the 'class' method because it is 22330b57cec5SDimitry Andric // such a common method name. For other C++ keywords that are 22340b57cec5SDimitry Andric // Objective-C method names, one must use the message send syntax. 22350b57cec5SDimitry Andric IdentifierInfo *Id = Tok.getIdentifierInfo(); 22360b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 22370b57cec5SDimitry Andric Name.setIdentifier(Id, Loc); 22385ffd83dbSDimitry Andric } else if (ParseUnqualifiedId( 22395ffd83dbSDimitry Andric SS, ObjectType, LHS.get() && LHS.get()->containsErrors(), 22400b57cec5SDimitry Andric /*EnteringContext=*/false, 22410b57cec5SDimitry Andric /*AllowDestructorName=*/true, 22420b57cec5SDimitry Andric /*AllowConstructorName=*/ 22435ffd83dbSDimitry Andric getLangOpts().MicrosoftExt && SS.isNotEmpty(), 22445ffd83dbSDimitry Andric /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) { 22450b57cec5SDimitry Andric (void)Actions.CorrectDelayedTyposInExpr(LHS); 22460b57cec5SDimitry Andric LHS = ExprError(); 22470b57cec5SDimitry Andric } 22480b57cec5SDimitry Andric 22490b57cec5SDimitry Andric if (!LHS.isInvalid()) 22500b57cec5SDimitry Andric LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 22510b57cec5SDimitry Andric OpKind, SS, TemplateKWLoc, Name, 22520b57cec5SDimitry Andric CurParsedObjCImpl ? CurParsedObjCImpl->Dcl 22530b57cec5SDimitry Andric : nullptr); 22545ffd83dbSDimitry Andric if (!LHS.isInvalid()) { 22555ffd83dbSDimitry Andric if (Tok.is(tok::less)) 22560b57cec5SDimitry Andric checkPotentialAngleBracket(LHS); 22575ffd83dbSDimitry Andric } else if (OrigLHS && Name.isValid()) { 22585ffd83dbSDimitry Andric // Preserve the LHS if the RHS is an invalid member. 22595ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), 22605ffd83dbSDimitry Andric Name.getEndLoc(), {OrigLHS}); 22615ffd83dbSDimitry Andric } 22620b57cec5SDimitry Andric break; 22630b57cec5SDimitry Andric } 22640b57cec5SDimitry Andric case tok::plusplus: // postfix-expression: postfix-expression '++' 22650b57cec5SDimitry Andric case tok::minusminus: // postfix-expression: postfix-expression '--' 22660b57cec5SDimitry Andric if (!LHS.isInvalid()) { 22675ffd83dbSDimitry Andric Expr *Arg = LHS.get(); 22680b57cec5SDimitry Andric LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), 22695ffd83dbSDimitry Andric Tok.getKind(), Arg); 22705ffd83dbSDimitry Andric if (LHS.isInvalid()) 22715ffd83dbSDimitry Andric LHS = Actions.CreateRecoveryExpr(Arg->getBeginLoc(), 22725ffd83dbSDimitry Andric Tok.getLocation(), Arg); 22730b57cec5SDimitry Andric } 22740b57cec5SDimitry Andric ConsumeToken(); 22750b57cec5SDimitry Andric break; 22760b57cec5SDimitry Andric } 22770b57cec5SDimitry Andric } 22780b57cec5SDimitry Andric } 22790b57cec5SDimitry Andric 22800b57cec5SDimitry Andric /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/ 22810b57cec5SDimitry Andric /// vec_step and we are at the start of an expression or a parenthesized 22820b57cec5SDimitry Andric /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the 22830b57cec5SDimitry Andric /// expression (isCastExpr == false) or the type (isCastExpr == true). 22840b57cec5SDimitry Andric /// 22850b57cec5SDimitry Andric /// \verbatim 22860b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 22870b57cec5SDimitry Andric /// 'sizeof' unary-expression 22880b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 22890b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 22900b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 22910b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 22920b57cec5SDimitry Andric /// [C++0x] 'alignof' '(' type-id ')' 22930b57cec5SDimitry Andric /// 22940b57cec5SDimitry Andric /// [GNU] typeof-specifier: 22950b57cec5SDimitry Andric /// typeof ( expressions ) 22960b57cec5SDimitry Andric /// typeof ( type-name ) 22970b57cec5SDimitry Andric /// [GNU/C++] typeof unary-expression 2298bdd1243dSDimitry Andric /// [C2x] typeof-specifier: 2299bdd1243dSDimitry Andric /// typeof '(' typeof-specifier-argument ')' 2300bdd1243dSDimitry Andric /// typeof_unqual '(' typeof-specifier-argument ')' 2301bdd1243dSDimitry Andric /// 2302bdd1243dSDimitry Andric /// typeof-specifier-argument: 2303bdd1243dSDimitry Andric /// expression 2304bdd1243dSDimitry Andric /// type-name 23050b57cec5SDimitry Andric /// 23060b57cec5SDimitry Andric /// [OpenCL 1.1 6.11.12] vec_step built-in function: 23070b57cec5SDimitry Andric /// vec_step ( expressions ) 23080b57cec5SDimitry Andric /// vec_step ( type-name ) 23090b57cec5SDimitry Andric /// \endverbatim 23100b57cec5SDimitry Andric ExprResult 23110b57cec5SDimitry Andric Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, 23120b57cec5SDimitry Andric bool &isCastExpr, 23130b57cec5SDimitry Andric ParsedType &CastTy, 23140b57cec5SDimitry Andric SourceRange &CastRange) { 23150b57cec5SDimitry Andric 2316bdd1243dSDimitry Andric assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof, 2317bdd1243dSDimitry Andric tok::kw___alignof, tok::kw_alignof, tok::kw__Alignof, 2318bdd1243dSDimitry Andric tok::kw_vec_step, 23190b57cec5SDimitry Andric tok::kw___builtin_omp_required_simd_align) && 23200b57cec5SDimitry Andric "Not a typeof/sizeof/alignof/vec_step expression!"); 23210b57cec5SDimitry Andric 23220b57cec5SDimitry Andric ExprResult Operand; 23230b57cec5SDimitry Andric 23240b57cec5SDimitry Andric // If the operand doesn't start with an '(', it must be an expression. 23250b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) { 23260b57cec5SDimitry Andric // If construct allows a form without parenthesis, user may forget to put 23270b57cec5SDimitry Andric // pathenthesis around type name. 23280b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, 23290b57cec5SDimitry Andric tok::kw__Alignof)) { 23300b57cec5SDimitry Andric if (isTypeIdUnambiguously()) { 23310b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 23320b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 233381ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 233481ad6265SDimitry Andric DeclaratorContext::TypeName); 23350b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 23360b57cec5SDimitry Andric 23370b57cec5SDimitry Andric SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); 23380b57cec5SDimitry Andric SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); 2339e8d8bef9SDimitry Andric if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) { 2340e8d8bef9SDimitry Andric Diag(OpTok.getLocation(), 2341e8d8bef9SDimitry Andric diag::err_expected_parentheses_around_typename) 2342e8d8bef9SDimitry Andric << OpTok.getName(); 2343e8d8bef9SDimitry Andric } else { 23440b57cec5SDimitry Andric Diag(LParenLoc, diag::err_expected_parentheses_around_typename) 2345e8d8bef9SDimitry Andric << OpTok.getName() << FixItHint::CreateInsertion(LParenLoc, "(") 23460b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 2347e8d8bef9SDimitry Andric } 23480b57cec5SDimitry Andric isCastExpr = true; 23490b57cec5SDimitry Andric return ExprEmpty(); 23500b57cec5SDimitry Andric } 23510b57cec5SDimitry Andric } 23520b57cec5SDimitry Andric 23530b57cec5SDimitry Andric isCastExpr = false; 2354bdd1243dSDimitry Andric if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) && 2355bdd1243dSDimitry Andric !getLangOpts().CPlusPlus) { 23560b57cec5SDimitry Andric Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo() 23570b57cec5SDimitry Andric << tok::l_paren; 23580b57cec5SDimitry Andric return ExprError(); 23590b57cec5SDimitry Andric } 23600b57cec5SDimitry Andric 2361480093f4SDimitry Andric Operand = ParseCastExpression(UnaryExprOnly); 23620b57cec5SDimitry Andric } else { 23630b57cec5SDimitry Andric // If it starts with a '(', we know that it is either a parenthesized 23640b57cec5SDimitry Andric // type-name, or it is a unary-expression that starts with a compound 23650b57cec5SDimitry Andric // literal, or starts with a primary-expression that is a parenthesized 23660b57cec5SDimitry Andric // expression. 23670b57cec5SDimitry Andric ParenParseOption ExprType = CastExpr; 23680b57cec5SDimitry Andric SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 23690b57cec5SDimitry Andric 23700b57cec5SDimitry Andric Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 23710b57cec5SDimitry Andric false, CastTy, RParenLoc); 23720b57cec5SDimitry Andric CastRange = SourceRange(LParenLoc, RParenLoc); 23730b57cec5SDimitry Andric 23740b57cec5SDimitry Andric // If ParseParenExpression parsed a '(typename)' sequence only, then this is 23750b57cec5SDimitry Andric // a type. 23760b57cec5SDimitry Andric if (ExprType == CastExpr) { 23770b57cec5SDimitry Andric isCastExpr = true; 23780b57cec5SDimitry Andric return ExprEmpty(); 23790b57cec5SDimitry Andric } 23800b57cec5SDimitry Andric 2381bdd1243dSDimitry Andric if (getLangOpts().CPlusPlus || 2382bdd1243dSDimitry Andric !OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) { 23830b57cec5SDimitry Andric // GNU typeof in C requires the expression to be parenthesized. Not so for 23840b57cec5SDimitry Andric // sizeof/alignof or in C++. Therefore, the parenthesized expression is 23850b57cec5SDimitry Andric // the start of a unary-expression, but doesn't include any postfix 23860b57cec5SDimitry Andric // pieces. Parse these now if present. 23870b57cec5SDimitry Andric if (!Operand.isInvalid()) 23880b57cec5SDimitry Andric Operand = ParsePostfixExpressionSuffix(Operand.get()); 23890b57cec5SDimitry Andric } 23900b57cec5SDimitry Andric } 23910b57cec5SDimitry Andric 23920b57cec5SDimitry Andric // If we get here, the operand to the typeof/sizeof/alignof was an expression. 23930b57cec5SDimitry Andric isCastExpr = false; 23940b57cec5SDimitry Andric return Operand; 23950b57cec5SDimitry Andric } 23960b57cec5SDimitry Andric 2397fe6060f1SDimitry Andric /// Parse a __builtin_sycl_unique_stable_name expression. Accepts a type-id as 2398fe6060f1SDimitry Andric /// a parameter. 2399fe6060f1SDimitry Andric ExprResult Parser::ParseSYCLUniqueStableNameExpression() { 2400fe6060f1SDimitry Andric assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) && 2401349cc55cSDimitry Andric "Not __builtin_sycl_unique_stable_name"); 2402fe6060f1SDimitry Andric 2403fe6060f1SDimitry Andric SourceLocation OpLoc = ConsumeToken(); 2404fe6060f1SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 2405fe6060f1SDimitry Andric 2406fe6060f1SDimitry Andric // __builtin_sycl_unique_stable_name expressions are always parenthesized. 2407fe6060f1SDimitry Andric if (T.expectAndConsume(diag::err_expected_lparen_after, 2408fe6060f1SDimitry Andric "__builtin_sycl_unique_stable_name")) 2409fe6060f1SDimitry Andric return ExprError(); 2410fe6060f1SDimitry Andric 2411fe6060f1SDimitry Andric TypeResult Ty = ParseTypeName(); 2412fe6060f1SDimitry Andric 2413fe6060f1SDimitry Andric if (Ty.isInvalid()) { 2414fe6060f1SDimitry Andric T.skipToEnd(); 2415fe6060f1SDimitry Andric return ExprError(); 2416fe6060f1SDimitry Andric } 2417fe6060f1SDimitry Andric 2418fe6060f1SDimitry Andric if (T.consumeClose()) 2419fe6060f1SDimitry Andric return ExprError(); 2420fe6060f1SDimitry Andric 2421fe6060f1SDimitry Andric return Actions.ActOnSYCLUniqueStableNameExpr(OpLoc, T.getOpenLocation(), 2422fe6060f1SDimitry Andric T.getCloseLocation(), Ty.get()); 2423fe6060f1SDimitry Andric } 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andric /// Parse a sizeof or alignof expression. 24260b57cec5SDimitry Andric /// 24270b57cec5SDimitry Andric /// \verbatim 24280b57cec5SDimitry Andric /// unary-expression: [C99 6.5.3] 24290b57cec5SDimitry Andric /// 'sizeof' unary-expression 24300b57cec5SDimitry Andric /// 'sizeof' '(' type-name ')' 24310b57cec5SDimitry Andric /// [C++11] 'sizeof' '...' '(' identifier ')' 24320b57cec5SDimitry Andric /// [GNU] '__alignof' unary-expression 24330b57cec5SDimitry Andric /// [GNU] '__alignof' '(' type-name ')' 24340b57cec5SDimitry Andric /// [C11] '_Alignof' '(' type-name ')' 24350b57cec5SDimitry Andric /// [C++11] 'alignof' '(' type-id ')' 24360b57cec5SDimitry Andric /// \endverbatim 24370b57cec5SDimitry Andric ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { 24380b57cec5SDimitry Andric assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, 24390b57cec5SDimitry Andric tok::kw__Alignof, tok::kw_vec_step, 24400b57cec5SDimitry Andric tok::kw___builtin_omp_required_simd_align) && 24410b57cec5SDimitry Andric "Not a sizeof/alignof/vec_step expression!"); 24420b57cec5SDimitry Andric Token OpTok = Tok; 24430b57cec5SDimitry Andric ConsumeToken(); 24440b57cec5SDimitry Andric 24450b57cec5SDimitry Andric // [C++11] 'sizeof' '...' '(' identifier ')' 24460b57cec5SDimitry Andric if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { 24470b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 24480b57cec5SDimitry Andric SourceLocation LParenLoc, RParenLoc; 24490b57cec5SDimitry Andric IdentifierInfo *Name = nullptr; 24500b57cec5SDimitry Andric SourceLocation NameLoc; 24510b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 24520b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 24530b57cec5SDimitry Andric T.consumeOpen(); 24540b57cec5SDimitry Andric LParenLoc = T.getOpenLocation(); 24550b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 24560b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 24570b57cec5SDimitry Andric NameLoc = ConsumeToken(); 24580b57cec5SDimitry Andric T.consumeClose(); 24590b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 24600b57cec5SDimitry Andric if (RParenLoc.isInvalid()) 24610b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 24620b57cec5SDimitry Andric } else { 24630b57cec5SDimitry Andric Diag(Tok, diag::err_expected_parameter_pack); 24640b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 24650b57cec5SDimitry Andric } 24660b57cec5SDimitry Andric } else if (Tok.is(tok::identifier)) { 24670b57cec5SDimitry Andric Name = Tok.getIdentifierInfo(); 24680b57cec5SDimitry Andric NameLoc = ConsumeToken(); 24690b57cec5SDimitry Andric LParenLoc = PP.getLocForEndOfToken(EllipsisLoc); 24700b57cec5SDimitry Andric RParenLoc = PP.getLocForEndOfToken(NameLoc); 24710b57cec5SDimitry Andric Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack) 24720b57cec5SDimitry Andric << Name 24730b57cec5SDimitry Andric << FixItHint::CreateInsertion(LParenLoc, "(") 24740b57cec5SDimitry Andric << FixItHint::CreateInsertion(RParenLoc, ")"); 24750b57cec5SDimitry Andric } else { 24760b57cec5SDimitry Andric Diag(Tok, diag::err_sizeof_parameter_pack); 24770b57cec5SDimitry Andric } 24780b57cec5SDimitry Andric 24790b57cec5SDimitry Andric if (!Name) 24800b57cec5SDimitry Andric return ExprError(); 24810b57cec5SDimitry Andric 24820b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 24830b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 24840b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andric return Actions.ActOnSizeofParameterPackExpr(getCurScope(), 24870b57cec5SDimitry Andric OpTok.getLocation(), 24880b57cec5SDimitry Andric *Name, NameLoc, 24890b57cec5SDimitry Andric RParenLoc); 24900b57cec5SDimitry Andric } 24910b57cec5SDimitry Andric 2492*06c3fb27SDimitry Andric if (getLangOpts().CPlusPlus && 2493*06c3fb27SDimitry Andric OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 24940b57cec5SDimitry Andric Diag(OpTok, diag::warn_cxx98_compat_alignof); 2495*06c3fb27SDimitry Andric else if (getLangOpts().C2x && OpTok.is(tok::kw_alignof)) 2496*06c3fb27SDimitry Andric Diag(OpTok, diag::warn_c2x_compat_keyword) << OpTok.getName(); 24970b57cec5SDimitry Andric 24980b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 24990b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated, 25000b57cec5SDimitry Andric Sema::ReuseLambdaContextDecl); 25010b57cec5SDimitry Andric 25020b57cec5SDimitry Andric bool isCastExpr; 25030b57cec5SDimitry Andric ParsedType CastTy; 25040b57cec5SDimitry Andric SourceRange CastRange; 25050b57cec5SDimitry Andric ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, 25060b57cec5SDimitry Andric isCastExpr, 25070b57cec5SDimitry Andric CastTy, 25080b57cec5SDimitry Andric CastRange); 25090b57cec5SDimitry Andric 25100b57cec5SDimitry Andric UnaryExprOrTypeTrait ExprKind = UETT_SizeOf; 25110b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 25120b57cec5SDimitry Andric ExprKind = UETT_AlignOf; 25130b57cec5SDimitry Andric else if (OpTok.is(tok::kw___alignof)) 25140b57cec5SDimitry Andric ExprKind = UETT_PreferredAlignOf; 25150b57cec5SDimitry Andric else if (OpTok.is(tok::kw_vec_step)) 25160b57cec5SDimitry Andric ExprKind = UETT_VecStep; 25170b57cec5SDimitry Andric else if (OpTok.is(tok::kw___builtin_omp_required_simd_align)) 25180b57cec5SDimitry Andric ExprKind = UETT_OpenMPRequiredSimdAlign; 25190b57cec5SDimitry Andric 25200b57cec5SDimitry Andric if (isCastExpr) 25210b57cec5SDimitry Andric return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 25220b57cec5SDimitry Andric ExprKind, 25230b57cec5SDimitry Andric /*IsType=*/true, 25240b57cec5SDimitry Andric CastTy.getAsOpaquePtr(), 25250b57cec5SDimitry Andric CastRange); 25260b57cec5SDimitry Andric 25270b57cec5SDimitry Andric if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof)) 25280b57cec5SDimitry Andric Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); 25290b57cec5SDimitry Andric 25300b57cec5SDimitry Andric // If we get here, the operand to the sizeof/alignof was an expression. 25310b57cec5SDimitry Andric if (!Operand.isInvalid()) 25320b57cec5SDimitry Andric Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 25330b57cec5SDimitry Andric ExprKind, 25340b57cec5SDimitry Andric /*IsType=*/false, 25350b57cec5SDimitry Andric Operand.get(), 25360b57cec5SDimitry Andric CastRange); 25370b57cec5SDimitry Andric return Operand; 25380b57cec5SDimitry Andric } 25390b57cec5SDimitry Andric 25400b57cec5SDimitry Andric /// ParseBuiltinPrimaryExpression 25410b57cec5SDimitry Andric /// 25420b57cec5SDimitry Andric /// \verbatim 25430b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 25440b57cec5SDimitry Andric /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 25450b57cec5SDimitry Andric /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 25460b57cec5SDimitry Andric /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 25470b57cec5SDimitry Andric /// assign-expr ')' 25480b57cec5SDimitry Andric /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 25490b57cec5SDimitry Andric /// [GNU] '__builtin_FILE' '(' ')' 2550*06c3fb27SDimitry Andric /// [CLANG] '__builtin_FILE_NAME' '(' ')' 25510b57cec5SDimitry Andric /// [GNU] '__builtin_FUNCTION' '(' ')' 2552*06c3fb27SDimitry Andric /// [MS] '__builtin_FUNCSIG' '(' ')' 25530b57cec5SDimitry Andric /// [GNU] '__builtin_LINE' '(' ')' 25540b57cec5SDimitry Andric /// [CLANG] '__builtin_COLUMN' '(' ')' 255581ad6265SDimitry Andric /// [GNU] '__builtin_source_location' '(' ')' 25560b57cec5SDimitry Andric /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' 25570b57cec5SDimitry Andric /// 25580b57cec5SDimitry Andric /// [GNU] offsetof-member-designator: 25590b57cec5SDimitry Andric /// [GNU] identifier 25600b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '.' identifier 25610b57cec5SDimitry Andric /// [GNU] offsetof-member-designator '[' expression ']' 25620b57cec5SDimitry Andric /// \endverbatim 25630b57cec5SDimitry Andric ExprResult Parser::ParseBuiltinPrimaryExpression() { 25640b57cec5SDimitry Andric ExprResult Res; 25650b57cec5SDimitry Andric const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 25660b57cec5SDimitry Andric 25670b57cec5SDimitry Andric tok::TokenKind T = Tok.getKind(); 25680b57cec5SDimitry Andric SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 25690b57cec5SDimitry Andric 25700b57cec5SDimitry Andric // All of these start with an open paren. 25710b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) 25720b57cec5SDimitry Andric return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII 25730b57cec5SDimitry Andric << tok::l_paren); 25740b57cec5SDimitry Andric 25750b57cec5SDimitry Andric BalancedDelimiterTracker PT(*this, tok::l_paren); 25760b57cec5SDimitry Andric PT.consumeOpen(); 25770b57cec5SDimitry Andric 25780b57cec5SDimitry Andric // TODO: Build AST. 25790b57cec5SDimitry Andric 25800b57cec5SDimitry Andric switch (T) { 25810b57cec5SDimitry Andric default: llvm_unreachable("Not a builtin primary expression!"); 25820b57cec5SDimitry Andric case tok::kw___builtin_va_arg: { 25830b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 25860b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 25870b57cec5SDimitry Andric Expr = ExprError(); 25880b57cec5SDimitry Andric } 25890b57cec5SDimitry Andric 25900b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 25910b57cec5SDimitry Andric 25920b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 25930b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 25940b57cec5SDimitry Andric Expr = ExprError(); 25950b57cec5SDimitry Andric } 25960b57cec5SDimitry Andric 25970b57cec5SDimitry Andric if (Expr.isInvalid() || Ty.isInvalid()) 25980b57cec5SDimitry Andric Res = ExprError(); 25990b57cec5SDimitry Andric else 26000b57cec5SDimitry Andric Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen()); 26010b57cec5SDimitry Andric break; 26020b57cec5SDimitry Andric } 26030b57cec5SDimitry Andric case tok::kw___builtin_offsetof: { 26040b57cec5SDimitry Andric SourceLocation TypeLoc = Tok.getLocation(); 2605bdd1243dSDimitry Andric auto OOK = Sema::OffsetOfKind::OOK_Builtin; 2606bdd1243dSDimitry Andric if (Tok.getLocation().isMacroID()) { 2607bdd1243dSDimitry Andric StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics( 2608bdd1243dSDimitry Andric Tok.getLocation(), PP.getSourceManager(), getLangOpts()); 2609bdd1243dSDimitry Andric if (MacroName == "offsetof") 2610bdd1243dSDimitry Andric OOK = Sema::OffsetOfKind::OOK_Macro; 2611bdd1243dSDimitry Andric } 2612bdd1243dSDimitry Andric TypeResult Ty; 2613bdd1243dSDimitry Andric { 2614bdd1243dSDimitry Andric OffsetOfStateRAIIObject InOffsetof(*this, OOK); 2615bdd1243dSDimitry Andric Ty = ParseTypeName(); 26160b57cec5SDimitry Andric if (Ty.isInvalid()) { 26170b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26180b57cec5SDimitry Andric return ExprError(); 26190b57cec5SDimitry Andric } 2620bdd1243dSDimitry Andric } 26210b57cec5SDimitry Andric 26220b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 26230b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26240b57cec5SDimitry Andric return ExprError(); 26250b57cec5SDimitry Andric } 26260b57cec5SDimitry Andric 26270b57cec5SDimitry Andric // We must have at least one identifier here. 26280b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 26290b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 26300b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26310b57cec5SDimitry Andric return ExprError(); 26320b57cec5SDimitry Andric } 26330b57cec5SDimitry Andric 26340b57cec5SDimitry Andric // Keep track of the various subcomponents we see. 26350b57cec5SDimitry Andric SmallVector<Sema::OffsetOfComponent, 4> Comps; 26360b57cec5SDimitry Andric 26370b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 26380b57cec5SDimitry Andric Comps.back().isBrackets = false; 26390b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 26400b57cec5SDimitry Andric Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 26410b57cec5SDimitry Andric 26420b57cec5SDimitry Andric // FIXME: This loop leaks the index expressions on error. 264304eeddc0SDimitry Andric while (true) { 26440b57cec5SDimitry Andric if (Tok.is(tok::period)) { 26450b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-designator '.' identifier 26460b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 26470b57cec5SDimitry Andric Comps.back().isBrackets = false; 26480b57cec5SDimitry Andric Comps.back().LocStart = ConsumeToken(); 26490b57cec5SDimitry Andric 26500b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 26510b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 26520b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26530b57cec5SDimitry Andric return ExprError(); 26540b57cec5SDimitry Andric } 26550b57cec5SDimitry Andric Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 26560b57cec5SDimitry Andric Comps.back().LocEnd = ConsumeToken(); 26570b57cec5SDimitry Andric } else if (Tok.is(tok::l_square)) { 26580b57cec5SDimitry Andric if (CheckProhibitedCXX11Attribute()) 26590b57cec5SDimitry Andric return ExprError(); 26600b57cec5SDimitry Andric 26610b57cec5SDimitry Andric // offsetof-member-designator: offsetof-member-design '[' expression ']' 26620b57cec5SDimitry Andric Comps.push_back(Sema::OffsetOfComponent()); 26630b57cec5SDimitry Andric Comps.back().isBrackets = true; 26640b57cec5SDimitry Andric BalancedDelimiterTracker ST(*this, tok::l_square); 26650b57cec5SDimitry Andric ST.consumeOpen(); 26660b57cec5SDimitry Andric Comps.back().LocStart = ST.getOpenLocation(); 26670b57cec5SDimitry Andric Res = ParseExpression(); 26680b57cec5SDimitry Andric if (Res.isInvalid()) { 26690b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26700b57cec5SDimitry Andric return Res; 26710b57cec5SDimitry Andric } 26720b57cec5SDimitry Andric Comps.back().U.E = Res.get(); 26730b57cec5SDimitry Andric 26740b57cec5SDimitry Andric ST.consumeClose(); 26750b57cec5SDimitry Andric Comps.back().LocEnd = ST.getCloseLocation(); 26760b57cec5SDimitry Andric } else { 26770b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 26780b57cec5SDimitry Andric PT.consumeClose(); 26790b57cec5SDimitry Andric Res = ExprError(); 26800b57cec5SDimitry Andric } else if (Ty.isInvalid()) { 26810b57cec5SDimitry Andric Res = ExprError(); 26820b57cec5SDimitry Andric } else { 26830b57cec5SDimitry Andric PT.consumeClose(); 26840b57cec5SDimitry Andric Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc, 26850b57cec5SDimitry Andric Ty.get(), Comps, 26860b57cec5SDimitry Andric PT.getCloseLocation()); 26870b57cec5SDimitry Andric } 26880b57cec5SDimitry Andric break; 26890b57cec5SDimitry Andric } 26900b57cec5SDimitry Andric } 26910b57cec5SDimitry Andric break; 26920b57cec5SDimitry Andric } 26930b57cec5SDimitry Andric case tok::kw___builtin_choose_expr: { 26940b57cec5SDimitry Andric ExprResult Cond(ParseAssignmentExpression()); 26950b57cec5SDimitry Andric if (Cond.isInvalid()) { 26960b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 26970b57cec5SDimitry Andric return Cond; 26980b57cec5SDimitry Andric } 26990b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27000b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27010b57cec5SDimitry Andric return ExprError(); 27020b57cec5SDimitry Andric } 27030b57cec5SDimitry Andric 27040b57cec5SDimitry Andric ExprResult Expr1(ParseAssignmentExpression()); 27050b57cec5SDimitry Andric if (Expr1.isInvalid()) { 27060b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27070b57cec5SDimitry Andric return Expr1; 27080b57cec5SDimitry Andric } 27090b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27100b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27110b57cec5SDimitry Andric return ExprError(); 27120b57cec5SDimitry Andric } 27130b57cec5SDimitry Andric 27140b57cec5SDimitry Andric ExprResult Expr2(ParseAssignmentExpression()); 27150b57cec5SDimitry Andric if (Expr2.isInvalid()) { 27160b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27170b57cec5SDimitry Andric return Expr2; 27180b57cec5SDimitry Andric } 27190b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27200b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27210b57cec5SDimitry Andric return ExprError(); 27220b57cec5SDimitry Andric } 27230b57cec5SDimitry Andric Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(), 27240b57cec5SDimitry Andric Expr2.get(), ConsumeParen()); 27250b57cec5SDimitry Andric break; 27260b57cec5SDimitry Andric } 27270b57cec5SDimitry Andric case tok::kw___builtin_astype: { 27280b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 27290b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 27300b57cec5SDimitry Andric if (Expr.isInvalid()) { 27310b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27320b57cec5SDimitry Andric return ExprError(); 27330b57cec5SDimitry Andric } 27340b57cec5SDimitry Andric 27350b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27360b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27370b57cec5SDimitry Andric return ExprError(); 27380b57cec5SDimitry Andric } 27390b57cec5SDimitry Andric 27400b57cec5SDimitry Andric // Second argument is the type to bitcast to. 27410b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 27420b57cec5SDimitry Andric if (DestTy.isInvalid()) 27430b57cec5SDimitry Andric return ExprError(); 27440b57cec5SDimitry Andric 27450b57cec5SDimitry Andric // Attempt to consume the r-paren. 27460b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27470b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27480b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27490b57cec5SDimitry Andric return ExprError(); 27500b57cec5SDimitry Andric } 27510b57cec5SDimitry Andric 27520b57cec5SDimitry Andric Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 27530b57cec5SDimitry Andric ConsumeParen()); 27540b57cec5SDimitry Andric break; 27550b57cec5SDimitry Andric } 27560b57cec5SDimitry Andric case tok::kw___builtin_convertvector: { 27570b57cec5SDimitry Andric // The first argument is an expression to be converted, followed by a comma. 27580b57cec5SDimitry Andric ExprResult Expr(ParseAssignmentExpression()); 27590b57cec5SDimitry Andric if (Expr.isInvalid()) { 27600b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27610b57cec5SDimitry Andric return ExprError(); 27620b57cec5SDimitry Andric } 27630b57cec5SDimitry Andric 27640b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 27650b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27660b57cec5SDimitry Andric return ExprError(); 27670b57cec5SDimitry Andric } 27680b57cec5SDimitry Andric 27690b57cec5SDimitry Andric // Second argument is the type to bitcast to. 27700b57cec5SDimitry Andric TypeResult DestTy = ParseTypeName(); 27710b57cec5SDimitry Andric if (DestTy.isInvalid()) 27720b57cec5SDimitry Andric return ExprError(); 27730b57cec5SDimitry Andric 27740b57cec5SDimitry Andric // Attempt to consume the r-paren. 27750b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27760b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27770b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27780b57cec5SDimitry Andric return ExprError(); 27790b57cec5SDimitry Andric } 27800b57cec5SDimitry Andric 27810b57cec5SDimitry Andric Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 27820b57cec5SDimitry Andric ConsumeParen()); 27830b57cec5SDimitry Andric break; 27840b57cec5SDimitry Andric } 27850b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 27860b57cec5SDimitry Andric case tok::kw___builtin_FILE: 2787*06c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 27880b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 2789*06c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 279081ad6265SDimitry Andric case tok::kw___builtin_LINE: 279181ad6265SDimitry Andric case tok::kw___builtin_source_location: { 27920b57cec5SDimitry Andric // Attempt to consume the r-paren. 27930b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 27940b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::r_paren; 27950b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 27960b57cec5SDimitry Andric return ExprError(); 27970b57cec5SDimitry Andric } 27980b57cec5SDimitry Andric SourceLocExpr::IdentKind Kind = [&] { 27990b57cec5SDimitry Andric switch (T) { 28000b57cec5SDimitry Andric case tok::kw___builtin_FILE: 28010b57cec5SDimitry Andric return SourceLocExpr::File; 2802*06c3fb27SDimitry Andric case tok::kw___builtin_FILE_NAME: 2803*06c3fb27SDimitry Andric return SourceLocExpr::FileName; 28040b57cec5SDimitry Andric case tok::kw___builtin_FUNCTION: 28050b57cec5SDimitry Andric return SourceLocExpr::Function; 2806*06c3fb27SDimitry Andric case tok::kw___builtin_FUNCSIG: 2807*06c3fb27SDimitry Andric return SourceLocExpr::FuncSig; 28080b57cec5SDimitry Andric case tok::kw___builtin_LINE: 28090b57cec5SDimitry Andric return SourceLocExpr::Line; 28100b57cec5SDimitry Andric case tok::kw___builtin_COLUMN: 28110b57cec5SDimitry Andric return SourceLocExpr::Column; 281281ad6265SDimitry Andric case tok::kw___builtin_source_location: 281381ad6265SDimitry Andric return SourceLocExpr::SourceLocStruct; 28140b57cec5SDimitry Andric default: 28150b57cec5SDimitry Andric llvm_unreachable("invalid keyword"); 28160b57cec5SDimitry Andric } 28170b57cec5SDimitry Andric }(); 28180b57cec5SDimitry Andric Res = Actions.ActOnSourceLocExpr(Kind, StartLoc, ConsumeParen()); 28190b57cec5SDimitry Andric break; 28200b57cec5SDimitry Andric } 28210b57cec5SDimitry Andric } 28220b57cec5SDimitry Andric 28230b57cec5SDimitry Andric if (Res.isInvalid()) 28240b57cec5SDimitry Andric return ExprError(); 28250b57cec5SDimitry Andric 28260b57cec5SDimitry Andric // These can be followed by postfix-expr pieces because they are 28270b57cec5SDimitry Andric // primary-expressions. 28280b57cec5SDimitry Andric return ParsePostfixExpressionSuffix(Res.get()); 28290b57cec5SDimitry Andric } 28300b57cec5SDimitry Andric 28315ffd83dbSDimitry Andric bool Parser::tryParseOpenMPArrayShapingCastPart() { 28325ffd83dbSDimitry Andric assert(Tok.is(tok::l_square) && "Expected open bracket"); 28335ffd83dbSDimitry Andric bool ErrorFound = true; 28345ffd83dbSDimitry Andric TentativeParsingAction TPA(*this); 28355ffd83dbSDimitry Andric do { 28365ffd83dbSDimitry Andric if (Tok.isNot(tok::l_square)) 28375ffd83dbSDimitry Andric break; 28385ffd83dbSDimitry Andric // Consume '[' 28395ffd83dbSDimitry Andric ConsumeBracket(); 28405ffd83dbSDimitry Andric // Skip inner expression. 28415ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end, 28425ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 28435ffd83dbSDimitry Andric ; 28445ffd83dbSDimitry Andric if (Tok.isNot(tok::r_square)) 28455ffd83dbSDimitry Andric break; 28465ffd83dbSDimitry Andric // Consume ']' 28475ffd83dbSDimitry Andric ConsumeBracket(); 28485ffd83dbSDimitry Andric // Found ')' - done. 28495ffd83dbSDimitry Andric if (Tok.is(tok::r_paren)) { 28505ffd83dbSDimitry Andric ErrorFound = false; 28515ffd83dbSDimitry Andric break; 28525ffd83dbSDimitry Andric } 28535ffd83dbSDimitry Andric } while (Tok.isNot(tok::annot_pragma_openmp_end)); 28545ffd83dbSDimitry Andric TPA.Revert(); 28555ffd83dbSDimitry Andric return !ErrorFound; 28565ffd83dbSDimitry Andric } 28575ffd83dbSDimitry Andric 28580b57cec5SDimitry Andric /// ParseParenExpression - This parses the unit that starts with a '(' token, 28590b57cec5SDimitry Andric /// based on what is allowed by ExprType. The actual thing parsed is returned 28600b57cec5SDimitry Andric /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 28610b57cec5SDimitry Andric /// not the parsed cast-expression. 28620b57cec5SDimitry Andric /// 28630b57cec5SDimitry Andric /// \verbatim 28640b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 28650b57cec5SDimitry Andric /// '(' expression ')' 28660b57cec5SDimitry Andric /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 28670b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 28680b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 28690b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 28700b57cec5SDimitry Andric /// cast-expression: [C99 6.5.4] 28710b57cec5SDimitry Andric /// '(' type-name ')' cast-expression 28720b57cec5SDimitry Andric /// [ARC] bridged-cast-expression 28730b57cec5SDimitry Andric /// [ARC] bridged-cast-expression: 28740b57cec5SDimitry Andric /// (__bridge type-name) cast-expression 28750b57cec5SDimitry Andric /// (__bridge_transfer type-name) cast-expression 28760b57cec5SDimitry Andric /// (__bridge_retained type-name) cast-expression 28770b57cec5SDimitry Andric /// fold-expression: [C++1z] 28780b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' ')' 28790b57cec5SDimitry Andric /// '(' '...' fold-operator cast-expression ')' 28800b57cec5SDimitry Andric /// '(' cast-expression fold-operator '...' 28810b57cec5SDimitry Andric /// fold-operator cast-expression ')' 28825ffd83dbSDimitry Andric /// [OPENMP] Array shaping operation 28835ffd83dbSDimitry Andric /// '(' '[' expression ']' { '[' expression ']' } cast-expression 28840b57cec5SDimitry Andric /// \endverbatim 28850b57cec5SDimitry Andric ExprResult 28860b57cec5SDimitry Andric Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 28870b57cec5SDimitry Andric bool isTypeCast, ParsedType &CastTy, 28880b57cec5SDimitry Andric SourceLocation &RParenLoc) { 28890b57cec5SDimitry Andric assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 28900b57cec5SDimitry Andric ColonProtectionRAIIObject ColonProtection(*this, false); 28910b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 28920b57cec5SDimitry Andric if (T.consumeOpen()) 28930b57cec5SDimitry Andric return ExprError(); 28940b57cec5SDimitry Andric SourceLocation OpenLoc = T.getOpenLocation(); 28950b57cec5SDimitry Andric 28960b57cec5SDimitry Andric PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc); 28970b57cec5SDimitry Andric 28980b57cec5SDimitry Andric ExprResult Result(true); 28990b57cec5SDimitry Andric bool isAmbiguousTypeId; 29000b57cec5SDimitry Andric CastTy = nullptr; 29010b57cec5SDimitry Andric 29020b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 2903fe6060f1SDimitry Andric cutOffParsing(); 29040b57cec5SDimitry Andric Actions.CodeCompleteExpression( 29050b57cec5SDimitry Andric getCurScope(), PreferredType.get(Tok.getLocation()), 29060b57cec5SDimitry Andric /*IsParenthesized=*/ExprType >= CompoundLiteral); 29070b57cec5SDimitry Andric return ExprError(); 29080b57cec5SDimitry Andric } 29090b57cec5SDimitry Andric 29100b57cec5SDimitry Andric // Diagnose use of bridge casts in non-arc mode. 29110b57cec5SDimitry Andric bool BridgeCast = (getLangOpts().ObjC && 29120b57cec5SDimitry Andric Tok.isOneOf(tok::kw___bridge, 29130b57cec5SDimitry Andric tok::kw___bridge_transfer, 29140b57cec5SDimitry Andric tok::kw___bridge_retained, 29150b57cec5SDimitry Andric tok::kw___bridge_retain)); 29160b57cec5SDimitry Andric if (BridgeCast && !getLangOpts().ObjCAutoRefCount) { 29170b57cec5SDimitry Andric if (!TryConsumeToken(tok::kw___bridge)) { 29180b57cec5SDimitry Andric StringRef BridgeCastName = Tok.getName(); 29190b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 29200b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 29210b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc) 29220b57cec5SDimitry Andric << BridgeCastName 29230b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, ""); 29240b57cec5SDimitry Andric } 29250b57cec5SDimitry Andric BridgeCast = false; 29260b57cec5SDimitry Andric } 29270b57cec5SDimitry Andric 29280b57cec5SDimitry Andric // None of these cases should fall through with an invalid Result 29290b57cec5SDimitry Andric // unless they've already reported an error. 29300b57cec5SDimitry Andric if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 293181ad6265SDimitry Andric Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro 293281ad6265SDimitry Andric : diag::ext_gnu_statement_expr); 29330b57cec5SDimitry Andric 2934e8d8bef9SDimitry Andric checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin); 2935e8d8bef9SDimitry Andric 29360b57cec5SDimitry Andric if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) { 29370b57cec5SDimitry Andric Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope)); 29380b57cec5SDimitry Andric } else { 29390b57cec5SDimitry Andric // Find the nearest non-record decl context. Variables declared in a 29400b57cec5SDimitry Andric // statement expression behave as if they were declared in the enclosing 29410b57cec5SDimitry Andric // function, block, or other code construct. 29420b57cec5SDimitry Andric DeclContext *CodeDC = Actions.CurContext; 29430b57cec5SDimitry Andric while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) { 29440b57cec5SDimitry Andric CodeDC = CodeDC->getParent(); 29450b57cec5SDimitry Andric assert(CodeDC && !CodeDC->isFileContext() && 29460b57cec5SDimitry Andric "statement expr not in code context"); 29470b57cec5SDimitry Andric } 29480b57cec5SDimitry Andric Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false); 29490b57cec5SDimitry Andric 29500b57cec5SDimitry Andric Actions.ActOnStartStmtExpr(); 29510b57cec5SDimitry Andric 29520b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatement(true)); 29530b57cec5SDimitry Andric ExprType = CompoundStmt; 29540b57cec5SDimitry Andric 29550b57cec5SDimitry Andric // If the substmt parsed correctly, build the AST node. 29560b57cec5SDimitry Andric if (!Stmt.isInvalid()) { 29578c27c554SDimitry Andric Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(), 29588c27c554SDimitry Andric Tok.getLocation()); 29590b57cec5SDimitry Andric } else { 29600b57cec5SDimitry Andric Actions.ActOnStmtExprError(); 29610b57cec5SDimitry Andric } 29620b57cec5SDimitry Andric } 29630b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && BridgeCast) { 29640b57cec5SDimitry Andric tok::TokenKind tokenKind = Tok.getKind(); 29650b57cec5SDimitry Andric SourceLocation BridgeKeywordLoc = ConsumeToken(); 29660b57cec5SDimitry Andric 29670b57cec5SDimitry Andric // Parse an Objective-C ARC ownership cast expression. 29680b57cec5SDimitry Andric ObjCBridgeCastKind Kind; 29690b57cec5SDimitry Andric if (tokenKind == tok::kw___bridge) 29700b57cec5SDimitry Andric Kind = OBC_Bridge; 29710b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_transfer) 29720b57cec5SDimitry Andric Kind = OBC_BridgeTransfer; 29730b57cec5SDimitry Andric else if (tokenKind == tok::kw___bridge_retained) 29740b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 29750b57cec5SDimitry Andric else { 29760b57cec5SDimitry Andric // As a hopefully temporary workaround, allow __bridge_retain as 29770b57cec5SDimitry Andric // a synonym for __bridge_retained, but only in system headers. 29780b57cec5SDimitry Andric assert(tokenKind == tok::kw___bridge_retain); 29790b57cec5SDimitry Andric Kind = OBC_BridgeRetained; 29800b57cec5SDimitry Andric if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 29810b57cec5SDimitry Andric Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain) 29820b57cec5SDimitry Andric << FixItHint::CreateReplacement(BridgeKeywordLoc, 29830b57cec5SDimitry Andric "__bridge_retained"); 29840b57cec5SDimitry Andric } 29850b57cec5SDimitry Andric 29860b57cec5SDimitry Andric TypeResult Ty = ParseTypeName(); 29870b57cec5SDimitry Andric T.consumeClose(); 29880b57cec5SDimitry Andric ColonProtection.restore(); 29890b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 29900b57cec5SDimitry Andric 29910b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); 2992480093f4SDimitry Andric ExprResult SubExpr = ParseCastExpression(AnyCastExpr); 29930b57cec5SDimitry Andric 29940b57cec5SDimitry Andric if (Ty.isInvalid() || SubExpr.isInvalid()) 29950b57cec5SDimitry Andric return ExprError(); 29960b57cec5SDimitry Andric 29970b57cec5SDimitry Andric return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, 29980b57cec5SDimitry Andric BridgeKeywordLoc, Ty.get(), 29990b57cec5SDimitry Andric RParenLoc, SubExpr.get()); 30000b57cec5SDimitry Andric } else if (ExprType >= CompoundLiteral && 30010b57cec5SDimitry Andric isTypeIdInParens(isAmbiguousTypeId)) { 30020b57cec5SDimitry Andric 30030b57cec5SDimitry Andric // Otherwise, this is a compound literal expression or cast expression. 30040b57cec5SDimitry Andric 30050b57cec5SDimitry Andric // In C++, if the type-id is ambiguous we disambiguate based on context. 30060b57cec5SDimitry Andric // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 30070b57cec5SDimitry Andric // in which case we should treat it as type-id. 30080b57cec5SDimitry Andric // if stopIfCastExpr is false, we need to determine the context past the 30090b57cec5SDimitry Andric // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 30100b57cec5SDimitry Andric if (isAmbiguousTypeId && !stopIfCastExpr) { 30110b57cec5SDimitry Andric ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T, 30120b57cec5SDimitry Andric ColonProtection); 30130b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 30140b57cec5SDimitry Andric return res; 30150b57cec5SDimitry Andric } 30160b57cec5SDimitry Andric 30170b57cec5SDimitry Andric // Parse the type declarator. 30180b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 30190b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 302081ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 302181ad6265SDimitry Andric DeclaratorContext::TypeName); 30220b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 30230b57cec5SDimitry Andric 30240b57cec5SDimitry Andric // If our type is followed by an identifier and either ':' or ']', then 30250b57cec5SDimitry Andric // this is probably an Objective-C message send where the leading '[' is 30260b57cec5SDimitry Andric // missing. Recover as if that were the case. 30270b57cec5SDimitry Andric if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && 30280b57cec5SDimitry Andric !InMessageExpression && getLangOpts().ObjC && 30290b57cec5SDimitry Andric (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 30300b57cec5SDimitry Andric TypeResult Ty; 30310b57cec5SDimitry Andric { 30320b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 30330b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 30340b57cec5SDimitry Andric } 30350b57cec5SDimitry Andric Result = ParseObjCMessageExpressionBody(SourceLocation(), 30360b57cec5SDimitry Andric SourceLocation(), 30370b57cec5SDimitry Andric Ty.get(), nullptr); 30380b57cec5SDimitry Andric } else { 30390b57cec5SDimitry Andric // Match the ')'. 30400b57cec5SDimitry Andric T.consumeClose(); 30410b57cec5SDimitry Andric ColonProtection.restore(); 30420b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 30430b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) { 30440b57cec5SDimitry Andric ExprType = CompoundLiteral; 30450b57cec5SDimitry Andric TypeResult Ty; 30460b57cec5SDimitry Andric { 30470b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 30480b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 30490b57cec5SDimitry Andric } 30500b57cec5SDimitry Andric return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 30510b57cec5SDimitry Andric } 30520b57cec5SDimitry Andric 30530b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 30540b57cec5SDimitry Andric // This could be OpenCL vector Literals 30550b57cec5SDimitry Andric if (getLangOpts().OpenCL) 30560b57cec5SDimitry Andric { 30570b57cec5SDimitry Andric TypeResult Ty; 30580b57cec5SDimitry Andric { 30590b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 30600b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 30610b57cec5SDimitry Andric } 30620b57cec5SDimitry Andric if(Ty.isInvalid()) 30630b57cec5SDimitry Andric { 30640b57cec5SDimitry Andric return ExprError(); 30650b57cec5SDimitry Andric } 30660b57cec5SDimitry Andric QualType QT = Ty.get().get().getCanonicalType(); 30670b57cec5SDimitry Andric if (QT->isVectorType()) 30680b57cec5SDimitry Andric { 30690b57cec5SDimitry Andric // We parsed '(' vector-type-name ')' followed by '(' 30700b57cec5SDimitry Andric 30710b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 30720b57cec5SDimitry Andric // isVectorLiteral = true will make sure we don't parse any 30730b57cec5SDimitry Andric // Postfix expression yet 3074480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 30750b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 30760b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast, 30770b57cec5SDimitry Andric /*isVectorLiteral=*/true); 30780b57cec5SDimitry Andric 30790b57cec5SDimitry Andric if (!Result.isInvalid()) { 30800b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 30810b57cec5SDimitry Andric DeclaratorInfo, CastTy, 30820b57cec5SDimitry Andric RParenLoc, Result.get()); 30830b57cec5SDimitry Andric } 30840b57cec5SDimitry Andric 30850b57cec5SDimitry Andric // After we performed the cast we can check for postfix-expr pieces. 30860b57cec5SDimitry Andric if (!Result.isInvalid()) { 30870b57cec5SDimitry Andric Result = ParsePostfixExpressionSuffix(Result); 30880b57cec5SDimitry Andric } 30890b57cec5SDimitry Andric 30900b57cec5SDimitry Andric return Result; 30910b57cec5SDimitry Andric } 30920b57cec5SDimitry Andric } 30930b57cec5SDimitry Andric } 30940b57cec5SDimitry Andric 30950b57cec5SDimitry Andric if (ExprType == CastExpr) { 30960b57cec5SDimitry Andric // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 30970b57cec5SDimitry Andric 30980b57cec5SDimitry Andric if (DeclaratorInfo.isInvalidType()) 30990b57cec5SDimitry Andric return ExprError(); 31000b57cec5SDimitry Andric 31010b57cec5SDimitry Andric // Note that this doesn't parse the subsequent cast-expression, it just 31020b57cec5SDimitry Andric // returns the parsed type to the callee. 31030b57cec5SDimitry Andric if (stopIfCastExpr) { 31040b57cec5SDimitry Andric TypeResult Ty; 31050b57cec5SDimitry Andric { 31060b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31070b57cec5SDimitry Andric Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 31080b57cec5SDimitry Andric } 31090b57cec5SDimitry Andric CastTy = Ty.get(); 31100b57cec5SDimitry Andric return ExprResult(); 31110b57cec5SDimitry Andric } 31120b57cec5SDimitry Andric 31130b57cec5SDimitry Andric // Reject the cast of super idiom in ObjC. 31140b57cec5SDimitry Andric if (Tok.is(tok::identifier) && getLangOpts().ObjC && 31150b57cec5SDimitry Andric Tok.getIdentifierInfo() == Ident_super && 31160b57cec5SDimitry Andric getCurScope()->isInObjcMethodScope() && 31170b57cec5SDimitry Andric GetLookAheadToken(1).isNot(tok::period)) { 31180b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_illegal_super_cast) 31190b57cec5SDimitry Andric << SourceRange(OpenLoc, RParenLoc); 31200b57cec5SDimitry Andric return ExprError(); 31210b57cec5SDimitry Andric } 31220b57cec5SDimitry Andric 31230b57cec5SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get()); 31240b57cec5SDimitry Andric // Parse the cast-expression that follows it next. 31250b57cec5SDimitry Andric // TODO: For cast expression with CastTy. 3126480093f4SDimitry Andric Result = ParseCastExpression(/*isUnaryExpression=*/AnyCastExpr, 31270b57cec5SDimitry Andric /*isAddressOfOperand=*/false, 31280b57cec5SDimitry Andric /*isTypeCast=*/IsTypeCast); 31290b57cec5SDimitry Andric if (!Result.isInvalid()) { 31300b57cec5SDimitry Andric Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 31310b57cec5SDimitry Andric DeclaratorInfo, CastTy, 31320b57cec5SDimitry Andric RParenLoc, Result.get()); 31330b57cec5SDimitry Andric } 31340b57cec5SDimitry Andric return Result; 31350b57cec5SDimitry Andric } 31360b57cec5SDimitry Andric 31370b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 31380b57cec5SDimitry Andric return ExprError(); 31390b57cec5SDimitry Andric } 31400b57cec5SDimitry Andric } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && 31410b57cec5SDimitry Andric isFoldOperator(NextToken().getKind())) { 31420b57cec5SDimitry Andric ExprType = FoldExpr; 31430b57cec5SDimitry Andric return ParseFoldExpression(ExprResult(), T); 31440b57cec5SDimitry Andric } else if (isTypeCast) { 31450b57cec5SDimitry Andric // Parse the expression-list. 31460b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31470b57cec5SDimitry Andric ExprVector ArgExprs; 31480b57cec5SDimitry Andric 3149bdd1243dSDimitry Andric if (!ParseSimpleExpressionList(ArgExprs)) { 31500b57cec5SDimitry Andric // FIXME: If we ever support comma expressions as operands to 31510b57cec5SDimitry Andric // fold-expressions, we'll need to allow multiple ArgExprs here. 31520b57cec5SDimitry Andric if (ExprType >= FoldExpr && ArgExprs.size() == 1 && 31530b57cec5SDimitry Andric isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { 31540b57cec5SDimitry Andric ExprType = FoldExpr; 31550b57cec5SDimitry Andric return ParseFoldExpression(ArgExprs[0], T); 31560b57cec5SDimitry Andric } 31570b57cec5SDimitry Andric 31580b57cec5SDimitry Andric ExprType = SimpleExpr; 31590b57cec5SDimitry Andric Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), 31600b57cec5SDimitry Andric ArgExprs); 31610b57cec5SDimitry Andric } 31625ffd83dbSDimitry Andric } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing && 31635ffd83dbSDimitry Andric ExprType == CastExpr && Tok.is(tok::l_square) && 31645ffd83dbSDimitry Andric tryParseOpenMPArrayShapingCastPart()) { 31655ffd83dbSDimitry Andric bool ErrorFound = false; 31665ffd83dbSDimitry Andric SmallVector<Expr *, 4> OMPDimensions; 31675ffd83dbSDimitry Andric SmallVector<SourceRange, 4> OMPBracketsRanges; 31685ffd83dbSDimitry Andric do { 31695ffd83dbSDimitry Andric BalancedDelimiterTracker TS(*this, tok::l_square); 31705ffd83dbSDimitry Andric TS.consumeOpen(); 31715ffd83dbSDimitry Andric ExprResult NumElements = 31725ffd83dbSDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseExpression()); 31735ffd83dbSDimitry Andric if (!NumElements.isUsable()) { 31745ffd83dbSDimitry Andric ErrorFound = true; 31755ffd83dbSDimitry Andric while (!SkipUntil(tok::r_square, tok::r_paren, 31765ffd83dbSDimitry Andric StopAtSemi | StopBeforeMatch)) 31775ffd83dbSDimitry Andric ; 31785ffd83dbSDimitry Andric } 31795ffd83dbSDimitry Andric TS.consumeClose(); 31805ffd83dbSDimitry Andric OMPDimensions.push_back(NumElements.get()); 31815ffd83dbSDimitry Andric OMPBracketsRanges.push_back(TS.getRange()); 31825ffd83dbSDimitry Andric } while (Tok.isNot(tok::r_paren)); 31835ffd83dbSDimitry Andric // Match the ')'. 31845ffd83dbSDimitry Andric T.consumeClose(); 31855ffd83dbSDimitry Andric RParenLoc = T.getCloseLocation(); 31865ffd83dbSDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 31875ffd83dbSDimitry Andric if (ErrorFound) { 31885ffd83dbSDimitry Andric Result = ExprError(); 31895ffd83dbSDimitry Andric } else if (!Result.isInvalid()) { 31905ffd83dbSDimitry Andric Result = Actions.ActOnOMPArrayShapingExpr( 31915ffd83dbSDimitry Andric Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges); 31925ffd83dbSDimitry Andric } 31935ffd83dbSDimitry Andric return Result; 31940b57cec5SDimitry Andric } else { 31950b57cec5SDimitry Andric InMessageExpressionRAIIObject InMessage(*this, false); 31960b57cec5SDimitry Andric 31970b57cec5SDimitry Andric Result = ParseExpression(MaybeTypeCast); 3198bdd1243dSDimitry Andric if (!getLangOpts().CPlusPlus && Result.isUsable()) { 31990b57cec5SDimitry Andric // Correct typos in non-C++ code earlier so that implicit-cast-like 32000b57cec5SDimitry Andric // expressions are parsed correctly. 32010b57cec5SDimitry Andric Result = Actions.CorrectDelayedTyposInExpr(Result); 32020b57cec5SDimitry Andric } 32030b57cec5SDimitry Andric 32040b57cec5SDimitry Andric if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && 32050b57cec5SDimitry Andric NextToken().is(tok::ellipsis)) { 32060b57cec5SDimitry Andric ExprType = FoldExpr; 32070b57cec5SDimitry Andric return ParseFoldExpression(Result, T); 32080b57cec5SDimitry Andric } 32090b57cec5SDimitry Andric ExprType = SimpleExpr; 32100b57cec5SDimitry Andric 32110b57cec5SDimitry Andric // Don't build a paren expression unless we actually match a ')'. 32120b57cec5SDimitry Andric if (!Result.isInvalid() && Tok.is(tok::r_paren)) 32130b57cec5SDimitry Andric Result = 32140b57cec5SDimitry Andric Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get()); 32150b57cec5SDimitry Andric } 32160b57cec5SDimitry Andric 32170b57cec5SDimitry Andric // Match the ')'. 32180b57cec5SDimitry Andric if (Result.isInvalid()) { 32190b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 32200b57cec5SDimitry Andric return ExprError(); 32210b57cec5SDimitry Andric } 32220b57cec5SDimitry Andric 32230b57cec5SDimitry Andric T.consumeClose(); 32240b57cec5SDimitry Andric RParenLoc = T.getCloseLocation(); 32250b57cec5SDimitry Andric return Result; 32260b57cec5SDimitry Andric } 32270b57cec5SDimitry Andric 32280b57cec5SDimitry Andric /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 32290b57cec5SDimitry Andric /// and we are at the left brace. 32300b57cec5SDimitry Andric /// 32310b57cec5SDimitry Andric /// \verbatim 32320b57cec5SDimitry Andric /// postfix-expression: [C99 6.5.2] 32330b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list '}' 32340b57cec5SDimitry Andric /// '(' type-name ')' '{' initializer-list ',' '}' 32350b57cec5SDimitry Andric /// \endverbatim 32360b57cec5SDimitry Andric ExprResult 32370b57cec5SDimitry Andric Parser::ParseCompoundLiteralExpression(ParsedType Ty, 32380b57cec5SDimitry Andric SourceLocation LParenLoc, 32390b57cec5SDimitry Andric SourceLocation RParenLoc) { 32400b57cec5SDimitry Andric assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 32410b57cec5SDimitry Andric if (!getLangOpts().C99) // Compound literals don't exist in C90. 32420b57cec5SDimitry Andric Diag(LParenLoc, diag::ext_c99_compound_literal); 3243e8d8bef9SDimitry Andric PreferredType.enterTypeCast(Tok.getLocation(), Ty.get()); 32440b57cec5SDimitry Andric ExprResult Result = ParseInitializer(); 32450b57cec5SDimitry Andric if (!Result.isInvalid() && Ty) 32460b57cec5SDimitry Andric return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get()); 32470b57cec5SDimitry Andric return Result; 32480b57cec5SDimitry Andric } 32490b57cec5SDimitry Andric 32500b57cec5SDimitry Andric /// ParseStringLiteralExpression - This handles the various token types that 32510b57cec5SDimitry Andric /// form string literals, and also handles string concatenation [C99 5.1.1.2, 32520b57cec5SDimitry Andric /// translation phase #6]. 32530b57cec5SDimitry Andric /// 32540b57cec5SDimitry Andric /// \verbatim 32550b57cec5SDimitry Andric /// primary-expression: [C99 6.5.1] 32560b57cec5SDimitry Andric /// string-literal 32570b57cec5SDimitry Andric /// \verbatim 32580b57cec5SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) { 3259*06c3fb27SDimitry Andric return ParseStringLiteralExpression(AllowUserDefinedLiteral, 3260*06c3fb27SDimitry Andric /*Unevaluated=*/false); 3261*06c3fb27SDimitry Andric } 3262*06c3fb27SDimitry Andric 3263*06c3fb27SDimitry Andric ExprResult Parser::ParseUnevaluatedStringLiteralExpression() { 3264*06c3fb27SDimitry Andric return ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false, 3265*06c3fb27SDimitry Andric /*Unevaluated=*/true); 3266*06c3fb27SDimitry Andric } 3267*06c3fb27SDimitry Andric 3268*06c3fb27SDimitry Andric ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral, 3269*06c3fb27SDimitry Andric bool Unevaluated) { 32700b57cec5SDimitry Andric assert(isTokenStringLiteral() && "Not a string literal!"); 32710b57cec5SDimitry Andric 32720b57cec5SDimitry Andric // String concat. Note that keywords like __func__ and __FUNCTION__ are not 32730b57cec5SDimitry Andric // considered to be strings for concatenation purposes. 32740b57cec5SDimitry Andric SmallVector<Token, 4> StringToks; 32750b57cec5SDimitry Andric 32760b57cec5SDimitry Andric do { 32770b57cec5SDimitry Andric StringToks.push_back(Tok); 32780b57cec5SDimitry Andric ConsumeStringToken(); 32790b57cec5SDimitry Andric } while (isTokenStringLiteral()); 32800b57cec5SDimitry Andric 3281*06c3fb27SDimitry Andric if (Unevaluated) { 3282*06c3fb27SDimitry Andric assert(!AllowUserDefinedLiteral && "UDL are always evaluated"); 3283*06c3fb27SDimitry Andric return Actions.ActOnUnevaluatedStringLiteral(StringToks); 3284*06c3fb27SDimitry Andric } 3285*06c3fb27SDimitry Andric 32860b57cec5SDimitry Andric // Pass the set of string tokens, ready for concatenation, to the actions. 32870b57cec5SDimitry Andric return Actions.ActOnStringLiteral(StringToks, 32880b57cec5SDimitry Andric AllowUserDefinedLiteral ? getCurScope() 32890b57cec5SDimitry Andric : nullptr); 32900b57cec5SDimitry Andric } 32910b57cec5SDimitry Andric 32920b57cec5SDimitry Andric /// ParseGenericSelectionExpression - Parse a C11 generic-selection 32930b57cec5SDimitry Andric /// [C11 6.5.1.1]. 32940b57cec5SDimitry Andric /// 32950b57cec5SDimitry Andric /// \verbatim 32960b57cec5SDimitry Andric /// generic-selection: 32970b57cec5SDimitry Andric /// _Generic ( assignment-expression , generic-assoc-list ) 32980b57cec5SDimitry Andric /// generic-assoc-list: 32990b57cec5SDimitry Andric /// generic-association 33000b57cec5SDimitry Andric /// generic-assoc-list , generic-association 33010b57cec5SDimitry Andric /// generic-association: 33020b57cec5SDimitry Andric /// type-name : assignment-expression 33030b57cec5SDimitry Andric /// default : assignment-expression 33040b57cec5SDimitry Andric /// \endverbatim 3305*06c3fb27SDimitry Andric /// 3306*06c3fb27SDimitry Andric /// As an extension, Clang also accepts: 3307*06c3fb27SDimitry Andric /// \verbatim 3308*06c3fb27SDimitry Andric /// generic-selection: 3309*06c3fb27SDimitry Andric /// _Generic ( type-name, generic-assoc-list ) 3310*06c3fb27SDimitry Andric /// \endverbatim 33110b57cec5SDimitry Andric ExprResult Parser::ParseGenericSelectionExpression() { 33120b57cec5SDimitry Andric assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected"); 33130b57cec5SDimitry Andric if (!getLangOpts().C11) 3314a7dea167SDimitry Andric Diag(Tok, diag::ext_c11_feature) << Tok.getName(); 33150b57cec5SDimitry Andric 3316a7dea167SDimitry Andric SourceLocation KeyLoc = ConsumeToken(); 33170b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 33180b57cec5SDimitry Andric if (T.expectAndConsume()) 33190b57cec5SDimitry Andric return ExprError(); 33200b57cec5SDimitry Andric 3321*06c3fb27SDimitry Andric // We either have a controlling expression or we have a controlling type, and 3322*06c3fb27SDimitry Andric // we need to figure out which it is. 3323*06c3fb27SDimitry Andric TypeResult ControllingType; 33240b57cec5SDimitry Andric ExprResult ControllingExpr; 3325*06c3fb27SDimitry Andric if (isTypeIdForGenericSelection()) { 3326*06c3fb27SDimitry Andric ControllingType = ParseTypeName(); 3327*06c3fb27SDimitry Andric if (ControllingType.isInvalid()) { 3328*06c3fb27SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 3329*06c3fb27SDimitry Andric return ExprError(); 3330*06c3fb27SDimitry Andric } 3331*06c3fb27SDimitry Andric const auto *LIT = cast<LocInfoType>(ControllingType.get().get()); 3332*06c3fb27SDimitry Andric SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 3333*06c3fb27SDimitry Andric Diag(Loc, diag::ext_generic_with_type_arg); 3334*06c3fb27SDimitry Andric } else { 33350b57cec5SDimitry Andric // C11 6.5.1.1p3 "The controlling expression of a generic selection is 33360b57cec5SDimitry Andric // not evaluated." 33370b57cec5SDimitry Andric EnterExpressionEvaluationContext Unevaluated( 33380b57cec5SDimitry Andric Actions, Sema::ExpressionEvaluationContext::Unevaluated); 33390b57cec5SDimitry Andric ControllingExpr = 33400b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 33410b57cec5SDimitry Andric if (ControllingExpr.isInvalid()) { 33420b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33430b57cec5SDimitry Andric return ExprError(); 33440b57cec5SDimitry Andric } 33450b57cec5SDimitry Andric } 33460b57cec5SDimitry Andric 33470b57cec5SDimitry Andric if (ExpectAndConsume(tok::comma)) { 33480b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33490b57cec5SDimitry Andric return ExprError(); 33500b57cec5SDimitry Andric } 33510b57cec5SDimitry Andric 33520b57cec5SDimitry Andric SourceLocation DefaultLoc; 3353bdd1243dSDimitry Andric SmallVector<ParsedType, 12> Types; 33540b57cec5SDimitry Andric ExprVector Exprs; 33550b57cec5SDimitry Andric do { 33560b57cec5SDimitry Andric ParsedType Ty; 33570b57cec5SDimitry Andric if (Tok.is(tok::kw_default)) { 33580b57cec5SDimitry Andric // C11 6.5.1.1p2 "A generic selection shall have no more than one default 33590b57cec5SDimitry Andric // generic association." 33600b57cec5SDimitry Andric if (!DefaultLoc.isInvalid()) { 33610b57cec5SDimitry Andric Diag(Tok, diag::err_duplicate_default_assoc); 33620b57cec5SDimitry Andric Diag(DefaultLoc, diag::note_previous_default_assoc); 33630b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33640b57cec5SDimitry Andric return ExprError(); 33650b57cec5SDimitry Andric } 33660b57cec5SDimitry Andric DefaultLoc = ConsumeToken(); 33670b57cec5SDimitry Andric Ty = nullptr; 33680b57cec5SDimitry Andric } else { 33690b57cec5SDimitry Andric ColonProtectionRAIIObject X(*this); 337081ad6265SDimitry Andric TypeResult TR = ParseTypeName(nullptr, DeclaratorContext::Association); 33710b57cec5SDimitry Andric if (TR.isInvalid()) { 33720b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33730b57cec5SDimitry Andric return ExprError(); 33740b57cec5SDimitry Andric } 33750b57cec5SDimitry Andric Ty = TR.get(); 33760b57cec5SDimitry Andric } 33770b57cec5SDimitry Andric Types.push_back(Ty); 33780b57cec5SDimitry Andric 33790b57cec5SDimitry Andric if (ExpectAndConsume(tok::colon)) { 33800b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33810b57cec5SDimitry Andric return ExprError(); 33820b57cec5SDimitry Andric } 33830b57cec5SDimitry Andric 33840b57cec5SDimitry Andric // FIXME: These expressions should be parsed in a potentially potentially 33850b57cec5SDimitry Andric // evaluated context. 33860b57cec5SDimitry Andric ExprResult ER( 33870b57cec5SDimitry Andric Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); 33880b57cec5SDimitry Andric if (ER.isInvalid()) { 33890b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 33900b57cec5SDimitry Andric return ExprError(); 33910b57cec5SDimitry Andric } 33920b57cec5SDimitry Andric Exprs.push_back(ER.get()); 33930b57cec5SDimitry Andric } while (TryConsumeToken(tok::comma)); 33940b57cec5SDimitry Andric 33950b57cec5SDimitry Andric T.consumeClose(); 33960b57cec5SDimitry Andric if (T.getCloseLocation().isInvalid()) 33970b57cec5SDimitry Andric return ExprError(); 33980b57cec5SDimitry Andric 3399*06c3fb27SDimitry Andric void *ExprOrTy = ControllingExpr.isUsable() 3400*06c3fb27SDimitry Andric ? ControllingExpr.get() 3401*06c3fb27SDimitry Andric : ControllingType.get().getAsOpaquePtr(); 3402*06c3fb27SDimitry Andric 3403*06c3fb27SDimitry Andric return Actions.ActOnGenericSelectionExpr( 3404*06c3fb27SDimitry Andric KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.isUsable(), 3405*06c3fb27SDimitry Andric ExprOrTy, Types, Exprs); 34060b57cec5SDimitry Andric } 34070b57cec5SDimitry Andric 34080b57cec5SDimitry Andric /// Parse A C++1z fold-expression after the opening paren and optional 34090b57cec5SDimitry Andric /// left-hand-side expression. 34100b57cec5SDimitry Andric /// 34110b57cec5SDimitry Andric /// \verbatim 34120b57cec5SDimitry Andric /// fold-expression: 34130b57cec5SDimitry Andric /// ( cast-expression fold-operator ... ) 34140b57cec5SDimitry Andric /// ( ... fold-operator cast-expression ) 34150b57cec5SDimitry Andric /// ( cast-expression fold-operator ... fold-operator cast-expression ) 34160b57cec5SDimitry Andric ExprResult Parser::ParseFoldExpression(ExprResult LHS, 34170b57cec5SDimitry Andric BalancedDelimiterTracker &T) { 34180b57cec5SDimitry Andric if (LHS.isInvalid()) { 34190b57cec5SDimitry Andric T.skipToEnd(); 34200b57cec5SDimitry Andric return true; 34210b57cec5SDimitry Andric } 34220b57cec5SDimitry Andric 34230b57cec5SDimitry Andric tok::TokenKind Kind = tok::unknown; 34240b57cec5SDimitry Andric SourceLocation FirstOpLoc; 34250b57cec5SDimitry Andric if (LHS.isUsable()) { 34260b57cec5SDimitry Andric Kind = Tok.getKind(); 34270b57cec5SDimitry Andric assert(isFoldOperator(Kind) && "missing fold-operator"); 34280b57cec5SDimitry Andric FirstOpLoc = ConsumeToken(); 34290b57cec5SDimitry Andric } 34300b57cec5SDimitry Andric 34310b57cec5SDimitry Andric assert(Tok.is(tok::ellipsis) && "not a fold-expression"); 34320b57cec5SDimitry Andric SourceLocation EllipsisLoc = ConsumeToken(); 34330b57cec5SDimitry Andric 34340b57cec5SDimitry Andric ExprResult RHS; 34350b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) { 34360b57cec5SDimitry Andric if (!isFoldOperator(Tok.getKind())) 34370b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_fold_operator); 34380b57cec5SDimitry Andric 34390b57cec5SDimitry Andric if (Kind != tok::unknown && Tok.getKind() != Kind) 34400b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_fold_operator_mismatch) 34410b57cec5SDimitry Andric << SourceRange(FirstOpLoc); 34420b57cec5SDimitry Andric Kind = Tok.getKind(); 34430b57cec5SDimitry Andric ConsumeToken(); 34440b57cec5SDimitry Andric 34450b57cec5SDimitry Andric RHS = ParseExpression(); 34460b57cec5SDimitry Andric if (RHS.isInvalid()) { 34470b57cec5SDimitry Andric T.skipToEnd(); 34480b57cec5SDimitry Andric return true; 34490b57cec5SDimitry Andric } 34500b57cec5SDimitry Andric } 34510b57cec5SDimitry Andric 34520b57cec5SDimitry Andric Diag(EllipsisLoc, getLangOpts().CPlusPlus17 34530b57cec5SDimitry Andric ? diag::warn_cxx14_compat_fold_expression 34540b57cec5SDimitry Andric : diag::ext_fold_expression); 34550b57cec5SDimitry Andric 34560b57cec5SDimitry Andric T.consumeClose(); 3457e8d8bef9SDimitry Andric return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(), 3458e8d8bef9SDimitry Andric Kind, EllipsisLoc, RHS.get(), 3459e8d8bef9SDimitry Andric T.getCloseLocation()); 34600b57cec5SDimitry Andric } 34610b57cec5SDimitry Andric 34620b57cec5SDimitry Andric /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 34630b57cec5SDimitry Andric /// 34640b57cec5SDimitry Andric /// \verbatim 34650b57cec5SDimitry Andric /// argument-expression-list: 34660b57cec5SDimitry Andric /// assignment-expression 34670b57cec5SDimitry Andric /// argument-expression-list , assignment-expression 34680b57cec5SDimitry Andric /// 34690b57cec5SDimitry Andric /// [C++] expression-list: 34700b57cec5SDimitry Andric /// [C++] assignment-expression 34710b57cec5SDimitry Andric /// [C++] expression-list , assignment-expression 34720b57cec5SDimitry Andric /// 34730b57cec5SDimitry Andric /// [C++0x] expression-list: 34740b57cec5SDimitry Andric /// [C++0x] initializer-list 34750b57cec5SDimitry Andric /// 34760b57cec5SDimitry Andric /// [C++0x] initializer-list 34770b57cec5SDimitry Andric /// [C++0x] initializer-clause ...[opt] 34780b57cec5SDimitry Andric /// [C++0x] initializer-list , initializer-clause ...[opt] 34790b57cec5SDimitry Andric /// 34800b57cec5SDimitry Andric /// [C++0x] initializer-clause: 34810b57cec5SDimitry Andric /// [C++0x] assignment-expression 34820b57cec5SDimitry Andric /// [C++0x] braced-init-list 34830b57cec5SDimitry Andric /// \endverbatim 34840b57cec5SDimitry Andric bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, 348581ad6265SDimitry Andric llvm::function_ref<void()> ExpressionStarts, 348681ad6265SDimitry Andric bool FailImmediatelyOnInvalidExpr, 348781ad6265SDimitry Andric bool EarlyTypoCorrection) { 34880b57cec5SDimitry Andric bool SawError = false; 348904eeddc0SDimitry Andric while (true) { 34900b57cec5SDimitry Andric if (ExpressionStarts) 34910b57cec5SDimitry Andric ExpressionStarts(); 34920b57cec5SDimitry Andric 34930b57cec5SDimitry Andric ExprResult Expr; 34940b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 34950b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 34960b57cec5SDimitry Andric Expr = ParseBraceInitializer(); 34970b57cec5SDimitry Andric } else 34980b57cec5SDimitry Andric Expr = ParseAssignmentExpression(); 34990b57cec5SDimitry Andric 350081ad6265SDimitry Andric if (EarlyTypoCorrection) 350181ad6265SDimitry Andric Expr = Actions.CorrectDelayedTyposInExpr(Expr); 350281ad6265SDimitry Andric 35030b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) 35040b57cec5SDimitry Andric Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); 35055ffd83dbSDimitry Andric else if (Tok.is(tok::code_completion)) { 35065ffd83dbSDimitry Andric // There's nothing to suggest in here as we parsed a full expression. 35075ffd83dbSDimitry Andric // Instead fail and propogate the error since caller might have something 35085ffd83dbSDimitry Andric // the suggest, e.g. signature help in function call. Note that this is 35095ffd83dbSDimitry Andric // performed before pushing the \p Expr, so that signature help can report 35105ffd83dbSDimitry Andric // current argument correctly. 35115ffd83dbSDimitry Andric SawError = true; 35125ffd83dbSDimitry Andric cutOffParsing(); 35135ffd83dbSDimitry Andric break; 35145ffd83dbSDimitry Andric } 35150b57cec5SDimitry Andric if (Expr.isInvalid()) { 35160b57cec5SDimitry Andric SawError = true; 351781ad6265SDimitry Andric if (FailImmediatelyOnInvalidExpr) 351881ad6265SDimitry Andric break; 351981ad6265SDimitry Andric SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); 35200b57cec5SDimitry Andric } else { 35210b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 35220b57cec5SDimitry Andric } 35230b57cec5SDimitry Andric 35240b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 35250b57cec5SDimitry Andric break; 35260b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 35270b57cec5SDimitry Andric Token Comma = Tok; 3528bdd1243dSDimitry Andric ConsumeToken(); 35290b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 35300b57cec5SDimitry Andric } 35310b57cec5SDimitry Andric if (SawError) { 35320b57cec5SDimitry Andric // Ensure typos get diagnosed when errors were encountered while parsing the 35330b57cec5SDimitry Andric // expression list. 35340b57cec5SDimitry Andric for (auto &E : Exprs) { 35350b57cec5SDimitry Andric ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); 35360b57cec5SDimitry Andric if (Expr.isUsable()) E = Expr.get(); 35370b57cec5SDimitry Andric } 35380b57cec5SDimitry Andric } 35390b57cec5SDimitry Andric return SawError; 35400b57cec5SDimitry Andric } 35410b57cec5SDimitry Andric 35420b57cec5SDimitry Andric /// ParseSimpleExpressionList - A simple comma-separated list of expressions, 35430b57cec5SDimitry Andric /// used for misc language extensions. 35440b57cec5SDimitry Andric /// 35450b57cec5SDimitry Andric /// \verbatim 35460b57cec5SDimitry Andric /// simple-expression-list: 35470b57cec5SDimitry Andric /// assignment-expression 35480b57cec5SDimitry Andric /// simple-expression-list , assignment-expression 35490b57cec5SDimitry Andric /// \endverbatim 3550bdd1243dSDimitry Andric bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) { 355104eeddc0SDimitry Andric while (true) { 35520b57cec5SDimitry Andric ExprResult Expr = ParseAssignmentExpression(); 35530b57cec5SDimitry Andric if (Expr.isInvalid()) 35540b57cec5SDimitry Andric return true; 35550b57cec5SDimitry Andric 35560b57cec5SDimitry Andric Exprs.push_back(Expr.get()); 35570b57cec5SDimitry Andric 3558bdd1243dSDimitry Andric // We might be parsing the LHS of a fold-expression. If we reached the fold 3559bdd1243dSDimitry Andric // operator, stop. 3560bdd1243dSDimitry Andric if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis)) 35610b57cec5SDimitry Andric return false; 35620b57cec5SDimitry Andric 35630b57cec5SDimitry Andric // Move to the next argument, remember where the comma was. 35640b57cec5SDimitry Andric Token Comma = Tok; 3565bdd1243dSDimitry Andric ConsumeToken(); 35660b57cec5SDimitry Andric checkPotentialAngleBracketDelimiter(Comma); 35670b57cec5SDimitry Andric } 35680b57cec5SDimitry Andric } 35690b57cec5SDimitry Andric 35700b57cec5SDimitry Andric /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 35710b57cec5SDimitry Andric /// 35720b57cec5SDimitry Andric /// \verbatim 35730b57cec5SDimitry Andric /// [clang] block-id: 35740b57cec5SDimitry Andric /// [clang] specifier-qualifier-list block-declarator 35750b57cec5SDimitry Andric /// \endverbatim 35760b57cec5SDimitry Andric void Parser::ParseBlockId(SourceLocation CaretLoc) { 35770b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 3578fe6060f1SDimitry Andric cutOffParsing(); 35790b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); 3580fe6060f1SDimitry Andric return; 35810b57cec5SDimitry Andric } 35820b57cec5SDimitry Andric 35830b57cec5SDimitry Andric // Parse the specifier-qualifier-list piece. 35840b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 35850b57cec5SDimitry Andric ParseSpecifierQualifierList(DS); 35860b57cec5SDimitry Andric 35870b57cec5SDimitry Andric // Parse the block-declarator. 358881ad6265SDimitry Andric Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), 358981ad6265SDimitry Andric DeclaratorContext::BlockLiteral); 3590e8d8bef9SDimitry Andric DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 35910b57cec5SDimitry Andric ParseDeclarator(DeclaratorInfo); 35920b57cec5SDimitry Andric 35930b57cec5SDimitry Andric MaybeParseGNUAttributes(DeclaratorInfo); 35940b57cec5SDimitry Andric 35950b57cec5SDimitry Andric // Inform sema that we are starting a block. 35960b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope()); 35970b57cec5SDimitry Andric } 35980b57cec5SDimitry Andric 35990b57cec5SDimitry Andric /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 36000b57cec5SDimitry Andric /// like ^(int x){ return x+1; } 36010b57cec5SDimitry Andric /// 36020b57cec5SDimitry Andric /// \verbatim 36030b57cec5SDimitry Andric /// block-literal: 36040b57cec5SDimitry Andric /// [clang] '^' block-args[opt] compound-statement 36050b57cec5SDimitry Andric /// [clang] '^' block-id compound-statement 36060b57cec5SDimitry Andric /// [clang] block-args: 36070b57cec5SDimitry Andric /// [clang] '(' parameter-list ')' 36080b57cec5SDimitry Andric /// \endverbatim 36090b57cec5SDimitry Andric ExprResult Parser::ParseBlockLiteralExpression() { 36100b57cec5SDimitry Andric assert(Tok.is(tok::caret) && "block literal starts with ^"); 36110b57cec5SDimitry Andric SourceLocation CaretLoc = ConsumeToken(); 36120b57cec5SDimitry Andric 36130b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 36140b57cec5SDimitry Andric "block literal parsing"); 36150b57cec5SDimitry Andric 36160b57cec5SDimitry Andric // Enter a scope to hold everything within the block. This includes the 36170b57cec5SDimitry Andric // argument decls, decls within the compound expression, etc. This also 36180b57cec5SDimitry Andric // allows determining whether a variable reference inside the block is 36190b57cec5SDimitry Andric // within or outside of the block. 36200b57cec5SDimitry Andric ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 36210b57cec5SDimitry Andric Scope::CompoundStmtScope | Scope::DeclScope); 36220b57cec5SDimitry Andric 36230b57cec5SDimitry Andric // Inform sema that we are starting a block. 36240b57cec5SDimitry Andric Actions.ActOnBlockStart(CaretLoc, getCurScope()); 36250b57cec5SDimitry Andric 36260b57cec5SDimitry Andric // Parse the return type if present. 36270b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 362881ad6265SDimitry Andric Declarator ParamInfo(DS, ParsedAttributesView::none(), 362981ad6265SDimitry Andric DeclaratorContext::BlockLiteral); 3630e8d8bef9SDimitry Andric ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 36310b57cec5SDimitry Andric // FIXME: Since the return type isn't actually parsed, it can't be used to 36320b57cec5SDimitry Andric // fill ParamInfo with an initial valid range, so do it manually. 36330b57cec5SDimitry Andric ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 36340b57cec5SDimitry Andric 36350b57cec5SDimitry Andric // If this block has arguments, parse them. There is no ambiguity here with 36360b57cec5SDimitry Andric // the expression case, because the expression case requires a parameter list. 36370b57cec5SDimitry Andric if (Tok.is(tok::l_paren)) { 36380b57cec5SDimitry Andric ParseParenDeclarator(ParamInfo); 36390b57cec5SDimitry Andric // Parse the pieces after the identifier as if we had "int(...)". 36400b57cec5SDimitry Andric // SetIdentifier sets the source range end, but in this case we're past 36410b57cec5SDimitry Andric // that location. 36420b57cec5SDimitry Andric SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 36430b57cec5SDimitry Andric ParamInfo.SetIdentifier(nullptr, CaretLoc); 36440b57cec5SDimitry Andric ParamInfo.SetRangeEnd(Tmp); 36450b57cec5SDimitry Andric if (ParamInfo.isInvalidType()) { 36460b57cec5SDimitry Andric // If there was an error parsing the arguments, they may have 36470b57cec5SDimitry Andric // tried to use ^(x+y) which requires an argument list. Just 36480b57cec5SDimitry Andric // skip the whole block literal. 36490b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 36500b57cec5SDimitry Andric return ExprError(); 36510b57cec5SDimitry Andric } 36520b57cec5SDimitry Andric 36530b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 36540b57cec5SDimitry Andric 36550b57cec5SDimitry Andric // Inform sema that we are starting a block. 36560b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 36570b57cec5SDimitry Andric } else if (!Tok.is(tok::l_brace)) { 36580b57cec5SDimitry Andric ParseBlockId(CaretLoc); 36590b57cec5SDimitry Andric } else { 36600b57cec5SDimitry Andric // Otherwise, pretend we saw (void). 36610b57cec5SDimitry Andric SourceLocation NoLoc; 36620b57cec5SDimitry Andric ParamInfo.AddTypeInfo( 36630b57cec5SDimitry Andric DeclaratorChunk::getFunction(/*HasProto=*/true, 36640b57cec5SDimitry Andric /*IsAmbiguous=*/false, 36650b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 36660b57cec5SDimitry Andric /*ArgInfo=*/nullptr, 36670b57cec5SDimitry Andric /*NumParams=*/0, 36680b57cec5SDimitry Andric /*EllipsisLoc=*/NoLoc, 36690b57cec5SDimitry Andric /*RParenLoc=*/NoLoc, 36700b57cec5SDimitry Andric /*RefQualifierIsLvalueRef=*/true, 36710b57cec5SDimitry Andric /*RefQualifierLoc=*/NoLoc, 36720b57cec5SDimitry Andric /*MutableLoc=*/NoLoc, EST_None, 36730b57cec5SDimitry Andric /*ESpecRange=*/SourceRange(), 36740b57cec5SDimitry Andric /*Exceptions=*/nullptr, 36750b57cec5SDimitry Andric /*ExceptionRanges=*/nullptr, 36760b57cec5SDimitry Andric /*NumExceptions=*/0, 36770b57cec5SDimitry Andric /*NoexceptExpr=*/nullptr, 36780b57cec5SDimitry Andric /*ExceptionSpecTokens=*/nullptr, 3679bdd1243dSDimitry Andric /*DeclsInPrototype=*/std::nullopt, 3680bdd1243dSDimitry Andric CaretLoc, CaretLoc, ParamInfo), 36810b57cec5SDimitry Andric CaretLoc); 36820b57cec5SDimitry Andric 36830b57cec5SDimitry Andric MaybeParseGNUAttributes(ParamInfo); 36840b57cec5SDimitry Andric 36850b57cec5SDimitry Andric // Inform sema that we are starting a block. 36860b57cec5SDimitry Andric Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 36870b57cec5SDimitry Andric } 36880b57cec5SDimitry Andric 36890b57cec5SDimitry Andric 36900b57cec5SDimitry Andric ExprResult Result(true); 36910b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 36920b57cec5SDimitry Andric // Saw something like: ^expr 36930b57cec5SDimitry Andric Diag(Tok, diag::err_expected_expression); 36940b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 36950b57cec5SDimitry Andric return ExprError(); 36960b57cec5SDimitry Andric } 36970b57cec5SDimitry Andric 36980b57cec5SDimitry Andric StmtResult Stmt(ParseCompoundStatementBody()); 36990b57cec5SDimitry Andric BlockScope.Exit(); 37000b57cec5SDimitry Andric if (!Stmt.isInvalid()) 37010b57cec5SDimitry Andric Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope()); 37020b57cec5SDimitry Andric else 37030b57cec5SDimitry Andric Actions.ActOnBlockError(CaretLoc, getCurScope()); 37040b57cec5SDimitry Andric return Result; 37050b57cec5SDimitry Andric } 37060b57cec5SDimitry Andric 37070b57cec5SDimitry Andric /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals. 37080b57cec5SDimitry Andric /// 37090b57cec5SDimitry Andric /// '__objc_yes' 37100b57cec5SDimitry Andric /// '__objc_no' 37110b57cec5SDimitry Andric ExprResult Parser::ParseObjCBoolLiteral() { 37120b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 37130b57cec5SDimitry Andric return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind); 37140b57cec5SDimitry Andric } 37150b57cec5SDimitry Andric 37160b57cec5SDimitry Andric /// Validate availability spec list, emitting diagnostics if necessary. Returns 37170b57cec5SDimitry Andric /// true if invalid. 37180b57cec5SDimitry Andric static bool CheckAvailabilitySpecList(Parser &P, 37190b57cec5SDimitry Andric ArrayRef<AvailabilitySpec> AvailSpecs) { 37200b57cec5SDimitry Andric llvm::SmallSet<StringRef, 4> Platforms; 37210b57cec5SDimitry Andric bool HasOtherPlatformSpec = false; 37220b57cec5SDimitry Andric bool Valid = true; 37230b57cec5SDimitry Andric for (const auto &Spec : AvailSpecs) { 37240b57cec5SDimitry Andric if (Spec.isOtherPlatformSpec()) { 37250b57cec5SDimitry Andric if (HasOtherPlatformSpec) { 37260b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_star); 37270b57cec5SDimitry Andric Valid = false; 37280b57cec5SDimitry Andric } 37290b57cec5SDimitry Andric 37300b57cec5SDimitry Andric HasOtherPlatformSpec = true; 37310b57cec5SDimitry Andric continue; 37320b57cec5SDimitry Andric } 37330b57cec5SDimitry Andric 37340b57cec5SDimitry Andric bool Inserted = Platforms.insert(Spec.getPlatform()).second; 37350b57cec5SDimitry Andric if (!Inserted) { 37360b57cec5SDimitry Andric // Rule out multiple version specs referring to the same platform. 37370b57cec5SDimitry Andric // For example, we emit an error for: 37380b57cec5SDimitry Andric // @available(macos 10.10, macos 10.11, *) 37390b57cec5SDimitry Andric StringRef Platform = Spec.getPlatform(); 37400b57cec5SDimitry Andric P.Diag(Spec.getBeginLoc(), diag::err_availability_query_repeated_platform) 37410b57cec5SDimitry Andric << Spec.getEndLoc() << Platform; 37420b57cec5SDimitry Andric Valid = false; 37430b57cec5SDimitry Andric } 37440b57cec5SDimitry Andric } 37450b57cec5SDimitry Andric 37460b57cec5SDimitry Andric if (!HasOtherPlatformSpec) { 37470b57cec5SDimitry Andric SourceLocation InsertWildcardLoc = AvailSpecs.back().getEndLoc(); 37480b57cec5SDimitry Andric P.Diag(InsertWildcardLoc, diag::err_availability_query_wildcard_required) 37490b57cec5SDimitry Andric << FixItHint::CreateInsertion(InsertWildcardLoc, ", *"); 37500b57cec5SDimitry Andric return true; 37510b57cec5SDimitry Andric } 37520b57cec5SDimitry Andric 37530b57cec5SDimitry Andric return !Valid; 37540b57cec5SDimitry Andric } 37550b57cec5SDimitry Andric 37560b57cec5SDimitry Andric /// Parse availability query specification. 37570b57cec5SDimitry Andric /// 37580b57cec5SDimitry Andric /// availability-spec: 37590b57cec5SDimitry Andric /// '*' 37600b57cec5SDimitry Andric /// identifier version-tuple 3761bdd1243dSDimitry Andric std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() { 37620b57cec5SDimitry Andric if (Tok.is(tok::star)) { 37630b57cec5SDimitry Andric return AvailabilitySpec(ConsumeToken()); 37640b57cec5SDimitry Andric } else { 37650b57cec5SDimitry Andric // Parse the platform name. 37660b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 37670b57cec5SDimitry Andric cutOffParsing(); 3768fe6060f1SDimitry Andric Actions.CodeCompleteAvailabilityPlatformName(); 3769bdd1243dSDimitry Andric return std::nullopt; 37700b57cec5SDimitry Andric } 37710b57cec5SDimitry Andric if (Tok.isNot(tok::identifier)) { 37720b57cec5SDimitry Andric Diag(Tok, diag::err_avail_query_expected_platform_name); 3773bdd1243dSDimitry Andric return std::nullopt; 37740b57cec5SDimitry Andric } 37750b57cec5SDimitry Andric 37760b57cec5SDimitry Andric IdentifierLoc *PlatformIdentifier = ParseIdentifierLoc(); 37770b57cec5SDimitry Andric SourceRange VersionRange; 37780b57cec5SDimitry Andric VersionTuple Version = ParseVersionTuple(VersionRange); 37790b57cec5SDimitry Andric 37800b57cec5SDimitry Andric if (Version.empty()) 3781bdd1243dSDimitry Andric return std::nullopt; 37820b57cec5SDimitry Andric 37830b57cec5SDimitry Andric StringRef GivenPlatform = PlatformIdentifier->Ident->getName(); 37840b57cec5SDimitry Andric StringRef Platform = 37850b57cec5SDimitry Andric AvailabilityAttr::canonicalizePlatformName(GivenPlatform); 37860b57cec5SDimitry Andric 37870b57cec5SDimitry Andric if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) { 37880b57cec5SDimitry Andric Diag(PlatformIdentifier->Loc, 37890b57cec5SDimitry Andric diag::err_avail_query_unrecognized_platform_name) 37900b57cec5SDimitry Andric << GivenPlatform; 3791bdd1243dSDimitry Andric return std::nullopt; 37920b57cec5SDimitry Andric } 37930b57cec5SDimitry Andric 37940b57cec5SDimitry Andric return AvailabilitySpec(Version, Platform, PlatformIdentifier->Loc, 37950b57cec5SDimitry Andric VersionRange.getEnd()); 37960b57cec5SDimitry Andric } 37970b57cec5SDimitry Andric } 37980b57cec5SDimitry Andric 37990b57cec5SDimitry Andric ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { 38000b57cec5SDimitry Andric assert(Tok.is(tok::kw___builtin_available) || 38010b57cec5SDimitry Andric Tok.isObjCAtKeyword(tok::objc_available)); 38020b57cec5SDimitry Andric 38030b57cec5SDimitry Andric // Eat the available or __builtin_available. 38040b57cec5SDimitry Andric ConsumeToken(); 38050b57cec5SDimitry Andric 38060b57cec5SDimitry Andric BalancedDelimiterTracker Parens(*this, tok::l_paren); 38070b57cec5SDimitry Andric if (Parens.expectAndConsume()) 38080b57cec5SDimitry Andric return ExprError(); 38090b57cec5SDimitry Andric 38100b57cec5SDimitry Andric SmallVector<AvailabilitySpec, 4> AvailSpecs; 38110b57cec5SDimitry Andric bool HasError = false; 38120b57cec5SDimitry Andric while (true) { 3813bdd1243dSDimitry Andric std::optional<AvailabilitySpec> Spec = ParseAvailabilitySpec(); 38140b57cec5SDimitry Andric if (!Spec) 38150b57cec5SDimitry Andric HasError = true; 38160b57cec5SDimitry Andric else 38170b57cec5SDimitry Andric AvailSpecs.push_back(*Spec); 38180b57cec5SDimitry Andric 38190b57cec5SDimitry Andric if (!TryConsumeToken(tok::comma)) 38200b57cec5SDimitry Andric break; 38210b57cec5SDimitry Andric } 38220b57cec5SDimitry Andric 38230b57cec5SDimitry Andric if (HasError) { 38240b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi); 38250b57cec5SDimitry Andric return ExprError(); 38260b57cec5SDimitry Andric } 38270b57cec5SDimitry Andric 38280b57cec5SDimitry Andric CheckAvailabilitySpecList(*this, AvailSpecs); 38290b57cec5SDimitry Andric 38300b57cec5SDimitry Andric if (Parens.consumeClose()) 38310b57cec5SDimitry Andric return ExprError(); 38320b57cec5SDimitry Andric 38330b57cec5SDimitry Andric return Actions.ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, 38340b57cec5SDimitry Andric Parens.getCloseLocation()); 38350b57cec5SDimitry Andric } 3836