clang API Documentation
00001 //===--- ParseExpr.cpp - Expression Parsing -------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the Expression parsing implementation. Expressions in 00011 // C99 basically consist of a bunch of binary operators with unary operators and 00012 // other random stuff at the leaves. 00013 // 00014 // In the C99 grammar, these unary operators bind tightest and are represented 00015 // as the 'cast-expression' production. Everything else is either a binary 00016 // operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are 00017 // handled by ParseCastExpression, the higher level pieces are handled by 00018 // ParseBinaryExpression. 00019 // 00020 //===----------------------------------------------------------------------===// 00021 00022 #include "clang/Parse/Parser.h" 00023 #include "clang/Parse/DeclSpec.h" 00024 #include "clang/Parse/Scope.h" 00025 #include "clang/Parse/Template.h" 00026 #include "clang/Basic/PrettyStackTrace.h" 00027 #include "RAIIObjectsForParser.h" 00028 #include "llvm/ADT/SmallVector.h" 00029 #include "llvm/ADT/SmallString.h" 00030 using namespace clang; 00031 00032 /// PrecedenceLevels - These are precedences for the binary/ternary operators in 00033 /// the C99 grammar. These have been named to relate with the C99 grammar 00034 /// productions. Low precedences numbers bind more weakly than high numbers. 00035 namespace prec { 00036 enum Level { 00037 Unknown = 0, // Not binary operator. 00038 Comma = 1, // , 00039 Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= 00040 Conditional = 3, // ? 00041 LogicalOr = 4, // || 00042 LogicalAnd = 5, // && 00043 InclusiveOr = 6, // | 00044 ExclusiveOr = 7, // ^ 00045 And = 8, // & 00046 Equality = 9, // ==, != 00047 Relational = 10, // >=, <=, >, < 00048 Shift = 11, // <<, >> 00049 Additive = 12, // -, + 00050 Multiplicative = 13, // *, /, % 00051 PointerToMember = 14 // .*, ->* 00052 }; 00053 } 00054 00055 00056 /// getBinOpPrecedence - Return the precedence of the specified binary operator 00057 /// token. This returns: 00058 /// 00059 static prec::Level getBinOpPrecedence(tok::TokenKind Kind, 00060 bool GreaterThanIsOperator, 00061 bool CPlusPlus0x) { 00062 switch (Kind) { 00063 case tok::greater: 00064 // C++ [temp.names]p3: 00065 // [...] When parsing a template-argument-list, the first 00066 // non-nested > is taken as the ending delimiter rather than a 00067 // greater-than operator. [...] 00068 if (GreaterThanIsOperator) 00069 return prec::Relational; 00070 return prec::Unknown; 00071 00072 case tok::greatergreater: 00073 // C++0x [temp.names]p3: 00074 // 00075 // [...] Similarly, the first non-nested >> is treated as two 00076 // consecutive but distinct > tokens, the first of which is 00077 // taken as the end of the template-argument-list and completes 00078 // the template-id. [...] 00079 if (GreaterThanIsOperator || !CPlusPlus0x) 00080 return prec::Shift; 00081 return prec::Unknown; 00082 00083 default: return prec::Unknown; 00084 case tok::comma: return prec::Comma; 00085 case tok::equal: 00086 case tok::starequal: 00087 case tok::slashequal: 00088 case tok::percentequal: 00089 case tok::plusequal: 00090 case tok::minusequal: 00091 case tok::lesslessequal: 00092 case tok::greatergreaterequal: 00093 case tok::ampequal: 00094 case tok::caretequal: 00095 case tok::pipeequal: return prec::Assignment; 00096 case tok::question: return prec::Conditional; 00097 case tok::pipepipe: return prec::LogicalOr; 00098 case tok::ampamp: return prec::LogicalAnd; 00099 case tok::pipe: return prec::InclusiveOr; 00100 case tok::caret: return prec::ExclusiveOr; 00101 case tok::amp: return prec::And; 00102 case tok::exclaimequal: 00103 case tok::equalequal: return prec::Equality; 00104 case tok::lessequal: 00105 case tok::less: 00106 case tok::greaterequal: return prec::Relational; 00107 case tok::lessless: return prec::Shift; 00108 case tok::plus: 00109 case tok::minus: return prec::Additive; 00110 case tok::percent: 00111 case tok::slash: 00112 case tok::star: return prec::Multiplicative; 00113 case tok::periodstar: 00114 case tok::arrowstar: return prec::PointerToMember; 00115 } 00116 } 00117 00118 00119 /// ParseExpression - Simple precedence-based parser for binary/ternary 00120 /// operators. 00121 /// 00122 /// Note: we diverge from the C99 grammar when parsing the assignment-expression 00123 /// production. C99 specifies that the LHS of an assignment operator should be 00124 /// parsed as a unary-expression, but consistency dictates that it be a 00125 /// conditional-expession. In practice, the important thing here is that the 00126 /// LHS of an assignment has to be an l-value, which productions between 00127 /// unary-expression and conditional-expression don't produce. Because we want 00128 /// consistency, we parse the LHS as a conditional-expression, then check for 00129 /// l-value-ness in semantic analysis stages. 00130 /// 00131 /// pm-expression: [C++ 5.5] 00132 /// cast-expression 00133 /// pm-expression '.*' cast-expression 00134 /// pm-expression '->*' cast-expression 00135 /// 00136 /// multiplicative-expression: [C99 6.5.5] 00137 /// Note: in C++, apply pm-expression instead of cast-expression 00138 /// cast-expression 00139 /// multiplicative-expression '*' cast-expression 00140 /// multiplicative-expression '/' cast-expression 00141 /// multiplicative-expression '%' cast-expression 00142 /// 00143 /// additive-expression: [C99 6.5.6] 00144 /// multiplicative-expression 00145 /// additive-expression '+' multiplicative-expression 00146 /// additive-expression '-' multiplicative-expression 00147 /// 00148 /// shift-expression: [C99 6.5.7] 00149 /// additive-expression 00150 /// shift-expression '<<' additive-expression 00151 /// shift-expression '>>' additive-expression 00152 /// 00153 /// relational-expression: [C99 6.5.8] 00154 /// shift-expression 00155 /// relational-expression '<' shift-expression 00156 /// relational-expression '>' shift-expression 00157 /// relational-expression '<=' shift-expression 00158 /// relational-expression '>=' shift-expression 00159 /// 00160 /// equality-expression: [C99 6.5.9] 00161 /// relational-expression 00162 /// equality-expression '==' relational-expression 00163 /// equality-expression '!=' relational-expression 00164 /// 00165 /// AND-expression: [C99 6.5.10] 00166 /// equality-expression 00167 /// AND-expression '&' equality-expression 00168 /// 00169 /// exclusive-OR-expression: [C99 6.5.11] 00170 /// AND-expression 00171 /// exclusive-OR-expression '^' AND-expression 00172 /// 00173 /// inclusive-OR-expression: [C99 6.5.12] 00174 /// exclusive-OR-expression 00175 /// inclusive-OR-expression '|' exclusive-OR-expression 00176 /// 00177 /// logical-AND-expression: [C99 6.5.13] 00178 /// inclusive-OR-expression 00179 /// logical-AND-expression '&&' inclusive-OR-expression 00180 /// 00181 /// logical-OR-expression: [C99 6.5.14] 00182 /// logical-AND-expression 00183 /// logical-OR-expression '||' logical-AND-expression 00184 /// 00185 /// conditional-expression: [C99 6.5.15] 00186 /// logical-OR-expression 00187 /// logical-OR-expression '?' expression ':' conditional-expression 00188 /// [GNU] logical-OR-expression '?' ':' conditional-expression 00189 /// [C++] the third operand is an assignment-expression 00190 /// 00191 /// assignment-expression: [C99 6.5.16] 00192 /// conditional-expression 00193 /// unary-expression assignment-operator assignment-expression 00194 /// [C++] throw-expression [C++ 15] 00195 /// 00196 /// assignment-operator: one of 00197 /// = *= /= %= += -= <<= >>= &= ^= |= 00198 /// 00199 /// expression: [C99 6.5.17] 00200 /// assignment-expression 00201 /// expression ',' assignment-expression 00202 /// 00203 Parser::OwningExprResult Parser::ParseExpression() { 00204 OwningExprResult LHS(ParseAssignmentExpression()); 00205 if (LHS.isInvalid()) return move(LHS); 00206 00207 return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); 00208 } 00209 00210 /// This routine is called when the '@' is seen and consumed. 00211 /// Current token is an Identifier and is not a 'try'. This 00212 /// routine is necessary to disambiguate @try-statement from, 00213 /// for example, @encode-expression. 00214 /// 00215 Parser::OwningExprResult 00216 Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { 00217 OwningExprResult LHS(ParseObjCAtExpression(AtLoc)); 00218 if (LHS.isInvalid()) return move(LHS); 00219 00220 return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); 00221 } 00222 00223 /// This routine is called when a leading '__extension__' is seen and 00224 /// consumed. This is necessary because the token gets consumed in the 00225 /// process of disambiguating between an expression and a declaration. 00226 Parser::OwningExprResult 00227 Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { 00228 OwningExprResult LHS(Actions, true); 00229 { 00230 // Silence extension warnings in the sub-expression 00231 ExtensionRAIIObject O(Diags); 00232 00233 LHS = ParseCastExpression(false); 00234 if (LHS.isInvalid()) return move(LHS); 00235 } 00236 00237 LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, 00238 move(LHS)); 00239 if (LHS.isInvalid()) return move(LHS); 00240 00241 return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); 00242 } 00243 00244 /// ParseAssignmentExpression - Parse an expr that doesn't include commas. 00245 /// 00246 Parser::OwningExprResult Parser::ParseAssignmentExpression() { 00247 if (Tok.is(tok::code_completion)) { 00248 Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression); 00249 ConsumeToken(); 00250 } 00251 00252 if (Tok.is(tok::kw_throw)) 00253 return ParseThrowExpression(); 00254 00255 OwningExprResult LHS(ParseCastExpression(false)); 00256 if (LHS.isInvalid()) return move(LHS); 00257 00258 return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment); 00259 } 00260 00261 /// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression 00262 /// where part of an objc message send has already been parsed. In this case 00263 /// LBracLoc indicates the location of the '[' of the message send, and either 00264 /// ReceiverName or ReceiverExpr is non-null indicating the receiver of the 00265 /// message. 00266 /// 00267 /// Since this handles full assignment-expression's, it handles postfix 00268 /// expressions and other binary operators for these expressions as well. 00269 Parser::OwningExprResult 00270 Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, 00271 SourceLocation NameLoc, 00272 IdentifierInfo *ReceiverName, 00273 ExprArg ReceiverExpr) { 00274 OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, NameLoc, 00275 ReceiverName, 00276 move(ReceiverExpr))); 00277 if (R.isInvalid()) return move(R); 00278 R = ParsePostfixExpressionSuffix(move(R)); 00279 if (R.isInvalid()) return move(R); 00280 return ParseRHSOfBinaryExpression(move(R), prec::Assignment); 00281 } 00282 00283 00284 Parser::OwningExprResult Parser::ParseConstantExpression() { 00285 // C++ [basic.def.odr]p2: 00286 // An expression is potentially evaluated unless it appears where an 00287 // integral constant expression is required (see 5.19) [...]. 00288 EnterExpressionEvaluationContext Unevaluated(Actions, 00289 Action::Unevaluated); 00290 00291 OwningExprResult LHS(ParseCastExpression(false)); 00292 if (LHS.isInvalid()) return move(LHS); 00293 00294 return ParseRHSOfBinaryExpression(move(LHS), prec::Conditional); 00295 } 00296 00297 /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with 00298 /// LHS and has a precedence of at least MinPrec. 00299 Parser::OwningExprResult 00300 Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) { 00301 unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind(), 00302 GreaterThanIsOperator, 00303 getLang().CPlusPlus0x); 00304 SourceLocation ColonLoc; 00305 00306 while (1) { 00307 // If this token has a lower precedence than we are allowed to parse (e.g. 00308 // because we are called recursively, or because the token is not a binop), 00309 // then we are done! 00310 if (NextTokPrec < MinPrec) 00311 return move(LHS); 00312 00313 // Consume the operator, saving the operator token for error reporting. 00314 Token OpToken = Tok; 00315 ConsumeToken(); 00316 00317 // Special case handling for the ternary operator. 00318 OwningExprResult TernaryMiddle(Actions, true); 00319 if (NextTokPrec == prec::Conditional) { 00320 if (Tok.isNot(tok::colon)) { 00321 // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 00322 ColonProtectionRAIIObject X(*this); 00323 00324 // Handle this production specially: 00325 // logical-OR-expression '?' expression ':' conditional-expression 00326 // In particular, the RHS of the '?' is 'expression', not 00327 // 'logical-OR-expression' as we might expect. 00328 TernaryMiddle = ParseExpression(); 00329 if (TernaryMiddle.isInvalid()) 00330 return move(TernaryMiddle); 00331 } else { 00332 // Special case handling of "X ? Y : Z" where Y is empty: 00333 // logical-OR-expression '?' ':' conditional-expression [GNU] 00334 TernaryMiddle = 0; 00335 Diag(Tok, diag::ext_gnu_conditional_expr); 00336 } 00337 00338 if (Tok.isNot(tok::colon)) { 00339 Diag(Tok, diag::err_expected_colon); 00340 Diag(OpToken, diag::note_matching) << "?"; 00341 return ExprError(); 00342 } 00343 00344 // Eat the colon. 00345 ColonLoc = ConsumeToken(); 00346 } 00347 00348 // Parse another leaf here for the RHS of the operator. 00349 // ParseCastExpression works here because all RHS expressions in C have it 00350 // as a prefix, at least. However, in C++, an assignment-expression could 00351 // be a throw-expression, which is not a valid cast-expression. 00352 // Therefore we need some special-casing here. 00353 // Also note that the third operand of the conditional operator is 00354 // an assignment-expression in C++. 00355 OwningExprResult RHS(Actions); 00356 if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional) 00357 RHS = ParseAssignmentExpression(); 00358 else 00359 RHS = ParseCastExpression(false); 00360 if (RHS.isInvalid()) 00361 return move(RHS); 00362 00363 // Remember the precedence of this operator and get the precedence of the 00364 // operator immediately to the right of the RHS. 00365 unsigned ThisPrec = NextTokPrec; 00366 NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 00367 getLang().CPlusPlus0x); 00368 00369 // Assignment and conditional expressions are right-associative. 00370 bool isRightAssoc = ThisPrec == prec::Conditional || 00371 ThisPrec == prec::Assignment; 00372 00373 // Get the precedence of the operator to the right of the RHS. If it binds 00374 // more tightly with RHS than we do, evaluate it completely first. 00375 if (ThisPrec < NextTokPrec || 00376 (ThisPrec == NextTokPrec && isRightAssoc)) { 00377 // If this is left-associative, only parse things on the RHS that bind 00378 // more tightly than the current operator. If it is left-associative, it 00379 // is okay, to bind exactly as tightly. For example, compile A=B=C=D as 00380 // A=(B=(C=D)), where each paren is a level of recursion here. 00381 // The function takes ownership of the RHS. 00382 RHS = ParseRHSOfBinaryExpression(move(RHS), ThisPrec + !isRightAssoc); 00383 if (RHS.isInvalid()) 00384 return move(RHS); 00385 00386 NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, 00387 getLang().CPlusPlus0x); 00388 } 00389 assert(NextTokPrec <= ThisPrec && "Recursion didn't work!"); 00390 00391 if (!LHS.isInvalid()) { 00392 // Combine the LHS and RHS into the LHS (e.g. build AST). 00393 if (TernaryMiddle.isInvalid()) { 00394 // If we're using '>>' as an operator within a template 00395 // argument list (in C++98), suggest the addition of 00396 // parentheses so that the code remains well-formed in C++0x. 00397 if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) 00398 SuggestParentheses(OpToken.getLocation(), 00399 diag::warn_cxx0x_right_shift_in_template_arg, 00400 SourceRange(Actions.getExprRange(LHS.get()).getBegin(), 00401 Actions.getExprRange(RHS.get()).getEnd())); 00402 00403 LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(), 00404 OpToken.getKind(), move(LHS), move(RHS)); 00405 } else 00406 LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, 00407 move(LHS), move(TernaryMiddle), 00408 move(RHS)); 00409 } 00410 } 00411 } 00412 00413 /// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is 00414 /// true, parse a unary-expression. isAddressOfOperand exists because an 00415 /// id-expression that is the operand of address-of gets special treatment 00416 /// due to member pointers. 00417 /// 00418 Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, 00419 bool isAddressOfOperand, 00420 TypeTy *TypeOfCast) { 00421 bool NotCastExpr; 00422 OwningExprResult Res = ParseCastExpression(isUnaryExpression, 00423 isAddressOfOperand, 00424 NotCastExpr, 00425 TypeOfCast); 00426 if (NotCastExpr) 00427 Diag(Tok, diag::err_expected_expression); 00428 return move(Res); 00429 } 00430 00431 /// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is 00432 /// true, parse a unary-expression. isAddressOfOperand exists because an 00433 /// id-expression that is the operand of address-of gets special treatment 00434 /// due to member pointers. NotCastExpr is set to true if the token is not the 00435 /// start of a cast-expression, and no diagnostic is emitted in this case. 00436 /// 00437 /// cast-expression: [C99 6.5.4] 00438 /// unary-expression 00439 /// '(' type-name ')' cast-expression 00440 /// 00441 /// unary-expression: [C99 6.5.3] 00442 /// postfix-expression 00443 /// '++' unary-expression 00444 /// '--' unary-expression 00445 /// unary-operator cast-expression 00446 /// 'sizeof' unary-expression 00447 /// 'sizeof' '(' type-name ')' 00448 /// [GNU] '__alignof' unary-expression 00449 /// [GNU] '__alignof' '(' type-name ')' 00450 /// [C++0x] 'alignof' '(' type-id ')' 00451 /// [GNU] '&&' identifier 00452 /// [C++] new-expression 00453 /// [C++] delete-expression 00454 /// 00455 /// unary-operator: one of 00456 /// '&' '*' '+' '-' '~' '!' 00457 /// [GNU] '__extension__' '__real' '__imag' 00458 /// 00459 /// primary-expression: [C99 6.5.1] 00460 /// [C99] identifier 00461 /// [C++] id-expression 00462 /// constant 00463 /// string-literal 00464 /// [C++] boolean-literal [C++ 2.13.5] 00465 /// [C++0x] 'nullptr' [C++0x 2.14.7] 00466 /// '(' expression ')' 00467 /// '__func__' [C99 6.4.2.2] 00468 /// [GNU] '__FUNCTION__' 00469 /// [GNU] '__PRETTY_FUNCTION__' 00470 /// [GNU] '(' compound-statement ')' 00471 /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 00472 /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 00473 /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 00474 /// assign-expr ')' 00475 /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 00476 /// [GNU] '__null' 00477 /// [OBJC] '[' objc-message-expr ']' 00478 /// [OBJC] '@selector' '(' objc-selector-arg ')' 00479 /// [OBJC] '@protocol' '(' identifier ')' 00480 /// [OBJC] '@encode' '(' type-name ')' 00481 /// [OBJC] objc-string-literal 00482 /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 00483 /// [C++] typename-specifier '(' expression-list[opt] ')' [TODO] 00484 /// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 00485 /// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 00486 /// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 00487 /// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] 00488 /// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] 00489 /// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1] 00490 /// [C++] 'this' [C++ 9.3.2] 00491 /// [G++] unary-type-trait '(' type-id ')' 00492 /// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] 00493 /// [clang] '^' block-literal 00494 /// 00495 /// constant: [C99 6.4.4] 00496 /// integer-constant 00497 /// floating-constant 00498 /// enumeration-constant -> identifier 00499 /// character-constant 00500 /// 00501 /// id-expression: [C++ 5.1] 00502 /// unqualified-id 00503 /// qualified-id [TODO] 00504 /// 00505 /// unqualified-id: [C++ 5.1] 00506 /// identifier 00507 /// operator-function-id 00508 /// conversion-function-id [TODO] 00509 /// '~' class-name [TODO] 00510 /// template-id [TODO] 00511 /// 00512 /// new-expression: [C++ 5.3.4] 00513 /// '::'[opt] 'new' new-placement[opt] new-type-id 00514 /// new-initializer[opt] 00515 /// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 00516 /// new-initializer[opt] 00517 /// 00518 /// delete-expression: [C++ 5.3.5] 00519 /// '::'[opt] 'delete' cast-expression 00520 /// '::'[opt] 'delete' '[' ']' cast-expression 00521 /// 00522 /// [GNU] unary-type-trait: 00523 /// '__has_nothrow_assign' [TODO] 00524 /// '__has_nothrow_copy' [TODO] 00525 /// '__has_nothrow_constructor' [TODO] 00526 /// '__has_trivial_assign' [TODO] 00527 /// '__has_trivial_copy' [TODO] 00528 /// '__has_trivial_constructor' 00529 /// '__has_trivial_destructor' 00530 /// '__has_virtual_destructor' [TODO] 00531 /// '__is_abstract' [TODO] 00532 /// '__is_class' 00533 /// '__is_empty' [TODO] 00534 /// '__is_enum' 00535 /// '__is_pod' 00536 /// '__is_polymorphic' 00537 /// '__is_union' 00538 /// 00539 /// [GNU] binary-type-trait: 00540 /// '__is_base_of' [TODO] 00541 /// 00542 Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, 00543 bool isAddressOfOperand, 00544 bool &NotCastExpr, 00545 TypeTy *TypeOfCast) { 00546 OwningExprResult Res(Actions); 00547 tok::TokenKind SavedKind = Tok.getKind(); 00548 NotCastExpr = false; 00549 00550 // This handles all of cast-expression, unary-expression, postfix-expression, 00551 // and primary-expression. We handle them together like this for efficiency 00552 // and to simplify handling of an expression starting with a '(' token: which 00553 // may be one of a parenthesized expression, cast-expression, compound literal 00554 // expression, or statement expression. 00555 // 00556 // If the parsed tokens consist of a primary-expression, the cases below 00557 // call ParsePostfixExpressionSuffix to handle the postfix expression 00558 // suffixes. Cases that cannot be followed by postfix exprs should 00559 // return without invoking ParsePostfixExpressionSuffix. 00560 switch (SavedKind) { 00561 case tok::l_paren: { 00562 // If this expression is limited to being a unary-expression, the parent can 00563 // not start a cast expression. 00564 ParenParseOption ParenExprType = 00565 isUnaryExpression ? CompoundLiteral : CastExpr; 00566 TypeTy *CastTy; 00567 SourceLocation LParenLoc = Tok.getLocation(); 00568 SourceLocation RParenLoc; 00569 00570 { 00571 // The inside of the parens don't need to be a colon protected scope. 00572 ColonProtectionRAIIObject X(*this, false); 00573 00574 Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, 00575 TypeOfCast, CastTy, RParenLoc); 00576 if (Res.isInvalid()) return move(Res); 00577 } 00578 00579 switch (ParenExprType) { 00580 case SimpleExpr: break; // Nothing else to do. 00581 case CompoundStmt: break; // Nothing else to do. 00582 case CompoundLiteral: 00583 // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of 00584 // postfix-expression exist, parse them now. 00585 break; 00586 case CastExpr: 00587 // We have parsed the cast-expression and no postfix-expr pieces are 00588 // following. 00589 return move(Res); 00590 } 00591 00592 // These can be followed by postfix-expr pieces. 00593 return ParsePostfixExpressionSuffix(move(Res)); 00594 } 00595 00596 // primary-expression 00597 case tok::numeric_constant: 00598 // constant: integer-constant 00599 // constant: floating-constant 00600 00601 Res = Actions.ActOnNumericConstant(Tok); 00602 ConsumeToken(); 00603 00604 // These can be followed by postfix-expr pieces. 00605 return ParsePostfixExpressionSuffix(move(Res)); 00606 00607 case tok::kw_true: 00608 case tok::kw_false: 00609 return ParseCXXBoolLiteral(); 00610 00611 case tok::kw_nullptr: 00612 return Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); 00613 00614 case tok::identifier: { // primary-expression: identifier 00615 // unqualified-id: identifier 00616 // constant: enumeration-constant 00617 // Turn a potentially qualified name into a annot_typename or 00618 // annot_cxxscope if it would be valid. This handles things like x::y, etc. 00619 if (getLang().CPlusPlus) { 00620 // Avoid the unnecessary parse-time lookup in the common case 00621 // where the syntax forbids a type. 00622 const Token &Next = NextToken(); 00623 if (Next.is(tok::coloncolon) || 00624 (!ColonIsSacred && Next.is(tok::colon)) || 00625 Next.is(tok::less) || 00626 Next.is(tok::l_paren)) { 00627 // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. 00628 if (TryAnnotateTypeOrScopeToken()) 00629 return ExprError(); 00630 if (!Tok.is(tok::identifier)) 00631 return ParseCastExpression(isUnaryExpression, isAddressOfOperand); 00632 } 00633 } 00634 00635 // Consume the identifier so that we can see if it is followed by a '(' or 00636 // '.'. 00637 IdentifierInfo &II = *Tok.getIdentifierInfo(); 00638 SourceLocation ILoc = ConsumeToken(); 00639 00640 // Support 'Class.property' notation. We don't use 00641 // isTokObjCMessageIdentifierReceiver(), since it allows 'super' (which is 00642 // inappropriate here). 00643 if (getLang().ObjC1 && Tok.is(tok::period) && 00644 Actions.getTypeName(II, ILoc, CurScope)) { 00645 SourceLocation DotLoc = ConsumeToken(); 00646 00647 if (Tok.isNot(tok::identifier)) { 00648 Diag(Tok, diag::err_expected_property_name); 00649 return ExprError(); 00650 } 00651 IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); 00652 SourceLocation PropertyLoc = ConsumeToken(); 00653 00654 Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, 00655 ILoc, PropertyLoc); 00656 // These can be followed by postfix-expr pieces. 00657 return ParsePostfixExpressionSuffix(move(Res)); 00658 } 00659 00660 // Function designators are allowed to be undeclared (C99 6.5.1p2), so we 00661 // need to know whether or not this identifier is a function designator or 00662 // not. 00663 UnqualifiedId Name; 00664 CXXScopeSpec ScopeSpec; 00665 Name.setIdentifier(&II, ILoc); 00666 Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name, 00667 Tok.is(tok::l_paren), false); 00668 // These can be followed by postfix-expr pieces. 00669 return ParsePostfixExpressionSuffix(move(Res)); 00670 } 00671 case tok::char_constant: // constant: character-constant 00672 Res = Actions.ActOnCharacterConstant(Tok); 00673 ConsumeToken(); 00674 // These can be followed by postfix-expr pieces. 00675 return ParsePostfixExpressionSuffix(move(Res)); 00676 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] 00677 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] 00678 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] 00679 Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); 00680 ConsumeToken(); 00681 // These can be followed by postfix-expr pieces. 00682 return ParsePostfixExpressionSuffix(move(Res)); 00683 case tok::string_literal: // primary-expression: string-literal 00684 case tok::wide_string_literal: 00685 Res = ParseStringLiteralExpression(); 00686 if (Res.isInvalid()) return move(Res); 00687 // This can be followed by postfix-expr pieces (e.g. "foo"[1]). 00688 return ParsePostfixExpressionSuffix(move(Res)); 00689 case tok::kw___builtin_va_arg: 00690 case tok::kw___builtin_offsetof: 00691 case tok::kw___builtin_choose_expr: 00692 case tok::kw___builtin_types_compatible_p: 00693 return ParseBuiltinPrimaryExpression(); 00694 case tok::kw___null: 00695 return Actions.ActOnGNUNullExpr(ConsumeToken()); 00696 break; 00697 case tok::plusplus: // unary-expression: '++' unary-expression 00698 case tok::minusminus: { // unary-expression: '--' unary-expression 00699 SourceLocation SavedLoc = ConsumeToken(); 00700 Res = ParseCastExpression(true); 00701 if (!Res.isInvalid()) 00702 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res)); 00703 return move(Res); 00704 } 00705 case tok::amp: { // unary-expression: '&' cast-expression 00706 // Special treatment because of member pointers 00707 SourceLocation SavedLoc = ConsumeToken(); 00708 Res = ParseCastExpression(false, true); 00709 if (!Res.isInvalid()) 00710 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res)); 00711 return move(Res); 00712 } 00713 00714 case tok::star: // unary-expression: '*' cast-expression 00715 case tok::plus: // unary-expression: '+' cast-expression 00716 case tok::minus: // unary-expression: '-' cast-expression 00717 case tok::tilde: // unary-expression: '~' cast-expression 00718 case tok::exclaim: // unary-expression: '!' cast-expression 00719 case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] 00720 case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] 00721 SourceLocation SavedLoc = ConsumeToken(); 00722 Res = ParseCastExpression(false); 00723 if (!Res.isInvalid()) 00724 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res)); 00725 return move(Res); 00726 } 00727 00728 case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU] 00729 // __extension__ silences extension warnings in the subexpression. 00730 ExtensionRAIIObject O(Diags); // Use RAII to do this. 00731 SourceLocation SavedLoc = ConsumeToken(); 00732 Res = ParseCastExpression(false); 00733 if (!Res.isInvalid()) 00734 Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res)); 00735 return move(Res); 00736 } 00737 case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression 00738 // unary-expression: 'sizeof' '(' type-name ')' 00739 case tok::kw_alignof: 00740 case tok::kw___alignof: // unary-expression: '__alignof' unary-expression 00741 // unary-expression: '__alignof' '(' type-name ')' 00742 // unary-expression: 'alignof' '(' type-id ')' 00743 return ParseSizeofAlignofExpression(); 00744 case tok::ampamp: { // unary-expression: '&&' identifier 00745 SourceLocation AmpAmpLoc = ConsumeToken(); 00746 if (Tok.isNot(tok::identifier)) 00747 return ExprError(Diag(Tok, diag::err_expected_ident)); 00748 00749 Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); 00750 Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), 00751 Tok.getIdentifierInfo()); 00752 ConsumeToken(); 00753 return move(Res); 00754 } 00755 case tok::kw_const_cast: 00756 case tok::kw_dynamic_cast: 00757 case tok::kw_reinterpret_cast: 00758 case tok::kw_static_cast: 00759 Res = ParseCXXCasts(); 00760 // These can be followed by postfix-expr pieces. 00761 return ParsePostfixExpressionSuffix(move(Res)); 00762 case tok::kw_typeid: 00763 Res = ParseCXXTypeid(); 00764 // This can be followed by postfix-expr pieces. 00765 return ParsePostfixExpressionSuffix(move(Res)); 00766 case tok::kw_this: 00767 Res = ParseCXXThis(); 00768 // This can be followed by postfix-expr pieces. 00769 return ParsePostfixExpressionSuffix(move(Res)); 00770 00771 case tok::kw_char: 00772 case tok::kw_wchar_t: 00773 case tok::kw_char16_t: 00774 case tok::kw_char32_t: 00775 case tok::kw_bool: 00776 case tok::kw_short: 00777 case tok::kw_int: 00778 case tok::kw_long: 00779 case tok::kw_signed: 00780 case tok::kw_unsigned: 00781 case tok::kw_float: 00782 case tok::kw_double: 00783 case tok::kw_void: 00784 case tok::kw_typename: 00785 case tok::kw_typeof: 00786 case tok::kw___vector: 00787 case tok::annot_typename: { 00788 if (!getLang().CPlusPlus) { 00789 Diag(Tok, diag::err_expected_expression); 00790 return ExprError(); 00791 } 00792 00793 if (SavedKind == tok::kw_typename) { 00794 // postfix-expression: typename-specifier '(' expression-list[opt] ')' 00795 if (TryAnnotateTypeOrScopeToken()) 00796 return ExprError(); 00797 } 00798 00799 // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' 00800 // 00801 DeclSpec DS; 00802 ParseCXXSimpleTypeSpecifier(DS); 00803 if (Tok.isNot(tok::l_paren)) 00804 return ExprError(Diag(Tok, diag::err_expected_lparen_after_type) 00805 << DS.getSourceRange()); 00806 00807 Res = ParseCXXTypeConstructExpression(DS); 00808 // This can be followed by postfix-expr pieces. 00809 return ParsePostfixExpressionSuffix(move(Res)); 00810 } 00811 00812 case tok::annot_cxxscope: { // [C++] id-expression: qualified-id 00813 Token Next = NextToken(); 00814 if (Next.is(tok::annot_template_id)) { 00815 TemplateIdAnnotation *TemplateId 00816 = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()); 00817 if (TemplateId->Kind == TNK_Type_template) { 00818 // We have a qualified template-id that we know refers to a 00819 // type, translate it into a type and continue parsing as a 00820 // cast expression. 00821 CXXScopeSpec SS; 00822 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); 00823 AnnotateTemplateIdTokenAsType(&SS); 00824 return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 00825 NotCastExpr, TypeOfCast); 00826 } 00827 } 00828 00829 // Parse as an id-expression. 00830 Res = ParseCXXIdExpression(isAddressOfOperand); 00831 return ParsePostfixExpressionSuffix(move(Res)); 00832 } 00833 00834 case tok::annot_template_id: { // [C++] template-id 00835 TemplateIdAnnotation *TemplateId 00836 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 00837 if (TemplateId->Kind == TNK_Type_template) { 00838 // We have a template-id that we know refers to a type, 00839 // translate it into a type and continue parsing as a cast 00840 // expression. 00841 AnnotateTemplateIdTokenAsType(); 00842 return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 00843 NotCastExpr, TypeOfCast); 00844 } 00845 00846 // Fall through to treat the template-id as an id-expression. 00847 } 00848 00849 case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id 00850 Res = ParseCXXIdExpression(isAddressOfOperand); 00851 return ParsePostfixExpressionSuffix(move(Res)); 00852 00853 case tok::coloncolon: { 00854 // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken 00855 // annotates the token, tail recurse. 00856 if (TryAnnotateTypeOrScopeToken()) 00857 return ExprError(); 00858 if (!Tok.is(tok::coloncolon)) 00859 return ParseCastExpression(isUnaryExpression, isAddressOfOperand); 00860 00861 // ::new -> [C++] new-expression 00862 // ::delete -> [C++] delete-expression 00863 SourceLocation CCLoc = ConsumeToken(); 00864 if (Tok.is(tok::kw_new)) 00865 return ParseCXXNewExpression(true, CCLoc); 00866 if (Tok.is(tok::kw_delete)) 00867 return ParseCXXDeleteExpression(true, CCLoc); 00868 00869 // This is not a type name or scope specifier, it is an invalid expression. 00870 Diag(CCLoc, diag::err_expected_expression); 00871 return ExprError(); 00872 } 00873 00874 case tok::kw_new: // [C++] new-expression 00875 return ParseCXXNewExpression(false, Tok.getLocation()); 00876 00877 case tok::kw_delete: // [C++] delete-expression 00878 return ParseCXXDeleteExpression(false, Tok.getLocation()); 00879 00880 case tok::kw___is_pod: // [GNU] unary-type-trait 00881 case tok::kw___is_class: 00882 case tok::kw___is_enum: 00883 case tok::kw___is_union: 00884 case tok::kw___is_empty: 00885 case tok::kw___is_polymorphic: 00886 case tok::kw___is_abstract: 00887 case tok::kw___is_literal: 00888 case tok::kw___has_trivial_constructor: 00889 case tok::kw___has_trivial_copy: 00890 case tok::kw___has_trivial_assign: 00891 case tok::kw___has_trivial_destructor: 00892 return ParseUnaryTypeTrait(); 00893 00894 case tok::at: { 00895 SourceLocation AtLoc = ConsumeToken(); 00896 return ParseObjCAtExpression(AtLoc); 00897 } 00898 case tok::caret: 00899 return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression()); 00900 case tok::l_square: 00901 // These can be followed by postfix-expr pieces. 00902 if (getLang().ObjC1) 00903 return ParsePostfixExpressionSuffix(ParseObjCMessageExpression()); 00904 // FALL THROUGH. 00905 default: 00906 NotCastExpr = true; 00907 return ExprError(); 00908 } 00909 00910 // unreachable. 00911 abort(); 00912 } 00913 00914 /// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression 00915 /// is parsed, this method parses any suffixes that apply. 00916 /// 00917 /// postfix-expression: [C99 6.5.2] 00918 /// primary-expression 00919 /// postfix-expression '[' expression ']' 00920 /// postfix-expression '(' argument-expression-list[opt] ')' 00921 /// postfix-expression '.' identifier 00922 /// postfix-expression '->' identifier 00923 /// postfix-expression '++' 00924 /// postfix-expression '--' 00925 /// '(' type-name ')' '{' initializer-list '}' 00926 /// '(' type-name ')' '{' initializer-list ',' '}' 00927 /// 00928 /// argument-expression-list: [C99 6.5.2] 00929 /// argument-expression 00930 /// argument-expression-list ',' assignment-expression 00931 /// 00932 Parser::OwningExprResult 00933 Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { 00934 // Now that the primary-expression piece of the postfix-expression has been 00935 // parsed, see if there are any postfix-expression pieces here. 00936 SourceLocation Loc; 00937 while (1) { 00938 switch (Tok.getKind()) { 00939 default: // Not a postfix-expression suffix. 00940 return move(LHS); 00941 case tok::l_square: { // postfix-expression: p-e '[' expression ']' 00942 Loc = ConsumeBracket(); 00943 OwningExprResult Idx(ParseExpression()); 00944 00945 SourceLocation RLoc = Tok.getLocation(); 00946 00947 if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) { 00948 LHS = Actions.ActOnArraySubscriptExpr(CurScope, move(LHS), Loc, 00949 move(Idx), RLoc); 00950 } else 00951 LHS = ExprError(); 00952 00953 // Match the ']'. 00954 MatchRHSPunctuation(tok::r_square, Loc); 00955 break; 00956 } 00957 00958 case tok::l_paren: { // p-e: p-e '(' argument-expression-list[opt] ')' 00959 ExprVector ArgExprs(Actions); 00960 CommaLocsTy CommaLocs; 00961 00962 Loc = ConsumeParen(); 00963 00964 if (Tok.is(tok::code_completion)) { 00965 Actions.CodeCompleteCall(CurScope, LHS.get(), 0, 0); 00966 ConsumeToken(); 00967 } 00968 00969 if (Tok.isNot(tok::r_paren)) { 00970 if (ParseExpressionList(ArgExprs, CommaLocs, &Action::CodeCompleteCall, 00971 LHS.get())) { 00972 SkipUntil(tok::r_paren); 00973 return ExprError(); 00974 } 00975 } 00976 00977 // Match the ')'. 00978 if (Tok.isNot(tok::r_paren)) { 00979 MatchRHSPunctuation(tok::r_paren, Loc); 00980 return ExprError(); 00981 } 00982 00983 if (!LHS.isInvalid()) { 00984 assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&& 00985 "Unexpected number of commas!"); 00986 LHS = Actions.ActOnCallExpr(CurScope, move(LHS), Loc, 00987 move_arg(ArgExprs), CommaLocs.data(), 00988 Tok.getLocation()); 00989 } 00990 00991 ConsumeParen(); 00992 break; 00993 } 00994 case tok::arrow: 00995 case tok::period: { 00996 // postfix-expression: p-e '->' template[opt] id-expression 00997 // postfix-expression: p-e '.' template[opt] id-expression 00998 tok::TokenKind OpKind = Tok.getKind(); 00999 SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. 01000 01001 CXXScopeSpec SS; 01002 Action::TypeTy *ObjectType = 0; 01003 bool MayBePseudoDestructor = false; 01004 if (getLang().CPlusPlus && !LHS.isInvalid()) { 01005 LHS = Actions.ActOnStartCXXMemberReference(CurScope, move(LHS), 01006 OpLoc, OpKind, ObjectType, 01007 MayBePseudoDestructor); 01008 if (LHS.isInvalid()) 01009 break; 01010 01011 ParseOptionalCXXScopeSpecifier(SS, ObjectType, false, 01012 &MayBePseudoDestructor); 01013 } 01014 01015 if (Tok.is(tok::code_completion)) { 01016 // Code completion for a member access expression. 01017 Actions.CodeCompleteMemberReferenceExpr(CurScope, LHS.get(), 01018 OpLoc, OpKind == tok::arrow); 01019 01020 ConsumeToken(); 01021 } 01022 01023 if (MayBePseudoDestructor) { 01024 LHS = ParseCXXPseudoDestructor(move(LHS), OpLoc, OpKind, SS, 01025 ObjectType); 01026 break; 01027 } 01028 01029 // Either the action has told is that this cannot be a 01030 // pseudo-destructor expression (based on the type of base 01031 // expression), or we didn't see a '~' in the right place. We 01032 // can still parse a destructor name here, but in that case it 01033 // names a real destructor. 01034 UnqualifiedId Name; 01035 if (ParseUnqualifiedId(SS, 01036 /*EnteringContext=*/false, 01037 /*AllowDestructorName=*/true, 01038 /*AllowConstructorName=*/false, 01039 ObjectType, 01040 Name)) 01041 return ExprError(); 01042 01043 if (!LHS.isInvalid()) 01044 LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, 01045 OpKind, SS, Name, ObjCImpDecl, 01046 Tok.is(tok::l_paren)); 01047 break; 01048 } 01049 case tok::plusplus: // postfix-expression: postfix-expression '++' 01050 case tok::minusminus: // postfix-expression: postfix-expression '--' 01051 if (!LHS.isInvalid()) { 01052 LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(), 01053 Tok.getKind(), move(LHS)); 01054 } 01055 ConsumeToken(); 01056 break; 01057 } 01058 } 01059 } 01060 01061 /// ParseExprAfterTypeofSizeofAlignof - We parsed a typeof/sizeof/alignof and 01062 /// we are at the start of an expression or a parenthesized type-id. 01063 /// OpTok is the operand token (typeof/sizeof/alignof). Returns the expression 01064 /// (isCastExpr == false) or the type (isCastExpr == true). 01065 /// 01066 /// unary-expression: [C99 6.5.3] 01067 /// 'sizeof' unary-expression 01068 /// 'sizeof' '(' type-name ')' 01069 /// [GNU] '__alignof' unary-expression 01070 /// [GNU] '__alignof' '(' type-name ')' 01071 /// [C++0x] 'alignof' '(' type-id ')' 01072 /// 01073 /// [GNU] typeof-specifier: 01074 /// typeof ( expressions ) 01075 /// typeof ( type-name ) 01076 /// [GNU/C++] typeof unary-expression 01077 /// 01078 Parser::OwningExprResult 01079 Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, 01080 bool &isCastExpr, 01081 TypeTy *&CastTy, 01082 SourceRange &CastRange) { 01083 01084 assert((OpTok.is(tok::kw_typeof) || OpTok.is(tok::kw_sizeof) || 01085 OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof)) && 01086 "Not a typeof/sizeof/alignof expression!"); 01087 01088 OwningExprResult Operand(Actions); 01089 01090 // If the operand doesn't start with an '(', it must be an expression. 01091 if (Tok.isNot(tok::l_paren)) { 01092 isCastExpr = false; 01093 if (OpTok.is(tok::kw_typeof) && !getLang().CPlusPlus) { 01094 Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo(); 01095 return ExprError(); 01096 } 01097 01098 // C++0x [expr.sizeof]p1: 01099 // [...] The operand is either an expression, which is an unevaluated 01100 // operand (Clause 5) [...] 01101 // 01102 // The GNU typeof and alignof extensions also behave as unevaluated 01103 // operands. 01104 EnterExpressionEvaluationContext Unevaluated(Actions, 01105 Action::Unevaluated); 01106 Operand = ParseCastExpression(true/*isUnaryExpression*/); 01107 } else { 01108 // If it starts with a '(', we know that it is either a parenthesized 01109 // type-name, or it is a unary-expression that starts with a compound 01110 // literal, or starts with a primary-expression that is a parenthesized 01111 // expression. 01112 ParenParseOption ExprType = CastExpr; 01113 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 01114 01115 // C++0x [expr.sizeof]p1: 01116 // [...] The operand is either an expression, which is an unevaluated 01117 // operand (Clause 5) [...] 01118 // 01119 // The GNU typeof and alignof extensions also behave as unevaluated 01120 // operands. 01121 EnterExpressionEvaluationContext Unevaluated(Actions, 01122 Action::Unevaluated); 01123 Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 01124 0/*TypeOfCast*/, 01125 CastTy, RParenLoc); 01126 CastRange = SourceRange(LParenLoc, RParenLoc); 01127 01128 // If ParseParenExpression parsed a '(typename)' sequence only, then this is 01129 // a type. 01130 if (ExprType == CastExpr) { 01131 isCastExpr = true; 01132 return ExprEmpty(); 01133 } 01134 01135 // If this is a parenthesized expression, it is the start of a 01136 // unary-expression, but doesn't include any postfix pieces. Parse these 01137 // now if present. 01138 Operand = ParsePostfixExpressionSuffix(move(Operand)); 01139 } 01140 01141 // If we get here, the operand to the typeof/sizeof/alignof was an expresion. 01142 isCastExpr = false; 01143 return move(Operand); 01144 } 01145 01146 01147 /// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression. 01148 /// unary-expression: [C99 6.5.3] 01149 /// 'sizeof' unary-expression 01150 /// 'sizeof' '(' type-name ')' 01151 /// [GNU] '__alignof' unary-expression 01152 /// [GNU] '__alignof' '(' type-name ')' 01153 /// [C++0x] 'alignof' '(' type-id ')' 01154 Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() { 01155 assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof) 01156 || Tok.is(tok::kw_alignof)) && 01157 "Not a sizeof/alignof expression!"); 01158 Token OpTok = Tok; 01159 ConsumeToken(); 01160 01161 bool isCastExpr; 01162 TypeTy *CastTy; 01163 SourceRange CastRange; 01164 OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok, 01165 isCastExpr, 01166 CastTy, 01167 CastRange); 01168 01169 if (isCastExpr) 01170 return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), 01171 OpTok.is(tok::kw_sizeof), 01172 /*isType=*/true, CastTy, 01173 CastRange); 01174 01175 // If we get here, the operand to the sizeof/alignof was an expresion. 01176 if (!Operand.isInvalid()) 01177 Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), 01178 OpTok.is(tok::kw_sizeof), 01179 /*isType=*/false, 01180 Operand.release(), CastRange); 01181 return move(Operand); 01182 } 01183 01184 /// ParseBuiltinPrimaryExpression 01185 /// 01186 /// primary-expression: [C99 6.5.1] 01187 /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' 01188 /// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')' 01189 /// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ',' 01190 /// assign-expr ')' 01191 /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' 01192 /// 01193 /// [GNU] offsetof-member-designator: 01194 /// [GNU] identifier 01195 /// [GNU] offsetof-member-designator '.' identifier 01196 /// [GNU] offsetof-member-designator '[' expression ']' 01197 /// 01198 Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { 01199 OwningExprResult Res(Actions); 01200 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); 01201 01202 tok::TokenKind T = Tok.getKind(); 01203 SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier. 01204 01205 // All of these start with an open paren. 01206 if (Tok.isNot(tok::l_paren)) 01207 return ExprError(Diag(Tok, diag::err_expected_lparen_after_id) 01208 << BuiltinII); 01209 01210 SourceLocation LParenLoc = ConsumeParen(); 01211 // TODO: Build AST. 01212 01213 switch (T) { 01214 default: assert(0 && "Not a builtin primary expression!"); 01215 case tok::kw___builtin_va_arg: { 01216 OwningExprResult Expr(ParseAssignmentExpression()); 01217 if (Expr.isInvalid()) { 01218 SkipUntil(tok::r_paren); 01219 return ExprError(); 01220 } 01221 01222 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 01223 return ExprError(); 01224 01225 TypeResult Ty = ParseTypeName(); 01226 01227 if (Tok.isNot(tok::r_paren)) { 01228 Diag(Tok, diag::err_expected_rparen); 01229 return ExprError(); 01230 } 01231 if (Ty.isInvalid()) 01232 Res = ExprError(); 01233 else 01234 Res = Actions.ActOnVAArg(StartLoc, move(Expr), Ty.get(), ConsumeParen()); 01235 break; 01236 } 01237 case tok::kw___builtin_offsetof: { 01238 SourceLocation TypeLoc = Tok.getLocation(); 01239 TypeResult Ty = ParseTypeName(); 01240 if (Ty.isInvalid()) { 01241 SkipUntil(tok::r_paren); 01242 return ExprError(); 01243 } 01244 01245 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 01246 return ExprError(); 01247 01248 // We must have at least one identifier here. 01249 if (Tok.isNot(tok::identifier)) { 01250 Diag(Tok, diag::err_expected_ident); 01251 SkipUntil(tok::r_paren); 01252 return ExprError(); 01253 } 01254 01255 // Keep track of the various subcomponents we see. 01256 llvm::SmallVector<Action::OffsetOfComponent, 4> Comps; 01257 01258 Comps.push_back(Action::OffsetOfComponent()); 01259 Comps.back().isBrackets = false; 01260 Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 01261 Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); 01262 01263 // FIXME: This loop leaks the index expressions on error. 01264 while (1) { 01265 if (Tok.is(tok::period)) { 01266 // offsetof-member-designator: offsetof-member-designator '.' identifier 01267 Comps.push_back(Action::OffsetOfComponent()); 01268 Comps.back().isBrackets = false; 01269 Comps.back().LocStart = ConsumeToken(); 01270 01271 if (Tok.isNot(tok::identifier)) { 01272 Diag(Tok, diag::err_expected_ident); 01273 SkipUntil(tok::r_paren); 01274 return ExprError(); 01275 } 01276 Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); 01277 Comps.back().LocEnd = ConsumeToken(); 01278 01279 } else if (Tok.is(tok::l_square)) { 01280 // offsetof-member-designator: offsetof-member-design '[' expression ']' 01281 Comps.push_back(Action::OffsetOfComponent()); 01282 Comps.back().isBrackets = true; 01283 Comps.back().LocStart = ConsumeBracket(); 01284 Res = ParseExpression(); 01285 if (Res.isInvalid()) { 01286 SkipUntil(tok::r_paren); 01287 return move(Res); 01288 } 01289 Comps.back().U.E = Res.release(); 01290 01291 Comps.back().LocEnd = 01292 MatchRHSPunctuation(tok::r_square, Comps.back().LocStart); 01293 } else { 01294 if (Tok.isNot(tok::r_paren)) { 01295 MatchRHSPunctuation(tok::r_paren, LParenLoc); 01296 Res = ExprError(); 01297 } else if (Ty.isInvalid()) { 01298 Res = ExprError(); 01299 } else { 01300 Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc, 01301 Ty.get(), &Comps[0], 01302 Comps.size(), ConsumeParen()); 01303 } 01304 break; 01305 } 01306 } 01307 break; 01308 } 01309 case tok::kw___builtin_choose_expr: { 01310 OwningExprResult Cond(ParseAssignmentExpression()); 01311 if (Cond.isInvalid()) { 01312 SkipUntil(tok::r_paren); 01313 return move(Cond); 01314 } 01315 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 01316 return ExprError(); 01317 01318 OwningExprResult Expr1(ParseAssignmentExpression()); 01319 if (Expr1.isInvalid()) { 01320 SkipUntil(tok::r_paren); 01321 return move(Expr1); 01322 } 01323 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 01324 return ExprError(); 01325 01326 OwningExprResult Expr2(ParseAssignmentExpression()); 01327 if (Expr2.isInvalid()) { 01328 SkipUntil(tok::r_paren); 01329 return move(Expr2); 01330 } 01331 if (Tok.isNot(tok::r_paren)) { 01332 Diag(Tok, diag::err_expected_rparen); 01333 return ExprError(); 01334 } 01335 Res = Actions.ActOnChooseExpr(StartLoc, move(Cond), move(Expr1), 01336 move(Expr2), ConsumeParen()); 01337 break; 01338 } 01339 case tok::kw___builtin_types_compatible_p: 01340 TypeResult Ty1 = ParseTypeName(); 01341 01342 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) 01343 return ExprError(); 01344 01345 TypeResult Ty2 = ParseTypeName(); 01346 01347 if (Tok.isNot(tok::r_paren)) { 01348 Diag(Tok, diag::err_expected_rparen); 01349 return ExprError(); 01350 } 01351 01352 if (Ty1.isInvalid() || Ty2.isInvalid()) 01353 Res = ExprError(); 01354 else 01355 Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1.get(), Ty2.get(), 01356 ConsumeParen()); 01357 break; 01358 } 01359 01360 // These can be followed by postfix-expr pieces because they are 01361 // primary-expressions. 01362 return ParsePostfixExpressionSuffix(move(Res)); 01363 } 01364 01365 /// ParseParenExpression - This parses the unit that starts with a '(' token, 01366 /// based on what is allowed by ExprType. The actual thing parsed is returned 01367 /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, 01368 /// not the parsed cast-expression. 01369 /// 01370 /// primary-expression: [C99 6.5.1] 01371 /// '(' expression ')' 01372 /// [GNU] '(' compound-statement ')' (if !ParenExprOnly) 01373 /// postfix-expression: [C99 6.5.2] 01374 /// '(' type-name ')' '{' initializer-list '}' 01375 /// '(' type-name ')' '{' initializer-list ',' '}' 01376 /// cast-expression: [C99 6.5.4] 01377 /// '(' type-name ')' cast-expression 01378 /// 01379 Parser::OwningExprResult 01380 Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, 01381 TypeTy *TypeOfCast, TypeTy *&CastTy, 01382 SourceLocation &RParenLoc) { 01383 assert(Tok.is(tok::l_paren) && "Not a paren expr!"); 01384 GreaterThanIsOperatorScope G(GreaterThanIsOperator, true); 01385 SourceLocation OpenLoc = ConsumeParen(); 01386 OwningExprResult Result(Actions, true); 01387 bool isAmbiguousTypeId; 01388 CastTy = 0; 01389 01390 if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { 01391 Diag(Tok, diag::ext_gnu_statement_expr); 01392 OwningStmtResult Stmt(ParseCompoundStatement(0, true)); 01393 ExprType = CompoundStmt; 01394 01395 // If the substmt parsed correctly, build the AST node. 01396 if (!Stmt.isInvalid() && Tok.is(tok::r_paren)) 01397 Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation()); 01398 01399 } else if (ExprType >= CompoundLiteral && 01400 isTypeIdInParens(isAmbiguousTypeId)) { 01401 01402 // Otherwise, this is a compound literal expression or cast expression. 01403 01404 // In C++, if the type-id is ambiguous we disambiguate based on context. 01405 // If stopIfCastExpr is true the context is a typeof/sizeof/alignof 01406 // in which case we should treat it as type-id. 01407 // if stopIfCastExpr is false, we need to determine the context past the 01408 // parens, so we defer to ParseCXXAmbiguousParenExpression for that. 01409 if (isAmbiguousTypeId && !stopIfCastExpr) 01410 return ParseCXXAmbiguousParenExpression(ExprType, CastTy, 01411 OpenLoc, RParenLoc); 01412 01413 TypeResult Ty = ParseTypeName(); 01414 01415 // Match the ')'. 01416 if (Tok.is(tok::r_paren)) 01417 RParenLoc = ConsumeParen(); 01418 else 01419 MatchRHSPunctuation(tok::r_paren, OpenLoc); 01420 01421 if (Tok.is(tok::l_brace)) { 01422 ExprType = CompoundLiteral; 01423 return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); 01424 } 01425 01426 if (ExprType == CastExpr) { 01427 // We parsed '(' type-name ')' and the thing after it wasn't a '{'. 01428 01429 if (Ty.isInvalid()) 01430 return ExprError(); 01431 01432 CastTy = Ty.get(); 01433 01434 if (stopIfCastExpr) { 01435 // Note that this doesn't parse the subsequent cast-expression, it just 01436 // returns the parsed type to the callee. 01437 return OwningExprResult(Actions); 01438 } 01439 01440 // Parse the cast-expression that follows it next. 01441 // TODO: For cast expression with CastTy. 01442 Result = ParseCastExpression(false, false, CastTy); 01443 if (!Result.isInvalid()) 01444 Result = Actions.ActOnCastExpr(CurScope, OpenLoc, CastTy, RParenLoc, 01445 move(Result)); 01446 return move(Result); 01447 } 01448 01449 Diag(Tok, diag::err_expected_lbrace_in_compound_literal); 01450 return ExprError(); 01451 } else if (TypeOfCast) { 01452 // Parse the expression-list. 01453 ExprVector ArgExprs(Actions); 01454 CommaLocsTy CommaLocs; 01455 01456 if (!ParseExpressionList(ArgExprs, CommaLocs)) { 01457 ExprType = SimpleExpr; 01458 Result = Actions.ActOnParenOrParenListExpr(OpenLoc, Tok.getLocation(), 01459 move_arg(ArgExprs), TypeOfCast); 01460 } 01461 } else { 01462 Result = ParseExpression(); 01463 ExprType = SimpleExpr; 01464 if (!Result.isInvalid() && Tok.is(tok::r_paren)) 01465 Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), move(Result)); 01466 } 01467 01468 // Match the ')'. 01469 if (Result.isInvalid()) { 01470 SkipUntil(tok::r_paren); 01471 return ExprError(); 01472 } 01473 01474 if (Tok.is(tok::r_paren)) 01475 RParenLoc = ConsumeParen(); 01476 else 01477 MatchRHSPunctuation(tok::r_paren, OpenLoc); 01478 01479 return move(Result); 01480 } 01481 01482 /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name 01483 /// and we are at the left brace. 01484 /// 01485 /// postfix-expression: [C99 6.5.2] 01486 /// '(' type-name ')' '{' initializer-list '}' 01487 /// '(' type-name ')' '{' initializer-list ',' '}' 01488 /// 01489 Parser::OwningExprResult 01490 Parser::ParseCompoundLiteralExpression(TypeTy *Ty, 01491 SourceLocation LParenLoc, 01492 SourceLocation RParenLoc) { 01493 assert(Tok.is(tok::l_brace) && "Not a compound literal!"); 01494 if (!getLang().C99) // Compound literals don't exist in C90. 01495 Diag(LParenLoc, diag::ext_c99_compound_literal); 01496 OwningExprResult Result = ParseInitializer(); 01497 if (!Result.isInvalid() && Ty) 01498 return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, move(Result)); 01499 return move(Result); 01500 } 01501 01502 /// ParseStringLiteralExpression - This handles the various token types that 01503 /// form string literals, and also handles string concatenation [C99 5.1.1.2, 01504 /// translation phase #6]. 01505 /// 01506 /// primary-expression: [C99 6.5.1] 01507 /// string-literal 01508 Parser::OwningExprResult Parser::ParseStringLiteralExpression() { 01509 assert(isTokenStringLiteral() && "Not a string literal!"); 01510 01511 // String concat. Note that keywords like __func__ and __FUNCTION__ are not 01512 // considered to be strings for concatenation purposes. 01513 llvm::SmallVector<Token, 4> StringToks; 01514 01515 do { 01516 StringToks.push_back(Tok); 01517 ConsumeStringToken(); 01518 } while (isTokenStringLiteral()); 01519 01520 // Pass the set of string tokens, ready for concatenation, to the actions. 01521 return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size()); 01522 } 01523 01524 /// ParseExpressionList - Used for C/C++ (argument-)expression-list. 01525 /// 01526 /// argument-expression-list: 01527 /// assignment-expression 01528 /// argument-expression-list , assignment-expression 01529 /// 01530 /// [C++] expression-list: 01531 /// [C++] assignment-expression 01532 /// [C++] expression-list , assignment-expression 01533 /// 01534 bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs, 01535 void (Action::*Completer)(Scope *S, 01536 void *Data, 01537 ExprTy **Args, 01538 unsigned NumArgs), 01539 void *Data) { 01540 while (1) { 01541 if (Tok.is(tok::code_completion)) { 01542 if (Completer) 01543 (Actions.*Completer)(CurScope, Data, Exprs.data(), Exprs.size()); 01544 ConsumeToken(); 01545 } 01546 01547 OwningExprResult Expr(ParseAssignmentExpression()); 01548 if (Expr.isInvalid()) 01549 return true; 01550 01551 Exprs.push_back(Expr.release()); 01552 01553 if (Tok.isNot(tok::comma)) 01554 return false; 01555 // Move to the next argument, remember where the comma was. 01556 CommaLocs.push_back(ConsumeToken()); 01557 } 01558 } 01559 01560 /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). 01561 /// 01562 /// [clang] block-id: 01563 /// [clang] specifier-qualifier-list block-declarator 01564 /// 01565 void Parser::ParseBlockId() { 01566 // Parse the specifier-qualifier-list piece. 01567 DeclSpec DS; 01568 ParseSpecifierQualifierList(DS); 01569 01570 // Parse the block-declarator. 01571 Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext); 01572 ParseDeclarator(DeclaratorInfo); 01573 01574 // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes. 01575 DeclaratorInfo.AddAttributes(DS.TakeAttributes(), 01576 SourceLocation()); 01577 01578 if (Tok.is(tok::kw___attribute)) { 01579 SourceLocation Loc; 01580 AttributeList *AttrList = ParseGNUAttributes(&Loc); 01581 DeclaratorInfo.AddAttributes(AttrList, Loc); 01582 } 01583 01584 // Inform sema that we are starting a block. 01585 Actions.ActOnBlockArguments(DeclaratorInfo, CurScope); 01586 } 01587 01588 /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks 01589 /// like ^(int x){ return x+1; } 01590 /// 01591 /// block-literal: 01592 /// [clang] '^' block-args[opt] compound-statement 01593 /// [clang] '^' block-id compound-statement 01594 /// [clang] block-args: 01595 /// [clang] '(' parameter-list ')' 01596 /// 01597 Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { 01598 assert(Tok.is(tok::caret) && "block literal starts with ^"); 01599 SourceLocation CaretLoc = ConsumeToken(); 01600 01601 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc, 01602 "block literal parsing"); 01603 01604 // Enter a scope to hold everything within the block. This includes the 01605 // argument decls, decls within the compound expression, etc. This also 01606 // allows determining whether a variable reference inside the block is 01607 // within or outside of the block. 01608 ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | 01609 Scope::BreakScope | Scope::ContinueScope | 01610 Scope::DeclScope); 01611 01612 // Inform sema that we are starting a block. 01613 Actions.ActOnBlockStart(CaretLoc, CurScope); 01614 01615 // Parse the return type if present. 01616 DeclSpec DS; 01617 Declarator ParamInfo(DS, Declarator::BlockLiteralContext); 01618 // FIXME: Since the return type isn't actually parsed, it can't be used to 01619 // fill ParamInfo with an initial valid range, so do it manually. 01620 ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation())); 01621 01622 // If this block has arguments, parse them. There is no ambiguity here with 01623 // the expression case, because the expression case requires a parameter list. 01624 if (Tok.is(tok::l_paren)) { 01625 ParseParenDeclarator(ParamInfo); 01626 // Parse the pieces after the identifier as if we had "int(...)". 01627 // SetIdentifier sets the source range end, but in this case we're past 01628 // that location. 01629 SourceLocation Tmp = ParamInfo.getSourceRange().getEnd(); 01630 ParamInfo.SetIdentifier(0, CaretLoc); 01631 ParamInfo.SetRangeEnd(Tmp); 01632 if (ParamInfo.isInvalidType()) { 01633 // If there was an error parsing the arguments, they may have 01634 // tried to use ^(x+y) which requires an argument list. Just 01635 // skip the whole block literal. 01636 Actions.ActOnBlockError(CaretLoc, CurScope); 01637 return ExprError(); 01638 } 01639 01640 if (Tok.is(tok::kw___attribute)) { 01641 SourceLocation Loc; 01642 AttributeList *AttrList = ParseGNUAttributes(&Loc); 01643 ParamInfo.AddAttributes(AttrList, Loc); 01644 } 01645 01646 // Inform sema that we are starting a block. 01647 Actions.ActOnBlockArguments(ParamInfo, CurScope); 01648 } else if (!Tok.is(tok::l_brace)) { 01649 ParseBlockId(); 01650 } else { 01651 // Otherwise, pretend we saw (void). 01652 ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false, 01653 SourceLocation(), 01654 0, 0, 0, 01655 false, SourceLocation(), 01656 false, 0, 0, 0, 01657 CaretLoc, CaretLoc, 01658 ParamInfo), 01659 CaretLoc); 01660 01661 if (Tok.is(tok::kw___attribute)) { 01662 SourceLocation Loc; 01663 AttributeList *AttrList = ParseGNUAttributes(&Loc); 01664 ParamInfo.AddAttributes(AttrList, Loc); 01665 } 01666 01667 // Inform sema that we are starting a block. 01668 Actions.ActOnBlockArguments(ParamInfo, CurScope); 01669 } 01670 01671 01672 OwningExprResult Result(Actions, true); 01673 if (!Tok.is(tok::l_brace)) { 01674 // Saw something like: ^expr 01675 Diag(Tok, diag::err_expected_expression); 01676 Actions.ActOnBlockError(CaretLoc, CurScope); 01677 return ExprError(); 01678 } 01679 01680 OwningStmtResult Stmt(ParseCompoundStatementBody()); 01681 if (!Stmt.isInvalid()) 01682 Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope); 01683 else 01684 Actions.ActOnBlockError(CaretLoc, CurScope); 01685 return move(Result); 01686 }