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