1*f4a2713aSLionel Sambuc //===--- ParseExpr.cpp - Expression Parsing -------------------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc /// 10*f4a2713aSLionel Sambuc /// \file 11*f4a2713aSLionel Sambuc /// \brief Provides the Expression parsing implementation. 12*f4a2713aSLionel Sambuc /// 13*f4a2713aSLionel Sambuc /// Expressions in C99 basically consist of a bunch of binary operators with 14*f4a2713aSLionel Sambuc /// unary operators and other random stuff at the leaves. 15*f4a2713aSLionel Sambuc /// 16*f4a2713aSLionel Sambuc /// In the C99 grammar, these unary operators bind tightest and are represented 17*f4a2713aSLionel Sambuc /// as the 'cast-expression' production. Everything else is either a binary 18*f4a2713aSLionel Sambuc /// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are 19*f4a2713aSLionel Sambuc /// handled by ParseCastExpression, the higher level pieces are handled by 20*f4a2713aSLionel Sambuc /// ParseBinaryExpression. 21*f4a2713aSLionel Sambuc /// 22*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h" 25*f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h" 26*f4a2713aSLionel Sambuc #include "clang/Basic/PrettyStackTrace.h" 27*f4a2713aSLionel Sambuc #include "clang/Sema/DeclSpec.h" 28*f4a2713aSLionel Sambuc #include "clang/Sema/ParsedTemplate.h" 29*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h" 30*f4a2713aSLionel Sambuc #include "clang/Sema/TypoCorrection.h" 31*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h" 32*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallVector.h" 33*f4a2713aSLionel Sambuc using namespace clang; 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambuc /// \brief Simple precedence-based parser for binary/ternary operators. 36*f4a2713aSLionel Sambuc /// 37*f4a2713aSLionel Sambuc /// Note: we diverge from the C99 grammar when parsing the assignment-expression 38*f4a2713aSLionel Sambuc /// production. C99 specifies that the LHS of an assignment operator should be 39*f4a2713aSLionel Sambuc /// parsed as a unary-expression, but consistency dictates that it be a 40*f4a2713aSLionel Sambuc /// conditional-expession. In practice, the important thing here is that the 41*f4a2713aSLionel Sambuc /// LHS of an assignment has to be an l-value, which productions between 42*f4a2713aSLionel Sambuc /// unary-expression and conditional-expression don't produce. Because we want 43*f4a2713aSLionel Sambuc /// consistency, we parse the LHS as a conditional-expression, then check for 44*f4a2713aSLionel Sambuc /// l-value-ness in semantic analysis stages. 45*f4a2713aSLionel Sambuc /// 46*f4a2713aSLionel Sambuc /// \verbatim 47*f4a2713aSLionel Sambuc /// pm-expression: [C++ 5.5] 48*f4a2713aSLionel Sambuc /// cast-expression 49*f4a2713aSLionel Sambuc /// pm-expression '.*' cast-expression 50*f4a2713aSLionel Sambuc /// pm-expression '->*' cast-expression 51*f4a2713aSLionel Sambuc /// 52*f4a2713aSLionel Sambuc /// multiplicative-expression: [C99 6.5.5] 53*f4a2713aSLionel Sambuc /// Note: in C++, apply pm-expression instead of cast-expression 54*f4a2713aSLionel Sambuc /// cast-expression 55*f4a2713aSLionel Sambuc /// multiplicative-expression '*' cast-expression 56*f4a2713aSLionel Sambuc /// multiplicative-expression '/' cast-expression 57*f4a2713aSLionel Sambuc /// multiplicative-expression '%' cast-expression 58*f4a2713aSLionel Sambuc /// 59*f4a2713aSLionel Sambuc /// additive-expression: [C99 6.5.6] 60*f4a2713aSLionel Sambuc /// multiplicative-expression 61*f4a2713aSLionel Sambuc /// additive-expression '+' multiplicative-expression 62*f4a2713aSLionel Sambuc /// additive-expression '-' multiplicative-expression 63*f4a2713aSLionel Sambuc /// 64*f4a2713aSLionel Sambuc /// shift-expression: [C99 6.5.7] 65*f4a2713aSLionel Sambuc /// additive-expression 66*f4a2713aSLionel Sambuc /// shift-expression '<<' additive-expression 67*f4a2713aSLionel Sambuc /// shift-expression '>>' additive-expression 68*f4a2713aSLionel Sambuc /// 69*f4a2713aSLionel Sambuc /// relational-expression: [C99 6.5.8] 70*f4a2713aSLionel Sambuc /// shift-expression 71*f4a2713aSLionel Sambuc /// relational-expression '<' shift-expression 72*f4a2713aSLionel Sambuc /// relational-expression '>' shift-expression 73*f4a2713aSLionel Sambuc /// relational-expression '<=' shift-expression 74*f4a2713aSLionel Sambuc /// relational-expression '>=' shift-expression 75*f4a2713aSLionel Sambuc /// 76*f4a2713aSLionel Sambuc /// equality-expression: [C99 6.5.9] 77*f4a2713aSLionel Sambuc /// relational-expression 78*f4a2713aSLionel Sambuc /// equality-expression '==' relational-expression 79*f4a2713aSLionel Sambuc /// equality-expression '!=' relational-expression 80*f4a2713aSLionel Sambuc /// 81*f4a2713aSLionel Sambuc /// AND-expression: [C99 6.5.10] 82*f4a2713aSLionel Sambuc /// equality-expression 83*f4a2713aSLionel Sambuc /// AND-expression '&' equality-expression 84*f4a2713aSLionel Sambuc /// 85*f4a2713aSLionel Sambuc /// exclusive-OR-expression: [C99 6.5.11] 86*f4a2713aSLionel Sambuc /// AND-expression 87*f4a2713aSLionel Sambuc /// exclusive-OR-expression '^' AND-expression 88*f4a2713aSLionel Sambuc /// 89*f4a2713aSLionel Sambuc /// inclusive-OR-expression: [C99 6.5.12] 90*f4a2713aSLionel Sambuc /// exclusive-OR-expression 91*f4a2713aSLionel Sambuc /// inclusive-OR-expression '|' exclusive-OR-expression 92*f4a2713aSLionel Sambuc /// 93*f4a2713aSLionel Sambuc /// logical-AND-expression: [C99 6.5.13] 94*f4a2713aSLionel Sambuc /// inclusive-OR-expression 95*f4a2713aSLionel Sambuc /// logical-AND-expression '&&' inclusive-OR-expression 96*f4a2713aSLionel Sambuc /// 97*f4a2713aSLionel Sambuc /// logical-OR-expression: [C99 6.5.14] 98*f4a2713aSLionel Sambuc /// logical-AND-expression 99*f4a2713aSLionel Sambuc /// logical-OR-expression '||' logical-AND-expression 100*f4a2713aSLionel Sambuc /// 101*f4a2713aSLionel Sambuc /// conditional-expression: [C99 6.5.15] 102*f4a2713aSLionel Sambuc /// logical-OR-expression 103*f4a2713aSLionel Sambuc /// logical-OR-expression '?' expression ':' conditional-expression 104*f4a2713aSLionel Sambuc /// [GNU] logical-OR-expression '?' ':' conditional-expression 105*f4a2713aSLionel Sambuc /// [C++] the third operand is an assignment-expression 106*f4a2713aSLionel Sambuc /// 107*f4a2713aSLionel Sambuc /// assignment-expression: [C99 6.5.16] 108*f4a2713aSLionel Sambuc /// conditional-expression 109*f4a2713aSLionel Sambuc /// unary-expression assignment-operator assignment-expression 110*f4a2713aSLionel Sambuc /// [C++] throw-expression [C++ 15] 111*f4a2713aSLionel Sambuc /// 112*f4a2713aSLionel Sambuc /// assignment-operator: one of 113*f4a2713aSLionel Sambuc /// = *= /= %= += -= <<= >>= &= ^= |= 114*f4a2713aSLionel Sambuc /// 115*f4a2713aSLionel Sambuc /// expression: [C99 6.5.17] 116*f4a2713aSLionel Sambuc /// assignment-expression ...[opt] 117*f4a2713aSLionel Sambuc /// expression ',' assignment-expression ...[opt] 118*f4a2713aSLionel Sambuc /// \endverbatim 119*f4a2713aSLionel Sambuc ExprResult Parser::ParseExpression(TypeCastState isTypeCast) { 120*f4a2713aSLionel Sambuc ExprResult LHS(ParseAssignmentExpression(isTypeCast)); 121*f4a2713aSLionel Sambuc return ParseRHSOfBinaryExpression(LHS, prec::Comma); 122*f4a2713aSLionel Sambuc } 123*f4a2713aSLionel Sambuc 124*f4a2713aSLionel Sambuc /// This routine is called when the '@' is seen and consumed. 125*f4a2713aSLionel Sambuc /// Current token is an Identifier and is not a 'try'. This 126*f4a2713aSLionel Sambuc /// routine is necessary to disambiguate \@try-statement from, 127*f4a2713aSLionel Sambuc /// for example, \@encode-expression. 128*f4a2713aSLionel Sambuc /// 129*f4a2713aSLionel Sambuc ExprResult 130*f4a2713aSLionel Sambuc Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { 131*f4a2713aSLionel Sambuc ExprResult LHS(ParseObjCAtExpression(AtLoc)); 132*f4a2713aSLionel Sambuc return ParseRHSOfBinaryExpression(LHS, prec::Comma); 133*f4a2713aSLionel Sambuc } 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc /// This routine is called when a leading '__extension__' is seen and 136*f4a2713aSLionel Sambuc /// consumed. This is necessary because the token gets consumed in the 137*f4a2713aSLionel Sambuc /// process of disambiguating between an expression and a declaration. 138*f4a2713aSLionel Sambuc ExprResult 139*f4a2713aSLionel Sambuc Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { 140*f4a2713aSLionel Sambuc ExprResult LHS(true); 141*f4a2713aSLionel Sambuc { 142*f4a2713aSLionel Sambuc // Silence extension warnings in the sub-expression 143*f4a2713aSLionel Sambuc ExtensionRAIIObject O(Diags); 144*f4a2713aSLionel Sambuc 145*f4a2713aSLionel Sambuc LHS = ParseCastExpression(false); 146*f4a2713aSLionel Sambuc } 147*f4a2713aSLionel Sambuc 148*f4a2713aSLionel Sambuc if (!LHS.isInvalid()) 149*f4a2713aSLionel Sambuc LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__, 150*f4a2713aSLionel Sambuc LHS.take()); 151*f4a2713aSLionel Sambuc 152*f4a2713aSLionel Sambuc return ParseRHSOfBinaryExpression(LHS, prec::Comma); 153*f4a2713aSLionel Sambuc } 154*f4a2713aSLionel Sambuc 155*f4a2713aSLionel Sambuc /// \brief Parse an expr that doesn't include (top-level) commas. 156*f4a2713aSLionel Sambuc ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { 157*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 158*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); 159*f4a2713aSLionel Sambuc cutOffParsing(); 160*f4a2713aSLionel Sambuc return ExprError(); 161*f4a2713aSLionel Sambuc } 162*f4a2713aSLionel Sambuc 163*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_throw)) 164*f4a2713aSLionel Sambuc return ParseThrowExpression(); 165*f4a2713aSLionel Sambuc 166*f4a2713aSLionel Sambuc ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false, 167*f4a2713aSLionel Sambuc /*isAddressOfOperand=*/false, 168*f4a2713aSLionel Sambuc isTypeCast); 169*f4a2713aSLionel Sambuc return ParseRHSOfBinaryExpression(LHS, prec::Assignment); 170*f4a2713aSLionel Sambuc } 171*f4a2713aSLionel Sambuc 172*f4a2713aSLionel Sambuc /// \brief Parse an assignment expression where part of an Objective-C message 173*f4a2713aSLionel Sambuc /// send has already been parsed. 174*f4a2713aSLionel Sambuc /// 175*f4a2713aSLionel Sambuc /// In this case \p LBracLoc indicates the location of the '[' of the message 176*f4a2713aSLionel Sambuc /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating 177*f4a2713aSLionel Sambuc /// the receiver of the message. 178*f4a2713aSLionel Sambuc /// 179*f4a2713aSLionel Sambuc /// Since this handles full assignment-expression's, it handles postfix 180*f4a2713aSLionel Sambuc /// expressions and other binary operators for these expressions as well. 181*f4a2713aSLionel Sambuc ExprResult 182*f4a2713aSLionel Sambuc Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, 183*f4a2713aSLionel Sambuc SourceLocation SuperLoc, 184*f4a2713aSLionel Sambuc ParsedType ReceiverType, 185*f4a2713aSLionel Sambuc Expr *ReceiverExpr) { 186*f4a2713aSLionel Sambuc ExprResult R 187*f4a2713aSLionel Sambuc = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, 188*f4a2713aSLionel Sambuc ReceiverType, ReceiverExpr); 189*f4a2713aSLionel Sambuc R = ParsePostfixExpressionSuffix(R); 190*f4a2713aSLionel Sambuc return ParseRHSOfBinaryExpression(R, prec::Assignment); 191*f4a2713aSLionel Sambuc } 192*f4a2713aSLionel Sambuc 193*f4a2713aSLionel Sambuc 194*f4a2713aSLionel Sambuc ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) { 195*f4a2713aSLionel Sambuc // C++03 [basic.def.odr]p2: 196*f4a2713aSLionel Sambuc // An expression is potentially evaluated unless it appears where an 197*f4a2713aSLionel Sambuc // integral constant expression is required (see 5.19) [...]. 198*f4a2713aSLionel Sambuc // C++98 and C++11 have no such rule, but this is only a defect in C++98. 199*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, 200*f4a2713aSLionel Sambuc Sema::ConstantEvaluated); 201*f4a2713aSLionel Sambuc 202*f4a2713aSLionel Sambuc ExprResult LHS(ParseCastExpression(false, false, isTypeCast)); 203*f4a2713aSLionel Sambuc ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 204*f4a2713aSLionel Sambuc return Actions.ActOnConstantExpression(Res); 205*f4a2713aSLionel Sambuc } 206*f4a2713aSLionel Sambuc 207*f4a2713aSLionel Sambuc bool Parser::isNotExpressionStart() { 208*f4a2713aSLionel Sambuc tok::TokenKind K = Tok.getKind(); 209*f4a2713aSLionel Sambuc if (K == tok::l_brace || K == tok::r_brace || 210*f4a2713aSLionel Sambuc K == tok::kw_for || K == tok::kw_while || 211*f4a2713aSLionel Sambuc K == tok::kw_if || K == tok::kw_else || 212*f4a2713aSLionel Sambuc K == tok::kw_goto || K == tok::kw_try) 213*f4a2713aSLionel Sambuc return true; 214*f4a2713aSLionel Sambuc // If this is a decl-specifier, we can't be at the start of an expression. 215*f4a2713aSLionel Sambuc return isKnownToBeDeclarationSpecifier(); 216*f4a2713aSLionel Sambuc } 217*f4a2713aSLionel Sambuc 218*f4a2713aSLionel Sambuc /// \brief Parse a binary expression that starts with \p LHS and has a 219*f4a2713aSLionel Sambuc /// precedence of at least \p MinPrec. 220*f4a2713aSLionel Sambuc ExprResult 221*f4a2713aSLionel Sambuc Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { 222*f4a2713aSLionel Sambuc prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(), 223*f4a2713aSLionel Sambuc GreaterThanIsOperator, 224*f4a2713aSLionel Sambuc getLangOpts().CPlusPlus11); 225*f4a2713aSLionel Sambuc SourceLocation ColonLoc; 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel Sambuc while (1) { 228*f4a2713aSLionel Sambuc // If this token has a lower precedence than we are allowed to parse (e.g. 229*f4a2713aSLionel Sambuc // because we are called recursively, or because the token is not a binop), 230*f4a2713aSLionel Sambuc // then we are done! 231*f4a2713aSLionel Sambuc if (NextTokPrec < MinPrec) 232*f4a2713aSLionel Sambuc return LHS; 233*f4a2713aSLionel Sambuc 234*f4a2713aSLionel Sambuc // Consume the operator, saving the operator token for error reporting. 235*f4a2713aSLionel Sambuc Token OpToken = Tok; 236*f4a2713aSLionel Sambuc ConsumeToken(); 237*f4a2713aSLionel Sambuc 238*f4a2713aSLionel Sambuc // Bail out when encountering a comma followed by a token which can't 239*f4a2713aSLionel Sambuc // possibly be the start of an expression. For instance: 240*f4a2713aSLionel Sambuc // int f() { return 1, } 241*f4a2713aSLionel Sambuc // We can't do this before consuming the comma, because 242*f4a2713aSLionel Sambuc // isNotExpressionStart() looks at the token stream. 243*f4a2713aSLionel Sambuc if (OpToken.is(tok::comma) && isNotExpressionStart()) { 244*f4a2713aSLionel Sambuc PP.EnterToken(Tok); 245*f4a2713aSLionel Sambuc Tok = OpToken; 246*f4a2713aSLionel Sambuc return LHS; 247*f4a2713aSLionel Sambuc } 248*f4a2713aSLionel Sambuc 249*f4a2713aSLionel Sambuc // Special case handling for the ternary operator. 250*f4a2713aSLionel Sambuc ExprResult TernaryMiddle(true); 251*f4a2713aSLionel Sambuc if (NextTokPrec == prec::Conditional) { 252*f4a2713aSLionel Sambuc if (Tok.isNot(tok::colon)) { 253*f4a2713aSLionel Sambuc // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 254*f4a2713aSLionel Sambuc ColonProtectionRAIIObject X(*this); 255*f4a2713aSLionel Sambuc 256*f4a2713aSLionel Sambuc // Handle this production specially: 257*f4a2713aSLionel Sambuc // logical-OR-expression '?' expression ':' conditional-expression 258*f4a2713aSLionel Sambuc // In particular, the RHS of the '?' is 'expression', not 259*f4a2713aSLionel Sambuc // 'logical-OR-expression' as we might expect. 260*f4a2713aSLionel Sambuc TernaryMiddle = ParseExpression(); 261*f4a2713aSLionel Sambuc if (TernaryMiddle.isInvalid()) { 262*f4a2713aSLionel Sambuc LHS = ExprError(); 263*f4a2713aSLionel Sambuc TernaryMiddle = 0; 264*f4a2713aSLionel Sambuc } 265*f4a2713aSLionel Sambuc } else { 266*f4a2713aSLionel Sambuc // Special case handling of "X ? Y : Z" where Y is empty: 267*f4a2713aSLionel Sambuc // logical-OR-expression '?' ':' conditional-expression [GNU] 268*f4a2713aSLionel Sambuc TernaryMiddle = 0; 269*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_gnu_conditional_expr); 270*f4a2713aSLionel Sambuc } 271*f4a2713aSLionel Sambuc 272*f4a2713aSLionel Sambuc if (Tok.is(tok::colon)) { 273*f4a2713aSLionel Sambuc // Eat the colon. 274*f4a2713aSLionel Sambuc ColonLoc = ConsumeToken(); 275*f4a2713aSLionel Sambuc } else { 276*f4a2713aSLionel Sambuc // Otherwise, we're missing a ':'. Assume that this was a typo that 277*f4a2713aSLionel Sambuc // the user forgot. If we're not in a macro expansion, we can suggest 278*f4a2713aSLionel Sambuc // a fixit hint. If there were two spaces before the current token, 279*f4a2713aSLionel Sambuc // suggest inserting the colon in between them, otherwise insert ": ". 280*f4a2713aSLionel Sambuc SourceLocation FILoc = Tok.getLocation(); 281*f4a2713aSLionel Sambuc const char *FIText = ": "; 282*f4a2713aSLionel Sambuc const SourceManager &SM = PP.getSourceManager(); 283*f4a2713aSLionel Sambuc if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) { 284*f4a2713aSLionel Sambuc assert(FILoc.isFileID()); 285*f4a2713aSLionel Sambuc bool IsInvalid = false; 286*f4a2713aSLionel Sambuc const char *SourcePtr = 287*f4a2713aSLionel Sambuc SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid); 288*f4a2713aSLionel Sambuc if (!IsInvalid && *SourcePtr == ' ') { 289*f4a2713aSLionel Sambuc SourcePtr = 290*f4a2713aSLionel Sambuc SM.getCharacterData(FILoc.getLocWithOffset(-2), &IsInvalid); 291*f4a2713aSLionel Sambuc if (!IsInvalid && *SourcePtr == ' ') { 292*f4a2713aSLionel Sambuc FILoc = FILoc.getLocWithOffset(-1); 293*f4a2713aSLionel Sambuc FIText = ":"; 294*f4a2713aSLionel Sambuc } 295*f4a2713aSLionel Sambuc } 296*f4a2713aSLionel Sambuc } 297*f4a2713aSLionel Sambuc 298*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_colon) 299*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(FILoc, FIText); 300*f4a2713aSLionel Sambuc Diag(OpToken, diag::note_matching) << "?"; 301*f4a2713aSLionel Sambuc ColonLoc = Tok.getLocation(); 302*f4a2713aSLionel Sambuc } 303*f4a2713aSLionel Sambuc } 304*f4a2713aSLionel Sambuc 305*f4a2713aSLionel Sambuc // Code completion for the right-hand side of an assignment expression 306*f4a2713aSLionel Sambuc // goes through a special hook that takes the left-hand side into account. 307*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion) && NextTokPrec == prec::Assignment) { 308*f4a2713aSLionel Sambuc Actions.CodeCompleteAssignmentRHS(getCurScope(), LHS.get()); 309*f4a2713aSLionel Sambuc cutOffParsing(); 310*f4a2713aSLionel Sambuc return ExprError(); 311*f4a2713aSLionel Sambuc } 312*f4a2713aSLionel Sambuc 313*f4a2713aSLionel Sambuc // Parse another leaf here for the RHS of the operator. 314*f4a2713aSLionel Sambuc // ParseCastExpression works here because all RHS expressions in C have it 315*f4a2713aSLionel Sambuc // as a prefix, at least. However, in C++, an assignment-expression could 316*f4a2713aSLionel Sambuc // be a throw-expression, which is not a valid cast-expression. 317*f4a2713aSLionel Sambuc // Therefore we need some special-casing here. 318*f4a2713aSLionel Sambuc // Also note that the third operand of the conditional operator is 319*f4a2713aSLionel Sambuc // an assignment-expression in C++, and in C++11, we can have a 320*f4a2713aSLionel Sambuc // braced-init-list on the RHS of an assignment. For better diagnostics, 321*f4a2713aSLionel Sambuc // parse as if we were allowed braced-init-lists everywhere, and check that 322*f4a2713aSLionel Sambuc // they only appear on the RHS of assignments later. 323*f4a2713aSLionel Sambuc ExprResult RHS; 324*f4a2713aSLionel Sambuc bool RHSIsInitList = false; 325*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 326*f4a2713aSLionel Sambuc RHS = ParseBraceInitializer(); 327*f4a2713aSLionel Sambuc RHSIsInitList = true; 328*f4a2713aSLionel Sambuc } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional) 329*f4a2713aSLionel Sambuc RHS = ParseAssignmentExpression(); 330*f4a2713aSLionel Sambuc else 331*f4a2713aSLionel Sambuc RHS = ParseCastExpression(false); 332*f4a2713aSLionel Sambuc 333*f4a2713aSLionel Sambuc if (RHS.isInvalid()) 334*f4a2713aSLionel Sambuc LHS = ExprError(); 335*f4a2713aSLionel Sambuc 336*f4a2713aSLionel Sambuc // Remember the precedence of this operator and get the precedence of the 337*f4a2713aSLionel Sambuc // operator immediately to the right of the RHS. 338*f4a2713aSLionel Sambuc prec::Level ThisPrec = NextTokPrec; 339*f4a2713aSLionel Sambuc NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 340*f4a2713aSLionel Sambuc getLangOpts().CPlusPlus11); 341*f4a2713aSLionel Sambuc 342*f4a2713aSLionel Sambuc // Assignment and conditional expressions are right-associative. 343*f4a2713aSLionel Sambuc bool isRightAssoc = ThisPrec == prec::Conditional || 344*f4a2713aSLionel Sambuc ThisPrec == prec::Assignment; 345*f4a2713aSLionel Sambuc 346*f4a2713aSLionel Sambuc // Get the precedence of the operator to the right of the RHS. If it binds 347*f4a2713aSLionel Sambuc // more tightly with RHS than we do, evaluate it completely first. 348*f4a2713aSLionel Sambuc if (ThisPrec < NextTokPrec || 349*f4a2713aSLionel Sambuc (ThisPrec == NextTokPrec && isRightAssoc)) { 350*f4a2713aSLionel Sambuc if (!RHS.isInvalid() && RHSIsInitList) { 351*f4a2713aSLionel Sambuc Diag(Tok, diag::err_init_list_bin_op) 352*f4a2713aSLionel Sambuc << /*LHS*/0 << PP.getSpelling(Tok) << Actions.getExprRange(RHS.get()); 353*f4a2713aSLionel Sambuc RHS = ExprError(); 354*f4a2713aSLionel Sambuc } 355*f4a2713aSLionel Sambuc // If this is left-associative, only parse things on the RHS that bind 356*f4a2713aSLionel Sambuc // more tightly than the current operator. If it is left-associative, it 357*f4a2713aSLionel Sambuc // is okay, to bind exactly as tightly. For example, compile A=B=C=D as 358*f4a2713aSLionel Sambuc // A=(B=(C=D)), where each paren is a level of recursion here. 359*f4a2713aSLionel Sambuc // The function takes ownership of the RHS. 360*f4a2713aSLionel Sambuc RHS = ParseRHSOfBinaryExpression(RHS, 361*f4a2713aSLionel Sambuc static_cast<prec::Level>(ThisPrec + !isRightAssoc)); 362*f4a2713aSLionel Sambuc RHSIsInitList = false; 363*f4a2713aSLionel Sambuc 364*f4a2713aSLionel Sambuc if (RHS.isInvalid()) 365*f4a2713aSLionel Sambuc LHS = ExprError(); 366*f4a2713aSLionel Sambuc 367*f4a2713aSLionel Sambuc NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 368*f4a2713aSLionel Sambuc getLangOpts().CPlusPlus11); 369*f4a2713aSLionel Sambuc } 370*f4a2713aSLionel Sambuc assert(NextTokPrec <= ThisPrec && "Recursion didn't work!"); 371*f4a2713aSLionel Sambuc 372*f4a2713aSLionel Sambuc if (!RHS.isInvalid() && RHSIsInitList) { 373*f4a2713aSLionel Sambuc if (ThisPrec == prec::Assignment) { 374*f4a2713aSLionel Sambuc Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists) 375*f4a2713aSLionel Sambuc << Actions.getExprRange(RHS.get()); 376*f4a2713aSLionel Sambuc } else { 377*f4a2713aSLionel Sambuc Diag(OpToken, diag::err_init_list_bin_op) 378*f4a2713aSLionel Sambuc << /*RHS*/1 << PP.getSpelling(OpToken) 379*f4a2713aSLionel Sambuc << Actions.getExprRange(RHS.get()); 380*f4a2713aSLionel Sambuc LHS = ExprError(); 381*f4a2713aSLionel Sambuc } 382*f4a2713aSLionel Sambuc } 383*f4a2713aSLionel Sambuc 384*f4a2713aSLionel Sambuc if (!LHS.isInvalid()) { 385*f4a2713aSLionel Sambuc // Combine the LHS and RHS into the LHS (e.g. build AST). 386*f4a2713aSLionel Sambuc if (TernaryMiddle.isInvalid()) { 387*f4a2713aSLionel Sambuc // If we're using '>>' as an operator within a template 388*f4a2713aSLionel Sambuc // argument list (in C++98), suggest the addition of 389*f4a2713aSLionel Sambuc // parentheses so that the code remains well-formed in C++0x. 390*f4a2713aSLionel Sambuc if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) 391*f4a2713aSLionel Sambuc SuggestParentheses(OpToken.getLocation(), 392*f4a2713aSLionel Sambuc diag::warn_cxx11_right_shift_in_template_arg, 393*f4a2713aSLionel Sambuc SourceRange(Actions.getExprRange(LHS.get()).getBegin(), 394*f4a2713aSLionel Sambuc Actions.getExprRange(RHS.get()).getEnd())); 395*f4a2713aSLionel Sambuc 396*f4a2713aSLionel Sambuc LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), 397*f4a2713aSLionel Sambuc OpToken.getKind(), LHS.take(), RHS.take()); 398*f4a2713aSLionel Sambuc } else 399*f4a2713aSLionel Sambuc LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, 400*f4a2713aSLionel Sambuc LHS.take(), TernaryMiddle.take(), 401*f4a2713aSLionel Sambuc RHS.take()); 402*f4a2713aSLionel Sambuc } 403*f4a2713aSLionel Sambuc } 404*f4a2713aSLionel Sambuc } 405*f4a2713aSLionel Sambuc 406*f4a2713aSLionel Sambuc /// \brief Parse a cast-expression, or, if \p isUnaryExpression is true, 407*f4a2713aSLionel Sambuc /// parse a unary-expression. 408*f4a2713aSLionel Sambuc /// 409*f4a2713aSLionel Sambuc /// \p isAddressOfOperand exists because an id-expression that is the 410*f4a2713aSLionel Sambuc /// operand of address-of gets special treatment due to member pointers. 411*f4a2713aSLionel Sambuc /// 412*f4a2713aSLionel Sambuc ExprResult Parser::ParseCastExpression(bool isUnaryExpression, 413*f4a2713aSLionel Sambuc bool isAddressOfOperand, 414*f4a2713aSLionel Sambuc TypeCastState isTypeCast) { 415*f4a2713aSLionel Sambuc bool NotCastExpr; 416*f4a2713aSLionel Sambuc ExprResult Res = ParseCastExpression(isUnaryExpression, 417*f4a2713aSLionel Sambuc isAddressOfOperand, 418*f4a2713aSLionel Sambuc NotCastExpr, 419*f4a2713aSLionel Sambuc isTypeCast); 420*f4a2713aSLionel Sambuc if (NotCastExpr) 421*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_expression); 422*f4a2713aSLionel Sambuc return Res; 423*f4a2713aSLionel Sambuc } 424*f4a2713aSLionel Sambuc 425*f4a2713aSLionel Sambuc namespace { 426*f4a2713aSLionel Sambuc class CastExpressionIdValidator : public CorrectionCandidateCallback { 427*f4a2713aSLionel Sambuc public: 428*f4a2713aSLionel Sambuc CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes) 429*f4a2713aSLionel Sambuc : AllowNonTypes(AllowNonTypes) { 430*f4a2713aSLionel Sambuc WantTypeSpecifiers = AllowTypes; 431*f4a2713aSLionel Sambuc } 432*f4a2713aSLionel Sambuc 433*f4a2713aSLionel Sambuc virtual bool ValidateCandidate(const TypoCorrection &candidate) { 434*f4a2713aSLionel Sambuc NamedDecl *ND = candidate.getCorrectionDecl(); 435*f4a2713aSLionel Sambuc if (!ND) 436*f4a2713aSLionel Sambuc return candidate.isKeyword(); 437*f4a2713aSLionel Sambuc 438*f4a2713aSLionel Sambuc if (isa<TypeDecl>(ND)) 439*f4a2713aSLionel Sambuc return WantTypeSpecifiers; 440*f4a2713aSLionel Sambuc return AllowNonTypes; 441*f4a2713aSLionel Sambuc } 442*f4a2713aSLionel Sambuc 443*f4a2713aSLionel Sambuc private: 444*f4a2713aSLionel Sambuc bool AllowNonTypes; 445*f4a2713aSLionel Sambuc }; 446*f4a2713aSLionel Sambuc } 447*f4a2713aSLionel Sambuc 448*f4a2713aSLionel Sambuc /// \brief Parse a cast-expression, or, if \pisUnaryExpression is true, parse 449*f4a2713aSLionel Sambuc /// a unary-expression. 450*f4a2713aSLionel Sambuc /// 451*f4a2713aSLionel Sambuc /// \p isAddressOfOperand exists because an id-expression that is the operand 452*f4a2713aSLionel Sambuc /// of address-of gets special treatment due to member pointers. NotCastExpr 453*f4a2713aSLionel Sambuc /// is set to true if the token is not the start of a cast-expression, and no 454*f4a2713aSLionel Sambuc /// diagnostic is emitted in this case. 455*f4a2713aSLionel Sambuc /// 456*f4a2713aSLionel Sambuc /// \verbatim 457*f4a2713aSLionel Sambuc /// cast-expression: [C99 6.5.4] 458*f4a2713aSLionel Sambuc /// unary-expression 459*f4a2713aSLionel Sambuc /// '(' type-name ')' cast-expression 460*f4a2713aSLionel Sambuc /// 461*f4a2713aSLionel Sambuc /// unary-expression: [C99 6.5.3] 462*f4a2713aSLionel Sambuc /// postfix-expression 463*f4a2713aSLionel Sambuc /// '++' unary-expression 464*f4a2713aSLionel Sambuc /// '--' unary-expression 465*f4a2713aSLionel Sambuc /// unary-operator cast-expression 466*f4a2713aSLionel Sambuc /// 'sizeof' unary-expression 467*f4a2713aSLionel Sambuc /// 'sizeof' '(' type-name ')' 468*f4a2713aSLionel Sambuc /// [C++11] 'sizeof' '...' '(' identifier ')' 469*f4a2713aSLionel Sambuc /// [GNU] '__alignof' unary-expression 470*f4a2713aSLionel Sambuc /// [GNU] '__alignof' '(' type-name ')' 471*f4a2713aSLionel Sambuc /// [C11] '_Alignof' '(' type-name ')' 472*f4a2713aSLionel Sambuc /// [C++11] 'alignof' '(' type-id ')' 473*f4a2713aSLionel Sambuc /// [GNU] '&&' identifier 474*f4a2713aSLionel Sambuc /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7] 475*f4a2713aSLionel Sambuc /// [C++] new-expression 476*f4a2713aSLionel Sambuc /// [C++] delete-expression 477*f4a2713aSLionel Sambuc /// 478*f4a2713aSLionel Sambuc /// unary-operator: one of 479*f4a2713aSLionel Sambuc /// '&' '*' '+' '-' '~' '!' 480*f4a2713aSLionel Sambuc /// [GNU] '__extension__' '__real' '__imag' 481*f4a2713aSLionel Sambuc /// 482*f4a2713aSLionel Sambuc /// primary-expression: [C99 6.5.1] 483*f4a2713aSLionel Sambuc /// [C99] identifier 484*f4a2713aSLionel Sambuc /// [C++] id-expression 485*f4a2713aSLionel Sambuc /// constant 486*f4a2713aSLionel Sambuc /// string-literal 487*f4a2713aSLionel Sambuc /// [C++] boolean-literal [C++ 2.13.5] 488*f4a2713aSLionel Sambuc /// [C++11] 'nullptr' [C++11 2.14.7] 489*f4a2713aSLionel Sambuc /// [C++11] user-defined-literal 490*f4a2713aSLionel Sambuc /// '(' expression ')' 491*f4a2713aSLionel Sambuc /// [C11] generic-selection 492*f4a2713aSLionel Sambuc /// '__func__' [C99 6.4.2.2] 493*f4a2713aSLionel Sambuc /// [GNU] '__FUNCTION__' 494*f4a2713aSLionel Sambuc /// [MS] '__FUNCDNAME__' 495*f4a2713aSLionel Sambuc /// [MS] 'L__FUNCTION__' 496*f4a2713aSLionel Sambuc /// [GNU] '__PRETTY_FUNCTION__' 497*f4a2713aSLionel Sambuc /// [GNU] '(' compound-statement ')' 498*f4a2713aSLionel Sambuc /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 499*f4a2713aSLionel Sambuc /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 500*f4a2713aSLionel Sambuc /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 501*f4a2713aSLionel Sambuc /// assign-expr ')' 502*f4a2713aSLionel Sambuc /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 503*f4a2713aSLionel Sambuc /// [GNU] '__null' 504*f4a2713aSLionel Sambuc /// [OBJC] '[' objc-message-expr ']' 505*f4a2713aSLionel Sambuc /// [OBJC] '\@selector' '(' objc-selector-arg ')' 506*f4a2713aSLionel Sambuc /// [OBJC] '\@protocol' '(' identifier ')' 507*f4a2713aSLionel Sambuc /// [OBJC] '\@encode' '(' type-name ')' 508*f4a2713aSLionel Sambuc /// [OBJC] objc-string-literal 509*f4a2713aSLionel Sambuc /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 510*f4a2713aSLionel Sambuc /// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] 511*f4a2713aSLionel Sambuc /// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 512*f4a2713aSLionel Sambuc /// [C++11] typename-specifier braced-init-list [C++11 5.2.3] 513*f4a2713aSLionel Sambuc /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 514*f4a2713aSLionel Sambuc /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 515*f4a2713aSLionel Sambuc /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 516*f4a2713aSLionel Sambuc /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 517*f4a2713aSLionel Sambuc /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 518*f4a2713aSLionel Sambuc /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 519*f4a2713aSLionel Sambuc /// [C++] 'this' [C++ 9.3.2] 520*f4a2713aSLionel Sambuc /// [G++] unary-type-trait '(' type-id ')' 521*f4a2713aSLionel Sambuc /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 522*f4a2713aSLionel Sambuc /// [EMBT] array-type-trait '(' type-id ',' integer ')' 523*f4a2713aSLionel Sambuc /// [clang] '^' block-literal 524*f4a2713aSLionel Sambuc /// 525*f4a2713aSLionel Sambuc /// constant: [C99 6.4.4] 526*f4a2713aSLionel Sambuc /// integer-constant 527*f4a2713aSLionel Sambuc /// floating-constant 528*f4a2713aSLionel Sambuc /// enumeration-constant -> identifier 529*f4a2713aSLionel Sambuc /// character-constant 530*f4a2713aSLionel Sambuc /// 531*f4a2713aSLionel Sambuc /// id-expression: [C++ 5.1] 532*f4a2713aSLionel Sambuc /// unqualified-id 533*f4a2713aSLionel Sambuc /// qualified-id 534*f4a2713aSLionel Sambuc /// 535*f4a2713aSLionel Sambuc /// unqualified-id: [C++ 5.1] 536*f4a2713aSLionel Sambuc /// identifier 537*f4a2713aSLionel Sambuc /// operator-function-id 538*f4a2713aSLionel Sambuc /// conversion-function-id 539*f4a2713aSLionel Sambuc /// '~' class-name 540*f4a2713aSLionel Sambuc /// template-id 541*f4a2713aSLionel Sambuc /// 542*f4a2713aSLionel Sambuc /// new-expression: [C++ 5.3.4] 543*f4a2713aSLionel Sambuc /// '::'[opt] 'new' new-placement[opt] new-type-id 544*f4a2713aSLionel Sambuc /// new-initializer[opt] 545*f4a2713aSLionel Sambuc /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 546*f4a2713aSLionel Sambuc /// new-initializer[opt] 547*f4a2713aSLionel Sambuc /// 548*f4a2713aSLionel Sambuc /// delete-expression: [C++ 5.3.5] 549*f4a2713aSLionel Sambuc /// '::'[opt] 'delete' cast-expression 550*f4a2713aSLionel Sambuc /// '::'[opt] 'delete' '[' ']' cast-expression 551*f4a2713aSLionel Sambuc /// 552*f4a2713aSLionel Sambuc /// [GNU/Embarcadero] unary-type-trait: 553*f4a2713aSLionel Sambuc /// '__is_arithmetic' 554*f4a2713aSLionel Sambuc /// '__is_floating_point' 555*f4a2713aSLionel Sambuc /// '__is_integral' 556*f4a2713aSLionel Sambuc /// '__is_lvalue_expr' 557*f4a2713aSLionel Sambuc /// '__is_rvalue_expr' 558*f4a2713aSLionel Sambuc /// '__is_complete_type' 559*f4a2713aSLionel Sambuc /// '__is_void' 560*f4a2713aSLionel Sambuc /// '__is_array' 561*f4a2713aSLionel Sambuc /// '__is_function' 562*f4a2713aSLionel Sambuc /// '__is_reference' 563*f4a2713aSLionel Sambuc /// '__is_lvalue_reference' 564*f4a2713aSLionel Sambuc /// '__is_rvalue_reference' 565*f4a2713aSLionel Sambuc /// '__is_fundamental' 566*f4a2713aSLionel Sambuc /// '__is_object' 567*f4a2713aSLionel Sambuc /// '__is_scalar' 568*f4a2713aSLionel Sambuc /// '__is_compound' 569*f4a2713aSLionel Sambuc /// '__is_pointer' 570*f4a2713aSLionel Sambuc /// '__is_member_object_pointer' 571*f4a2713aSLionel Sambuc /// '__is_member_function_pointer' 572*f4a2713aSLionel Sambuc /// '__is_member_pointer' 573*f4a2713aSLionel Sambuc /// '__is_const' 574*f4a2713aSLionel Sambuc /// '__is_volatile' 575*f4a2713aSLionel Sambuc /// '__is_trivial' 576*f4a2713aSLionel Sambuc /// '__is_standard_layout' 577*f4a2713aSLionel Sambuc /// '__is_signed' 578*f4a2713aSLionel Sambuc /// '__is_unsigned' 579*f4a2713aSLionel Sambuc /// 580*f4a2713aSLionel Sambuc /// [GNU] unary-type-trait: 581*f4a2713aSLionel Sambuc /// '__has_nothrow_assign' 582*f4a2713aSLionel Sambuc /// '__has_nothrow_copy' 583*f4a2713aSLionel Sambuc /// '__has_nothrow_constructor' 584*f4a2713aSLionel Sambuc /// '__has_trivial_assign' [TODO] 585*f4a2713aSLionel Sambuc /// '__has_trivial_copy' [TODO] 586*f4a2713aSLionel Sambuc /// '__has_trivial_constructor' 587*f4a2713aSLionel Sambuc /// '__has_trivial_destructor' 588*f4a2713aSLionel Sambuc /// '__has_virtual_destructor' 589*f4a2713aSLionel Sambuc /// '__is_abstract' [TODO] 590*f4a2713aSLionel Sambuc /// '__is_class' 591*f4a2713aSLionel Sambuc /// '__is_empty' [TODO] 592*f4a2713aSLionel Sambuc /// '__is_enum' 593*f4a2713aSLionel Sambuc /// '__is_final' 594*f4a2713aSLionel Sambuc /// '__is_pod' 595*f4a2713aSLionel Sambuc /// '__is_polymorphic' 596*f4a2713aSLionel Sambuc /// '__is_sealed' [MS] 597*f4a2713aSLionel Sambuc /// '__is_trivial' 598*f4a2713aSLionel Sambuc /// '__is_union' 599*f4a2713aSLionel Sambuc /// 600*f4a2713aSLionel Sambuc /// [Clang] unary-type-trait: 601*f4a2713aSLionel Sambuc /// '__trivially_copyable' 602*f4a2713aSLionel Sambuc /// 603*f4a2713aSLionel Sambuc /// binary-type-trait: 604*f4a2713aSLionel Sambuc /// [GNU] '__is_base_of' 605*f4a2713aSLionel Sambuc /// [MS] '__is_convertible_to' 606*f4a2713aSLionel Sambuc /// '__is_convertible' 607*f4a2713aSLionel Sambuc /// '__is_same' 608*f4a2713aSLionel Sambuc /// 609*f4a2713aSLionel Sambuc /// [Embarcadero] array-type-trait: 610*f4a2713aSLionel Sambuc /// '__array_rank' 611*f4a2713aSLionel Sambuc /// '__array_extent' 612*f4a2713aSLionel Sambuc /// 613*f4a2713aSLionel Sambuc /// [Embarcadero] expression-trait: 614*f4a2713aSLionel Sambuc /// '__is_lvalue_expr' 615*f4a2713aSLionel Sambuc /// '__is_rvalue_expr' 616*f4a2713aSLionel Sambuc /// \endverbatim 617*f4a2713aSLionel Sambuc /// 618*f4a2713aSLionel Sambuc ExprResult Parser::ParseCastExpression(bool isUnaryExpression, 619*f4a2713aSLionel Sambuc bool isAddressOfOperand, 620*f4a2713aSLionel Sambuc bool &NotCastExpr, 621*f4a2713aSLionel Sambuc TypeCastState isTypeCast) { 622*f4a2713aSLionel Sambuc ExprResult Res; 623*f4a2713aSLionel Sambuc tok::TokenKind SavedKind = Tok.getKind(); 624*f4a2713aSLionel Sambuc NotCastExpr = false; 625*f4a2713aSLionel Sambuc 626*f4a2713aSLionel Sambuc // This handles all of cast-expression, unary-expression, postfix-expression, 627*f4a2713aSLionel Sambuc // and primary-expression. We handle them together like this for efficiency 628*f4a2713aSLionel Sambuc // and to simplify handling of an expression starting with a '(' token: which 629*f4a2713aSLionel Sambuc // may be one of a parenthesized expression, cast-expression, compound literal 630*f4a2713aSLionel Sambuc // expression, or statement expression. 631*f4a2713aSLionel Sambuc // 632*f4a2713aSLionel Sambuc // If the parsed tokens consist of a primary-expression, the cases below 633*f4a2713aSLionel Sambuc // break out of the switch; at the end we call ParsePostfixExpressionSuffix 634*f4a2713aSLionel Sambuc // to handle the postfix expression suffixes. Cases that cannot be followed 635*f4a2713aSLionel Sambuc // by postfix exprs should return without invoking 636*f4a2713aSLionel Sambuc // ParsePostfixExpressionSuffix. 637*f4a2713aSLionel Sambuc switch (SavedKind) { 638*f4a2713aSLionel Sambuc case tok::l_paren: { 639*f4a2713aSLionel Sambuc // If this expression is limited to being a unary-expression, the parent can 640*f4a2713aSLionel Sambuc // not start a cast expression. 641*f4a2713aSLionel Sambuc ParenParseOption ParenExprType = 642*f4a2713aSLionel Sambuc (isUnaryExpression && !getLangOpts().CPlusPlus)? CompoundLiteral : CastExpr; 643*f4a2713aSLionel Sambuc ParsedType CastTy; 644*f4a2713aSLionel Sambuc SourceLocation RParenLoc; 645*f4a2713aSLionel Sambuc 646*f4a2713aSLionel Sambuc { 647*f4a2713aSLionel Sambuc // The inside of the parens don't need to be a colon protected scope, and 648*f4a2713aSLionel Sambuc // isn't immediately a message send. 649*f4a2713aSLionel Sambuc ColonProtectionRAIIObject X(*this, false); 650*f4a2713aSLionel Sambuc 651*f4a2713aSLionel Sambuc Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 652*f4a2713aSLionel Sambuc isTypeCast == IsTypeCast, CastTy, RParenLoc); 653*f4a2713aSLionel Sambuc } 654*f4a2713aSLionel Sambuc 655*f4a2713aSLionel Sambuc switch (ParenExprType) { 656*f4a2713aSLionel Sambuc case SimpleExpr: break; // Nothing else to do. 657*f4a2713aSLionel Sambuc case CompoundStmt: break; // Nothing else to do. 658*f4a2713aSLionel Sambuc case CompoundLiteral: 659*f4a2713aSLionel Sambuc // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 660*f4a2713aSLionel Sambuc // postfix-expression exist, parse them now. 661*f4a2713aSLionel Sambuc break; 662*f4a2713aSLionel Sambuc case CastExpr: 663*f4a2713aSLionel Sambuc // We have parsed the cast-expression and no postfix-expr pieces are 664*f4a2713aSLionel Sambuc // following. 665*f4a2713aSLionel Sambuc return Res; 666*f4a2713aSLionel Sambuc } 667*f4a2713aSLionel Sambuc 668*f4a2713aSLionel Sambuc break; 669*f4a2713aSLionel Sambuc } 670*f4a2713aSLionel Sambuc 671*f4a2713aSLionel Sambuc // primary-expression 672*f4a2713aSLionel Sambuc case tok::numeric_constant: 673*f4a2713aSLionel Sambuc // constant: integer-constant 674*f4a2713aSLionel Sambuc // constant: floating-constant 675*f4a2713aSLionel Sambuc 676*f4a2713aSLionel Sambuc Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope()); 677*f4a2713aSLionel Sambuc ConsumeToken(); 678*f4a2713aSLionel Sambuc break; 679*f4a2713aSLionel Sambuc 680*f4a2713aSLionel Sambuc case tok::kw_true: 681*f4a2713aSLionel Sambuc case tok::kw_false: 682*f4a2713aSLionel Sambuc return ParseCXXBoolLiteral(); 683*f4a2713aSLionel Sambuc 684*f4a2713aSLionel Sambuc case tok::kw___objc_yes: 685*f4a2713aSLionel Sambuc case tok::kw___objc_no: 686*f4a2713aSLionel Sambuc return ParseObjCBoolLiteral(); 687*f4a2713aSLionel Sambuc 688*f4a2713aSLionel Sambuc case tok::kw_nullptr: 689*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_nullptr); 690*f4a2713aSLionel Sambuc return Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 691*f4a2713aSLionel Sambuc 692*f4a2713aSLionel Sambuc case tok::annot_primary_expr: 693*f4a2713aSLionel Sambuc assert(Res.get() == 0 && "Stray primary-expression annotation?"); 694*f4a2713aSLionel Sambuc Res = getExprAnnotation(Tok); 695*f4a2713aSLionel Sambuc ConsumeToken(); 696*f4a2713aSLionel Sambuc break; 697*f4a2713aSLionel Sambuc 698*f4a2713aSLionel Sambuc case tok::kw_decltype: 699*f4a2713aSLionel Sambuc // Annotate the token and tail recurse. 700*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 701*f4a2713aSLionel Sambuc return ExprError(); 702*f4a2713aSLionel Sambuc assert(Tok.isNot(tok::kw_decltype)); 703*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand); 704*f4a2713aSLionel Sambuc 705*f4a2713aSLionel Sambuc case tok::identifier: { // primary-expression: identifier 706*f4a2713aSLionel Sambuc // unqualified-id: identifier 707*f4a2713aSLionel Sambuc // constant: enumeration-constant 708*f4a2713aSLionel Sambuc // Turn a potentially qualified name into a annot_typename or 709*f4a2713aSLionel Sambuc // annot_cxxscope if it would be valid. This handles things like x::y, etc. 710*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus) { 711*f4a2713aSLionel Sambuc // Avoid the unnecessary parse-time lookup in the common case 712*f4a2713aSLionel Sambuc // where the syntax forbids a type. 713*f4a2713aSLionel Sambuc const Token &Next = NextToken(); 714*f4a2713aSLionel Sambuc 715*f4a2713aSLionel Sambuc // If this identifier was reverted from a token ID, and the next token 716*f4a2713aSLionel Sambuc // is a parenthesis, this is likely to be a use of a type trait. Check 717*f4a2713aSLionel Sambuc // those tokens. 718*f4a2713aSLionel Sambuc if (Next.is(tok::l_paren) && 719*f4a2713aSLionel Sambuc Tok.is(tok::identifier) && 720*f4a2713aSLionel Sambuc Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) { 721*f4a2713aSLionel Sambuc IdentifierInfo *II = Tok.getIdentifierInfo(); 722*f4a2713aSLionel Sambuc // Build up the mapping of revertable type traits, for future use. 723*f4a2713aSLionel Sambuc if (RevertableTypeTraits.empty()) { 724*f4a2713aSLionel Sambuc #define RTT_JOIN(X,Y) X##Y 725*f4a2713aSLionel Sambuc #define REVERTABLE_TYPE_TRAIT(Name) \ 726*f4a2713aSLionel Sambuc RevertableTypeTraits[PP.getIdentifierInfo(#Name)] \ 727*f4a2713aSLionel Sambuc = RTT_JOIN(tok::kw_,Name) 728*f4a2713aSLionel Sambuc 729*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_arithmetic); 730*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_convertible); 731*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_empty); 732*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_floating_point); 733*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_function); 734*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_fundamental); 735*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_integral); 736*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_member_function_pointer); 737*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_member_pointer); 738*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_pod); 739*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_pointer); 740*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_same); 741*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_scalar); 742*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_signed); 743*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_unsigned); 744*f4a2713aSLionel Sambuc REVERTABLE_TYPE_TRAIT(__is_void); 745*f4a2713aSLionel Sambuc #undef REVERTABLE_TYPE_TRAIT 746*f4a2713aSLionel Sambuc #undef RTT_JOIN 747*f4a2713aSLionel Sambuc } 748*f4a2713aSLionel Sambuc 749*f4a2713aSLionel Sambuc // If we find that this is in fact the name of a type trait, 750*f4a2713aSLionel Sambuc // update the token kind in place and parse again to treat it as 751*f4a2713aSLionel Sambuc // the appropriate kind of type trait. 752*f4a2713aSLionel Sambuc llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known 753*f4a2713aSLionel Sambuc = RevertableTypeTraits.find(II); 754*f4a2713aSLionel Sambuc if (Known != RevertableTypeTraits.end()) { 755*f4a2713aSLionel Sambuc Tok.setKind(Known->second); 756*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 757*f4a2713aSLionel Sambuc NotCastExpr, isTypeCast); 758*f4a2713aSLionel Sambuc } 759*f4a2713aSLionel Sambuc } 760*f4a2713aSLionel Sambuc 761*f4a2713aSLionel Sambuc if (Next.is(tok::coloncolon) || 762*f4a2713aSLionel Sambuc (!ColonIsSacred && Next.is(tok::colon)) || 763*f4a2713aSLionel Sambuc Next.is(tok::less) || 764*f4a2713aSLionel Sambuc Next.is(tok::l_paren) || 765*f4a2713aSLionel Sambuc Next.is(tok::l_brace)) { 766*f4a2713aSLionel Sambuc // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 767*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 768*f4a2713aSLionel Sambuc return ExprError(); 769*f4a2713aSLionel Sambuc if (!Tok.is(tok::identifier)) 770*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand); 771*f4a2713aSLionel Sambuc } 772*f4a2713aSLionel Sambuc } 773*f4a2713aSLionel Sambuc 774*f4a2713aSLionel Sambuc // Consume the identifier so that we can see if it is followed by a '(' or 775*f4a2713aSLionel Sambuc // '.'. 776*f4a2713aSLionel Sambuc IdentifierInfo &II = *Tok.getIdentifierInfo(); 777*f4a2713aSLionel Sambuc SourceLocation ILoc = ConsumeToken(); 778*f4a2713aSLionel Sambuc 779*f4a2713aSLionel Sambuc // Support 'Class.property' and 'super.property' notation. 780*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && Tok.is(tok::period) && 781*f4a2713aSLionel Sambuc (Actions.getTypeName(II, ILoc, getCurScope()) || 782*f4a2713aSLionel Sambuc // Allow the base to be 'super' if in an objc-method. 783*f4a2713aSLionel Sambuc (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { 784*f4a2713aSLionel Sambuc ConsumeToken(); 785*f4a2713aSLionel Sambuc 786*f4a2713aSLionel Sambuc // Allow either an identifier or the keyword 'class' (in C++). 787*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier) && 788*f4a2713aSLionel Sambuc !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { 789*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_property_name); 790*f4a2713aSLionel Sambuc return ExprError(); 791*f4a2713aSLionel Sambuc } 792*f4a2713aSLionel Sambuc IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 793*f4a2713aSLionel Sambuc SourceLocation PropertyLoc = ConsumeToken(); 794*f4a2713aSLionel Sambuc 795*f4a2713aSLionel Sambuc Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, 796*f4a2713aSLionel Sambuc ILoc, PropertyLoc); 797*f4a2713aSLionel Sambuc break; 798*f4a2713aSLionel Sambuc } 799*f4a2713aSLionel Sambuc 800*f4a2713aSLionel Sambuc // In an Objective-C method, if we have "super" followed by an identifier, 801*f4a2713aSLionel Sambuc // the token sequence is ill-formed. However, if there's a ':' or ']' after 802*f4a2713aSLionel Sambuc // that identifier, this is probably a message send with a missing open 803*f4a2713aSLionel Sambuc // bracket. Treat it as such. 804*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && &II == Ident_super && !InMessageExpression && 805*f4a2713aSLionel Sambuc getCurScope()->isInObjcMethodScope() && 806*f4a2713aSLionel Sambuc ((Tok.is(tok::identifier) && 807*f4a2713aSLionel Sambuc (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || 808*f4a2713aSLionel Sambuc Tok.is(tok::code_completion))) { 809*f4a2713aSLionel Sambuc Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, ParsedType(), 810*f4a2713aSLionel Sambuc 0); 811*f4a2713aSLionel Sambuc break; 812*f4a2713aSLionel Sambuc } 813*f4a2713aSLionel Sambuc 814*f4a2713aSLionel Sambuc // If we have an Objective-C class name followed by an identifier 815*f4a2713aSLionel Sambuc // and either ':' or ']', this is an Objective-C class message 816*f4a2713aSLionel Sambuc // send that's missing the opening '['. Recovery 817*f4a2713aSLionel Sambuc // appropriately. Also take this path if we're performing code 818*f4a2713aSLionel Sambuc // completion after an Objective-C class name. 819*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && 820*f4a2713aSLionel Sambuc ((Tok.is(tok::identifier) && !InMessageExpression) || 821*f4a2713aSLionel Sambuc Tok.is(tok::code_completion))) { 822*f4a2713aSLionel Sambuc const Token& Next = NextToken(); 823*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion) || 824*f4a2713aSLionel Sambuc Next.is(tok::colon) || Next.is(tok::r_square)) 825*f4a2713aSLionel Sambuc if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) 826*f4a2713aSLionel Sambuc if (Typ.get()->isObjCObjectOrInterfaceType()) { 827*f4a2713aSLionel Sambuc // Fake up a Declarator to use with ActOnTypeName. 828*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 829*f4a2713aSLionel Sambuc DS.SetRangeStart(ILoc); 830*f4a2713aSLionel Sambuc DS.SetRangeEnd(ILoc); 831*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 832*f4a2713aSLionel Sambuc unsigned DiagID; 833*f4a2713aSLionel Sambuc DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ); 834*f4a2713aSLionel Sambuc 835*f4a2713aSLionel Sambuc Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 836*f4a2713aSLionel Sambuc TypeResult Ty = Actions.ActOnTypeName(getCurScope(), 837*f4a2713aSLionel Sambuc DeclaratorInfo); 838*f4a2713aSLionel Sambuc if (Ty.isInvalid()) 839*f4a2713aSLionel Sambuc break; 840*f4a2713aSLionel Sambuc 841*f4a2713aSLionel Sambuc Res = ParseObjCMessageExpressionBody(SourceLocation(), 842*f4a2713aSLionel Sambuc SourceLocation(), 843*f4a2713aSLionel Sambuc Ty.get(), 0); 844*f4a2713aSLionel Sambuc break; 845*f4a2713aSLionel Sambuc } 846*f4a2713aSLionel Sambuc } 847*f4a2713aSLionel Sambuc 848*f4a2713aSLionel Sambuc // Make sure to pass down the right value for isAddressOfOperand. 849*f4a2713aSLionel Sambuc if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 850*f4a2713aSLionel Sambuc isAddressOfOperand = false; 851*f4a2713aSLionel Sambuc 852*f4a2713aSLionel Sambuc // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 853*f4a2713aSLionel Sambuc // need to know whether or not this identifier is a function designator or 854*f4a2713aSLionel Sambuc // not. 855*f4a2713aSLionel Sambuc UnqualifiedId Name; 856*f4a2713aSLionel Sambuc CXXScopeSpec ScopeSpec; 857*f4a2713aSLionel Sambuc SourceLocation TemplateKWLoc; 858*f4a2713aSLionel Sambuc CastExpressionIdValidator Validator(isTypeCast != NotTypeCast, 859*f4a2713aSLionel Sambuc isTypeCast != IsTypeCast); 860*f4a2713aSLionel Sambuc Name.setIdentifier(&II, ILoc); 861*f4a2713aSLionel Sambuc Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, 862*f4a2713aSLionel Sambuc Name, Tok.is(tok::l_paren), 863*f4a2713aSLionel Sambuc isAddressOfOperand, &Validator); 864*f4a2713aSLionel Sambuc break; 865*f4a2713aSLionel Sambuc } 866*f4a2713aSLionel Sambuc case tok::char_constant: // constant: character-constant 867*f4a2713aSLionel Sambuc case tok::wide_char_constant: 868*f4a2713aSLionel Sambuc case tok::utf16_char_constant: 869*f4a2713aSLionel Sambuc case tok::utf32_char_constant: 870*f4a2713aSLionel Sambuc Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope()); 871*f4a2713aSLionel Sambuc ConsumeToken(); 872*f4a2713aSLionel Sambuc break; 873*f4a2713aSLionel Sambuc case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 874*f4a2713aSLionel Sambuc case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 875*f4a2713aSLionel Sambuc case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] 876*f4a2713aSLionel Sambuc case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] 877*f4a2713aSLionel Sambuc case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 878*f4a2713aSLionel Sambuc Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 879*f4a2713aSLionel Sambuc ConsumeToken(); 880*f4a2713aSLionel Sambuc break; 881*f4a2713aSLionel Sambuc case tok::string_literal: // primary-expression: string-literal 882*f4a2713aSLionel Sambuc case tok::wide_string_literal: 883*f4a2713aSLionel Sambuc case tok::utf8_string_literal: 884*f4a2713aSLionel Sambuc case tok::utf16_string_literal: 885*f4a2713aSLionel Sambuc case tok::utf32_string_literal: 886*f4a2713aSLionel Sambuc Res = ParseStringLiteralExpression(true); 887*f4a2713aSLionel Sambuc break; 888*f4a2713aSLionel Sambuc case tok::kw__Generic: // primary-expression: generic-selection [C11 6.5.1] 889*f4a2713aSLionel Sambuc Res = ParseGenericSelectionExpression(); 890*f4a2713aSLionel Sambuc break; 891*f4a2713aSLionel Sambuc case tok::kw___builtin_va_arg: 892*f4a2713aSLionel Sambuc case tok::kw___builtin_offsetof: 893*f4a2713aSLionel Sambuc case tok::kw___builtin_choose_expr: 894*f4a2713aSLionel Sambuc case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() 895*f4a2713aSLionel Sambuc case tok::kw___builtin_convertvector: 896*f4a2713aSLionel Sambuc return ParseBuiltinPrimaryExpression(); 897*f4a2713aSLionel Sambuc case tok::kw___null: 898*f4a2713aSLionel Sambuc return Actions.ActOnGNUNullExpr(ConsumeToken()); 899*f4a2713aSLionel Sambuc 900*f4a2713aSLionel Sambuc case tok::plusplus: // unary-expression: '++' unary-expression [C99] 901*f4a2713aSLionel Sambuc case tok::minusminus: { // unary-expression: '--' unary-expression [C99] 902*f4a2713aSLionel Sambuc // C++ [expr.unary] has: 903*f4a2713aSLionel Sambuc // unary-expression: 904*f4a2713aSLionel Sambuc // ++ cast-expression 905*f4a2713aSLionel Sambuc // -- cast-expression 906*f4a2713aSLionel Sambuc SourceLocation SavedLoc = ConsumeToken(); 907*f4a2713aSLionel Sambuc Res = ParseCastExpression(!getLangOpts().CPlusPlus); 908*f4a2713aSLionel Sambuc if (!Res.isInvalid()) 909*f4a2713aSLionel Sambuc Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 910*f4a2713aSLionel Sambuc return Res; 911*f4a2713aSLionel Sambuc } 912*f4a2713aSLionel Sambuc case tok::amp: { // unary-expression: '&' cast-expression 913*f4a2713aSLionel Sambuc // Special treatment because of member pointers 914*f4a2713aSLionel Sambuc SourceLocation SavedLoc = ConsumeToken(); 915*f4a2713aSLionel Sambuc Res = ParseCastExpression(false, true); 916*f4a2713aSLionel Sambuc if (!Res.isInvalid()) 917*f4a2713aSLionel Sambuc Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 918*f4a2713aSLionel Sambuc return Res; 919*f4a2713aSLionel Sambuc } 920*f4a2713aSLionel Sambuc 921*f4a2713aSLionel Sambuc case tok::star: // unary-expression: '*' cast-expression 922*f4a2713aSLionel Sambuc case tok::plus: // unary-expression: '+' cast-expression 923*f4a2713aSLionel Sambuc case tok::minus: // unary-expression: '-' cast-expression 924*f4a2713aSLionel Sambuc case tok::tilde: // unary-expression: '~' cast-expression 925*f4a2713aSLionel Sambuc case tok::exclaim: // unary-expression: '!' cast-expression 926*f4a2713aSLionel Sambuc case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 927*f4a2713aSLionel Sambuc case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 928*f4a2713aSLionel Sambuc SourceLocation SavedLoc = ConsumeToken(); 929*f4a2713aSLionel Sambuc Res = ParseCastExpression(false); 930*f4a2713aSLionel Sambuc if (!Res.isInvalid()) 931*f4a2713aSLionel Sambuc Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 932*f4a2713aSLionel Sambuc return Res; 933*f4a2713aSLionel Sambuc } 934*f4a2713aSLionel Sambuc 935*f4a2713aSLionel Sambuc case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 936*f4a2713aSLionel Sambuc // __extension__ silences extension warnings in the subexpression. 937*f4a2713aSLionel Sambuc ExtensionRAIIObject O(Diags); // Use RAII to do this. 938*f4a2713aSLionel Sambuc SourceLocation SavedLoc = ConsumeToken(); 939*f4a2713aSLionel Sambuc Res = ParseCastExpression(false); 940*f4a2713aSLionel Sambuc if (!Res.isInvalid()) 941*f4a2713aSLionel Sambuc Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); 942*f4a2713aSLionel Sambuc return Res; 943*f4a2713aSLionel Sambuc } 944*f4a2713aSLionel Sambuc case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' 945*f4a2713aSLionel Sambuc if (!getLangOpts().C11) 946*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_c11_alignment) << Tok.getName(); 947*f4a2713aSLionel Sambuc // fallthrough 948*f4a2713aSLionel Sambuc case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' 949*f4a2713aSLionel Sambuc case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 950*f4a2713aSLionel Sambuc // unary-expression: '__alignof' '(' type-name ')' 951*f4a2713aSLionel Sambuc case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 952*f4a2713aSLionel Sambuc // unary-expression: 'sizeof' '(' type-name ')' 953*f4a2713aSLionel Sambuc case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression 954*f4a2713aSLionel Sambuc return ParseUnaryExprOrTypeTraitExpression(); 955*f4a2713aSLionel Sambuc case tok::ampamp: { // unary-expression: '&&' identifier 956*f4a2713aSLionel Sambuc SourceLocation AmpAmpLoc = ConsumeToken(); 957*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) 958*f4a2713aSLionel Sambuc return ExprError(Diag(Tok, diag::err_expected_ident)); 959*f4a2713aSLionel Sambuc 960*f4a2713aSLionel Sambuc if (getCurScope()->getFnParent() == 0) 961*f4a2713aSLionel Sambuc return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); 962*f4a2713aSLionel Sambuc 963*f4a2713aSLionel Sambuc Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 964*f4a2713aSLionel Sambuc LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), 965*f4a2713aSLionel Sambuc Tok.getLocation()); 966*f4a2713aSLionel Sambuc Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); 967*f4a2713aSLionel Sambuc ConsumeToken(); 968*f4a2713aSLionel Sambuc return Res; 969*f4a2713aSLionel Sambuc } 970*f4a2713aSLionel Sambuc case tok::kw_const_cast: 971*f4a2713aSLionel Sambuc case tok::kw_dynamic_cast: 972*f4a2713aSLionel Sambuc case tok::kw_reinterpret_cast: 973*f4a2713aSLionel Sambuc case tok::kw_static_cast: 974*f4a2713aSLionel Sambuc Res = ParseCXXCasts(); 975*f4a2713aSLionel Sambuc break; 976*f4a2713aSLionel Sambuc case tok::kw_typeid: 977*f4a2713aSLionel Sambuc Res = ParseCXXTypeid(); 978*f4a2713aSLionel Sambuc break; 979*f4a2713aSLionel Sambuc case tok::kw___uuidof: 980*f4a2713aSLionel Sambuc Res = ParseCXXUuidof(); 981*f4a2713aSLionel Sambuc break; 982*f4a2713aSLionel Sambuc case tok::kw_this: 983*f4a2713aSLionel Sambuc Res = ParseCXXThis(); 984*f4a2713aSLionel Sambuc break; 985*f4a2713aSLionel Sambuc 986*f4a2713aSLionel Sambuc case tok::annot_typename: 987*f4a2713aSLionel Sambuc if (isStartOfObjCClassMessageMissingOpenBracket()) { 988*f4a2713aSLionel Sambuc ParsedType Type = getTypeAnnotation(Tok); 989*f4a2713aSLionel Sambuc 990*f4a2713aSLionel Sambuc // Fake up a Declarator to use with ActOnTypeName. 991*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 992*f4a2713aSLionel Sambuc DS.SetRangeStart(Tok.getLocation()); 993*f4a2713aSLionel Sambuc DS.SetRangeEnd(Tok.getLastLoc()); 994*f4a2713aSLionel Sambuc 995*f4a2713aSLionel Sambuc const char *PrevSpec = 0; 996*f4a2713aSLionel Sambuc unsigned DiagID; 997*f4a2713aSLionel Sambuc DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(), 998*f4a2713aSLionel Sambuc PrevSpec, DiagID, Type); 999*f4a2713aSLionel Sambuc 1000*f4a2713aSLionel Sambuc Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1001*f4a2713aSLionel Sambuc TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 1002*f4a2713aSLionel Sambuc if (Ty.isInvalid()) 1003*f4a2713aSLionel Sambuc break; 1004*f4a2713aSLionel Sambuc 1005*f4a2713aSLionel Sambuc ConsumeToken(); 1006*f4a2713aSLionel Sambuc Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 1007*f4a2713aSLionel Sambuc Ty.get(), 0); 1008*f4a2713aSLionel Sambuc break; 1009*f4a2713aSLionel Sambuc } 1010*f4a2713aSLionel Sambuc // Fall through 1011*f4a2713aSLionel Sambuc 1012*f4a2713aSLionel Sambuc case tok::annot_decltype: 1013*f4a2713aSLionel Sambuc case tok::kw_char: 1014*f4a2713aSLionel Sambuc case tok::kw_wchar_t: 1015*f4a2713aSLionel Sambuc case tok::kw_char16_t: 1016*f4a2713aSLionel Sambuc case tok::kw_char32_t: 1017*f4a2713aSLionel Sambuc case tok::kw_bool: 1018*f4a2713aSLionel Sambuc case tok::kw_short: 1019*f4a2713aSLionel Sambuc case tok::kw_int: 1020*f4a2713aSLionel Sambuc case tok::kw_long: 1021*f4a2713aSLionel Sambuc case tok::kw___int64: 1022*f4a2713aSLionel Sambuc case tok::kw___int128: 1023*f4a2713aSLionel Sambuc case tok::kw_signed: 1024*f4a2713aSLionel Sambuc case tok::kw_unsigned: 1025*f4a2713aSLionel Sambuc case tok::kw_half: 1026*f4a2713aSLionel Sambuc case tok::kw_float: 1027*f4a2713aSLionel Sambuc case tok::kw_double: 1028*f4a2713aSLionel Sambuc case tok::kw_void: 1029*f4a2713aSLionel Sambuc case tok::kw_typename: 1030*f4a2713aSLionel Sambuc case tok::kw_typeof: 1031*f4a2713aSLionel Sambuc case tok::kw___vector: 1032*f4a2713aSLionel Sambuc case tok::kw_image1d_t: 1033*f4a2713aSLionel Sambuc case tok::kw_image1d_array_t: 1034*f4a2713aSLionel Sambuc case tok::kw_image1d_buffer_t: 1035*f4a2713aSLionel Sambuc case tok::kw_image2d_t: 1036*f4a2713aSLionel Sambuc case tok::kw_image2d_array_t: 1037*f4a2713aSLionel Sambuc case tok::kw_image3d_t: 1038*f4a2713aSLionel Sambuc case tok::kw_sampler_t: 1039*f4a2713aSLionel Sambuc case tok::kw_event_t: { 1040*f4a2713aSLionel Sambuc if (!getLangOpts().CPlusPlus) { 1041*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_expression); 1042*f4a2713aSLionel Sambuc return ExprError(); 1043*f4a2713aSLionel Sambuc } 1044*f4a2713aSLionel Sambuc 1045*f4a2713aSLionel Sambuc if (SavedKind == tok::kw_typename) { 1046*f4a2713aSLionel Sambuc // postfix-expression: typename-specifier '(' expression-list[opt] ')' 1047*f4a2713aSLionel Sambuc // typename-specifier braced-init-list 1048*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 1049*f4a2713aSLionel Sambuc return ExprError(); 1050*f4a2713aSLionel Sambuc 1051*f4a2713aSLionel Sambuc if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) 1052*f4a2713aSLionel Sambuc // We are trying to parse a simple-type-specifier but might not get such 1053*f4a2713aSLionel Sambuc // a token after error recovery. 1054*f4a2713aSLionel Sambuc return ExprError(); 1055*f4a2713aSLionel Sambuc } 1056*f4a2713aSLionel Sambuc 1057*f4a2713aSLionel Sambuc // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 1058*f4a2713aSLionel Sambuc // simple-type-specifier braced-init-list 1059*f4a2713aSLionel Sambuc // 1060*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 1061*f4a2713aSLionel Sambuc 1062*f4a2713aSLionel Sambuc ParseCXXSimpleTypeSpecifier(DS); 1063*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren) && 1064*f4a2713aSLionel Sambuc (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) 1065*f4a2713aSLionel Sambuc return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 1066*f4a2713aSLionel Sambuc << DS.getSourceRange()); 1067*f4a2713aSLionel Sambuc 1068*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace)) 1069*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1070*f4a2713aSLionel Sambuc 1071*f4a2713aSLionel Sambuc Res = ParseCXXTypeConstructExpression(DS); 1072*f4a2713aSLionel Sambuc break; 1073*f4a2713aSLionel Sambuc } 1074*f4a2713aSLionel Sambuc 1075*f4a2713aSLionel Sambuc case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 1076*f4a2713aSLionel Sambuc // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 1077*f4a2713aSLionel Sambuc // (We can end up in this situation after tentative parsing.) 1078*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 1079*f4a2713aSLionel Sambuc return ExprError(); 1080*f4a2713aSLionel Sambuc if (!Tok.is(tok::annot_cxxscope)) 1081*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 1082*f4a2713aSLionel Sambuc NotCastExpr, isTypeCast); 1083*f4a2713aSLionel Sambuc 1084*f4a2713aSLionel Sambuc Token Next = NextToken(); 1085*f4a2713aSLionel Sambuc if (Next.is(tok::annot_template_id)) { 1086*f4a2713aSLionel Sambuc TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); 1087*f4a2713aSLionel Sambuc if (TemplateId->Kind == TNK_Type_template) { 1088*f4a2713aSLionel Sambuc // We have a qualified template-id that we know refers to a 1089*f4a2713aSLionel Sambuc // type, translate it into a type and continue parsing as a 1090*f4a2713aSLionel Sambuc // cast expression. 1091*f4a2713aSLionel Sambuc CXXScopeSpec SS; 1092*f4a2713aSLionel Sambuc ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 1093*f4a2713aSLionel Sambuc /*EnteringContext=*/false); 1094*f4a2713aSLionel Sambuc AnnotateTemplateIdTokenAsType(); 1095*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 1096*f4a2713aSLionel Sambuc NotCastExpr, isTypeCast); 1097*f4a2713aSLionel Sambuc } 1098*f4a2713aSLionel Sambuc } 1099*f4a2713aSLionel Sambuc 1100*f4a2713aSLionel Sambuc // Parse as an id-expression. 1101*f4a2713aSLionel Sambuc Res = ParseCXXIdExpression(isAddressOfOperand); 1102*f4a2713aSLionel Sambuc break; 1103*f4a2713aSLionel Sambuc } 1104*f4a2713aSLionel Sambuc 1105*f4a2713aSLionel Sambuc case tok::annot_template_id: { // [C++] template-id 1106*f4a2713aSLionel Sambuc TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 1107*f4a2713aSLionel Sambuc if (TemplateId->Kind == TNK_Type_template) { 1108*f4a2713aSLionel Sambuc // We have a template-id that we know refers to a type, 1109*f4a2713aSLionel Sambuc // translate it into a type and continue parsing as a cast 1110*f4a2713aSLionel Sambuc // expression. 1111*f4a2713aSLionel Sambuc AnnotateTemplateIdTokenAsType(); 1112*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 1113*f4a2713aSLionel Sambuc NotCastExpr, isTypeCast); 1114*f4a2713aSLionel Sambuc } 1115*f4a2713aSLionel Sambuc 1116*f4a2713aSLionel Sambuc // Fall through to treat the template-id as an id-expression. 1117*f4a2713aSLionel Sambuc } 1118*f4a2713aSLionel Sambuc 1119*f4a2713aSLionel Sambuc case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 1120*f4a2713aSLionel Sambuc Res = ParseCXXIdExpression(isAddressOfOperand); 1121*f4a2713aSLionel Sambuc break; 1122*f4a2713aSLionel Sambuc 1123*f4a2713aSLionel Sambuc case tok::coloncolon: { 1124*f4a2713aSLionel Sambuc // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 1125*f4a2713aSLionel Sambuc // annotates the token, tail recurse. 1126*f4a2713aSLionel Sambuc if (TryAnnotateTypeOrScopeToken()) 1127*f4a2713aSLionel Sambuc return ExprError(); 1128*f4a2713aSLionel Sambuc if (!Tok.is(tok::coloncolon)) 1129*f4a2713aSLionel Sambuc return ParseCastExpression(isUnaryExpression, isAddressOfOperand); 1130*f4a2713aSLionel Sambuc 1131*f4a2713aSLionel Sambuc // ::new -> [C++] new-expression 1132*f4a2713aSLionel Sambuc // ::delete -> [C++] delete-expression 1133*f4a2713aSLionel Sambuc SourceLocation CCLoc = ConsumeToken(); 1134*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_new)) 1135*f4a2713aSLionel Sambuc return ParseCXXNewExpression(true, CCLoc); 1136*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_delete)) 1137*f4a2713aSLionel Sambuc return ParseCXXDeleteExpression(true, CCLoc); 1138*f4a2713aSLionel Sambuc 1139*f4a2713aSLionel Sambuc // This is not a type name or scope specifier, it is an invalid expression. 1140*f4a2713aSLionel Sambuc Diag(CCLoc, diag::err_expected_expression); 1141*f4a2713aSLionel Sambuc return ExprError(); 1142*f4a2713aSLionel Sambuc } 1143*f4a2713aSLionel Sambuc 1144*f4a2713aSLionel Sambuc case tok::kw_new: // [C++] new-expression 1145*f4a2713aSLionel Sambuc return ParseCXXNewExpression(false, Tok.getLocation()); 1146*f4a2713aSLionel Sambuc 1147*f4a2713aSLionel Sambuc case tok::kw_delete: // [C++] delete-expression 1148*f4a2713aSLionel Sambuc return ParseCXXDeleteExpression(false, Tok.getLocation()); 1149*f4a2713aSLionel Sambuc 1150*f4a2713aSLionel Sambuc case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' 1151*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_noexcept_expr); 1152*f4a2713aSLionel Sambuc SourceLocation KeyLoc = ConsumeToken(); 1153*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1154*f4a2713aSLionel Sambuc 1155*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen_after, "noexcept")) 1156*f4a2713aSLionel Sambuc return ExprError(); 1157*f4a2713aSLionel Sambuc // C++11 [expr.unary.noexcept]p1: 1158*f4a2713aSLionel Sambuc // The noexcept operator determines whether the evaluation of its operand, 1159*f4a2713aSLionel Sambuc // which is an unevaluated operand, can throw an exception. 1160*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 1161*f4a2713aSLionel Sambuc ExprResult Result = ParseExpression(); 1162*f4a2713aSLionel Sambuc 1163*f4a2713aSLionel Sambuc T.consumeClose(); 1164*f4a2713aSLionel Sambuc 1165*f4a2713aSLionel Sambuc if (!Result.isInvalid()) 1166*f4a2713aSLionel Sambuc Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), 1167*f4a2713aSLionel Sambuc Result.take(), T.getCloseLocation()); 1168*f4a2713aSLionel Sambuc return Result; 1169*f4a2713aSLionel Sambuc } 1170*f4a2713aSLionel Sambuc 1171*f4a2713aSLionel Sambuc case tok::kw___is_abstract: // [GNU] unary-type-trait 1172*f4a2713aSLionel Sambuc case tok::kw___is_class: 1173*f4a2713aSLionel Sambuc case tok::kw___is_empty: 1174*f4a2713aSLionel Sambuc case tok::kw___is_enum: 1175*f4a2713aSLionel Sambuc case tok::kw___is_interface_class: 1176*f4a2713aSLionel Sambuc case tok::kw___is_literal: 1177*f4a2713aSLionel Sambuc case tok::kw___is_arithmetic: 1178*f4a2713aSLionel Sambuc case tok::kw___is_integral: 1179*f4a2713aSLionel Sambuc case tok::kw___is_floating_point: 1180*f4a2713aSLionel Sambuc case tok::kw___is_complete_type: 1181*f4a2713aSLionel Sambuc case tok::kw___is_void: 1182*f4a2713aSLionel Sambuc case tok::kw___is_array: 1183*f4a2713aSLionel Sambuc case tok::kw___is_function: 1184*f4a2713aSLionel Sambuc case tok::kw___is_reference: 1185*f4a2713aSLionel Sambuc case tok::kw___is_lvalue_reference: 1186*f4a2713aSLionel Sambuc case tok::kw___is_rvalue_reference: 1187*f4a2713aSLionel Sambuc case tok::kw___is_fundamental: 1188*f4a2713aSLionel Sambuc case tok::kw___is_object: 1189*f4a2713aSLionel Sambuc case tok::kw___is_scalar: 1190*f4a2713aSLionel Sambuc case tok::kw___is_compound: 1191*f4a2713aSLionel Sambuc case tok::kw___is_pointer: 1192*f4a2713aSLionel Sambuc case tok::kw___is_member_object_pointer: 1193*f4a2713aSLionel Sambuc case tok::kw___is_member_function_pointer: 1194*f4a2713aSLionel Sambuc case tok::kw___is_member_pointer: 1195*f4a2713aSLionel Sambuc case tok::kw___is_const: 1196*f4a2713aSLionel Sambuc case tok::kw___is_volatile: 1197*f4a2713aSLionel Sambuc case tok::kw___is_standard_layout: 1198*f4a2713aSLionel Sambuc case tok::kw___is_signed: 1199*f4a2713aSLionel Sambuc case tok::kw___is_unsigned: 1200*f4a2713aSLionel Sambuc case tok::kw___is_literal_type: 1201*f4a2713aSLionel Sambuc case tok::kw___is_pod: 1202*f4a2713aSLionel Sambuc case tok::kw___is_polymorphic: 1203*f4a2713aSLionel Sambuc case tok::kw___is_trivial: 1204*f4a2713aSLionel Sambuc case tok::kw___is_trivially_copyable: 1205*f4a2713aSLionel Sambuc case tok::kw___is_union: 1206*f4a2713aSLionel Sambuc case tok::kw___is_final: 1207*f4a2713aSLionel Sambuc case tok::kw___is_sealed: 1208*f4a2713aSLionel Sambuc case tok::kw___has_trivial_constructor: 1209*f4a2713aSLionel Sambuc case tok::kw___has_trivial_move_constructor: 1210*f4a2713aSLionel Sambuc case tok::kw___has_trivial_copy: 1211*f4a2713aSLionel Sambuc case tok::kw___has_trivial_assign: 1212*f4a2713aSLionel Sambuc case tok::kw___has_trivial_move_assign: 1213*f4a2713aSLionel Sambuc case tok::kw___has_trivial_destructor: 1214*f4a2713aSLionel Sambuc case tok::kw___has_nothrow_assign: 1215*f4a2713aSLionel Sambuc case tok::kw___has_nothrow_move_assign: 1216*f4a2713aSLionel Sambuc case tok::kw___has_nothrow_copy: 1217*f4a2713aSLionel Sambuc case tok::kw___has_nothrow_constructor: 1218*f4a2713aSLionel Sambuc case tok::kw___has_virtual_destructor: 1219*f4a2713aSLionel Sambuc return ParseUnaryTypeTrait(); 1220*f4a2713aSLionel Sambuc 1221*f4a2713aSLionel Sambuc case tok::kw___builtin_types_compatible_p: 1222*f4a2713aSLionel Sambuc case tok::kw___is_base_of: 1223*f4a2713aSLionel Sambuc case tok::kw___is_same: 1224*f4a2713aSLionel Sambuc case tok::kw___is_convertible: 1225*f4a2713aSLionel Sambuc case tok::kw___is_convertible_to: 1226*f4a2713aSLionel Sambuc case tok::kw___is_trivially_assignable: 1227*f4a2713aSLionel Sambuc return ParseBinaryTypeTrait(); 1228*f4a2713aSLionel Sambuc 1229*f4a2713aSLionel Sambuc case tok::kw___is_trivially_constructible: 1230*f4a2713aSLionel Sambuc return ParseTypeTrait(); 1231*f4a2713aSLionel Sambuc 1232*f4a2713aSLionel Sambuc case tok::kw___array_rank: 1233*f4a2713aSLionel Sambuc case tok::kw___array_extent: 1234*f4a2713aSLionel Sambuc return ParseArrayTypeTrait(); 1235*f4a2713aSLionel Sambuc 1236*f4a2713aSLionel Sambuc case tok::kw___is_lvalue_expr: 1237*f4a2713aSLionel Sambuc case tok::kw___is_rvalue_expr: 1238*f4a2713aSLionel Sambuc return ParseExpressionTrait(); 1239*f4a2713aSLionel Sambuc 1240*f4a2713aSLionel Sambuc case tok::at: { 1241*f4a2713aSLionel Sambuc SourceLocation AtLoc = ConsumeToken(); 1242*f4a2713aSLionel Sambuc return ParseObjCAtExpression(AtLoc); 1243*f4a2713aSLionel Sambuc } 1244*f4a2713aSLionel Sambuc case tok::caret: 1245*f4a2713aSLionel Sambuc Res = ParseBlockLiteralExpression(); 1246*f4a2713aSLionel Sambuc break; 1247*f4a2713aSLionel Sambuc case tok::code_completion: { 1248*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); 1249*f4a2713aSLionel Sambuc cutOffParsing(); 1250*f4a2713aSLionel Sambuc return ExprError(); 1251*f4a2713aSLionel Sambuc } 1252*f4a2713aSLionel Sambuc case tok::l_square: 1253*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11) { 1254*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1) { 1255*f4a2713aSLionel Sambuc // C++11 lambda expressions and Objective-C message sends both start with a 1256*f4a2713aSLionel Sambuc // square bracket. There are three possibilities here: 1257*f4a2713aSLionel Sambuc // we have a valid lambda expression, we have an invalid lambda 1258*f4a2713aSLionel Sambuc // expression, or we have something that doesn't appear to be a lambda. 1259*f4a2713aSLionel Sambuc // If we're in the last case, we fall back to ParseObjCMessageExpression. 1260*f4a2713aSLionel Sambuc Res = TryParseLambdaExpression(); 1261*f4a2713aSLionel Sambuc if (!Res.isInvalid() && !Res.get()) 1262*f4a2713aSLionel Sambuc Res = ParseObjCMessageExpression(); 1263*f4a2713aSLionel Sambuc break; 1264*f4a2713aSLionel Sambuc } 1265*f4a2713aSLionel Sambuc Res = ParseLambdaExpression(); 1266*f4a2713aSLionel Sambuc break; 1267*f4a2713aSLionel Sambuc } 1268*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1) { 1269*f4a2713aSLionel Sambuc Res = ParseObjCMessageExpression(); 1270*f4a2713aSLionel Sambuc break; 1271*f4a2713aSLionel Sambuc } 1272*f4a2713aSLionel Sambuc // FALL THROUGH. 1273*f4a2713aSLionel Sambuc default: 1274*f4a2713aSLionel Sambuc NotCastExpr = true; 1275*f4a2713aSLionel Sambuc return ExprError(); 1276*f4a2713aSLionel Sambuc } 1277*f4a2713aSLionel Sambuc 1278*f4a2713aSLionel Sambuc // These can be followed by postfix-expr pieces. 1279*f4a2713aSLionel Sambuc return ParsePostfixExpressionSuffix(Res); 1280*f4a2713aSLionel Sambuc } 1281*f4a2713aSLionel Sambuc 1282*f4a2713aSLionel Sambuc /// \brief Once the leading part of a postfix-expression is parsed, this 1283*f4a2713aSLionel Sambuc /// method parses any suffixes that apply. 1284*f4a2713aSLionel Sambuc /// 1285*f4a2713aSLionel Sambuc /// \verbatim 1286*f4a2713aSLionel Sambuc /// postfix-expression: [C99 6.5.2] 1287*f4a2713aSLionel Sambuc /// primary-expression 1288*f4a2713aSLionel Sambuc /// postfix-expression '[' expression ']' 1289*f4a2713aSLionel Sambuc /// postfix-expression '[' braced-init-list ']' 1290*f4a2713aSLionel Sambuc /// postfix-expression '(' argument-expression-list[opt] ')' 1291*f4a2713aSLionel Sambuc /// postfix-expression '.' identifier 1292*f4a2713aSLionel Sambuc /// postfix-expression '->' identifier 1293*f4a2713aSLionel Sambuc /// postfix-expression '++' 1294*f4a2713aSLionel Sambuc /// postfix-expression '--' 1295*f4a2713aSLionel Sambuc /// '(' type-name ')' '{' initializer-list '}' 1296*f4a2713aSLionel Sambuc /// '(' type-name ')' '{' initializer-list ',' '}' 1297*f4a2713aSLionel Sambuc /// 1298*f4a2713aSLionel Sambuc /// argument-expression-list: [C99 6.5.2] 1299*f4a2713aSLionel Sambuc /// argument-expression ...[opt] 1300*f4a2713aSLionel Sambuc /// argument-expression-list ',' assignment-expression ...[opt] 1301*f4a2713aSLionel Sambuc /// \endverbatim 1302*f4a2713aSLionel Sambuc ExprResult 1303*f4a2713aSLionel Sambuc Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { 1304*f4a2713aSLionel Sambuc // Now that the primary-expression piece of the postfix-expression has been 1305*f4a2713aSLionel Sambuc // parsed, see if there are any postfix-expression pieces here. 1306*f4a2713aSLionel Sambuc SourceLocation Loc; 1307*f4a2713aSLionel Sambuc while (1) { 1308*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 1309*f4a2713aSLionel Sambuc case tok::code_completion: 1310*f4a2713aSLionel Sambuc if (InMessageExpression) 1311*f4a2713aSLionel Sambuc return LHS; 1312*f4a2713aSLionel Sambuc 1313*f4a2713aSLionel Sambuc Actions.CodeCompletePostfixExpression(getCurScope(), LHS); 1314*f4a2713aSLionel Sambuc cutOffParsing(); 1315*f4a2713aSLionel Sambuc return ExprError(); 1316*f4a2713aSLionel Sambuc 1317*f4a2713aSLionel Sambuc case tok::identifier: 1318*f4a2713aSLionel Sambuc // If we see identifier: after an expression, and we're not already in a 1319*f4a2713aSLionel Sambuc // message send, then this is probably a message send with a missing 1320*f4a2713aSLionel Sambuc // opening bracket '['. 1321*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && !InMessageExpression && 1322*f4a2713aSLionel Sambuc (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 1323*f4a2713aSLionel Sambuc LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), 1324*f4a2713aSLionel Sambuc ParsedType(), LHS.get()); 1325*f4a2713aSLionel Sambuc break; 1326*f4a2713aSLionel Sambuc } 1327*f4a2713aSLionel Sambuc 1328*f4a2713aSLionel Sambuc // Fall through; this isn't a message send. 1329*f4a2713aSLionel Sambuc 1330*f4a2713aSLionel Sambuc default: // Not a postfix-expression suffix. 1331*f4a2713aSLionel Sambuc return LHS; 1332*f4a2713aSLionel Sambuc case tok::l_square: { // postfix-expression: p-e '[' expression ']' 1333*f4a2713aSLionel Sambuc // If we have a array postfix expression that starts on a new line and 1334*f4a2713aSLionel Sambuc // Objective-C is enabled, it is highly likely that the user forgot a 1335*f4a2713aSLionel Sambuc // semicolon after the base expression and that the array postfix-expr is 1336*f4a2713aSLionel Sambuc // actually another message send. In this case, do some look-ahead to see 1337*f4a2713aSLionel Sambuc // if the contents of the square brackets are obviously not a valid 1338*f4a2713aSLionel Sambuc // expression and recover by pretending there is no suffix. 1339*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && Tok.isAtStartOfLine() && 1340*f4a2713aSLionel Sambuc isSimpleObjCMessageExpression()) 1341*f4a2713aSLionel Sambuc return LHS; 1342*f4a2713aSLionel Sambuc 1343*f4a2713aSLionel Sambuc // Reject array indices starting with a lambda-expression. '[[' is 1344*f4a2713aSLionel Sambuc // reserved for attributes. 1345*f4a2713aSLionel Sambuc if (CheckProhibitedCXX11Attribute()) 1346*f4a2713aSLionel Sambuc return ExprError(); 1347*f4a2713aSLionel Sambuc 1348*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_square); 1349*f4a2713aSLionel Sambuc T.consumeOpen(); 1350*f4a2713aSLionel Sambuc Loc = T.getOpenLocation(); 1351*f4a2713aSLionel Sambuc ExprResult Idx; 1352*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 1353*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 1354*f4a2713aSLionel Sambuc Idx = ParseBraceInitializer(); 1355*f4a2713aSLionel Sambuc } else 1356*f4a2713aSLionel Sambuc Idx = ParseExpression(); 1357*f4a2713aSLionel Sambuc 1358*f4a2713aSLionel Sambuc SourceLocation RLoc = Tok.getLocation(); 1359*f4a2713aSLionel Sambuc 1360*f4a2713aSLionel Sambuc if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) { 1361*f4a2713aSLionel Sambuc LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.take(), Loc, 1362*f4a2713aSLionel Sambuc Idx.take(), RLoc); 1363*f4a2713aSLionel Sambuc } else 1364*f4a2713aSLionel Sambuc LHS = ExprError(); 1365*f4a2713aSLionel Sambuc 1366*f4a2713aSLionel Sambuc // Match the ']'. 1367*f4a2713aSLionel Sambuc T.consumeClose(); 1368*f4a2713aSLionel Sambuc break; 1369*f4a2713aSLionel Sambuc } 1370*f4a2713aSLionel Sambuc 1371*f4a2713aSLionel Sambuc case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' 1372*f4a2713aSLionel Sambuc case tok::lesslessless: { // p-e: p-e '<<<' argument-expression-list '>>>' 1373*f4a2713aSLionel Sambuc // '(' argument-expression-list[opt] ')' 1374*f4a2713aSLionel Sambuc tok::TokenKind OpKind = Tok.getKind(); 1375*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 1376*f4a2713aSLionel Sambuc 1377*f4a2713aSLionel Sambuc Expr *ExecConfig = 0; 1378*f4a2713aSLionel Sambuc 1379*f4a2713aSLionel Sambuc BalancedDelimiterTracker PT(*this, tok::l_paren); 1380*f4a2713aSLionel Sambuc 1381*f4a2713aSLionel Sambuc if (OpKind == tok::lesslessless) { 1382*f4a2713aSLionel Sambuc ExprVector ExecConfigExprs; 1383*f4a2713aSLionel Sambuc CommaLocsTy ExecConfigCommaLocs; 1384*f4a2713aSLionel Sambuc SourceLocation OpenLoc = ConsumeToken(); 1385*f4a2713aSLionel Sambuc 1386*f4a2713aSLionel Sambuc if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { 1387*f4a2713aSLionel Sambuc LHS = ExprError(); 1388*f4a2713aSLionel Sambuc } 1389*f4a2713aSLionel Sambuc 1390*f4a2713aSLionel Sambuc SourceLocation CloseLoc = Tok.getLocation(); 1391*f4a2713aSLionel Sambuc if (Tok.is(tok::greatergreatergreater)) { 1392*f4a2713aSLionel Sambuc ConsumeToken(); 1393*f4a2713aSLionel Sambuc } else if (LHS.isInvalid()) { 1394*f4a2713aSLionel Sambuc SkipUntil(tok::greatergreatergreater, StopAtSemi); 1395*f4a2713aSLionel Sambuc } else { 1396*f4a2713aSLionel Sambuc // There was an error closing the brackets 1397*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ggg); 1398*f4a2713aSLionel Sambuc Diag(OpenLoc, diag::note_matching) << "<<<"; 1399*f4a2713aSLionel Sambuc SkipUntil(tok::greatergreatergreater, StopAtSemi); 1400*f4a2713aSLionel Sambuc LHS = ExprError(); 1401*f4a2713aSLionel Sambuc } 1402*f4a2713aSLionel Sambuc 1403*f4a2713aSLionel Sambuc if (!LHS.isInvalid()) { 1404*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen, "")) 1405*f4a2713aSLionel Sambuc LHS = ExprError(); 1406*f4a2713aSLionel Sambuc else 1407*f4a2713aSLionel Sambuc Loc = PrevTokLocation; 1408*f4a2713aSLionel Sambuc } 1409*f4a2713aSLionel Sambuc 1410*f4a2713aSLionel Sambuc if (!LHS.isInvalid()) { 1411*f4a2713aSLionel Sambuc ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), 1412*f4a2713aSLionel Sambuc OpenLoc, 1413*f4a2713aSLionel Sambuc ExecConfigExprs, 1414*f4a2713aSLionel Sambuc CloseLoc); 1415*f4a2713aSLionel Sambuc if (ECResult.isInvalid()) 1416*f4a2713aSLionel Sambuc LHS = ExprError(); 1417*f4a2713aSLionel Sambuc else 1418*f4a2713aSLionel Sambuc ExecConfig = ECResult.get(); 1419*f4a2713aSLionel Sambuc } 1420*f4a2713aSLionel Sambuc } else { 1421*f4a2713aSLionel Sambuc PT.consumeOpen(); 1422*f4a2713aSLionel Sambuc Loc = PT.getOpenLocation(); 1423*f4a2713aSLionel Sambuc } 1424*f4a2713aSLionel Sambuc 1425*f4a2713aSLionel Sambuc ExprVector ArgExprs; 1426*f4a2713aSLionel Sambuc CommaLocsTy CommaLocs; 1427*f4a2713aSLionel Sambuc 1428*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1429*f4a2713aSLionel Sambuc Actions.CodeCompleteCall(getCurScope(), LHS.get(), None); 1430*f4a2713aSLionel Sambuc cutOffParsing(); 1431*f4a2713aSLionel Sambuc return ExprError(); 1432*f4a2713aSLionel Sambuc } 1433*f4a2713aSLionel Sambuc 1434*f4a2713aSLionel Sambuc if (OpKind == tok::l_paren || !LHS.isInvalid()) { 1435*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 1436*f4a2713aSLionel Sambuc if (ParseExpressionList(ArgExprs, CommaLocs, &Sema::CodeCompleteCall, 1437*f4a2713aSLionel Sambuc LHS.get())) { 1438*f4a2713aSLionel Sambuc LHS = ExprError(); 1439*f4a2713aSLionel Sambuc } 1440*f4a2713aSLionel Sambuc } 1441*f4a2713aSLionel Sambuc } 1442*f4a2713aSLionel Sambuc 1443*f4a2713aSLionel Sambuc // Match the ')'. 1444*f4a2713aSLionel Sambuc if (LHS.isInvalid()) { 1445*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1446*f4a2713aSLionel Sambuc } else if (Tok.isNot(tok::r_paren)) { 1447*f4a2713aSLionel Sambuc PT.consumeClose(); 1448*f4a2713aSLionel Sambuc LHS = ExprError(); 1449*f4a2713aSLionel Sambuc } else { 1450*f4a2713aSLionel Sambuc assert((ArgExprs.size() == 0 || 1451*f4a2713aSLionel Sambuc ArgExprs.size()-1 == CommaLocs.size())&& 1452*f4a2713aSLionel Sambuc "Unexpected number of commas!"); 1453*f4a2713aSLionel Sambuc LHS = Actions.ActOnCallExpr(getCurScope(), LHS.take(), Loc, 1454*f4a2713aSLionel Sambuc ArgExprs, Tok.getLocation(), 1455*f4a2713aSLionel Sambuc ExecConfig); 1456*f4a2713aSLionel Sambuc PT.consumeClose(); 1457*f4a2713aSLionel Sambuc } 1458*f4a2713aSLionel Sambuc 1459*f4a2713aSLionel Sambuc break; 1460*f4a2713aSLionel Sambuc } 1461*f4a2713aSLionel Sambuc case tok::arrow: 1462*f4a2713aSLionel Sambuc case tok::period: { 1463*f4a2713aSLionel Sambuc // postfix-expression: p-e '->' template[opt] id-expression 1464*f4a2713aSLionel Sambuc // postfix-expression: p-e '.' template[opt] id-expression 1465*f4a2713aSLionel Sambuc tok::TokenKind OpKind = Tok.getKind(); 1466*f4a2713aSLionel Sambuc SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 1467*f4a2713aSLionel Sambuc 1468*f4a2713aSLionel Sambuc CXXScopeSpec SS; 1469*f4a2713aSLionel Sambuc ParsedType ObjectType; 1470*f4a2713aSLionel Sambuc bool MayBePseudoDestructor = false; 1471*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { 1472*f4a2713aSLionel Sambuc Expr *Base = LHS.take(); 1473*f4a2713aSLionel Sambuc const Type* BaseType = Base->getType().getTypePtrOrNull(); 1474*f4a2713aSLionel Sambuc if (BaseType && Tok.is(tok::l_paren) && 1475*f4a2713aSLionel Sambuc (BaseType->isFunctionType() || 1476*f4a2713aSLionel Sambuc BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { 1477*f4a2713aSLionel Sambuc Diag(OpLoc, diag::err_function_is_not_record) 1478*f4a2713aSLionel Sambuc << (OpKind == tok::arrow) << Base->getSourceRange() 1479*f4a2713aSLionel Sambuc << FixItHint::CreateRemoval(OpLoc); 1480*f4a2713aSLionel Sambuc return ParsePostfixExpressionSuffix(Base); 1481*f4a2713aSLionel Sambuc } 1482*f4a2713aSLionel Sambuc 1483*f4a2713aSLionel Sambuc LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, 1484*f4a2713aSLionel Sambuc OpLoc, OpKind, ObjectType, 1485*f4a2713aSLionel Sambuc MayBePseudoDestructor); 1486*f4a2713aSLionel Sambuc if (LHS.isInvalid()) 1487*f4a2713aSLionel Sambuc break; 1488*f4a2713aSLionel Sambuc 1489*f4a2713aSLionel Sambuc ParseOptionalCXXScopeSpecifier(SS, ObjectType, 1490*f4a2713aSLionel Sambuc /*EnteringContext=*/false, 1491*f4a2713aSLionel Sambuc &MayBePseudoDestructor); 1492*f4a2713aSLionel Sambuc if (SS.isNotEmpty()) 1493*f4a2713aSLionel Sambuc ObjectType = ParsedType(); 1494*f4a2713aSLionel Sambuc } 1495*f4a2713aSLionel Sambuc 1496*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 1497*f4a2713aSLionel Sambuc // Code completion for a member access expression. 1498*f4a2713aSLionel Sambuc Actions.CodeCompleteMemberReferenceExpr(getCurScope(), LHS.get(), 1499*f4a2713aSLionel Sambuc OpLoc, OpKind == tok::arrow); 1500*f4a2713aSLionel Sambuc 1501*f4a2713aSLionel Sambuc cutOffParsing(); 1502*f4a2713aSLionel Sambuc return ExprError(); 1503*f4a2713aSLionel Sambuc } 1504*f4a2713aSLionel Sambuc 1505*f4a2713aSLionel Sambuc if (MayBePseudoDestructor && !LHS.isInvalid()) { 1506*f4a2713aSLionel Sambuc LHS = ParseCXXPseudoDestructor(LHS.take(), OpLoc, OpKind, SS, 1507*f4a2713aSLionel Sambuc ObjectType); 1508*f4a2713aSLionel Sambuc break; 1509*f4a2713aSLionel Sambuc } 1510*f4a2713aSLionel Sambuc 1511*f4a2713aSLionel Sambuc // Either the action has told is that this cannot be a 1512*f4a2713aSLionel Sambuc // pseudo-destructor expression (based on the type of base 1513*f4a2713aSLionel Sambuc // expression), or we didn't see a '~' in the right place. We 1514*f4a2713aSLionel Sambuc // can still parse a destructor name here, but in that case it 1515*f4a2713aSLionel Sambuc // names a real destructor. 1516*f4a2713aSLionel Sambuc // Allow explicit constructor calls in Microsoft mode. 1517*f4a2713aSLionel Sambuc // FIXME: Add support for explicit call of template constructor. 1518*f4a2713aSLionel Sambuc SourceLocation TemplateKWLoc; 1519*f4a2713aSLionel Sambuc UnqualifiedId Name; 1520*f4a2713aSLionel Sambuc if (getLangOpts().ObjC2 && OpKind == tok::period && Tok.is(tok::kw_class)) { 1521*f4a2713aSLionel Sambuc // Objective-C++: 1522*f4a2713aSLionel Sambuc // After a '.' in a member access expression, treat the keyword 1523*f4a2713aSLionel Sambuc // 'class' as if it were an identifier. 1524*f4a2713aSLionel Sambuc // 1525*f4a2713aSLionel Sambuc // This hack allows property access to the 'class' method because it is 1526*f4a2713aSLionel Sambuc // such a common method name. For other C++ keywords that are 1527*f4a2713aSLionel Sambuc // Objective-C method names, one must use the message send syntax. 1528*f4a2713aSLionel Sambuc IdentifierInfo *Id = Tok.getIdentifierInfo(); 1529*f4a2713aSLionel Sambuc SourceLocation Loc = ConsumeToken(); 1530*f4a2713aSLionel Sambuc Name.setIdentifier(Id, Loc); 1531*f4a2713aSLionel Sambuc } else if (ParseUnqualifiedId(SS, 1532*f4a2713aSLionel Sambuc /*EnteringContext=*/false, 1533*f4a2713aSLionel Sambuc /*AllowDestructorName=*/true, 1534*f4a2713aSLionel Sambuc /*AllowConstructorName=*/ 1535*f4a2713aSLionel Sambuc getLangOpts().MicrosoftExt, 1536*f4a2713aSLionel Sambuc ObjectType, TemplateKWLoc, Name)) 1537*f4a2713aSLionel Sambuc LHS = ExprError(); 1538*f4a2713aSLionel Sambuc 1539*f4a2713aSLionel Sambuc if (!LHS.isInvalid()) 1540*f4a2713aSLionel Sambuc LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc, 1541*f4a2713aSLionel Sambuc OpKind, SS, TemplateKWLoc, Name, 1542*f4a2713aSLionel Sambuc CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : 0, 1543*f4a2713aSLionel Sambuc Tok.is(tok::l_paren)); 1544*f4a2713aSLionel Sambuc break; 1545*f4a2713aSLionel Sambuc } 1546*f4a2713aSLionel Sambuc case tok::plusplus: // postfix-expression: postfix-expression '++' 1547*f4a2713aSLionel Sambuc case tok::minusminus: // postfix-expression: postfix-expression '--' 1548*f4a2713aSLionel Sambuc if (!LHS.isInvalid()) { 1549*f4a2713aSLionel Sambuc LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), 1550*f4a2713aSLionel Sambuc Tok.getKind(), LHS.take()); 1551*f4a2713aSLionel Sambuc } 1552*f4a2713aSLionel Sambuc ConsumeToken(); 1553*f4a2713aSLionel Sambuc break; 1554*f4a2713aSLionel Sambuc } 1555*f4a2713aSLionel Sambuc } 1556*f4a2713aSLionel Sambuc } 1557*f4a2713aSLionel Sambuc 1558*f4a2713aSLionel Sambuc /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/ 1559*f4a2713aSLionel Sambuc /// vec_step and we are at the start of an expression or a parenthesized 1560*f4a2713aSLionel Sambuc /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the 1561*f4a2713aSLionel Sambuc /// expression (isCastExpr == false) or the type (isCastExpr == true). 1562*f4a2713aSLionel Sambuc /// 1563*f4a2713aSLionel Sambuc /// \verbatim 1564*f4a2713aSLionel Sambuc /// unary-expression: [C99 6.5.3] 1565*f4a2713aSLionel Sambuc /// 'sizeof' unary-expression 1566*f4a2713aSLionel Sambuc /// 'sizeof' '(' type-name ')' 1567*f4a2713aSLionel Sambuc /// [GNU] '__alignof' unary-expression 1568*f4a2713aSLionel Sambuc /// [GNU] '__alignof' '(' type-name ')' 1569*f4a2713aSLionel Sambuc /// [C11] '_Alignof' '(' type-name ')' 1570*f4a2713aSLionel Sambuc /// [C++0x] 'alignof' '(' type-id ')' 1571*f4a2713aSLionel Sambuc /// 1572*f4a2713aSLionel Sambuc /// [GNU] typeof-specifier: 1573*f4a2713aSLionel Sambuc /// typeof ( expressions ) 1574*f4a2713aSLionel Sambuc /// typeof ( type-name ) 1575*f4a2713aSLionel Sambuc /// [GNU/C++] typeof unary-expression 1576*f4a2713aSLionel Sambuc /// 1577*f4a2713aSLionel Sambuc /// [OpenCL 1.1 6.11.12] vec_step built-in function: 1578*f4a2713aSLionel Sambuc /// vec_step ( expressions ) 1579*f4a2713aSLionel Sambuc /// vec_step ( type-name ) 1580*f4a2713aSLionel Sambuc /// \endverbatim 1581*f4a2713aSLionel Sambuc ExprResult 1582*f4a2713aSLionel Sambuc Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, 1583*f4a2713aSLionel Sambuc bool &isCastExpr, 1584*f4a2713aSLionel Sambuc ParsedType &CastTy, 1585*f4a2713aSLionel Sambuc SourceRange &CastRange) { 1586*f4a2713aSLionel Sambuc 1587*f4a2713aSLionel Sambuc assert((OpTok.is(tok::kw_typeof) || OpTok.is(tok::kw_sizeof) || 1588*f4a2713aSLionel Sambuc OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof) || 1589*f4a2713aSLionel Sambuc OpTok.is(tok::kw__Alignof) || OpTok.is(tok::kw_vec_step)) && 1590*f4a2713aSLionel Sambuc "Not a typeof/sizeof/alignof/vec_step expression!"); 1591*f4a2713aSLionel Sambuc 1592*f4a2713aSLionel Sambuc ExprResult Operand; 1593*f4a2713aSLionel Sambuc 1594*f4a2713aSLionel Sambuc // If the operand doesn't start with an '(', it must be an expression. 1595*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) { 1596*f4a2713aSLionel Sambuc // If construct allows a form without parenthesis, user may forget to put 1597*f4a2713aSLionel Sambuc // pathenthesis around type name. 1598*f4a2713aSLionel Sambuc if (OpTok.is(tok::kw_sizeof) || OpTok.is(tok::kw___alignof) || 1599*f4a2713aSLionel Sambuc OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) { 1600*f4a2713aSLionel Sambuc bool isAmbiguousTypeId; 1601*f4a2713aSLionel Sambuc if (isTypeIdInParens(isAmbiguousTypeId)) { 1602*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 1603*f4a2713aSLionel Sambuc ParseSpecifierQualifierList(DS); 1604*f4a2713aSLionel Sambuc Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1605*f4a2713aSLionel Sambuc ParseDeclarator(DeclaratorInfo); 1606*f4a2713aSLionel Sambuc 1607*f4a2713aSLionel Sambuc SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); 1608*f4a2713aSLionel Sambuc SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); 1609*f4a2713aSLionel Sambuc Diag(LParenLoc, diag::err_expected_parentheses_around_typename) 1610*f4a2713aSLionel Sambuc << OpTok.getName() 1611*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(LParenLoc, "(") 1612*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(RParenLoc, ")"); 1613*f4a2713aSLionel Sambuc isCastExpr = true; 1614*f4a2713aSLionel Sambuc return ExprEmpty(); 1615*f4a2713aSLionel Sambuc } 1616*f4a2713aSLionel Sambuc } 1617*f4a2713aSLionel Sambuc 1618*f4a2713aSLionel Sambuc isCastExpr = false; 1619*f4a2713aSLionel Sambuc if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) { 1620*f4a2713aSLionel Sambuc Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo(); 1621*f4a2713aSLionel Sambuc return ExprError(); 1622*f4a2713aSLionel Sambuc } 1623*f4a2713aSLionel Sambuc 1624*f4a2713aSLionel Sambuc Operand = ParseCastExpression(true/*isUnaryExpression*/); 1625*f4a2713aSLionel Sambuc } else { 1626*f4a2713aSLionel Sambuc // If it starts with a '(', we know that it is either a parenthesized 1627*f4a2713aSLionel Sambuc // type-name, or it is a unary-expression that starts with a compound 1628*f4a2713aSLionel Sambuc // literal, or starts with a primary-expression that is a parenthesized 1629*f4a2713aSLionel Sambuc // expression. 1630*f4a2713aSLionel Sambuc ParenParseOption ExprType = CastExpr; 1631*f4a2713aSLionel Sambuc SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 1632*f4a2713aSLionel Sambuc 1633*f4a2713aSLionel Sambuc Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 1634*f4a2713aSLionel Sambuc false, CastTy, RParenLoc); 1635*f4a2713aSLionel Sambuc CastRange = SourceRange(LParenLoc, RParenLoc); 1636*f4a2713aSLionel Sambuc 1637*f4a2713aSLionel Sambuc // If ParseParenExpression parsed a '(typename)' sequence only, then this is 1638*f4a2713aSLionel Sambuc // a type. 1639*f4a2713aSLionel Sambuc if (ExprType == CastExpr) { 1640*f4a2713aSLionel Sambuc isCastExpr = true; 1641*f4a2713aSLionel Sambuc return ExprEmpty(); 1642*f4a2713aSLionel Sambuc } 1643*f4a2713aSLionel Sambuc 1644*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { 1645*f4a2713aSLionel Sambuc // GNU typeof in C requires the expression to be parenthesized. Not so for 1646*f4a2713aSLionel Sambuc // sizeof/alignof or in C++. Therefore, the parenthesized expression is 1647*f4a2713aSLionel Sambuc // the start of a unary-expression, but doesn't include any postfix 1648*f4a2713aSLionel Sambuc // pieces. Parse these now if present. 1649*f4a2713aSLionel Sambuc if (!Operand.isInvalid()) 1650*f4a2713aSLionel Sambuc Operand = ParsePostfixExpressionSuffix(Operand.get()); 1651*f4a2713aSLionel Sambuc } 1652*f4a2713aSLionel Sambuc } 1653*f4a2713aSLionel Sambuc 1654*f4a2713aSLionel Sambuc // If we get here, the operand to the typeof/sizeof/alignof was an expresion. 1655*f4a2713aSLionel Sambuc isCastExpr = false; 1656*f4a2713aSLionel Sambuc return Operand; 1657*f4a2713aSLionel Sambuc } 1658*f4a2713aSLionel Sambuc 1659*f4a2713aSLionel Sambuc 1660*f4a2713aSLionel Sambuc /// \brief Parse a sizeof or alignof expression. 1661*f4a2713aSLionel Sambuc /// 1662*f4a2713aSLionel Sambuc /// \verbatim 1663*f4a2713aSLionel Sambuc /// unary-expression: [C99 6.5.3] 1664*f4a2713aSLionel Sambuc /// 'sizeof' unary-expression 1665*f4a2713aSLionel Sambuc /// 'sizeof' '(' type-name ')' 1666*f4a2713aSLionel Sambuc /// [C++11] 'sizeof' '...' '(' identifier ')' 1667*f4a2713aSLionel Sambuc /// [GNU] '__alignof' unary-expression 1668*f4a2713aSLionel Sambuc /// [GNU] '__alignof' '(' type-name ')' 1669*f4a2713aSLionel Sambuc /// [C11] '_Alignof' '(' type-name ')' 1670*f4a2713aSLionel Sambuc /// [C++11] 'alignof' '(' type-id ')' 1671*f4a2713aSLionel Sambuc /// \endverbatim 1672*f4a2713aSLionel Sambuc ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { 1673*f4a2713aSLionel Sambuc assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof) || 1674*f4a2713aSLionel Sambuc Tok.is(tok::kw_alignof) || Tok.is(tok::kw__Alignof) || 1675*f4a2713aSLionel Sambuc Tok.is(tok::kw_vec_step)) && 1676*f4a2713aSLionel Sambuc "Not a sizeof/alignof/vec_step expression!"); 1677*f4a2713aSLionel Sambuc Token OpTok = Tok; 1678*f4a2713aSLionel Sambuc ConsumeToken(); 1679*f4a2713aSLionel Sambuc 1680*f4a2713aSLionel Sambuc // [C++11] 'sizeof' '...' '(' identifier ')' 1681*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { 1682*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = ConsumeToken(); 1683*f4a2713aSLionel Sambuc SourceLocation LParenLoc, RParenLoc; 1684*f4a2713aSLionel Sambuc IdentifierInfo *Name = 0; 1685*f4a2713aSLionel Sambuc SourceLocation NameLoc; 1686*f4a2713aSLionel Sambuc if (Tok.is(tok::l_paren)) { 1687*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 1688*f4a2713aSLionel Sambuc T.consumeOpen(); 1689*f4a2713aSLionel Sambuc LParenLoc = T.getOpenLocation(); 1690*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) { 1691*f4a2713aSLionel Sambuc Name = Tok.getIdentifierInfo(); 1692*f4a2713aSLionel Sambuc NameLoc = ConsumeToken(); 1693*f4a2713aSLionel Sambuc T.consumeClose(); 1694*f4a2713aSLionel Sambuc RParenLoc = T.getCloseLocation(); 1695*f4a2713aSLionel Sambuc if (RParenLoc.isInvalid()) 1696*f4a2713aSLionel Sambuc RParenLoc = PP.getLocForEndOfToken(NameLoc); 1697*f4a2713aSLionel Sambuc } else { 1698*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_parameter_pack); 1699*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1700*f4a2713aSLionel Sambuc } 1701*f4a2713aSLionel Sambuc } else if (Tok.is(tok::identifier)) { 1702*f4a2713aSLionel Sambuc Name = Tok.getIdentifierInfo(); 1703*f4a2713aSLionel Sambuc NameLoc = ConsumeToken(); 1704*f4a2713aSLionel Sambuc LParenLoc = PP.getLocForEndOfToken(EllipsisLoc); 1705*f4a2713aSLionel Sambuc RParenLoc = PP.getLocForEndOfToken(NameLoc); 1706*f4a2713aSLionel Sambuc Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack) 1707*f4a2713aSLionel Sambuc << Name 1708*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(LParenLoc, "(") 1709*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(RParenLoc, ")"); 1710*f4a2713aSLionel Sambuc } else { 1711*f4a2713aSLionel Sambuc Diag(Tok, diag::err_sizeof_parameter_pack); 1712*f4a2713aSLionel Sambuc } 1713*f4a2713aSLionel Sambuc 1714*f4a2713aSLionel Sambuc if (!Name) 1715*f4a2713aSLionel Sambuc return ExprError(); 1716*f4a2713aSLionel Sambuc 1717*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 1718*f4a2713aSLionel Sambuc Sema::ReuseLambdaContextDecl); 1719*f4a2713aSLionel Sambuc 1720*f4a2713aSLionel Sambuc return Actions.ActOnSizeofParameterPackExpr(getCurScope(), 1721*f4a2713aSLionel Sambuc OpTok.getLocation(), 1722*f4a2713aSLionel Sambuc *Name, NameLoc, 1723*f4a2713aSLionel Sambuc RParenLoc); 1724*f4a2713aSLionel Sambuc } 1725*f4a2713aSLionel Sambuc 1726*f4a2713aSLionel Sambuc if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) 1727*f4a2713aSLionel Sambuc Diag(OpTok, diag::warn_cxx98_compat_alignof); 1728*f4a2713aSLionel Sambuc 1729*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 1730*f4a2713aSLionel Sambuc Sema::ReuseLambdaContextDecl); 1731*f4a2713aSLionel Sambuc 1732*f4a2713aSLionel Sambuc bool isCastExpr; 1733*f4a2713aSLionel Sambuc ParsedType CastTy; 1734*f4a2713aSLionel Sambuc SourceRange CastRange; 1735*f4a2713aSLionel Sambuc ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, 1736*f4a2713aSLionel Sambuc isCastExpr, 1737*f4a2713aSLionel Sambuc CastTy, 1738*f4a2713aSLionel Sambuc CastRange); 1739*f4a2713aSLionel Sambuc 1740*f4a2713aSLionel Sambuc UnaryExprOrTypeTrait ExprKind = UETT_SizeOf; 1741*f4a2713aSLionel Sambuc if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw___alignof) || 1742*f4a2713aSLionel Sambuc OpTok.is(tok::kw__Alignof)) 1743*f4a2713aSLionel Sambuc ExprKind = UETT_AlignOf; 1744*f4a2713aSLionel Sambuc else if (OpTok.is(tok::kw_vec_step)) 1745*f4a2713aSLionel Sambuc ExprKind = UETT_VecStep; 1746*f4a2713aSLionel Sambuc 1747*f4a2713aSLionel Sambuc if (isCastExpr) 1748*f4a2713aSLionel Sambuc return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 1749*f4a2713aSLionel Sambuc ExprKind, 1750*f4a2713aSLionel Sambuc /*isType=*/true, 1751*f4a2713aSLionel Sambuc CastTy.getAsOpaquePtr(), 1752*f4a2713aSLionel Sambuc CastRange); 1753*f4a2713aSLionel Sambuc 1754*f4a2713aSLionel Sambuc if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) 1755*f4a2713aSLionel Sambuc Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); 1756*f4a2713aSLionel Sambuc 1757*f4a2713aSLionel Sambuc // If we get here, the operand to the sizeof/alignof was an expresion. 1758*f4a2713aSLionel Sambuc if (!Operand.isInvalid()) 1759*f4a2713aSLionel Sambuc Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), 1760*f4a2713aSLionel Sambuc ExprKind, 1761*f4a2713aSLionel Sambuc /*isType=*/false, 1762*f4a2713aSLionel Sambuc Operand.release(), 1763*f4a2713aSLionel Sambuc CastRange); 1764*f4a2713aSLionel Sambuc return Operand; 1765*f4a2713aSLionel Sambuc } 1766*f4a2713aSLionel Sambuc 1767*f4a2713aSLionel Sambuc /// ParseBuiltinPrimaryExpression 1768*f4a2713aSLionel Sambuc /// 1769*f4a2713aSLionel Sambuc /// \verbatim 1770*f4a2713aSLionel Sambuc /// primary-expression: [C99 6.5.1] 1771*f4a2713aSLionel Sambuc /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 1772*f4a2713aSLionel Sambuc /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 1773*f4a2713aSLionel Sambuc /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 1774*f4a2713aSLionel Sambuc /// assign-expr ')' 1775*f4a2713aSLionel Sambuc /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 1776*f4a2713aSLionel Sambuc /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' 1777*f4a2713aSLionel Sambuc /// 1778*f4a2713aSLionel Sambuc /// [GNU] offsetof-member-designator: 1779*f4a2713aSLionel Sambuc /// [GNU] identifier 1780*f4a2713aSLionel Sambuc /// [GNU] offsetof-member-designator '.' identifier 1781*f4a2713aSLionel Sambuc /// [GNU] offsetof-member-designator '[' expression ']' 1782*f4a2713aSLionel Sambuc /// \endverbatim 1783*f4a2713aSLionel Sambuc ExprResult Parser::ParseBuiltinPrimaryExpression() { 1784*f4a2713aSLionel Sambuc ExprResult Res; 1785*f4a2713aSLionel Sambuc const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 1786*f4a2713aSLionel Sambuc 1787*f4a2713aSLionel Sambuc tok::TokenKind T = Tok.getKind(); 1788*f4a2713aSLionel Sambuc SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 1789*f4a2713aSLionel Sambuc 1790*f4a2713aSLionel Sambuc // All of these start with an open paren. 1791*f4a2713aSLionel Sambuc if (Tok.isNot(tok::l_paren)) 1792*f4a2713aSLionel Sambuc return ExprError(Diag(Tok, diag::err_expected_lparen_after_id) 1793*f4a2713aSLionel Sambuc << BuiltinII); 1794*f4a2713aSLionel Sambuc 1795*f4a2713aSLionel Sambuc BalancedDelimiterTracker PT(*this, tok::l_paren); 1796*f4a2713aSLionel Sambuc PT.consumeOpen(); 1797*f4a2713aSLionel Sambuc 1798*f4a2713aSLionel Sambuc // TODO: Build AST. 1799*f4a2713aSLionel Sambuc 1800*f4a2713aSLionel Sambuc switch (T) { 1801*f4a2713aSLionel Sambuc default: llvm_unreachable("Not a builtin primary expression!"); 1802*f4a2713aSLionel Sambuc case tok::kw___builtin_va_arg: { 1803*f4a2713aSLionel Sambuc ExprResult Expr(ParseAssignmentExpression()); 1804*f4a2713aSLionel Sambuc 1805*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 1806*f4a2713aSLionel Sambuc Expr = ExprError(); 1807*f4a2713aSLionel Sambuc 1808*f4a2713aSLionel Sambuc TypeResult Ty = ParseTypeName(); 1809*f4a2713aSLionel Sambuc 1810*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 1811*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_rparen); 1812*f4a2713aSLionel Sambuc Expr = ExprError(); 1813*f4a2713aSLionel Sambuc } 1814*f4a2713aSLionel Sambuc 1815*f4a2713aSLionel Sambuc if (Expr.isInvalid() || Ty.isInvalid()) 1816*f4a2713aSLionel Sambuc Res = ExprError(); 1817*f4a2713aSLionel Sambuc else 1818*f4a2713aSLionel Sambuc Res = Actions.ActOnVAArg(StartLoc, Expr.take(), Ty.get(), ConsumeParen()); 1819*f4a2713aSLionel Sambuc break; 1820*f4a2713aSLionel Sambuc } 1821*f4a2713aSLionel Sambuc case tok::kw___builtin_offsetof: { 1822*f4a2713aSLionel Sambuc SourceLocation TypeLoc = Tok.getLocation(); 1823*f4a2713aSLionel Sambuc TypeResult Ty = ParseTypeName(); 1824*f4a2713aSLionel Sambuc if (Ty.isInvalid()) { 1825*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1826*f4a2713aSLionel Sambuc return ExprError(); 1827*f4a2713aSLionel Sambuc } 1828*f4a2713aSLionel Sambuc 1829*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 1830*f4a2713aSLionel Sambuc return ExprError(); 1831*f4a2713aSLionel Sambuc 1832*f4a2713aSLionel Sambuc // We must have at least one identifier here. 1833*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 1834*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 1835*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1836*f4a2713aSLionel Sambuc return ExprError(); 1837*f4a2713aSLionel Sambuc } 1838*f4a2713aSLionel Sambuc 1839*f4a2713aSLionel Sambuc // Keep track of the various subcomponents we see. 1840*f4a2713aSLionel Sambuc SmallVector<Sema::OffsetOfComponent, 4> Comps; 1841*f4a2713aSLionel Sambuc 1842*f4a2713aSLionel Sambuc Comps.push_back(Sema::OffsetOfComponent()); 1843*f4a2713aSLionel Sambuc Comps.back().isBrackets = false; 1844*f4a2713aSLionel Sambuc Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 1845*f4a2713aSLionel Sambuc Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 1846*f4a2713aSLionel Sambuc 1847*f4a2713aSLionel Sambuc // FIXME: This loop leaks the index expressions on error. 1848*f4a2713aSLionel Sambuc while (1) { 1849*f4a2713aSLionel Sambuc if (Tok.is(tok::period)) { 1850*f4a2713aSLionel Sambuc // offsetof-member-designator: offsetof-member-designator '.' identifier 1851*f4a2713aSLionel Sambuc Comps.push_back(Sema::OffsetOfComponent()); 1852*f4a2713aSLionel Sambuc Comps.back().isBrackets = false; 1853*f4a2713aSLionel Sambuc Comps.back().LocStart = ConsumeToken(); 1854*f4a2713aSLionel Sambuc 1855*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 1856*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_ident); 1857*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1858*f4a2713aSLionel Sambuc return ExprError(); 1859*f4a2713aSLionel Sambuc } 1860*f4a2713aSLionel Sambuc Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 1861*f4a2713aSLionel Sambuc Comps.back().LocEnd = ConsumeToken(); 1862*f4a2713aSLionel Sambuc 1863*f4a2713aSLionel Sambuc } else if (Tok.is(tok::l_square)) { 1864*f4a2713aSLionel Sambuc if (CheckProhibitedCXX11Attribute()) 1865*f4a2713aSLionel Sambuc return ExprError(); 1866*f4a2713aSLionel Sambuc 1867*f4a2713aSLionel Sambuc // offsetof-member-designator: offsetof-member-design '[' expression ']' 1868*f4a2713aSLionel Sambuc Comps.push_back(Sema::OffsetOfComponent()); 1869*f4a2713aSLionel Sambuc Comps.back().isBrackets = true; 1870*f4a2713aSLionel Sambuc BalancedDelimiterTracker ST(*this, tok::l_square); 1871*f4a2713aSLionel Sambuc ST.consumeOpen(); 1872*f4a2713aSLionel Sambuc Comps.back().LocStart = ST.getOpenLocation(); 1873*f4a2713aSLionel Sambuc Res = ParseExpression(); 1874*f4a2713aSLionel Sambuc if (Res.isInvalid()) { 1875*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1876*f4a2713aSLionel Sambuc return Res; 1877*f4a2713aSLionel Sambuc } 1878*f4a2713aSLionel Sambuc Comps.back().U.E = Res.release(); 1879*f4a2713aSLionel Sambuc 1880*f4a2713aSLionel Sambuc ST.consumeClose(); 1881*f4a2713aSLionel Sambuc Comps.back().LocEnd = ST.getCloseLocation(); 1882*f4a2713aSLionel Sambuc } else { 1883*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 1884*f4a2713aSLionel Sambuc PT.consumeClose(); 1885*f4a2713aSLionel Sambuc Res = ExprError(); 1886*f4a2713aSLionel Sambuc } else if (Ty.isInvalid()) { 1887*f4a2713aSLionel Sambuc Res = ExprError(); 1888*f4a2713aSLionel Sambuc } else { 1889*f4a2713aSLionel Sambuc PT.consumeClose(); 1890*f4a2713aSLionel Sambuc Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc, 1891*f4a2713aSLionel Sambuc Ty.get(), &Comps[0], Comps.size(), 1892*f4a2713aSLionel Sambuc PT.getCloseLocation()); 1893*f4a2713aSLionel Sambuc } 1894*f4a2713aSLionel Sambuc break; 1895*f4a2713aSLionel Sambuc } 1896*f4a2713aSLionel Sambuc } 1897*f4a2713aSLionel Sambuc break; 1898*f4a2713aSLionel Sambuc } 1899*f4a2713aSLionel Sambuc case tok::kw___builtin_choose_expr: { 1900*f4a2713aSLionel Sambuc ExprResult Cond(ParseAssignmentExpression()); 1901*f4a2713aSLionel Sambuc if (Cond.isInvalid()) { 1902*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1903*f4a2713aSLionel Sambuc return Cond; 1904*f4a2713aSLionel Sambuc } 1905*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 1906*f4a2713aSLionel Sambuc return ExprError(); 1907*f4a2713aSLionel Sambuc 1908*f4a2713aSLionel Sambuc ExprResult Expr1(ParseAssignmentExpression()); 1909*f4a2713aSLionel Sambuc if (Expr1.isInvalid()) { 1910*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1911*f4a2713aSLionel Sambuc return Expr1; 1912*f4a2713aSLionel Sambuc } 1913*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 1914*f4a2713aSLionel Sambuc return ExprError(); 1915*f4a2713aSLionel Sambuc 1916*f4a2713aSLionel Sambuc ExprResult Expr2(ParseAssignmentExpression()); 1917*f4a2713aSLionel Sambuc if (Expr2.isInvalid()) { 1918*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1919*f4a2713aSLionel Sambuc return Expr2; 1920*f4a2713aSLionel Sambuc } 1921*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 1922*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_rparen); 1923*f4a2713aSLionel Sambuc return ExprError(); 1924*f4a2713aSLionel Sambuc } 1925*f4a2713aSLionel Sambuc Res = Actions.ActOnChooseExpr(StartLoc, Cond.take(), Expr1.take(), 1926*f4a2713aSLionel Sambuc Expr2.take(), ConsumeParen()); 1927*f4a2713aSLionel Sambuc break; 1928*f4a2713aSLionel Sambuc } 1929*f4a2713aSLionel Sambuc case tok::kw___builtin_astype: { 1930*f4a2713aSLionel Sambuc // The first argument is an expression to be converted, followed by a comma. 1931*f4a2713aSLionel Sambuc ExprResult Expr(ParseAssignmentExpression()); 1932*f4a2713aSLionel Sambuc if (Expr.isInvalid()) { 1933*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1934*f4a2713aSLionel Sambuc return ExprError(); 1935*f4a2713aSLionel Sambuc } 1936*f4a2713aSLionel Sambuc 1937*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", 1938*f4a2713aSLionel Sambuc tok::r_paren)) 1939*f4a2713aSLionel Sambuc return ExprError(); 1940*f4a2713aSLionel Sambuc 1941*f4a2713aSLionel Sambuc // Second argument is the type to bitcast to. 1942*f4a2713aSLionel Sambuc TypeResult DestTy = ParseTypeName(); 1943*f4a2713aSLionel Sambuc if (DestTy.isInvalid()) 1944*f4a2713aSLionel Sambuc return ExprError(); 1945*f4a2713aSLionel Sambuc 1946*f4a2713aSLionel Sambuc // Attempt to consume the r-paren. 1947*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 1948*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_rparen); 1949*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1950*f4a2713aSLionel Sambuc return ExprError(); 1951*f4a2713aSLionel Sambuc } 1952*f4a2713aSLionel Sambuc 1953*f4a2713aSLionel Sambuc Res = Actions.ActOnAsTypeExpr(Expr.take(), DestTy.get(), StartLoc, 1954*f4a2713aSLionel Sambuc ConsumeParen()); 1955*f4a2713aSLionel Sambuc break; 1956*f4a2713aSLionel Sambuc } 1957*f4a2713aSLionel Sambuc case tok::kw___builtin_convertvector: { 1958*f4a2713aSLionel Sambuc // The first argument is an expression to be converted, followed by a comma. 1959*f4a2713aSLionel Sambuc ExprResult Expr(ParseAssignmentExpression()); 1960*f4a2713aSLionel Sambuc if (Expr.isInvalid()) { 1961*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1962*f4a2713aSLionel Sambuc return ExprError(); 1963*f4a2713aSLionel Sambuc } 1964*f4a2713aSLionel Sambuc 1965*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", 1966*f4a2713aSLionel Sambuc tok::r_paren)) 1967*f4a2713aSLionel Sambuc return ExprError(); 1968*f4a2713aSLionel Sambuc 1969*f4a2713aSLionel Sambuc // Second argument is the type to bitcast to. 1970*f4a2713aSLionel Sambuc TypeResult DestTy = ParseTypeName(); 1971*f4a2713aSLionel Sambuc if (DestTy.isInvalid()) 1972*f4a2713aSLionel Sambuc return ExprError(); 1973*f4a2713aSLionel Sambuc 1974*f4a2713aSLionel Sambuc // Attempt to consume the r-paren. 1975*f4a2713aSLionel Sambuc if (Tok.isNot(tok::r_paren)) { 1976*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_rparen); 1977*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 1978*f4a2713aSLionel Sambuc return ExprError(); 1979*f4a2713aSLionel Sambuc } 1980*f4a2713aSLionel Sambuc 1981*f4a2713aSLionel Sambuc Res = Actions.ActOnConvertVectorExpr(Expr.take(), DestTy.get(), StartLoc, 1982*f4a2713aSLionel Sambuc ConsumeParen()); 1983*f4a2713aSLionel Sambuc break; 1984*f4a2713aSLionel Sambuc } 1985*f4a2713aSLionel Sambuc } 1986*f4a2713aSLionel Sambuc 1987*f4a2713aSLionel Sambuc if (Res.isInvalid()) 1988*f4a2713aSLionel Sambuc return ExprError(); 1989*f4a2713aSLionel Sambuc 1990*f4a2713aSLionel Sambuc // These can be followed by postfix-expr pieces because they are 1991*f4a2713aSLionel Sambuc // primary-expressions. 1992*f4a2713aSLionel Sambuc return ParsePostfixExpressionSuffix(Res.take()); 1993*f4a2713aSLionel Sambuc } 1994*f4a2713aSLionel Sambuc 1995*f4a2713aSLionel Sambuc /// ParseParenExpression - This parses the unit that starts with a '(' token, 1996*f4a2713aSLionel Sambuc /// based on what is allowed by ExprType. The actual thing parsed is returned 1997*f4a2713aSLionel Sambuc /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 1998*f4a2713aSLionel Sambuc /// not the parsed cast-expression. 1999*f4a2713aSLionel Sambuc /// 2000*f4a2713aSLionel Sambuc /// \verbatim 2001*f4a2713aSLionel Sambuc /// primary-expression: [C99 6.5.1] 2002*f4a2713aSLionel Sambuc /// '(' expression ')' 2003*f4a2713aSLionel Sambuc /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 2004*f4a2713aSLionel Sambuc /// postfix-expression: [C99 6.5.2] 2005*f4a2713aSLionel Sambuc /// '(' type-name ')' '{' initializer-list '}' 2006*f4a2713aSLionel Sambuc /// '(' type-name ')' '{' initializer-list ',' '}' 2007*f4a2713aSLionel Sambuc /// cast-expression: [C99 6.5.4] 2008*f4a2713aSLionel Sambuc /// '(' type-name ')' cast-expression 2009*f4a2713aSLionel Sambuc /// [ARC] bridged-cast-expression 2010*f4a2713aSLionel Sambuc /// 2011*f4a2713aSLionel Sambuc /// [ARC] bridged-cast-expression: 2012*f4a2713aSLionel Sambuc /// (__bridge type-name) cast-expression 2013*f4a2713aSLionel Sambuc /// (__bridge_transfer type-name) cast-expression 2014*f4a2713aSLionel Sambuc /// (__bridge_retained type-name) cast-expression 2015*f4a2713aSLionel Sambuc /// \endverbatim 2016*f4a2713aSLionel Sambuc ExprResult 2017*f4a2713aSLionel Sambuc Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 2018*f4a2713aSLionel Sambuc bool isTypeCast, ParsedType &CastTy, 2019*f4a2713aSLionel Sambuc SourceLocation &RParenLoc) { 2020*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 2021*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 2022*f4a2713aSLionel Sambuc if (T.consumeOpen()) 2023*f4a2713aSLionel Sambuc return ExprError(); 2024*f4a2713aSLionel Sambuc SourceLocation OpenLoc = T.getOpenLocation(); 2025*f4a2713aSLionel Sambuc 2026*f4a2713aSLionel Sambuc ExprResult Result(true); 2027*f4a2713aSLionel Sambuc bool isAmbiguousTypeId; 2028*f4a2713aSLionel Sambuc CastTy = ParsedType(); 2029*f4a2713aSLionel Sambuc 2030*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 2031*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), 2032*f4a2713aSLionel Sambuc ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression 2033*f4a2713aSLionel Sambuc : Sema::PCC_Expression); 2034*f4a2713aSLionel Sambuc cutOffParsing(); 2035*f4a2713aSLionel Sambuc return ExprError(); 2036*f4a2713aSLionel Sambuc } 2037*f4a2713aSLionel Sambuc 2038*f4a2713aSLionel Sambuc // Diagnose use of bridge casts in non-arc mode. 2039*f4a2713aSLionel Sambuc bool BridgeCast = (getLangOpts().ObjC2 && 2040*f4a2713aSLionel Sambuc (Tok.is(tok::kw___bridge) || 2041*f4a2713aSLionel Sambuc Tok.is(tok::kw___bridge_transfer) || 2042*f4a2713aSLionel Sambuc Tok.is(tok::kw___bridge_retained) || 2043*f4a2713aSLionel Sambuc Tok.is(tok::kw___bridge_retain))); 2044*f4a2713aSLionel Sambuc if (BridgeCast && !getLangOpts().ObjCAutoRefCount) { 2045*f4a2713aSLionel Sambuc if (Tok.isNot(tok::kw___bridge)) { 2046*f4a2713aSLionel Sambuc StringRef BridgeCastName = Tok.getName(); 2047*f4a2713aSLionel Sambuc SourceLocation BridgeKeywordLoc = ConsumeToken(); 2048*f4a2713aSLionel Sambuc if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 2049*f4a2713aSLionel Sambuc Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc) 2050*f4a2713aSLionel Sambuc << BridgeCastName 2051*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(BridgeKeywordLoc, ""); 2052*f4a2713aSLionel Sambuc } 2053*f4a2713aSLionel Sambuc else 2054*f4a2713aSLionel Sambuc ConsumeToken(); // consume __bridge 2055*f4a2713aSLionel Sambuc BridgeCast = false; 2056*f4a2713aSLionel Sambuc } 2057*f4a2713aSLionel Sambuc 2058*f4a2713aSLionel Sambuc // None of these cases should fall through with an invalid Result 2059*f4a2713aSLionel Sambuc // unless they've already reported an error. 2060*f4a2713aSLionel Sambuc if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 2061*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_gnu_statement_expr); 2062*f4a2713aSLionel Sambuc Actions.ActOnStartStmtExpr(); 2063*f4a2713aSLionel Sambuc 2064*f4a2713aSLionel Sambuc StmtResult Stmt(ParseCompoundStatement(true)); 2065*f4a2713aSLionel Sambuc ExprType = CompoundStmt; 2066*f4a2713aSLionel Sambuc 2067*f4a2713aSLionel Sambuc // If the substmt parsed correctly, build the AST node. 2068*f4a2713aSLionel Sambuc if (!Stmt.isInvalid()) { 2069*f4a2713aSLionel Sambuc Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation()); 2070*f4a2713aSLionel Sambuc } else { 2071*f4a2713aSLionel Sambuc Actions.ActOnStmtExprError(); 2072*f4a2713aSLionel Sambuc } 2073*f4a2713aSLionel Sambuc } else if (ExprType >= CompoundLiteral && BridgeCast) { 2074*f4a2713aSLionel Sambuc tok::TokenKind tokenKind = Tok.getKind(); 2075*f4a2713aSLionel Sambuc SourceLocation BridgeKeywordLoc = ConsumeToken(); 2076*f4a2713aSLionel Sambuc 2077*f4a2713aSLionel Sambuc // Parse an Objective-C ARC ownership cast expression. 2078*f4a2713aSLionel Sambuc ObjCBridgeCastKind Kind; 2079*f4a2713aSLionel Sambuc if (tokenKind == tok::kw___bridge) 2080*f4a2713aSLionel Sambuc Kind = OBC_Bridge; 2081*f4a2713aSLionel Sambuc else if (tokenKind == tok::kw___bridge_transfer) 2082*f4a2713aSLionel Sambuc Kind = OBC_BridgeTransfer; 2083*f4a2713aSLionel Sambuc else if (tokenKind == tok::kw___bridge_retained) 2084*f4a2713aSLionel Sambuc Kind = OBC_BridgeRetained; 2085*f4a2713aSLionel Sambuc else { 2086*f4a2713aSLionel Sambuc // As a hopefully temporary workaround, allow __bridge_retain as 2087*f4a2713aSLionel Sambuc // a synonym for __bridge_retained, but only in system headers. 2088*f4a2713aSLionel Sambuc assert(tokenKind == tok::kw___bridge_retain); 2089*f4a2713aSLionel Sambuc Kind = OBC_BridgeRetained; 2090*f4a2713aSLionel Sambuc if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc)) 2091*f4a2713aSLionel Sambuc Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain) 2092*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(BridgeKeywordLoc, 2093*f4a2713aSLionel Sambuc "__bridge_retained"); 2094*f4a2713aSLionel Sambuc } 2095*f4a2713aSLionel Sambuc 2096*f4a2713aSLionel Sambuc TypeResult Ty = ParseTypeName(); 2097*f4a2713aSLionel Sambuc T.consumeClose(); 2098*f4a2713aSLionel Sambuc RParenLoc = T.getCloseLocation(); 2099*f4a2713aSLionel Sambuc ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false); 2100*f4a2713aSLionel Sambuc 2101*f4a2713aSLionel Sambuc if (Ty.isInvalid() || SubExpr.isInvalid()) 2102*f4a2713aSLionel Sambuc return ExprError(); 2103*f4a2713aSLionel Sambuc 2104*f4a2713aSLionel Sambuc return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, 2105*f4a2713aSLionel Sambuc BridgeKeywordLoc, Ty.get(), 2106*f4a2713aSLionel Sambuc RParenLoc, SubExpr.get()); 2107*f4a2713aSLionel Sambuc } else if (ExprType >= CompoundLiteral && 2108*f4a2713aSLionel Sambuc isTypeIdInParens(isAmbiguousTypeId)) { 2109*f4a2713aSLionel Sambuc 2110*f4a2713aSLionel Sambuc // Otherwise, this is a compound literal expression or cast expression. 2111*f4a2713aSLionel Sambuc 2112*f4a2713aSLionel Sambuc // In C++, if the type-id is ambiguous we disambiguate based on context. 2113*f4a2713aSLionel Sambuc // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 2114*f4a2713aSLionel Sambuc // in which case we should treat it as type-id. 2115*f4a2713aSLionel Sambuc // if stopIfCastExpr is false, we need to determine the context past the 2116*f4a2713aSLionel Sambuc // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 2117*f4a2713aSLionel Sambuc if (isAmbiguousTypeId && !stopIfCastExpr) { 2118*f4a2713aSLionel Sambuc ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T); 2119*f4a2713aSLionel Sambuc RParenLoc = T.getCloseLocation(); 2120*f4a2713aSLionel Sambuc return res; 2121*f4a2713aSLionel Sambuc } 2122*f4a2713aSLionel Sambuc 2123*f4a2713aSLionel Sambuc // Parse the type declarator. 2124*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 2125*f4a2713aSLionel Sambuc ParseSpecifierQualifierList(DS); 2126*f4a2713aSLionel Sambuc Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 2127*f4a2713aSLionel Sambuc ParseDeclarator(DeclaratorInfo); 2128*f4a2713aSLionel Sambuc 2129*f4a2713aSLionel Sambuc // If our type is followed by an identifier and either ':' or ']', then 2130*f4a2713aSLionel Sambuc // this is probably an Objective-C message send where the leading '[' is 2131*f4a2713aSLionel Sambuc // missing. Recover as if that were the case. 2132*f4a2713aSLionel Sambuc if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && 2133*f4a2713aSLionel Sambuc !InMessageExpression && getLangOpts().ObjC1 && 2134*f4a2713aSLionel Sambuc (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { 2135*f4a2713aSLionel Sambuc TypeResult Ty; 2136*f4a2713aSLionel Sambuc { 2137*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 2138*f4a2713aSLionel Sambuc Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 2139*f4a2713aSLionel Sambuc } 2140*f4a2713aSLionel Sambuc Result = ParseObjCMessageExpressionBody(SourceLocation(), 2141*f4a2713aSLionel Sambuc SourceLocation(), 2142*f4a2713aSLionel Sambuc Ty.get(), 0); 2143*f4a2713aSLionel Sambuc } else { 2144*f4a2713aSLionel Sambuc // Match the ')'. 2145*f4a2713aSLionel Sambuc T.consumeClose(); 2146*f4a2713aSLionel Sambuc RParenLoc = T.getCloseLocation(); 2147*f4a2713aSLionel Sambuc if (Tok.is(tok::l_brace)) { 2148*f4a2713aSLionel Sambuc ExprType = CompoundLiteral; 2149*f4a2713aSLionel Sambuc TypeResult Ty; 2150*f4a2713aSLionel Sambuc { 2151*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 2152*f4a2713aSLionel Sambuc Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 2153*f4a2713aSLionel Sambuc } 2154*f4a2713aSLionel Sambuc return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 2155*f4a2713aSLionel Sambuc } 2156*f4a2713aSLionel Sambuc 2157*f4a2713aSLionel Sambuc if (ExprType == CastExpr) { 2158*f4a2713aSLionel Sambuc // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 2159*f4a2713aSLionel Sambuc 2160*f4a2713aSLionel Sambuc if (DeclaratorInfo.isInvalidType()) 2161*f4a2713aSLionel Sambuc return ExprError(); 2162*f4a2713aSLionel Sambuc 2163*f4a2713aSLionel Sambuc // Note that this doesn't parse the subsequent cast-expression, it just 2164*f4a2713aSLionel Sambuc // returns the parsed type to the callee. 2165*f4a2713aSLionel Sambuc if (stopIfCastExpr) { 2166*f4a2713aSLionel Sambuc TypeResult Ty; 2167*f4a2713aSLionel Sambuc { 2168*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 2169*f4a2713aSLionel Sambuc Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 2170*f4a2713aSLionel Sambuc } 2171*f4a2713aSLionel Sambuc CastTy = Ty.get(); 2172*f4a2713aSLionel Sambuc return ExprResult(); 2173*f4a2713aSLionel Sambuc } 2174*f4a2713aSLionel Sambuc 2175*f4a2713aSLionel Sambuc // Reject the cast of super idiom in ObjC. 2176*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier) && getLangOpts().ObjC1 && 2177*f4a2713aSLionel Sambuc Tok.getIdentifierInfo() == Ident_super && 2178*f4a2713aSLionel Sambuc getCurScope()->isInObjcMethodScope() && 2179*f4a2713aSLionel Sambuc GetLookAheadToken(1).isNot(tok::period)) { 2180*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_illegal_super_cast) 2181*f4a2713aSLionel Sambuc << SourceRange(OpenLoc, RParenLoc); 2182*f4a2713aSLionel Sambuc return ExprError(); 2183*f4a2713aSLionel Sambuc } 2184*f4a2713aSLionel Sambuc 2185*f4a2713aSLionel Sambuc // Parse the cast-expression that follows it next. 2186*f4a2713aSLionel Sambuc // TODO: For cast expression with CastTy. 2187*f4a2713aSLionel Sambuc Result = ParseCastExpression(/*isUnaryExpression=*/false, 2188*f4a2713aSLionel Sambuc /*isAddressOfOperand=*/false, 2189*f4a2713aSLionel Sambuc /*isTypeCast=*/IsTypeCast); 2190*f4a2713aSLionel Sambuc if (!Result.isInvalid()) { 2191*f4a2713aSLionel Sambuc Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, 2192*f4a2713aSLionel Sambuc DeclaratorInfo, CastTy, 2193*f4a2713aSLionel Sambuc RParenLoc, Result.take()); 2194*f4a2713aSLionel Sambuc } 2195*f4a2713aSLionel Sambuc return Result; 2196*f4a2713aSLionel Sambuc } 2197*f4a2713aSLionel Sambuc 2198*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 2199*f4a2713aSLionel Sambuc return ExprError(); 2200*f4a2713aSLionel Sambuc } 2201*f4a2713aSLionel Sambuc } else if (isTypeCast) { 2202*f4a2713aSLionel Sambuc // Parse the expression-list. 2203*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 2204*f4a2713aSLionel Sambuc 2205*f4a2713aSLionel Sambuc ExprVector ArgExprs; 2206*f4a2713aSLionel Sambuc CommaLocsTy CommaLocs; 2207*f4a2713aSLionel Sambuc 2208*f4a2713aSLionel Sambuc if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { 2209*f4a2713aSLionel Sambuc ExprType = SimpleExpr; 2210*f4a2713aSLionel Sambuc Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), 2211*f4a2713aSLionel Sambuc ArgExprs); 2212*f4a2713aSLionel Sambuc } 2213*f4a2713aSLionel Sambuc } else { 2214*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 2215*f4a2713aSLionel Sambuc 2216*f4a2713aSLionel Sambuc Result = ParseExpression(MaybeTypeCast); 2217*f4a2713aSLionel Sambuc ExprType = SimpleExpr; 2218*f4a2713aSLionel Sambuc 2219*f4a2713aSLionel Sambuc // Don't build a paren expression unless we actually match a ')'. 2220*f4a2713aSLionel Sambuc if (!Result.isInvalid() && Tok.is(tok::r_paren)) 2221*f4a2713aSLionel Sambuc Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.take()); 2222*f4a2713aSLionel Sambuc } 2223*f4a2713aSLionel Sambuc 2224*f4a2713aSLionel Sambuc // Match the ')'. 2225*f4a2713aSLionel Sambuc if (Result.isInvalid()) { 2226*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2227*f4a2713aSLionel Sambuc return ExprError(); 2228*f4a2713aSLionel Sambuc } 2229*f4a2713aSLionel Sambuc 2230*f4a2713aSLionel Sambuc T.consumeClose(); 2231*f4a2713aSLionel Sambuc RParenLoc = T.getCloseLocation(); 2232*f4a2713aSLionel Sambuc return Result; 2233*f4a2713aSLionel Sambuc } 2234*f4a2713aSLionel Sambuc 2235*f4a2713aSLionel Sambuc /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 2236*f4a2713aSLionel Sambuc /// and we are at the left brace. 2237*f4a2713aSLionel Sambuc /// 2238*f4a2713aSLionel Sambuc /// \verbatim 2239*f4a2713aSLionel Sambuc /// postfix-expression: [C99 6.5.2] 2240*f4a2713aSLionel Sambuc /// '(' type-name ')' '{' initializer-list '}' 2241*f4a2713aSLionel Sambuc /// '(' type-name ')' '{' initializer-list ',' '}' 2242*f4a2713aSLionel Sambuc /// \endverbatim 2243*f4a2713aSLionel Sambuc ExprResult 2244*f4a2713aSLionel Sambuc Parser::ParseCompoundLiteralExpression(ParsedType Ty, 2245*f4a2713aSLionel Sambuc SourceLocation LParenLoc, 2246*f4a2713aSLionel Sambuc SourceLocation RParenLoc) { 2247*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 2248*f4a2713aSLionel Sambuc if (!getLangOpts().C99) // Compound literals don't exist in C90. 2249*f4a2713aSLionel Sambuc Diag(LParenLoc, diag::ext_c99_compound_literal); 2250*f4a2713aSLionel Sambuc ExprResult Result = ParseInitializer(); 2251*f4a2713aSLionel Sambuc if (!Result.isInvalid() && Ty) 2252*f4a2713aSLionel Sambuc return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.take()); 2253*f4a2713aSLionel Sambuc return Result; 2254*f4a2713aSLionel Sambuc } 2255*f4a2713aSLionel Sambuc 2256*f4a2713aSLionel Sambuc /// ParseStringLiteralExpression - This handles the various token types that 2257*f4a2713aSLionel Sambuc /// form string literals, and also handles string concatenation [C99 5.1.1.2, 2258*f4a2713aSLionel Sambuc /// translation phase #6]. 2259*f4a2713aSLionel Sambuc /// 2260*f4a2713aSLionel Sambuc /// \verbatim 2261*f4a2713aSLionel Sambuc /// primary-expression: [C99 6.5.1] 2262*f4a2713aSLionel Sambuc /// string-literal 2263*f4a2713aSLionel Sambuc /// \verbatim 2264*f4a2713aSLionel Sambuc ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) { 2265*f4a2713aSLionel Sambuc assert(isTokenStringLiteral() && "Not a string literal!"); 2266*f4a2713aSLionel Sambuc 2267*f4a2713aSLionel Sambuc // String concat. Note that keywords like __func__ and __FUNCTION__ are not 2268*f4a2713aSLionel Sambuc // considered to be strings for concatenation purposes. 2269*f4a2713aSLionel Sambuc SmallVector<Token, 4> StringToks; 2270*f4a2713aSLionel Sambuc 2271*f4a2713aSLionel Sambuc do { 2272*f4a2713aSLionel Sambuc StringToks.push_back(Tok); 2273*f4a2713aSLionel Sambuc ConsumeStringToken(); 2274*f4a2713aSLionel Sambuc } while (isTokenStringLiteral()); 2275*f4a2713aSLionel Sambuc 2276*f4a2713aSLionel Sambuc // Pass the set of string tokens, ready for concatenation, to the actions. 2277*f4a2713aSLionel Sambuc return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size(), 2278*f4a2713aSLionel Sambuc AllowUserDefinedLiteral ? getCurScope() : 0); 2279*f4a2713aSLionel Sambuc } 2280*f4a2713aSLionel Sambuc 2281*f4a2713aSLionel Sambuc /// ParseGenericSelectionExpression - Parse a C11 generic-selection 2282*f4a2713aSLionel Sambuc /// [C11 6.5.1.1]. 2283*f4a2713aSLionel Sambuc /// 2284*f4a2713aSLionel Sambuc /// \verbatim 2285*f4a2713aSLionel Sambuc /// generic-selection: 2286*f4a2713aSLionel Sambuc /// _Generic ( assignment-expression , generic-assoc-list ) 2287*f4a2713aSLionel Sambuc /// generic-assoc-list: 2288*f4a2713aSLionel Sambuc /// generic-association 2289*f4a2713aSLionel Sambuc /// generic-assoc-list , generic-association 2290*f4a2713aSLionel Sambuc /// generic-association: 2291*f4a2713aSLionel Sambuc /// type-name : assignment-expression 2292*f4a2713aSLionel Sambuc /// default : assignment-expression 2293*f4a2713aSLionel Sambuc /// \endverbatim 2294*f4a2713aSLionel Sambuc ExprResult Parser::ParseGenericSelectionExpression() { 2295*f4a2713aSLionel Sambuc assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected"); 2296*f4a2713aSLionel Sambuc SourceLocation KeyLoc = ConsumeToken(); 2297*f4a2713aSLionel Sambuc 2298*f4a2713aSLionel Sambuc if (!getLangOpts().C11) 2299*f4a2713aSLionel Sambuc Diag(KeyLoc, diag::ext_c11_generic_selection); 2300*f4a2713aSLionel Sambuc 2301*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_paren); 2302*f4a2713aSLionel Sambuc if (T.expectAndConsume(diag::err_expected_lparen)) 2303*f4a2713aSLionel Sambuc return ExprError(); 2304*f4a2713aSLionel Sambuc 2305*f4a2713aSLionel Sambuc ExprResult ControllingExpr; 2306*f4a2713aSLionel Sambuc { 2307*f4a2713aSLionel Sambuc // C11 6.5.1.1p3 "The controlling expression of a generic selection is 2308*f4a2713aSLionel Sambuc // not evaluated." 2309*f4a2713aSLionel Sambuc EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 2310*f4a2713aSLionel Sambuc ControllingExpr = ParseAssignmentExpression(); 2311*f4a2713aSLionel Sambuc if (ControllingExpr.isInvalid()) { 2312*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2313*f4a2713aSLionel Sambuc return ExprError(); 2314*f4a2713aSLionel Sambuc } 2315*f4a2713aSLionel Sambuc } 2316*f4a2713aSLionel Sambuc 2317*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "")) { 2318*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2319*f4a2713aSLionel Sambuc return ExprError(); 2320*f4a2713aSLionel Sambuc } 2321*f4a2713aSLionel Sambuc 2322*f4a2713aSLionel Sambuc SourceLocation DefaultLoc; 2323*f4a2713aSLionel Sambuc TypeVector Types; 2324*f4a2713aSLionel Sambuc ExprVector Exprs; 2325*f4a2713aSLionel Sambuc while (1) { 2326*f4a2713aSLionel Sambuc ParsedType Ty; 2327*f4a2713aSLionel Sambuc if (Tok.is(tok::kw_default)) { 2328*f4a2713aSLionel Sambuc // C11 6.5.1.1p2 "A generic selection shall have no more than one default 2329*f4a2713aSLionel Sambuc // generic association." 2330*f4a2713aSLionel Sambuc if (!DefaultLoc.isInvalid()) { 2331*f4a2713aSLionel Sambuc Diag(Tok, diag::err_duplicate_default_assoc); 2332*f4a2713aSLionel Sambuc Diag(DefaultLoc, diag::note_previous_default_assoc); 2333*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2334*f4a2713aSLionel Sambuc return ExprError(); 2335*f4a2713aSLionel Sambuc } 2336*f4a2713aSLionel Sambuc DefaultLoc = ConsumeToken(); 2337*f4a2713aSLionel Sambuc Ty = ParsedType(); 2338*f4a2713aSLionel Sambuc } else { 2339*f4a2713aSLionel Sambuc ColonProtectionRAIIObject X(*this); 2340*f4a2713aSLionel Sambuc TypeResult TR = ParseTypeName(); 2341*f4a2713aSLionel Sambuc if (TR.isInvalid()) { 2342*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2343*f4a2713aSLionel Sambuc return ExprError(); 2344*f4a2713aSLionel Sambuc } 2345*f4a2713aSLionel Sambuc Ty = TR.release(); 2346*f4a2713aSLionel Sambuc } 2347*f4a2713aSLionel Sambuc Types.push_back(Ty); 2348*f4a2713aSLionel Sambuc 2349*f4a2713aSLionel Sambuc if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "")) { 2350*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2351*f4a2713aSLionel Sambuc return ExprError(); 2352*f4a2713aSLionel Sambuc } 2353*f4a2713aSLionel Sambuc 2354*f4a2713aSLionel Sambuc // FIXME: These expressions should be parsed in a potentially potentially 2355*f4a2713aSLionel Sambuc // evaluated context. 2356*f4a2713aSLionel Sambuc ExprResult ER(ParseAssignmentExpression()); 2357*f4a2713aSLionel Sambuc if (ER.isInvalid()) { 2358*f4a2713aSLionel Sambuc SkipUntil(tok::r_paren, StopAtSemi); 2359*f4a2713aSLionel Sambuc return ExprError(); 2360*f4a2713aSLionel Sambuc } 2361*f4a2713aSLionel Sambuc Exprs.push_back(ER.release()); 2362*f4a2713aSLionel Sambuc 2363*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 2364*f4a2713aSLionel Sambuc break; 2365*f4a2713aSLionel Sambuc ConsumeToken(); 2366*f4a2713aSLionel Sambuc } 2367*f4a2713aSLionel Sambuc 2368*f4a2713aSLionel Sambuc T.consumeClose(); 2369*f4a2713aSLionel Sambuc if (T.getCloseLocation().isInvalid()) 2370*f4a2713aSLionel Sambuc return ExprError(); 2371*f4a2713aSLionel Sambuc 2372*f4a2713aSLionel Sambuc return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, 2373*f4a2713aSLionel Sambuc T.getCloseLocation(), 2374*f4a2713aSLionel Sambuc ControllingExpr.release(), 2375*f4a2713aSLionel Sambuc Types, Exprs); 2376*f4a2713aSLionel Sambuc } 2377*f4a2713aSLionel Sambuc 2378*f4a2713aSLionel Sambuc /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 2379*f4a2713aSLionel Sambuc /// 2380*f4a2713aSLionel Sambuc /// \verbatim 2381*f4a2713aSLionel Sambuc /// argument-expression-list: 2382*f4a2713aSLionel Sambuc /// assignment-expression 2383*f4a2713aSLionel Sambuc /// argument-expression-list , assignment-expression 2384*f4a2713aSLionel Sambuc /// 2385*f4a2713aSLionel Sambuc /// [C++] expression-list: 2386*f4a2713aSLionel Sambuc /// [C++] assignment-expression 2387*f4a2713aSLionel Sambuc /// [C++] expression-list , assignment-expression 2388*f4a2713aSLionel Sambuc /// 2389*f4a2713aSLionel Sambuc /// [C++0x] expression-list: 2390*f4a2713aSLionel Sambuc /// [C++0x] initializer-list 2391*f4a2713aSLionel Sambuc /// 2392*f4a2713aSLionel Sambuc /// [C++0x] initializer-list 2393*f4a2713aSLionel Sambuc /// [C++0x] initializer-clause ...[opt] 2394*f4a2713aSLionel Sambuc /// [C++0x] initializer-list , initializer-clause ...[opt] 2395*f4a2713aSLionel Sambuc /// 2396*f4a2713aSLionel Sambuc /// [C++0x] initializer-clause: 2397*f4a2713aSLionel Sambuc /// [C++0x] assignment-expression 2398*f4a2713aSLionel Sambuc /// [C++0x] braced-init-list 2399*f4a2713aSLionel Sambuc /// \endverbatim 2400*f4a2713aSLionel Sambuc bool Parser::ParseExpressionList(SmallVectorImpl<Expr*> &Exprs, 2401*f4a2713aSLionel Sambuc SmallVectorImpl<SourceLocation> &CommaLocs, 2402*f4a2713aSLionel Sambuc void (Sema::*Completer)(Scope *S, 2403*f4a2713aSLionel Sambuc Expr *Data, 2404*f4a2713aSLionel Sambuc ArrayRef<Expr *> Args), 2405*f4a2713aSLionel Sambuc Expr *Data) { 2406*f4a2713aSLionel Sambuc while (1) { 2407*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 2408*f4a2713aSLionel Sambuc if (Completer) 2409*f4a2713aSLionel Sambuc (Actions.*Completer)(getCurScope(), Data, Exprs); 2410*f4a2713aSLionel Sambuc else 2411*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); 2412*f4a2713aSLionel Sambuc cutOffParsing(); 2413*f4a2713aSLionel Sambuc return true; 2414*f4a2713aSLionel Sambuc } 2415*f4a2713aSLionel Sambuc 2416*f4a2713aSLionel Sambuc ExprResult Expr; 2417*f4a2713aSLionel Sambuc if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 2418*f4a2713aSLionel Sambuc Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 2419*f4a2713aSLionel Sambuc Expr = ParseBraceInitializer(); 2420*f4a2713aSLionel Sambuc } else 2421*f4a2713aSLionel Sambuc Expr = ParseAssignmentExpression(); 2422*f4a2713aSLionel Sambuc 2423*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis)) 2424*f4a2713aSLionel Sambuc Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); 2425*f4a2713aSLionel Sambuc if (Expr.isInvalid()) 2426*f4a2713aSLionel Sambuc return true; 2427*f4a2713aSLionel Sambuc 2428*f4a2713aSLionel Sambuc Exprs.push_back(Expr.release()); 2429*f4a2713aSLionel Sambuc 2430*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 2431*f4a2713aSLionel Sambuc return false; 2432*f4a2713aSLionel Sambuc // Move to the next argument, remember where the comma was. 2433*f4a2713aSLionel Sambuc CommaLocs.push_back(ConsumeToken()); 2434*f4a2713aSLionel Sambuc } 2435*f4a2713aSLionel Sambuc } 2436*f4a2713aSLionel Sambuc 2437*f4a2713aSLionel Sambuc /// ParseSimpleExpressionList - A simple comma-separated list of expressions, 2438*f4a2713aSLionel Sambuc /// used for misc language extensions. 2439*f4a2713aSLionel Sambuc /// 2440*f4a2713aSLionel Sambuc /// \verbatim 2441*f4a2713aSLionel Sambuc /// simple-expression-list: 2442*f4a2713aSLionel Sambuc /// assignment-expression 2443*f4a2713aSLionel Sambuc /// simple-expression-list , assignment-expression 2444*f4a2713aSLionel Sambuc /// \endverbatim 2445*f4a2713aSLionel Sambuc bool 2446*f4a2713aSLionel Sambuc Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, 2447*f4a2713aSLionel Sambuc SmallVectorImpl<SourceLocation> &CommaLocs) { 2448*f4a2713aSLionel Sambuc while (1) { 2449*f4a2713aSLionel Sambuc ExprResult Expr = ParseAssignmentExpression(); 2450*f4a2713aSLionel Sambuc if (Expr.isInvalid()) 2451*f4a2713aSLionel Sambuc return true; 2452*f4a2713aSLionel Sambuc 2453*f4a2713aSLionel Sambuc Exprs.push_back(Expr.release()); 2454*f4a2713aSLionel Sambuc 2455*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) 2456*f4a2713aSLionel Sambuc return false; 2457*f4a2713aSLionel Sambuc 2458*f4a2713aSLionel Sambuc // Move to the next argument, remember where the comma was. 2459*f4a2713aSLionel Sambuc CommaLocs.push_back(ConsumeToken()); 2460*f4a2713aSLionel Sambuc } 2461*f4a2713aSLionel Sambuc } 2462*f4a2713aSLionel Sambuc 2463*f4a2713aSLionel Sambuc /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 2464*f4a2713aSLionel Sambuc /// 2465*f4a2713aSLionel Sambuc /// \verbatim 2466*f4a2713aSLionel Sambuc /// [clang] block-id: 2467*f4a2713aSLionel Sambuc /// [clang] specifier-qualifier-list block-declarator 2468*f4a2713aSLionel Sambuc /// \endverbatim 2469*f4a2713aSLionel Sambuc void Parser::ParseBlockId(SourceLocation CaretLoc) { 2470*f4a2713aSLionel Sambuc if (Tok.is(tok::code_completion)) { 2471*f4a2713aSLionel Sambuc Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); 2472*f4a2713aSLionel Sambuc return cutOffParsing(); 2473*f4a2713aSLionel Sambuc } 2474*f4a2713aSLionel Sambuc 2475*f4a2713aSLionel Sambuc // Parse the specifier-qualifier-list piece. 2476*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 2477*f4a2713aSLionel Sambuc ParseSpecifierQualifierList(DS); 2478*f4a2713aSLionel Sambuc 2479*f4a2713aSLionel Sambuc // Parse the block-declarator. 2480*f4a2713aSLionel Sambuc Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext); 2481*f4a2713aSLionel Sambuc ParseDeclarator(DeclaratorInfo); 2482*f4a2713aSLionel Sambuc 2483*f4a2713aSLionel Sambuc // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes. 2484*f4a2713aSLionel Sambuc DeclaratorInfo.takeAttributes(DS.getAttributes(), SourceLocation()); 2485*f4a2713aSLionel Sambuc 2486*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(DeclaratorInfo); 2487*f4a2713aSLionel Sambuc 2488*f4a2713aSLionel Sambuc // Inform sema that we are starting a block. 2489*f4a2713aSLionel Sambuc Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope()); 2490*f4a2713aSLionel Sambuc } 2491*f4a2713aSLionel Sambuc 2492*f4a2713aSLionel Sambuc /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 2493*f4a2713aSLionel Sambuc /// like ^(int x){ return x+1; } 2494*f4a2713aSLionel Sambuc /// 2495*f4a2713aSLionel Sambuc /// \verbatim 2496*f4a2713aSLionel Sambuc /// block-literal: 2497*f4a2713aSLionel Sambuc /// [clang] '^' block-args[opt] compound-statement 2498*f4a2713aSLionel Sambuc /// [clang] '^' block-id compound-statement 2499*f4a2713aSLionel Sambuc /// [clang] block-args: 2500*f4a2713aSLionel Sambuc /// [clang] '(' parameter-list ')' 2501*f4a2713aSLionel Sambuc /// \endverbatim 2502*f4a2713aSLionel Sambuc ExprResult Parser::ParseBlockLiteralExpression() { 2503*f4a2713aSLionel Sambuc assert(Tok.is(tok::caret) && "block literal starts with ^"); 2504*f4a2713aSLionel Sambuc SourceLocation CaretLoc = ConsumeToken(); 2505*f4a2713aSLionel Sambuc 2506*f4a2713aSLionel Sambuc PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 2507*f4a2713aSLionel Sambuc "block literal parsing"); 2508*f4a2713aSLionel Sambuc 2509*f4a2713aSLionel Sambuc // Enter a scope to hold everything within the block. This includes the 2510*f4a2713aSLionel Sambuc // argument decls, decls within the compound expression, etc. This also 2511*f4a2713aSLionel Sambuc // allows determining whether a variable reference inside the block is 2512*f4a2713aSLionel Sambuc // within or outside of the block. 2513*f4a2713aSLionel Sambuc ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 2514*f4a2713aSLionel Sambuc Scope::DeclScope); 2515*f4a2713aSLionel Sambuc 2516*f4a2713aSLionel Sambuc // Inform sema that we are starting a block. 2517*f4a2713aSLionel Sambuc Actions.ActOnBlockStart(CaretLoc, getCurScope()); 2518*f4a2713aSLionel Sambuc 2519*f4a2713aSLionel Sambuc // Parse the return type if present. 2520*f4a2713aSLionel Sambuc DeclSpec DS(AttrFactory); 2521*f4a2713aSLionel Sambuc Declarator ParamInfo(DS, Declarator::BlockLiteralContext); 2522*f4a2713aSLionel Sambuc // FIXME: Since the return type isn't actually parsed, it can't be used to 2523*f4a2713aSLionel Sambuc // fill ParamInfo with an initial valid range, so do it manually. 2524*f4a2713aSLionel Sambuc ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 2525*f4a2713aSLionel Sambuc 2526*f4a2713aSLionel Sambuc // If this block has arguments, parse them. There is no ambiguity here with 2527*f4a2713aSLionel Sambuc // the expression case, because the expression case requires a parameter list. 2528*f4a2713aSLionel Sambuc if (Tok.is(tok::l_paren)) { 2529*f4a2713aSLionel Sambuc ParseParenDeclarator(ParamInfo); 2530*f4a2713aSLionel Sambuc // Parse the pieces after the identifier as if we had "int(...)". 2531*f4a2713aSLionel Sambuc // SetIdentifier sets the source range end, but in this case we're past 2532*f4a2713aSLionel Sambuc // that location. 2533*f4a2713aSLionel Sambuc SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 2534*f4a2713aSLionel Sambuc ParamInfo.SetIdentifier(0, CaretLoc); 2535*f4a2713aSLionel Sambuc ParamInfo.SetRangeEnd(Tmp); 2536*f4a2713aSLionel Sambuc if (ParamInfo.isInvalidType()) { 2537*f4a2713aSLionel Sambuc // If there was an error parsing the arguments, they may have 2538*f4a2713aSLionel Sambuc // tried to use ^(x+y) which requires an argument list. Just 2539*f4a2713aSLionel Sambuc // skip the whole block literal. 2540*f4a2713aSLionel Sambuc Actions.ActOnBlockError(CaretLoc, getCurScope()); 2541*f4a2713aSLionel Sambuc return ExprError(); 2542*f4a2713aSLionel Sambuc } 2543*f4a2713aSLionel Sambuc 2544*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(ParamInfo); 2545*f4a2713aSLionel Sambuc 2546*f4a2713aSLionel Sambuc // Inform sema that we are starting a block. 2547*f4a2713aSLionel Sambuc Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 2548*f4a2713aSLionel Sambuc } else if (!Tok.is(tok::l_brace)) { 2549*f4a2713aSLionel Sambuc ParseBlockId(CaretLoc); 2550*f4a2713aSLionel Sambuc } else { 2551*f4a2713aSLionel Sambuc // Otherwise, pretend we saw (void). 2552*f4a2713aSLionel Sambuc ParsedAttributes attrs(AttrFactory); 2553*f4a2713aSLionel Sambuc SourceLocation NoLoc; 2554*f4a2713aSLionel Sambuc ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true, 2555*f4a2713aSLionel Sambuc /*IsAmbiguous=*/false, 2556*f4a2713aSLionel Sambuc /*RParenLoc=*/NoLoc, 2557*f4a2713aSLionel Sambuc /*ArgInfo=*/0, 2558*f4a2713aSLionel Sambuc /*NumArgs=*/0, 2559*f4a2713aSLionel Sambuc /*EllipsisLoc=*/NoLoc, 2560*f4a2713aSLionel Sambuc /*RParenLoc=*/NoLoc, 2561*f4a2713aSLionel Sambuc /*TypeQuals=*/0, 2562*f4a2713aSLionel Sambuc /*RefQualifierIsLvalueRef=*/true, 2563*f4a2713aSLionel Sambuc /*RefQualifierLoc=*/NoLoc, 2564*f4a2713aSLionel Sambuc /*ConstQualifierLoc=*/NoLoc, 2565*f4a2713aSLionel Sambuc /*VolatileQualifierLoc=*/NoLoc, 2566*f4a2713aSLionel Sambuc /*MutableLoc=*/NoLoc, 2567*f4a2713aSLionel Sambuc EST_None, 2568*f4a2713aSLionel Sambuc /*ESpecLoc=*/NoLoc, 2569*f4a2713aSLionel Sambuc /*Exceptions=*/0, 2570*f4a2713aSLionel Sambuc /*ExceptionRanges=*/0, 2571*f4a2713aSLionel Sambuc /*NumExceptions=*/0, 2572*f4a2713aSLionel Sambuc /*NoexceptExpr=*/0, 2573*f4a2713aSLionel Sambuc CaretLoc, CaretLoc, 2574*f4a2713aSLionel Sambuc ParamInfo), 2575*f4a2713aSLionel Sambuc attrs, CaretLoc); 2576*f4a2713aSLionel Sambuc 2577*f4a2713aSLionel Sambuc MaybeParseGNUAttributes(ParamInfo); 2578*f4a2713aSLionel Sambuc 2579*f4a2713aSLionel Sambuc // Inform sema that we are starting a block. 2580*f4a2713aSLionel Sambuc Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope()); 2581*f4a2713aSLionel Sambuc } 2582*f4a2713aSLionel Sambuc 2583*f4a2713aSLionel Sambuc 2584*f4a2713aSLionel Sambuc ExprResult Result(true); 2585*f4a2713aSLionel Sambuc if (!Tok.is(tok::l_brace)) { 2586*f4a2713aSLionel Sambuc // Saw something like: ^expr 2587*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_expression); 2588*f4a2713aSLionel Sambuc Actions.ActOnBlockError(CaretLoc, getCurScope()); 2589*f4a2713aSLionel Sambuc return ExprError(); 2590*f4a2713aSLionel Sambuc } 2591*f4a2713aSLionel Sambuc 2592*f4a2713aSLionel Sambuc StmtResult Stmt(ParseCompoundStatementBody()); 2593*f4a2713aSLionel Sambuc BlockScope.Exit(); 2594*f4a2713aSLionel Sambuc if (!Stmt.isInvalid()) 2595*f4a2713aSLionel Sambuc Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope()); 2596*f4a2713aSLionel Sambuc else 2597*f4a2713aSLionel Sambuc Actions.ActOnBlockError(CaretLoc, getCurScope()); 2598*f4a2713aSLionel Sambuc return Result; 2599*f4a2713aSLionel Sambuc } 2600*f4a2713aSLionel Sambuc 2601*f4a2713aSLionel Sambuc /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals. 2602*f4a2713aSLionel Sambuc /// 2603*f4a2713aSLionel Sambuc /// '__objc_yes' 2604*f4a2713aSLionel Sambuc /// '__objc_no' 2605*f4a2713aSLionel Sambuc ExprResult Parser::ParseObjCBoolLiteral() { 2606*f4a2713aSLionel Sambuc tok::TokenKind Kind = Tok.getKind(); 2607*f4a2713aSLionel Sambuc return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind); 2608*f4a2713aSLionel Sambuc } 2609