ParseExprCXX.cpp revision 314b97f8c564b465af605efaee23f91ec18a982b
1//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Expression parsing implementation for C++. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Parse/ParseDiagnostic.h" 15#include "clang/Parse/Parser.h" 16#include "clang/Parse/DeclSpec.h" 17#include "clang/Parse/Template.h" 18#include "llvm/Support/ErrorHandling.h" 19 20using namespace clang; 21 22/// \brief Parse global scope or nested-name-specifier if present. 23/// 24/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 25/// may be preceded by '::'). Note that this routine will not parse ::new or 26/// ::delete; it will just leave them in the token stream. 27/// 28/// '::'[opt] nested-name-specifier 29/// '::' 30/// 31/// nested-name-specifier: 32/// type-name '::' 33/// namespace-name '::' 34/// nested-name-specifier identifier '::' 35/// nested-name-specifier 'template'[opt] simple-template-id '::' 36/// 37/// 38/// \param SS the scope specifier that will be set to the parsed 39/// nested-name-specifier (or empty) 40/// 41/// \param ObjectType if this nested-name-specifier is being parsed following 42/// the "." or "->" of a member access expression, this parameter provides the 43/// type of the object whose members are being accessed. 44/// 45/// \param EnteringContext whether we will be entering into the context of 46/// the nested-name-specifier after parsing it. 47/// 48/// \returns true if a scope specifier was parsed. 49bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 50 Action::TypeTy *ObjectType, 51 bool EnteringContext) { 52 assert(getLang().CPlusPlus && 53 "Call sites of this function should be guarded by checking for C++"); 54 55 if (Tok.is(tok::annot_cxxscope)) { 56 SS.setScopeRep(Tok.getAnnotationValue()); 57 SS.setRange(Tok.getAnnotationRange()); 58 ConsumeToken(); 59 return true; 60 } 61 62 bool HasScopeSpecifier = false; 63 64 if (Tok.is(tok::coloncolon)) { 65 // ::new and ::delete aren't nested-name-specifiers. 66 tok::TokenKind NextKind = NextToken().getKind(); 67 if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 68 return false; 69 70 // '::' - Global scope qualifier. 71 SourceLocation CCLoc = ConsumeToken(); 72 SS.setBeginLoc(CCLoc); 73 SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 74 SS.setEndLoc(CCLoc); 75 HasScopeSpecifier = true; 76 } 77 78 while (true) { 79 if (HasScopeSpecifier) { 80 // C++ [basic.lookup.classref]p5: 81 // If the qualified-id has the form 82 // 83 // ::class-name-or-namespace-name::... 84 // 85 // the class-name-or-namespace-name is looked up in global scope as a 86 // class-name or namespace-name. 87 // 88 // To implement this, we clear out the object type as soon as we've 89 // seen a leading '::' or part of a nested-name-specifier. 90 ObjectType = 0; 91 92 if (Tok.is(tok::code_completion)) { 93 // Code completion for a nested-name-specifier, where the code 94 // code completion token follows the '::'. 95 Actions.CodeCompleteQualifiedId(CurScope, SS, EnteringContext); 96 ConsumeToken(); 97 } 98 } 99 100 // nested-name-specifier: 101 // nested-name-specifier 'template'[opt] simple-template-id '::' 102 103 // Parse the optional 'template' keyword, then make sure we have 104 // 'identifier <' after it. 105 if (Tok.is(tok::kw_template)) { 106 // If we don't have a scope specifier or an object type, this isn't a 107 // nested-name-specifier, since they aren't allowed to start with 108 // 'template'. 109 if (!HasScopeSpecifier && !ObjectType) 110 break; 111 112 SourceLocation TemplateKWLoc = ConsumeToken(); 113 114 UnqualifiedId TemplateName; 115 if (Tok.is(tok::identifier)) { 116 TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 117 118 // If the next token is not '<', we may have a stray 'template' keyword. 119 // Complain and suggest removing the template keyword, but otherwise 120 // allow parsing to continue. 121 if (NextToken().isNot(tok::less)) { 122 Diag(NextToken().getLocation(), 123 diag::err_less_after_template_name_in_nested_name_spec) 124 << Tok.getIdentifierInfo()->getName() 125 << CodeModificationHint::CreateRemoval(SourceRange(TemplateKWLoc)); 126 break; 127 } 128 129 // Consume the identifier. 130 ConsumeToken(); 131 } else if (Tok.is(tok::kw_operator)) { 132 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 133 TemplateName)) 134 break; 135 136 if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId) { 137 Diag(TemplateName.getSourceRange().getBegin(), 138 diag::err_id_after_template_in_nested_name_spec) 139 << TemplateName.getSourceRange(); 140 break; 141 } else if (Tok.isNot(tok::less)) { 142 std::string OperatorName = "operator "; 143 OperatorName += getOperatorSpelling( 144 TemplateName.OperatorFunctionId.Operator); 145 Diag(Tok.getLocation(), 146 diag::err_less_after_template_name_in_nested_name_spec) 147 << OperatorName 148 << TemplateName.getSourceRange(); 149 break; 150 } 151 } else { 152 Diag(Tok.getLocation(), 153 diag::err_id_after_template_in_nested_name_spec) 154 << SourceRange(TemplateKWLoc); 155 break; 156 } 157 158 TemplateTy Template 159 = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName, 160 ObjectType); 161 if (!Template) 162 break; 163 if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, 164 &SS, TemplateName, TemplateKWLoc, false)) 165 break; 166 167 continue; 168 } 169 170 if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 171 // We have 172 // 173 // simple-template-id '::' 174 // 175 // So we need to check whether the simple-template-id is of the 176 // right kind (it should name a type or be dependent), and then 177 // convert it into a type within the nested-name-specifier. 178 TemplateIdAnnotation *TemplateId 179 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 180 181 if (TemplateId->Kind == TNK_Type_template || 182 TemplateId->Kind == TNK_Dependent_template_name) { 183 AnnotateTemplateIdTokenAsType(&SS); 184 185 assert(Tok.is(tok::annot_typename) && 186 "AnnotateTemplateIdTokenAsType isn't working"); 187 Token TypeToken = Tok; 188 ConsumeToken(); 189 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 190 SourceLocation CCLoc = ConsumeToken(); 191 192 if (!HasScopeSpecifier) { 193 SS.setBeginLoc(TypeToken.getLocation()); 194 HasScopeSpecifier = true; 195 } 196 197 if (TypeToken.getAnnotationValue()) 198 SS.setScopeRep( 199 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, 200 TypeToken.getAnnotationValue(), 201 TypeToken.getAnnotationRange(), 202 CCLoc)); 203 else 204 SS.setScopeRep(0); 205 SS.setEndLoc(CCLoc); 206 continue; 207 } 208 209 assert(false && "FIXME: Only type template names supported here"); 210 } 211 212 213 // The rest of the nested-name-specifier possibilities start with 214 // tok::identifier. 215 if (Tok.isNot(tok::identifier)) 216 break; 217 218 IdentifierInfo &II = *Tok.getIdentifierInfo(); 219 220 // nested-name-specifier: 221 // type-name '::' 222 // namespace-name '::' 223 // nested-name-specifier identifier '::' 224 Token Next = NextToken(); 225 if (Next.is(tok::coloncolon)) { 226 // We have an identifier followed by a '::'. Lookup this name 227 // as the name in a nested-name-specifier. 228 SourceLocation IdLoc = ConsumeToken(); 229 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 230 SourceLocation CCLoc = ConsumeToken(); 231 232 if (!HasScopeSpecifier) { 233 SS.setBeginLoc(IdLoc); 234 HasScopeSpecifier = true; 235 } 236 237 if (SS.isInvalid()) 238 continue; 239 240 SS.setScopeRep( 241 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II, 242 ObjectType, EnteringContext)); 243 SS.setEndLoc(CCLoc); 244 continue; 245 } 246 247 // nested-name-specifier: 248 // type-name '<' 249 if (Next.is(tok::less)) { 250 TemplateTy Template; 251 UnqualifiedId TemplateName; 252 TemplateName.setIdentifier(&II, Tok.getLocation()); 253 if (TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, 254 TemplateName, 255 ObjectType, 256 EnteringContext, 257 Template)) { 258 // We have found a template name, so annotate this this token 259 // with a template-id annotation. We do not permit the 260 // template-id to be translated into a type annotation, 261 // because some clients (e.g., the parsing of class template 262 // specializations) still want to see the original template-id 263 // token. 264 ConsumeToken(); 265 if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 266 SourceLocation(), false)) 267 break; 268 continue; 269 } 270 } 271 272 // We don't have any tokens that form the beginning of a 273 // nested-name-specifier, so we're done. 274 break; 275 } 276 277 return HasScopeSpecifier; 278} 279 280/// ParseCXXIdExpression - Handle id-expression. 281/// 282/// id-expression: 283/// unqualified-id 284/// qualified-id 285/// 286/// qualified-id: 287/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 288/// '::' identifier 289/// '::' operator-function-id 290/// '::' template-id 291/// 292/// NOTE: The standard specifies that, for qualified-id, the parser does not 293/// expect: 294/// 295/// '::' conversion-function-id 296/// '::' '~' class-name 297/// 298/// This may cause a slight inconsistency on diagnostics: 299/// 300/// class C {}; 301/// namespace A {} 302/// void f() { 303/// :: A :: ~ C(); // Some Sema error about using destructor with a 304/// // namespace. 305/// :: ~ C(); // Some Parser error like 'unexpected ~'. 306/// } 307/// 308/// We simplify the parser a bit and make it work like: 309/// 310/// qualified-id: 311/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 312/// '::' unqualified-id 313/// 314/// That way Sema can handle and report similar errors for namespaces and the 315/// global scope. 316/// 317/// The isAddressOfOperand parameter indicates that this id-expression is a 318/// direct operand of the address-of operator. This is, besides member contexts, 319/// the only place where a qualified-id naming a non-static class member may 320/// appear. 321/// 322Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 323 // qualified-id: 324 // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 325 // '::' unqualified-id 326 // 327 CXXScopeSpec SS; 328 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); 329 330 UnqualifiedId Name; 331 if (ParseUnqualifiedId(SS, 332 /*EnteringContext=*/false, 333 /*AllowDestructorName=*/false, 334 /*AllowConstructorName=*/false, 335 /*ObjectType=*/0, 336 Name)) 337 return ExprError(); 338 339 return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren), 340 isAddressOfOperand); 341 342} 343 344/// ParseCXXCasts - This handles the various ways to cast expressions to another 345/// type. 346/// 347/// postfix-expression: [C++ 5.2p1] 348/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 349/// 'static_cast' '<' type-name '>' '(' expression ')' 350/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 351/// 'const_cast' '<' type-name '>' '(' expression ')' 352/// 353Parser::OwningExprResult Parser::ParseCXXCasts() { 354 tok::TokenKind Kind = Tok.getKind(); 355 const char *CastName = 0; // For error messages 356 357 switch (Kind) { 358 default: assert(0 && "Unknown C++ cast!"); abort(); 359 case tok::kw_const_cast: CastName = "const_cast"; break; 360 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 361 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 362 case tok::kw_static_cast: CastName = "static_cast"; break; 363 } 364 365 SourceLocation OpLoc = ConsumeToken(); 366 SourceLocation LAngleBracketLoc = Tok.getLocation(); 367 368 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 369 return ExprError(); 370 371 TypeResult CastTy = ParseTypeName(); 372 SourceLocation RAngleBracketLoc = Tok.getLocation(); 373 374 if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 375 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 376 377 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 378 379 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName)) 380 return ExprError(); 381 382 OwningExprResult Result = ParseExpression(); 383 384 // Match the ')'. 385 RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 386 387 if (!Result.isInvalid() && !CastTy.isInvalid()) 388 Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 389 LAngleBracketLoc, CastTy.get(), 390 RAngleBracketLoc, 391 LParenLoc, move(Result), RParenLoc); 392 393 return move(Result); 394} 395 396/// ParseCXXTypeid - This handles the C++ typeid expression. 397/// 398/// postfix-expression: [C++ 5.2p1] 399/// 'typeid' '(' expression ')' 400/// 'typeid' '(' type-id ')' 401/// 402Parser::OwningExprResult Parser::ParseCXXTypeid() { 403 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 404 405 SourceLocation OpLoc = ConsumeToken(); 406 SourceLocation LParenLoc = Tok.getLocation(); 407 SourceLocation RParenLoc; 408 409 // typeid expressions are always parenthesized. 410 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 411 "typeid")) 412 return ExprError(); 413 414 OwningExprResult Result(Actions); 415 416 if (isTypeIdInParens()) { 417 TypeResult Ty = ParseTypeName(); 418 419 // Match the ')'. 420 MatchRHSPunctuation(tok::r_paren, LParenLoc); 421 422 if (Ty.isInvalid()) 423 return ExprError(); 424 425 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 426 Ty.get(), RParenLoc); 427 } else { 428 // C++0x [expr.typeid]p3: 429 // When typeid is applied to an expression other than an lvalue of a 430 // polymorphic class type [...] The expression is an unevaluated 431 // operand (Clause 5). 432 // 433 // Note that we can't tell whether the expression is an lvalue of a 434 // polymorphic class type until after we've parsed the expression, so 435 // we the expression is potentially potentially evaluated. 436 EnterExpressionEvaluationContext Unevaluated(Actions, 437 Action::PotentiallyPotentiallyEvaluated); 438 Result = ParseExpression(); 439 440 // Match the ')'. 441 if (Result.isInvalid()) 442 SkipUntil(tok::r_paren); 443 else { 444 MatchRHSPunctuation(tok::r_paren, LParenLoc); 445 446 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 447 Result.release(), RParenLoc); 448 } 449 } 450 451 return move(Result); 452} 453 454/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 455/// 456/// boolean-literal: [C++ 2.13.5] 457/// 'true' 458/// 'false' 459Parser::OwningExprResult Parser::ParseCXXBoolLiteral() { 460 tok::TokenKind Kind = Tok.getKind(); 461 return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 462} 463 464/// ParseThrowExpression - This handles the C++ throw expression. 465/// 466/// throw-expression: [C++ 15] 467/// 'throw' assignment-expression[opt] 468Parser::OwningExprResult Parser::ParseThrowExpression() { 469 assert(Tok.is(tok::kw_throw) && "Not throw!"); 470 SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 471 472 // If the current token isn't the start of an assignment-expression, 473 // then the expression is not present. This handles things like: 474 // "C ? throw : (void)42", which is crazy but legal. 475 switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 476 case tok::semi: 477 case tok::r_paren: 478 case tok::r_square: 479 case tok::r_brace: 480 case tok::colon: 481 case tok::comma: 482 return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions)); 483 484 default: 485 OwningExprResult Expr(ParseAssignmentExpression()); 486 if (Expr.isInvalid()) return move(Expr); 487 return Actions.ActOnCXXThrow(ThrowLoc, move(Expr)); 488 } 489} 490 491/// ParseCXXThis - This handles the C++ 'this' pointer. 492/// 493/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 494/// a non-lvalue expression whose value is the address of the object for which 495/// the function is called. 496Parser::OwningExprResult Parser::ParseCXXThis() { 497 assert(Tok.is(tok::kw_this) && "Not 'this'!"); 498 SourceLocation ThisLoc = ConsumeToken(); 499 return Actions.ActOnCXXThis(ThisLoc); 500} 501 502/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 503/// Can be interpreted either as function-style casting ("int(x)") 504/// or class type construction ("ClassType(x,y,z)") 505/// or creation of a value-initialized type ("int()"). 506/// 507/// postfix-expression: [C++ 5.2p1] 508/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 509/// typename-specifier '(' expression-list[opt] ')' [TODO] 510/// 511Parser::OwningExprResult 512Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 513 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 514 TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get(); 515 516 assert(Tok.is(tok::l_paren) && "Expected '('!"); 517 SourceLocation LParenLoc = ConsumeParen(); 518 519 ExprVector Exprs(Actions); 520 CommaLocsTy CommaLocs; 521 522 if (Tok.isNot(tok::r_paren)) { 523 if (ParseExpressionList(Exprs, CommaLocs)) { 524 SkipUntil(tok::r_paren); 525 return ExprError(); 526 } 527 } 528 529 // Match the ')'. 530 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 531 532 // TypeRep could be null, if it references an invalid typedef. 533 if (!TypeRep) 534 return ExprError(); 535 536 assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 537 "Unexpected number of commas!"); 538 return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 539 LParenLoc, move_arg(Exprs), 540 CommaLocs.data(), RParenLoc); 541} 542 543/// ParseCXXCondition - if/switch/while/for condition expression. 544/// 545/// condition: 546/// expression 547/// type-specifier-seq declarator '=' assignment-expression 548/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 549/// '=' assignment-expression 550/// 551Parser::OwningExprResult Parser::ParseCXXCondition() { 552 if (!isCXXConditionDeclaration()) 553 return ParseExpression(); // expression 554 555 SourceLocation StartLoc = Tok.getLocation(); 556 557 // type-specifier-seq 558 DeclSpec DS; 559 ParseSpecifierQualifierList(DS); 560 561 // declarator 562 Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 563 ParseDeclarator(DeclaratorInfo); 564 565 // simple-asm-expr[opt] 566 if (Tok.is(tok::kw_asm)) { 567 SourceLocation Loc; 568 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); 569 if (AsmLabel.isInvalid()) { 570 SkipUntil(tok::semi); 571 return ExprError(); 572 } 573 DeclaratorInfo.setAsmLabel(AsmLabel.release()); 574 DeclaratorInfo.SetRangeEnd(Loc); 575 } 576 577 // If attributes are present, parse them. 578 if (Tok.is(tok::kw___attribute)) { 579 SourceLocation Loc; 580 AttributeList *AttrList = ParseAttributes(&Loc); 581 DeclaratorInfo.AddAttributes(AttrList, Loc); 582 } 583 584 // '=' assignment-expression 585 if (Tok.isNot(tok::equal)) 586 return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 587 SourceLocation EqualLoc = ConsumeToken(); 588 OwningExprResult AssignExpr(ParseAssignmentExpression()); 589 if (AssignExpr.isInvalid()) 590 return ExprError(); 591 592 return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 593 DeclaratorInfo,EqualLoc, 594 move(AssignExpr)); 595} 596 597/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 598/// This should only be called when the current token is known to be part of 599/// simple-type-specifier. 600/// 601/// simple-type-specifier: 602/// '::'[opt] nested-name-specifier[opt] type-name 603/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 604/// char 605/// wchar_t 606/// bool 607/// short 608/// int 609/// long 610/// signed 611/// unsigned 612/// float 613/// double 614/// void 615/// [GNU] typeof-specifier 616/// [C++0x] auto [TODO] 617/// 618/// type-name: 619/// class-name 620/// enum-name 621/// typedef-name 622/// 623void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 624 DS.SetRangeStart(Tok.getLocation()); 625 const char *PrevSpec; 626 unsigned DiagID; 627 SourceLocation Loc = Tok.getLocation(); 628 629 switch (Tok.getKind()) { 630 case tok::identifier: // foo::bar 631 case tok::coloncolon: // ::foo::bar 632 assert(0 && "Annotation token should already be formed!"); 633 default: 634 assert(0 && "Not a simple-type-specifier token!"); 635 abort(); 636 637 // type-name 638 case tok::annot_typename: { 639 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 640 Tok.getAnnotationValue()); 641 break; 642 } 643 644 // builtin types 645 case tok::kw_short: 646 DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID); 647 break; 648 case tok::kw_long: 649 DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID); 650 break; 651 case tok::kw_signed: 652 DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 653 break; 654 case tok::kw_unsigned: 655 DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 656 break; 657 case tok::kw_void: 658 DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); 659 break; 660 case tok::kw_char: 661 DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); 662 break; 663 case tok::kw_int: 664 DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID); 665 break; 666 case tok::kw_float: 667 DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID); 668 break; 669 case tok::kw_double: 670 DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID); 671 break; 672 case tok::kw_wchar_t: 673 DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID); 674 break; 675 case tok::kw_char16_t: 676 DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID); 677 break; 678 case tok::kw_char32_t: 679 DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID); 680 break; 681 case tok::kw_bool: 682 DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); 683 break; 684 685 // GNU typeof support. 686 case tok::kw_typeof: 687 ParseTypeofSpecifier(DS); 688 DS.Finish(Diags, PP); 689 return; 690 } 691 if (Tok.is(tok::annot_typename)) 692 DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 693 else 694 DS.SetRangeEnd(Tok.getLocation()); 695 ConsumeToken(); 696 DS.Finish(Diags, PP); 697} 698 699/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 700/// [dcl.name]), which is a non-empty sequence of type-specifiers, 701/// e.g., "const short int". Note that the DeclSpec is *not* finished 702/// by parsing the type-specifier-seq, because these sequences are 703/// typically followed by some form of declarator. Returns true and 704/// emits diagnostics if this is not a type-specifier-seq, false 705/// otherwise. 706/// 707/// type-specifier-seq: [C++ 8.1] 708/// type-specifier type-specifier-seq[opt] 709/// 710bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 711 DS.SetRangeStart(Tok.getLocation()); 712 const char *PrevSpec = 0; 713 unsigned DiagID; 714 bool isInvalid = 0; 715 716 // Parse one or more of the type specifiers. 717 if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) { 718 Diag(Tok, diag::err_operator_missing_type_specifier); 719 return true; 720 } 721 722 while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) ; 723 724 return false; 725} 726 727/// \brief Finish parsing a C++ unqualified-id that is a template-id of 728/// some form. 729/// 730/// This routine is invoked when a '<' is encountered after an identifier or 731/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 732/// whether the unqualified-id is actually a template-id. This routine will 733/// then parse the template arguments and form the appropriate template-id to 734/// return to the caller. 735/// 736/// \param SS the nested-name-specifier that precedes this template-id, if 737/// we're actually parsing a qualified-id. 738/// 739/// \param Name for constructor and destructor names, this is the actual 740/// identifier that may be a template-name. 741/// 742/// \param NameLoc the location of the class-name in a constructor or 743/// destructor. 744/// 745/// \param EnteringContext whether we're entering the scope of the 746/// nested-name-specifier. 747/// 748/// \param ObjectType if this unqualified-id occurs within a member access 749/// expression, the type of the base object whose member is being accessed. 750/// 751/// \param Id as input, describes the template-name or operator-function-id 752/// that precedes the '<'. If template arguments were parsed successfully, 753/// will be updated with the template-id. 754/// 755/// \returns true if a parse error occurred, false otherwise. 756bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 757 IdentifierInfo *Name, 758 SourceLocation NameLoc, 759 bool EnteringContext, 760 TypeTy *ObjectType, 761 UnqualifiedId &Id) { 762 assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id"); 763 764 TemplateTy Template; 765 TemplateNameKind TNK = TNK_Non_template; 766 switch (Id.getKind()) { 767 case UnqualifiedId::IK_Identifier: 768 case UnqualifiedId::IK_OperatorFunctionId: 769 TNK = Actions.isTemplateName(CurScope, SS, Id, ObjectType, EnteringContext, 770 Template); 771 break; 772 773 case UnqualifiedId::IK_ConstructorName: { 774 UnqualifiedId TemplateName; 775 TemplateName.setIdentifier(Name, NameLoc); 776 TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 777 EnteringContext, Template); 778 break; 779 } 780 781 case UnqualifiedId::IK_DestructorName: { 782 UnqualifiedId TemplateName; 783 TemplateName.setIdentifier(Name, NameLoc); 784 if (ObjectType) { 785 Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, 786 TemplateName, ObjectType); 787 TNK = TNK_Dependent_template_name; 788 if (!Template.get()) 789 return true; 790 } else { 791 TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 792 EnteringContext, Template); 793 794 if (TNK == TNK_Non_template && Id.DestructorName == 0) { 795 // The identifier following the destructor did not refer to a template 796 // or to a type. Complain. 797 if (ObjectType) 798 Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type) 799 << Name; 800 else 801 Diag(NameLoc, diag::err_destructor_class_name); 802 return true; 803 } 804 } 805 break; 806 } 807 808 default: 809 return false; 810 } 811 812 if (TNK == TNK_Non_template) 813 return false; 814 815 // Parse the enclosed template argument list. 816 SourceLocation LAngleLoc, RAngleLoc; 817 TemplateArgList TemplateArgs; 818 if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation, 819 &SS, true, LAngleLoc, 820 TemplateArgs, 821 RAngleLoc)) 822 return true; 823 824 if (Id.getKind() == UnqualifiedId::IK_Identifier || 825 Id.getKind() == UnqualifiedId::IK_OperatorFunctionId) { 826 // Form a parsed representation of the template-id to be stored in the 827 // UnqualifiedId. 828 TemplateIdAnnotation *TemplateId 829 = TemplateIdAnnotation::Allocate(TemplateArgs.size()); 830 831 if (Id.getKind() == UnqualifiedId::IK_Identifier) { 832 TemplateId->Name = Id.Identifier; 833 TemplateId->Operator = OO_None; 834 TemplateId->TemplateNameLoc = Id.StartLocation; 835 } else { 836 TemplateId->Name = 0; 837 TemplateId->Operator = Id.OperatorFunctionId.Operator; 838 TemplateId->TemplateNameLoc = Id.StartLocation; 839 } 840 841 TemplateId->Template = Template.getAs<void*>(); 842 TemplateId->Kind = TNK; 843 TemplateId->LAngleLoc = LAngleLoc; 844 TemplateId->RAngleLoc = RAngleLoc; 845 ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); 846 for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 847 Arg != ArgEnd; ++Arg) 848 Args[Arg] = TemplateArgs[Arg]; 849 850 Id.setTemplateId(TemplateId); 851 return false; 852 } 853 854 // Bundle the template arguments together. 855 ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), 856 TemplateArgs.size()); 857 858 // Constructor and destructor names. 859 Action::TypeResult Type 860 = Actions.ActOnTemplateIdType(Template, NameLoc, 861 LAngleLoc, TemplateArgsPtr, 862 RAngleLoc); 863 if (Type.isInvalid()) 864 return true; 865 866 if (Id.getKind() == UnqualifiedId::IK_ConstructorName) 867 Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 868 else 869 Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 870 871 return false; 872} 873 874/// \brief Parse an operator-function-id or conversion-function-id as part 875/// of a C++ unqualified-id. 876/// 877/// This routine is responsible only for parsing the operator-function-id or 878/// conversion-function-id; it does not handle template arguments in any way. 879/// 880/// \code 881/// operator-function-id: [C++ 13.5] 882/// 'operator' operator 883/// 884/// operator: one of 885/// new delete new[] delete[] 886/// + - * / % ^ & | ~ 887/// ! = < > += -= *= /= %= 888/// ^= &= |= << >> >>= <<= == != 889/// <= >= && || ++ -- , ->* -> 890/// () [] 891/// 892/// conversion-function-id: [C++ 12.3.2] 893/// operator conversion-type-id 894/// 895/// conversion-type-id: 896/// type-specifier-seq conversion-declarator[opt] 897/// 898/// conversion-declarator: 899/// ptr-operator conversion-declarator[opt] 900/// \endcode 901/// 902/// \param The nested-name-specifier that preceded this unqualified-id. If 903/// non-empty, then we are parsing the unqualified-id of a qualified-id. 904/// 905/// \param EnteringContext whether we are entering the scope of the 906/// nested-name-specifier. 907/// 908/// \param ObjectType if this unqualified-id occurs within a member access 909/// expression, the type of the base object whose member is being accessed. 910/// 911/// \param Result on a successful parse, contains the parsed unqualified-id. 912/// 913/// \returns true if parsing fails, false otherwise. 914bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 915 TypeTy *ObjectType, 916 UnqualifiedId &Result) { 917 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 918 919 // Consume the 'operator' keyword. 920 SourceLocation KeywordLoc = ConsumeToken(); 921 922 // Determine what kind of operator name we have. 923 unsigned SymbolIdx = 0; 924 SourceLocation SymbolLocations[3]; 925 OverloadedOperatorKind Op = OO_None; 926 switch (Tok.getKind()) { 927 case tok::kw_new: 928 case tok::kw_delete: { 929 bool isNew = Tok.getKind() == tok::kw_new; 930 // Consume the 'new' or 'delete'. 931 SymbolLocations[SymbolIdx++] = ConsumeToken(); 932 if (Tok.is(tok::l_square)) { 933 // Consume the '['. 934 SourceLocation LBracketLoc = ConsumeBracket(); 935 // Consume the ']'. 936 SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square, 937 LBracketLoc); 938 if (RBracketLoc.isInvalid()) 939 return true; 940 941 SymbolLocations[SymbolIdx++] = LBracketLoc; 942 SymbolLocations[SymbolIdx++] = RBracketLoc; 943 Op = isNew? OO_Array_New : OO_Array_Delete; 944 } else { 945 Op = isNew? OO_New : OO_Delete; 946 } 947 break; 948 } 949 950#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 951 case tok::Token: \ 952 SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 953 Op = OO_##Name; \ 954 break; 955#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 956#include "clang/Basic/OperatorKinds.def" 957 958 case tok::l_paren: { 959 // Consume the '('. 960 SourceLocation LParenLoc = ConsumeParen(); 961 // Consume the ')'. 962 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, 963 LParenLoc); 964 if (RParenLoc.isInvalid()) 965 return true; 966 967 SymbolLocations[SymbolIdx++] = LParenLoc; 968 SymbolLocations[SymbolIdx++] = RParenLoc; 969 Op = OO_Call; 970 break; 971 } 972 973 case tok::l_square: { 974 // Consume the '['. 975 SourceLocation LBracketLoc = ConsumeBracket(); 976 // Consume the ']'. 977 SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square, 978 LBracketLoc); 979 if (RBracketLoc.isInvalid()) 980 return true; 981 982 SymbolLocations[SymbolIdx++] = LBracketLoc; 983 SymbolLocations[SymbolIdx++] = RBracketLoc; 984 Op = OO_Subscript; 985 break; 986 } 987 988 case tok::code_completion: { 989 // Code completion for the operator name. 990 Actions.CodeCompleteOperatorName(CurScope); 991 992 // Consume the operator token. 993 ConsumeToken(); 994 995 // Don't try to parse any further. 996 return true; 997 } 998 999 default: 1000 break; 1001 } 1002 1003 if (Op != OO_None) { 1004 // We have parsed an operator-function-id. 1005 Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 1006 return false; 1007 } 1008 1009 // Parse a conversion-function-id. 1010 // 1011 // conversion-function-id: [C++ 12.3.2] 1012 // operator conversion-type-id 1013 // 1014 // conversion-type-id: 1015 // type-specifier-seq conversion-declarator[opt] 1016 // 1017 // conversion-declarator: 1018 // ptr-operator conversion-declarator[opt] 1019 1020 // Parse the type-specifier-seq. 1021 DeclSpec DS; 1022 if (ParseCXXTypeSpecifierSeq(DS)) 1023 return true; 1024 1025 // Parse the conversion-declarator, which is merely a sequence of 1026 // ptr-operators. 1027 Declarator D(DS, Declarator::TypeNameContext); 1028 ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 1029 1030 // Finish up the type. 1031 Action::TypeResult Ty = Actions.ActOnTypeName(CurScope, D); 1032 if (Ty.isInvalid()) 1033 return true; 1034 1035 // Note that this is a conversion-function-id. 1036 Result.setConversionFunctionId(KeywordLoc, Ty.get(), 1037 D.getSourceRange().getEnd()); 1038 return false; 1039} 1040 1041/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the 1042/// name of an entity. 1043/// 1044/// \code 1045/// unqualified-id: [C++ expr.prim.general] 1046/// identifier 1047/// operator-function-id 1048/// conversion-function-id 1049/// [C++0x] literal-operator-id [TODO] 1050/// ~ class-name 1051/// template-id 1052/// 1053/// \endcode 1054/// 1055/// \param The nested-name-specifier that preceded this unqualified-id. If 1056/// non-empty, then we are parsing the unqualified-id of a qualified-id. 1057/// 1058/// \param EnteringContext whether we are entering the scope of the 1059/// nested-name-specifier. 1060/// 1061/// \param AllowDestructorName whether we allow parsing of a destructor name. 1062/// 1063/// \param AllowConstructorName whether we allow parsing a constructor name. 1064/// 1065/// \param ObjectType if this unqualified-id occurs within a member access 1066/// expression, the type of the base object whose member is being accessed. 1067/// 1068/// \param Result on a successful parse, contains the parsed unqualified-id. 1069/// 1070/// \returns true if parsing fails, false otherwise. 1071bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, 1072 bool AllowDestructorName, 1073 bool AllowConstructorName, 1074 TypeTy *ObjectType, 1075 UnqualifiedId &Result) { 1076 // unqualified-id: 1077 // identifier 1078 // template-id (when it hasn't already been annotated) 1079 if (Tok.is(tok::identifier)) { 1080 // Consume the identifier. 1081 IdentifierInfo *Id = Tok.getIdentifierInfo(); 1082 SourceLocation IdLoc = ConsumeToken(); 1083 1084 if (AllowConstructorName && 1085 Actions.isCurrentClassName(*Id, CurScope, &SS)) { 1086 // We have parsed a constructor name. 1087 Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, CurScope, 1088 &SS, false), 1089 IdLoc, IdLoc); 1090 } else { 1091 // We have parsed an identifier. 1092 Result.setIdentifier(Id, IdLoc); 1093 } 1094 1095 // If the next token is a '<', we may have a template. 1096 if (Tok.is(tok::less)) 1097 return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 1098 ObjectType, Result); 1099 1100 return false; 1101 } 1102 1103 // unqualified-id: 1104 // template-id (already parsed and annotated) 1105 if (Tok.is(tok::annot_template_id)) { 1106 // FIXME: Could this be a constructor name??? 1107 1108 // We have already parsed a template-id; consume the annotation token as 1109 // our unqualified-id. 1110 Result.setTemplateId( 1111 static_cast<TemplateIdAnnotation*>(Tok.getAnnotationValue())); 1112 ConsumeToken(); 1113 return false; 1114 } 1115 1116 // unqualified-id: 1117 // operator-function-id 1118 // conversion-function-id 1119 if (Tok.is(tok::kw_operator)) { 1120 if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 1121 return true; 1122 1123 // If we have an operator-function-id and the next token is a '<', we may 1124 // have a 1125 // 1126 // template-id: 1127 // operator-function-id < template-argument-list[opt] > 1128 if (Result.getKind() == UnqualifiedId::IK_OperatorFunctionId && 1129 Tok.is(tok::less)) 1130 return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 1131 EnteringContext, ObjectType, 1132 Result); 1133 1134 return false; 1135 } 1136 1137 if ((AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 1138 // C++ [expr.unary.op]p10: 1139 // There is an ambiguity in the unary-expression ~X(), where X is a 1140 // class-name. The ambiguity is resolved in favor of treating ~ as a 1141 // unary complement rather than treating ~X as referring to a destructor. 1142 1143 // Parse the '~'. 1144 SourceLocation TildeLoc = ConsumeToken(); 1145 1146 // Parse the class-name. 1147 if (Tok.isNot(tok::identifier)) { 1148 Diag(Tok, diag::err_destructor_class_name); 1149 return true; 1150 } 1151 1152 // Parse the class-name (or template-name in a simple-template-id). 1153 IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 1154 SourceLocation ClassNameLoc = ConsumeToken(); 1155 1156 if (Tok.is(tok::less)) { 1157 Result.setDestructorName(TildeLoc, 0, ClassNameLoc); 1158 return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc, 1159 EnteringContext, ObjectType, Result); 1160 } 1161 1162 // Note that this is a destructor name. 1163 Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc, 1164 CurScope, &SS); 1165 if (!Ty) { 1166 if (ObjectType) 1167 Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type) 1168 << ClassName; 1169 else 1170 Diag(ClassNameLoc, diag::err_destructor_class_name); 1171 return true; 1172 } 1173 1174 Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 1175 return false; 1176 } 1177 1178 Diag(Tok, diag::err_expected_unqualified_id) 1179 << getLang().CPlusPlus; 1180 return true; 1181} 1182 1183/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 1184/// memory in a typesafe manner and call constructors. 1185/// 1186/// This method is called to parse the new expression after the optional :: has 1187/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 1188/// is its location. Otherwise, "Start" is the location of the 'new' token. 1189/// 1190/// new-expression: 1191/// '::'[opt] 'new' new-placement[opt] new-type-id 1192/// new-initializer[opt] 1193/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 1194/// new-initializer[opt] 1195/// 1196/// new-placement: 1197/// '(' expression-list ')' 1198/// 1199/// new-type-id: 1200/// type-specifier-seq new-declarator[opt] 1201/// 1202/// new-declarator: 1203/// ptr-operator new-declarator[opt] 1204/// direct-new-declarator 1205/// 1206/// new-initializer: 1207/// '(' expression-list[opt] ')' 1208/// [C++0x] braced-init-list [TODO] 1209/// 1210Parser::OwningExprResult 1211Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 1212 assert(Tok.is(tok::kw_new) && "expected 'new' token"); 1213 ConsumeToken(); // Consume 'new' 1214 1215 // A '(' now can be a new-placement or the '(' wrapping the type-id in the 1216 // second form of new-expression. It can't be a new-type-id. 1217 1218 ExprVector PlacementArgs(Actions); 1219 SourceLocation PlacementLParen, PlacementRParen; 1220 1221 bool ParenTypeId; 1222 DeclSpec DS; 1223 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1224 if (Tok.is(tok::l_paren)) { 1225 // If it turns out to be a placement, we change the type location. 1226 PlacementLParen = ConsumeParen(); 1227 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 1228 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1229 return ExprError(); 1230 } 1231 1232 PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 1233 if (PlacementRParen.isInvalid()) { 1234 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1235 return ExprError(); 1236 } 1237 1238 if (PlacementArgs.empty()) { 1239 // Reset the placement locations. There was no placement. 1240 PlacementLParen = PlacementRParen = SourceLocation(); 1241 ParenTypeId = true; 1242 } else { 1243 // We still need the type. 1244 if (Tok.is(tok::l_paren)) { 1245 SourceLocation LParen = ConsumeParen(); 1246 ParseSpecifierQualifierList(DS); 1247 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 1248 ParseDeclarator(DeclaratorInfo); 1249 MatchRHSPunctuation(tok::r_paren, LParen); 1250 ParenTypeId = true; 1251 } else { 1252 if (ParseCXXTypeSpecifierSeq(DS)) 1253 DeclaratorInfo.setInvalidType(true); 1254 else { 1255 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 1256 ParseDeclaratorInternal(DeclaratorInfo, 1257 &Parser::ParseDirectNewDeclarator); 1258 } 1259 ParenTypeId = false; 1260 } 1261 } 1262 } else { 1263 // A new-type-id is a simplified type-id, where essentially the 1264 // direct-declarator is replaced by a direct-new-declarator. 1265 if (ParseCXXTypeSpecifierSeq(DS)) 1266 DeclaratorInfo.setInvalidType(true); 1267 else { 1268 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 1269 ParseDeclaratorInternal(DeclaratorInfo, 1270 &Parser::ParseDirectNewDeclarator); 1271 } 1272 ParenTypeId = false; 1273 } 1274 if (DeclaratorInfo.isInvalidType()) { 1275 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1276 return ExprError(); 1277 } 1278 1279 ExprVector ConstructorArgs(Actions); 1280 SourceLocation ConstructorLParen, ConstructorRParen; 1281 1282 if (Tok.is(tok::l_paren)) { 1283 ConstructorLParen = ConsumeParen(); 1284 if (Tok.isNot(tok::r_paren)) { 1285 CommaLocsTy CommaLocs; 1286 if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 1287 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1288 return ExprError(); 1289 } 1290 } 1291 ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 1292 if (ConstructorRParen.isInvalid()) { 1293 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1294 return ExprError(); 1295 } 1296 } 1297 1298 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 1299 move_arg(PlacementArgs), PlacementRParen, 1300 ParenTypeId, DeclaratorInfo, ConstructorLParen, 1301 move_arg(ConstructorArgs), ConstructorRParen); 1302} 1303 1304/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 1305/// passed to ParseDeclaratorInternal. 1306/// 1307/// direct-new-declarator: 1308/// '[' expression ']' 1309/// direct-new-declarator '[' constant-expression ']' 1310/// 1311void Parser::ParseDirectNewDeclarator(Declarator &D) { 1312 // Parse the array dimensions. 1313 bool first = true; 1314 while (Tok.is(tok::l_square)) { 1315 SourceLocation LLoc = ConsumeBracket(); 1316 OwningExprResult Size(first ? ParseExpression() 1317 : ParseConstantExpression()); 1318 if (Size.isInvalid()) { 1319 // Recover 1320 SkipUntil(tok::r_square); 1321 return; 1322 } 1323 first = false; 1324 1325 SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc); 1326 D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 1327 Size.release(), LLoc, RLoc), 1328 RLoc); 1329 1330 if (RLoc.isInvalid()) 1331 return; 1332 } 1333} 1334 1335/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 1336/// This ambiguity appears in the syntax of the C++ new operator. 1337/// 1338/// new-expression: 1339/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 1340/// new-initializer[opt] 1341/// 1342/// new-placement: 1343/// '(' expression-list ')' 1344/// 1345bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 1346 Declarator &D) { 1347 // The '(' was already consumed. 1348 if (isTypeIdInParens()) { 1349 ParseSpecifierQualifierList(D.getMutableDeclSpec()); 1350 D.SetSourceRange(D.getDeclSpec().getSourceRange()); 1351 ParseDeclarator(D); 1352 return D.isInvalidType(); 1353 } 1354 1355 // It's not a type, it has to be an expression list. 1356 // Discard the comma locations - ActOnCXXNew has enough parameters. 1357 CommaLocsTy CommaLocs; 1358 return ParseExpressionList(PlacementArgs, CommaLocs); 1359} 1360 1361/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 1362/// to free memory allocated by new. 1363/// 1364/// This method is called to parse the 'delete' expression after the optional 1365/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 1366/// and "Start" is its location. Otherwise, "Start" is the location of the 1367/// 'delete' token. 1368/// 1369/// delete-expression: 1370/// '::'[opt] 'delete' cast-expression 1371/// '::'[opt] 'delete' '[' ']' cast-expression 1372Parser::OwningExprResult 1373Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 1374 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 1375 ConsumeToken(); // Consume 'delete' 1376 1377 // Array delete? 1378 bool ArrayDelete = false; 1379 if (Tok.is(tok::l_square)) { 1380 ArrayDelete = true; 1381 SourceLocation LHS = ConsumeBracket(); 1382 SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 1383 if (RHS.isInvalid()) 1384 return ExprError(); 1385 } 1386 1387 OwningExprResult Operand(ParseCastExpression(false)); 1388 if (Operand.isInvalid()) 1389 return move(Operand); 1390 1391 return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand)); 1392} 1393 1394static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { 1395 switch(kind) { 1396 default: assert(false && "Not a known unary type trait."); 1397 case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 1398 case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 1399 case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 1400 case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 1401 case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 1402 case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; 1403 case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 1404 case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 1405 case tok::kw___is_abstract: return UTT_IsAbstract; 1406 case tok::kw___is_class: return UTT_IsClass; 1407 case tok::kw___is_empty: return UTT_IsEmpty; 1408 case tok::kw___is_enum: return UTT_IsEnum; 1409 case tok::kw___is_pod: return UTT_IsPOD; 1410 case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 1411 case tok::kw___is_union: return UTT_IsUnion; 1412 } 1413} 1414 1415/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 1416/// pseudo-functions that allow implementation of the TR1/C++0x type traits 1417/// templates. 1418/// 1419/// primary-expression: 1420/// [GNU] unary-type-trait '(' type-id ')' 1421/// 1422Parser::OwningExprResult Parser::ParseUnaryTypeTrait() { 1423 UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 1424 SourceLocation Loc = ConsumeToken(); 1425 1426 SourceLocation LParen = Tok.getLocation(); 1427 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) 1428 return ExprError(); 1429 1430 // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 1431 // there will be cryptic errors about mismatched parentheses and missing 1432 // specifiers. 1433 TypeResult Ty = ParseTypeName(); 1434 1435 SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); 1436 1437 if (Ty.isInvalid()) 1438 return ExprError(); 1439 1440 return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen); 1441} 1442 1443/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 1444/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 1445/// based on the context past the parens. 1446Parser::OwningExprResult 1447Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 1448 TypeTy *&CastTy, 1449 SourceLocation LParenLoc, 1450 SourceLocation &RParenLoc) { 1451 assert(getLang().CPlusPlus && "Should only be called for C++!"); 1452 assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 1453 assert(isTypeIdInParens() && "Not a type-id!"); 1454 1455 OwningExprResult Result(Actions, true); 1456 CastTy = 0; 1457 1458 // We need to disambiguate a very ugly part of the C++ syntax: 1459 // 1460 // (T())x; - type-id 1461 // (T())*x; - type-id 1462 // (T())/x; - expression 1463 // (T()); - expression 1464 // 1465 // The bad news is that we cannot use the specialized tentative parser, since 1466 // it can only verify that the thing inside the parens can be parsed as 1467 // type-id, it is not useful for determining the context past the parens. 1468 // 1469 // The good news is that the parser can disambiguate this part without 1470 // making any unnecessary Action calls. 1471 // 1472 // It uses a scheme similar to parsing inline methods. The parenthesized 1473 // tokens are cached, the context that follows is determined (possibly by 1474 // parsing a cast-expression), and then we re-introduce the cached tokens 1475 // into the token stream and parse them appropriately. 1476 1477 ParenParseOption ParseAs; 1478 CachedTokens Toks; 1479 1480 // Store the tokens of the parentheses. We will parse them after we determine 1481 // the context that follows them. 1482 if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) { 1483 // We didn't find the ')' we expected. 1484 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1485 return ExprError(); 1486 } 1487 1488 if (Tok.is(tok::l_brace)) { 1489 ParseAs = CompoundLiteral; 1490 } else { 1491 bool NotCastExpr; 1492 // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 1493 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 1494 NotCastExpr = true; 1495 } else { 1496 // Try parsing the cast-expression that may follow. 1497 // If it is not a cast-expression, NotCastExpr will be true and no token 1498 // will be consumed. 1499 Result = ParseCastExpression(false/*isUnaryExpression*/, 1500 false/*isAddressofOperand*/, 1501 NotCastExpr, false); 1502 } 1503 1504 // If we parsed a cast-expression, it's really a type-id, otherwise it's 1505 // an expression. 1506 ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 1507 } 1508 1509 // The current token should go after the cached tokens. 1510 Toks.push_back(Tok); 1511 // Re-enter the stored parenthesized tokens into the token stream, so we may 1512 // parse them now. 1513 PP.EnterTokenStream(Toks.data(), Toks.size(), 1514 true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 1515 // Drop the current token and bring the first cached one. It's the same token 1516 // as when we entered this function. 1517 ConsumeAnyToken(); 1518 1519 if (ParseAs >= CompoundLiteral) { 1520 TypeResult Ty = ParseTypeName(); 1521 1522 // Match the ')'. 1523 if (Tok.is(tok::r_paren)) 1524 RParenLoc = ConsumeParen(); 1525 else 1526 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1527 1528 if (ParseAs == CompoundLiteral) { 1529 ExprType = CompoundLiteral; 1530 return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc); 1531 } 1532 1533 // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 1534 assert(ParseAs == CastExpr); 1535 1536 if (Ty.isInvalid()) 1537 return ExprError(); 1538 1539 CastTy = Ty.get(); 1540 1541 // Result is what ParseCastExpression returned earlier. 1542 if (!Result.isInvalid()) 1543 Result = Actions.ActOnCastExpr(CurScope, LParenLoc, CastTy, RParenLoc, 1544 move(Result)); 1545 return move(Result); 1546 } 1547 1548 // Not a compound literal, and not followed by a cast-expression. 1549 assert(ParseAs == SimpleExpr); 1550 1551 ExprType = SimpleExpr; 1552 Result = ParseExpression(); 1553 if (!Result.isInvalid() && Tok.is(tok::r_paren)) 1554 Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result)); 1555 1556 // Match the ')'. 1557 if (Result.isInvalid()) { 1558 SkipUntil(tok::r_paren); 1559 return ExprError(); 1560 } 1561 1562 if (Tok.is(tok::r_paren)) 1563 RParenLoc = ConsumeParen(); 1564 else 1565 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1566 1567 return move(Result); 1568} 1569