ParseExprCXX.cpp revision 1df5109f475bcbc528eb1fb9fdb179dcadbb33a6
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" 17using namespace clang; 18 19/// ParseOptionalCXXScopeSpecifier - Parse global scope or 20/// nested-name-specifier if present. Returns true if a nested-name-specifier 21/// was parsed from the token stream. Note that this routine will not parse 22/// ::new or ::delete, it will just leave them in the token stream. 23/// 24/// '::'[opt] nested-name-specifier 25/// '::' 26/// 27/// nested-name-specifier: 28/// type-name '::' 29/// namespace-name '::' 30/// nested-name-specifier identifier '::' 31/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 32/// 33bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { 34 assert(getLang().CPlusPlus && 35 "Call sites of this function should be guarded by checking for C++"); 36 37 if (Tok.is(tok::annot_cxxscope)) { 38 SS.setScopeRep(Tok.getAnnotationValue()); 39 SS.setRange(Tok.getAnnotationRange()); 40 ConsumeToken(); 41 return true; 42 } 43 44 bool HasScopeSpecifier = false; 45 46 if (Tok.is(tok::coloncolon)) { 47 // ::new and ::delete aren't nested-name-specifiers. 48 tok::TokenKind NextKind = NextToken().getKind(); 49 if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 50 return false; 51 52 // '::' - Global scope qualifier. 53 SourceLocation CCLoc = ConsumeToken(); 54 SS.setBeginLoc(CCLoc); 55 SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 56 SS.setEndLoc(CCLoc); 57 HasScopeSpecifier = true; 58 } 59 60 while (true) { 61 // nested-name-specifier: 62 // nested-name-specifier 'template'[opt] simple-template-id '::' 63 64 // Parse the optional 'template' keyword, then make sure we have 65 // 'identifier <' after it. 66 if (Tok.is(tok::kw_template)) { 67 SourceLocation TemplateKWLoc = ConsumeToken(); 68 69 if (Tok.isNot(tok::identifier)) { 70 Diag(Tok.getLocation(), 71 diag::err_id_after_template_in_nested_name_spec) 72 << SourceRange(TemplateKWLoc); 73 break; 74 } 75 76 if (NextToken().isNot(tok::less)) { 77 Diag(NextToken().getLocation(), 78 diag::err_less_after_template_name_in_nested_name_spec) 79 << Tok.getIdentifierInfo()->getName() 80 << SourceRange(TemplateKWLoc, Tok.getLocation()); 81 break; 82 } 83 84 TemplateTy Template 85 = Actions.ActOnDependentTemplateName(TemplateKWLoc, 86 *Tok.getIdentifierInfo(), 87 Tok.getLocation(), SS); 88 if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, 89 &SS, TemplateKWLoc, false)) 90 break; 91 92 continue; 93 } 94 95 if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 96 // We have 97 // 98 // simple-template-id '::' 99 // 100 // So we need to check whether the simple-template-id is of the 101 // right kind (it should name a type or be dependent), and then 102 // convert it into a type within the nested-name-specifier. 103 TemplateIdAnnotation *TemplateId 104 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 105 106 if (TemplateId->Kind == TNK_Type_template || 107 TemplateId->Kind == TNK_Dependent_template_name) { 108 AnnotateTemplateIdTokenAsType(&SS); 109 SS.setScopeRep(0); 110 111 assert(Tok.is(tok::annot_typename) && 112 "AnnotateTemplateIdTokenAsType isn't working"); 113 Token TypeToken = Tok; 114 ConsumeToken(); 115 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 116 SourceLocation CCLoc = ConsumeToken(); 117 118 if (!HasScopeSpecifier) { 119 SS.setBeginLoc(TypeToken.getLocation()); 120 HasScopeSpecifier = true; 121 } 122 123 if (TypeToken.getAnnotationValue()) 124 SS.setScopeRep( 125 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, 126 TypeToken.getAnnotationValue(), 127 TypeToken.getAnnotationRange(), 128 CCLoc)); 129 else 130 SS.setScopeRep(0); 131 SS.setEndLoc(CCLoc); 132 continue; 133 } 134 135 assert(false && "FIXME: Only type template names supported here"); 136 } 137 138 139 // The rest of the nested-name-specifier possibilities start with 140 // tok::identifier. 141 if (Tok.isNot(tok::identifier)) 142 break; 143 144 IdentifierInfo &II = *Tok.getIdentifierInfo(); 145 146 // nested-name-specifier: 147 // type-name '::' 148 // namespace-name '::' 149 // nested-name-specifier identifier '::' 150 Token Next = NextToken(); 151 if (Next.is(tok::coloncolon)) { 152 // We have an identifier followed by a '::'. Lookup this name 153 // as the name in a nested-name-specifier. 154 SourceLocation IdLoc = ConsumeToken(); 155 assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 156 SourceLocation CCLoc = ConsumeToken(); 157 158 if (!HasScopeSpecifier) { 159 SS.setBeginLoc(IdLoc); 160 HasScopeSpecifier = true; 161 } 162 163 if (SS.isInvalid()) 164 continue; 165 166 SS.setScopeRep( 167 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II)); 168 SS.setEndLoc(CCLoc); 169 continue; 170 } 171 172 // nested-name-specifier: 173 // type-name '<' 174 if (Next.is(tok::less)) { 175 TemplateTy Template; 176 if (TemplateNameKind TNK = Actions.isTemplateName(II, CurScope, 177 Template, &SS)) { 178 // We have found a template name, so annotate this this token 179 // with a template-id annotation. We do not permit the 180 // template-id to be translated into a type annotation, 181 // because some clients (e.g., the parsing of class template 182 // specializations) still want to see the original template-id 183 // token. 184 if (AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), 185 false)) 186 break; 187 continue; 188 } 189 } 190 191 // We don't have any tokens that form the beginning of a 192 // nested-name-specifier, so we're done. 193 break; 194 } 195 196 return HasScopeSpecifier; 197} 198 199/// ParseCXXIdExpression - Handle id-expression. 200/// 201/// id-expression: 202/// unqualified-id 203/// qualified-id 204/// 205/// unqualified-id: 206/// identifier 207/// operator-function-id 208/// conversion-function-id [TODO] 209/// '~' class-name [TODO] 210/// template-id 211/// 212/// qualified-id: 213/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 214/// '::' identifier 215/// '::' operator-function-id 216/// '::' template-id 217/// 218/// nested-name-specifier: 219/// type-name '::' 220/// namespace-name '::' 221/// nested-name-specifier identifier '::' 222/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 223/// 224/// NOTE: The standard specifies that, for qualified-id, the parser does not 225/// expect: 226/// 227/// '::' conversion-function-id 228/// '::' '~' class-name 229/// 230/// This may cause a slight inconsistency on diagnostics: 231/// 232/// class C {}; 233/// namespace A {} 234/// void f() { 235/// :: A :: ~ C(); // Some Sema error about using destructor with a 236/// // namespace. 237/// :: ~ C(); // Some Parser error like 'unexpected ~'. 238/// } 239/// 240/// We simplify the parser a bit and make it work like: 241/// 242/// qualified-id: 243/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 244/// '::' unqualified-id 245/// 246/// That way Sema can handle and report similar errors for namespaces and the 247/// global scope. 248/// 249/// The isAddressOfOperand parameter indicates that this id-expression is a 250/// direct operand of the address-of operator. This is, besides member contexts, 251/// the only place where a qualified-id naming a non-static class member may 252/// appear. 253/// 254Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 255 // qualified-id: 256 // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 257 // '::' unqualified-id 258 // 259 CXXScopeSpec SS; 260 ParseOptionalCXXScopeSpecifier(SS); 261 262 // unqualified-id: 263 // identifier 264 // operator-function-id 265 // conversion-function-id 266 // '~' class-name [TODO] 267 // template-id 268 // 269 switch (Tok.getKind()) { 270 default: 271 return ExprError(Diag(Tok, diag::err_expected_unqualified_id)); 272 273 case tok::identifier: { 274 // Consume the identifier so that we can see if it is followed by a '('. 275 IdentifierInfo &II = *Tok.getIdentifierInfo(); 276 SourceLocation L = ConsumeToken(); 277 return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren), 278 &SS, isAddressOfOperand); 279 } 280 281 case tok::kw_operator: { 282 SourceLocation OperatorLoc = Tok.getLocation(); 283 if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) 284 return Actions.ActOnCXXOperatorFunctionIdExpr( 285 CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS, 286 isAddressOfOperand); 287 if (TypeTy *Type = ParseConversionFunctionId()) 288 return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type, 289 Tok.is(tok::l_paren), SS, 290 isAddressOfOperand); 291 292 // We already complained about a bad conversion-function-id, 293 // above. 294 return ExprError(); 295 } 296 297 case tok::annot_template_id: { 298 TemplateIdAnnotation *TemplateId 299 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 300 assert((TemplateId->Kind == TNK_Function_template || 301 TemplateId->Kind == TNK_Dependent_template_name) && 302 "A template type name is not an ID expression"); 303 304 ASTTemplateArgsPtr TemplateArgsPtr(Actions, 305 TemplateId->getTemplateArgs(), 306 TemplateId->getTemplateArgIsType(), 307 TemplateId->NumArgs); 308 309 OwningExprResult Result 310 = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template), 311 TemplateId->TemplateNameLoc, 312 TemplateId->LAngleLoc, 313 TemplateArgsPtr, 314 TemplateId->getTemplateArgLocations(), 315 TemplateId->RAngleLoc); 316 ConsumeToken(); // Consume the template-id token 317 return move(Result); 318 } 319 320 } // switch. 321 322 assert(0 && "The switch was supposed to take care everything."); 323} 324 325/// ParseCXXCasts - This handles the various ways to cast expressions to another 326/// type. 327/// 328/// postfix-expression: [C++ 5.2p1] 329/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 330/// 'static_cast' '<' type-name '>' '(' expression ')' 331/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 332/// 'const_cast' '<' type-name '>' '(' expression ')' 333/// 334Parser::OwningExprResult Parser::ParseCXXCasts() { 335 tok::TokenKind Kind = Tok.getKind(); 336 const char *CastName = 0; // For error messages 337 338 switch (Kind) { 339 default: assert(0 && "Unknown C++ cast!"); abort(); 340 case tok::kw_const_cast: CastName = "const_cast"; break; 341 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 342 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 343 case tok::kw_static_cast: CastName = "static_cast"; break; 344 } 345 346 SourceLocation OpLoc = ConsumeToken(); 347 SourceLocation LAngleBracketLoc = Tok.getLocation(); 348 349 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 350 return ExprError(); 351 352 TypeResult CastTy = ParseTypeName(); 353 SourceLocation RAngleBracketLoc = Tok.getLocation(); 354 355 if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 356 return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 357 358 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 359 360 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName)) 361 return ExprError(); 362 363 OwningExprResult Result = ParseExpression(); 364 365 // Match the ')'. 366 if (Result.isInvalid()) 367 SkipUntil(tok::r_paren); 368 369 if (Tok.is(tok::r_paren)) 370 RParenLoc = ConsumeParen(); 371 else 372 MatchRHSPunctuation(tok::r_paren, LParenLoc); 373 374 if (!Result.isInvalid() && !CastTy.isInvalid()) 375 Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 376 LAngleBracketLoc, CastTy.get(), 377 RAngleBracketLoc, 378 LParenLoc, move(Result), RParenLoc); 379 380 return move(Result); 381} 382 383/// ParseCXXTypeid - This handles the C++ typeid expression. 384/// 385/// postfix-expression: [C++ 5.2p1] 386/// 'typeid' '(' expression ')' 387/// 'typeid' '(' type-id ')' 388/// 389Parser::OwningExprResult Parser::ParseCXXTypeid() { 390 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 391 392 SourceLocation OpLoc = ConsumeToken(); 393 SourceLocation LParenLoc = Tok.getLocation(); 394 SourceLocation RParenLoc; 395 396 // typeid expressions are always parenthesized. 397 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 398 "typeid")) 399 return ExprError(); 400 401 OwningExprResult Result(Actions); 402 403 if (isTypeIdInParens()) { 404 TypeResult Ty = ParseTypeName(); 405 406 // Match the ')'. 407 MatchRHSPunctuation(tok::r_paren, LParenLoc); 408 409 if (Ty.isInvalid()) 410 return ExprError(); 411 412 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 413 Ty.get(), RParenLoc); 414 } else { 415 // C++0x [expr.typeid]p3: 416 // When typeid is applied to an expression other than an lvalue of a 417 // polymorphic class type [...] The expression is an unevaluated 418 // operand (Clause 5). 419 // 420 // Note that we can't tell whether the expression is an lvalue of a 421 // polymorphic class type until after we've parsed the expression, so 422 // we the expression is potentially potentially evaluated. 423 EnterExpressionEvaluationContext Unevaluated(Actions, 424 Action::PotentiallyPotentiallyEvaluated); 425 Result = ParseExpression(); 426 427 // Match the ')'. 428 if (Result.isInvalid()) 429 SkipUntil(tok::r_paren); 430 else { 431 MatchRHSPunctuation(tok::r_paren, LParenLoc); 432 433 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 434 Result.release(), RParenLoc); 435 } 436 } 437 438 return move(Result); 439} 440 441/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 442/// 443/// boolean-literal: [C++ 2.13.5] 444/// 'true' 445/// 'false' 446Parser::OwningExprResult Parser::ParseCXXBoolLiteral() { 447 tok::TokenKind Kind = Tok.getKind(); 448 return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 449} 450 451/// ParseThrowExpression - This handles the C++ throw expression. 452/// 453/// throw-expression: [C++ 15] 454/// 'throw' assignment-expression[opt] 455Parser::OwningExprResult Parser::ParseThrowExpression() { 456 assert(Tok.is(tok::kw_throw) && "Not throw!"); 457 SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 458 459 // If the current token isn't the start of an assignment-expression, 460 // then the expression is not present. This handles things like: 461 // "C ? throw : (void)42", which is crazy but legal. 462 switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 463 case tok::semi: 464 case tok::r_paren: 465 case tok::r_square: 466 case tok::r_brace: 467 case tok::colon: 468 case tok::comma: 469 return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions)); 470 471 default: 472 OwningExprResult Expr(ParseAssignmentExpression()); 473 if (Expr.isInvalid()) return move(Expr); 474 return Actions.ActOnCXXThrow(ThrowLoc, move(Expr)); 475 } 476} 477 478/// ParseCXXThis - This handles the C++ 'this' pointer. 479/// 480/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 481/// a non-lvalue expression whose value is the address of the object for which 482/// the function is called. 483Parser::OwningExprResult Parser::ParseCXXThis() { 484 assert(Tok.is(tok::kw_this) && "Not 'this'!"); 485 SourceLocation ThisLoc = ConsumeToken(); 486 return Actions.ActOnCXXThis(ThisLoc); 487} 488 489/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 490/// Can be interpreted either as function-style casting ("int(x)") 491/// or class type construction ("ClassType(x,y,z)") 492/// or creation of a value-initialized type ("int()"). 493/// 494/// postfix-expression: [C++ 5.2p1] 495/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 496/// typename-specifier '(' expression-list[opt] ')' [TODO] 497/// 498Parser::OwningExprResult 499Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 500 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 501 TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get(); 502 503 assert(Tok.is(tok::l_paren) && "Expected '('!"); 504 SourceLocation LParenLoc = ConsumeParen(); 505 506 ExprVector Exprs(Actions); 507 CommaLocsTy CommaLocs; 508 509 if (Tok.isNot(tok::r_paren)) { 510 if (ParseExpressionList(Exprs, CommaLocs)) { 511 SkipUntil(tok::r_paren); 512 return ExprError(); 513 } 514 } 515 516 // Match the ')'. 517 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 518 519 // TypeRep could be null, if it references an invalid typedef. 520 if (!TypeRep) 521 return ExprError(); 522 523 assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 524 "Unexpected number of commas!"); 525 return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 526 LParenLoc, move_arg(Exprs), 527 CommaLocs.data(), RParenLoc); 528} 529 530/// ParseCXXCondition - if/switch/while/for condition expression. 531/// 532/// condition: 533/// expression 534/// type-specifier-seq declarator '=' assignment-expression 535/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 536/// '=' assignment-expression 537/// 538Parser::OwningExprResult Parser::ParseCXXCondition() { 539 if (!isCXXConditionDeclaration()) 540 return ParseExpression(); // expression 541 542 SourceLocation StartLoc = Tok.getLocation(); 543 544 // type-specifier-seq 545 DeclSpec DS; 546 ParseSpecifierQualifierList(DS); 547 548 // declarator 549 Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 550 ParseDeclarator(DeclaratorInfo); 551 552 // simple-asm-expr[opt] 553 if (Tok.is(tok::kw_asm)) { 554 SourceLocation Loc; 555 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); 556 if (AsmLabel.isInvalid()) { 557 SkipUntil(tok::semi); 558 return ExprError(); 559 } 560 DeclaratorInfo.setAsmLabel(AsmLabel.release()); 561 DeclaratorInfo.SetRangeEnd(Loc); 562 } 563 564 // If attributes are present, parse them. 565 if (Tok.is(tok::kw___attribute)) { 566 SourceLocation Loc; 567 AttributeList *AttrList = ParseAttributes(&Loc); 568 DeclaratorInfo.AddAttributes(AttrList, Loc); 569 } 570 571 // '=' assignment-expression 572 if (Tok.isNot(tok::equal)) 573 return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 574 SourceLocation EqualLoc = ConsumeToken(); 575 OwningExprResult AssignExpr(ParseAssignmentExpression()); 576 if (AssignExpr.isInvalid()) 577 return ExprError(); 578 579 return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 580 DeclaratorInfo,EqualLoc, 581 move(AssignExpr)); 582} 583 584/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 585/// This should only be called when the current token is known to be part of 586/// simple-type-specifier. 587/// 588/// simple-type-specifier: 589/// '::'[opt] nested-name-specifier[opt] type-name 590/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 591/// char 592/// wchar_t 593/// bool 594/// short 595/// int 596/// long 597/// signed 598/// unsigned 599/// float 600/// double 601/// void 602/// [GNU] typeof-specifier 603/// [C++0x] auto [TODO] 604/// 605/// type-name: 606/// class-name 607/// enum-name 608/// typedef-name 609/// 610void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 611 DS.SetRangeStart(Tok.getLocation()); 612 const char *PrevSpec; 613 unsigned DiagID; 614 SourceLocation Loc = Tok.getLocation(); 615 616 switch (Tok.getKind()) { 617 case tok::identifier: // foo::bar 618 case tok::coloncolon: // ::foo::bar 619 assert(0 && "Annotation token should already be formed!"); 620 default: 621 assert(0 && "Not a simple-type-specifier token!"); 622 abort(); 623 624 // type-name 625 case tok::annot_typename: { 626 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 627 Tok.getAnnotationValue()); 628 break; 629 } 630 631 // builtin types 632 case tok::kw_short: 633 DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID); 634 break; 635 case tok::kw_long: 636 DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID); 637 break; 638 case tok::kw_signed: 639 DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 640 break; 641 case tok::kw_unsigned: 642 DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 643 break; 644 case tok::kw_void: 645 DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); 646 break; 647 case tok::kw_char: 648 DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); 649 break; 650 case tok::kw_int: 651 DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID); 652 break; 653 case tok::kw_float: 654 DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID); 655 break; 656 case tok::kw_double: 657 DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID); 658 break; 659 case tok::kw_wchar_t: 660 DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID); 661 break; 662 case tok::kw_char16_t: 663 DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID); 664 break; 665 case tok::kw_char32_t: 666 DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID); 667 break; 668 case tok::kw_bool: 669 DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); 670 break; 671 672 // GNU typeof support. 673 case tok::kw_typeof: 674 ParseTypeofSpecifier(DS); 675 DS.Finish(Diags, PP); 676 return; 677 } 678 if (Tok.is(tok::annot_typename)) 679 DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 680 else 681 DS.SetRangeEnd(Tok.getLocation()); 682 ConsumeToken(); 683 DS.Finish(Diags, PP); 684} 685 686/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 687/// [dcl.name]), which is a non-empty sequence of type-specifiers, 688/// e.g., "const short int". Note that the DeclSpec is *not* finished 689/// by parsing the type-specifier-seq, because these sequences are 690/// typically followed by some form of declarator. Returns true and 691/// emits diagnostics if this is not a type-specifier-seq, false 692/// otherwise. 693/// 694/// type-specifier-seq: [C++ 8.1] 695/// type-specifier type-specifier-seq[opt] 696/// 697bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 698 DS.SetRangeStart(Tok.getLocation()); 699 const char *PrevSpec = 0; 700 unsigned DiagID; 701 bool isInvalid = 0; 702 703 // Parse one or more of the type specifiers. 704 if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) { 705 Diag(Tok, diag::err_operator_missing_type_specifier); 706 return true; 707 } 708 709 while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) ; 710 711 return false; 712} 713 714/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 715/// operator name (C++ [over.oper]). If successful, returns the 716/// predefined identifier that corresponds to that overloaded 717/// operator. Otherwise, returns NULL and does not consume any tokens. 718/// 719/// operator-function-id: [C++ 13.5] 720/// 'operator' operator 721/// 722/// operator: one of 723/// new delete new[] delete[] 724/// + - * / % ^ & | ~ 725/// ! = < > += -= *= /= %= 726/// ^= &= |= << >> >>= <<= == != 727/// <= >= && || ++ -- , ->* -> 728/// () [] 729OverloadedOperatorKind 730Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) { 731 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 732 SourceLocation Loc; 733 734 OverloadedOperatorKind Op = OO_None; 735 switch (NextToken().getKind()) { 736 case tok::kw_new: 737 ConsumeToken(); // 'operator' 738 Loc = ConsumeToken(); // 'new' 739 if (Tok.is(tok::l_square)) { 740 ConsumeBracket(); // '[' 741 Loc = Tok.getLocation(); 742 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 743 Op = OO_Array_New; 744 } else { 745 Op = OO_New; 746 } 747 if (EndLoc) 748 *EndLoc = Loc; 749 return Op; 750 751 case tok::kw_delete: 752 ConsumeToken(); // 'operator' 753 Loc = ConsumeToken(); // 'delete' 754 if (Tok.is(tok::l_square)) { 755 ConsumeBracket(); // '[' 756 Loc = Tok.getLocation(); 757 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 758 Op = OO_Array_Delete; 759 } else { 760 Op = OO_Delete; 761 } 762 if (EndLoc) 763 *EndLoc = Loc; 764 return Op; 765 766#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 767 case tok::Token: Op = OO_##Name; break; 768#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 769#include "clang/Basic/OperatorKinds.def" 770 771 case tok::l_paren: 772 ConsumeToken(); // 'operator' 773 ConsumeParen(); // '(' 774 Loc = Tok.getLocation(); 775 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 776 if (EndLoc) 777 *EndLoc = Loc; 778 return OO_Call; 779 780 case tok::l_square: 781 ConsumeToken(); // 'operator' 782 ConsumeBracket(); // '[' 783 Loc = Tok.getLocation(); 784 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 785 if (EndLoc) 786 *EndLoc = Loc; 787 return OO_Subscript; 788 789 default: 790 return OO_None; 791 } 792 793 ConsumeToken(); // 'operator' 794 Loc = ConsumeAnyToken(); // the operator itself 795 if (EndLoc) 796 *EndLoc = Loc; 797 return Op; 798} 799 800/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 801/// which expresses the name of a user-defined conversion operator 802/// (C++ [class.conv.fct]p1). Returns the type that this operator is 803/// specifying a conversion for, or NULL if there was an error. 804/// 805/// conversion-function-id: [C++ 12.3.2] 806/// operator conversion-type-id 807/// 808/// conversion-type-id: 809/// type-specifier-seq conversion-declarator[opt] 810/// 811/// conversion-declarator: 812/// ptr-operator conversion-declarator[opt] 813Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) { 814 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 815 ConsumeToken(); // 'operator' 816 817 // Parse the type-specifier-seq. 818 DeclSpec DS; 819 if (ParseCXXTypeSpecifierSeq(DS)) 820 return 0; 821 822 // Parse the conversion-declarator, which is merely a sequence of 823 // ptr-operators. 824 Declarator D(DS, Declarator::TypeNameContext); 825 ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 826 if (EndLoc) 827 *EndLoc = D.getSourceRange().getEnd(); 828 829 // Finish up the type. 830 Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 831 if (Result.isInvalid()) 832 return 0; 833 else 834 return Result.get(); 835} 836 837/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 838/// memory in a typesafe manner and call constructors. 839/// 840/// This method is called to parse the new expression after the optional :: has 841/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 842/// is its location. Otherwise, "Start" is the location of the 'new' token. 843/// 844/// new-expression: 845/// '::'[opt] 'new' new-placement[opt] new-type-id 846/// new-initializer[opt] 847/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 848/// new-initializer[opt] 849/// 850/// new-placement: 851/// '(' expression-list ')' 852/// 853/// new-type-id: 854/// type-specifier-seq new-declarator[opt] 855/// 856/// new-declarator: 857/// ptr-operator new-declarator[opt] 858/// direct-new-declarator 859/// 860/// new-initializer: 861/// '(' expression-list[opt] ')' 862/// [C++0x] braced-init-list [TODO] 863/// 864Parser::OwningExprResult 865Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 866 assert(Tok.is(tok::kw_new) && "expected 'new' token"); 867 ConsumeToken(); // Consume 'new' 868 869 // A '(' now can be a new-placement or the '(' wrapping the type-id in the 870 // second form of new-expression. It can't be a new-type-id. 871 872 ExprVector PlacementArgs(Actions); 873 SourceLocation PlacementLParen, PlacementRParen; 874 875 bool ParenTypeId; 876 DeclSpec DS; 877 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 878 if (Tok.is(tok::l_paren)) { 879 // If it turns out to be a placement, we change the type location. 880 PlacementLParen = ConsumeParen(); 881 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 882 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 883 return ExprError(); 884 } 885 886 PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 887 if (PlacementRParen.isInvalid()) { 888 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 889 return ExprError(); 890 } 891 892 if (PlacementArgs.empty()) { 893 // Reset the placement locations. There was no placement. 894 PlacementLParen = PlacementRParen = SourceLocation(); 895 ParenTypeId = true; 896 } else { 897 // We still need the type. 898 if (Tok.is(tok::l_paren)) { 899 SourceLocation LParen = ConsumeParen(); 900 ParseSpecifierQualifierList(DS); 901 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 902 ParseDeclarator(DeclaratorInfo); 903 MatchRHSPunctuation(tok::r_paren, LParen); 904 ParenTypeId = true; 905 } else { 906 if (ParseCXXTypeSpecifierSeq(DS)) 907 DeclaratorInfo.setInvalidType(true); 908 else { 909 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 910 ParseDeclaratorInternal(DeclaratorInfo, 911 &Parser::ParseDirectNewDeclarator); 912 } 913 ParenTypeId = false; 914 } 915 } 916 } else { 917 // A new-type-id is a simplified type-id, where essentially the 918 // direct-declarator is replaced by a direct-new-declarator. 919 if (ParseCXXTypeSpecifierSeq(DS)) 920 DeclaratorInfo.setInvalidType(true); 921 else { 922 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 923 ParseDeclaratorInternal(DeclaratorInfo, 924 &Parser::ParseDirectNewDeclarator); 925 } 926 ParenTypeId = false; 927 } 928 if (DeclaratorInfo.isInvalidType()) { 929 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 930 return ExprError(); 931 } 932 933 ExprVector ConstructorArgs(Actions); 934 SourceLocation ConstructorLParen, ConstructorRParen; 935 936 if (Tok.is(tok::l_paren)) { 937 ConstructorLParen = ConsumeParen(); 938 if (Tok.isNot(tok::r_paren)) { 939 CommaLocsTy CommaLocs; 940 if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 941 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 942 return ExprError(); 943 } 944 } 945 ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 946 if (ConstructorRParen.isInvalid()) { 947 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 948 return ExprError(); 949 } 950 } 951 952 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 953 move_arg(PlacementArgs), PlacementRParen, 954 ParenTypeId, DeclaratorInfo, ConstructorLParen, 955 move_arg(ConstructorArgs), ConstructorRParen); 956} 957 958/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 959/// passed to ParseDeclaratorInternal. 960/// 961/// direct-new-declarator: 962/// '[' expression ']' 963/// direct-new-declarator '[' constant-expression ']' 964/// 965void Parser::ParseDirectNewDeclarator(Declarator &D) { 966 // Parse the array dimensions. 967 bool first = true; 968 while (Tok.is(tok::l_square)) { 969 SourceLocation LLoc = ConsumeBracket(); 970 OwningExprResult Size(first ? ParseExpression() 971 : ParseConstantExpression()); 972 if (Size.isInvalid()) { 973 // Recover 974 SkipUntil(tok::r_square); 975 return; 976 } 977 first = false; 978 979 SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc); 980 D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 981 Size.release(), LLoc, RLoc), 982 RLoc); 983 984 if (RLoc.isInvalid()) 985 return; 986 } 987} 988 989/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 990/// This ambiguity appears in the syntax of the C++ new operator. 991/// 992/// new-expression: 993/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 994/// new-initializer[opt] 995/// 996/// new-placement: 997/// '(' expression-list ')' 998/// 999bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 1000 Declarator &D) { 1001 // The '(' was already consumed. 1002 if (isTypeIdInParens()) { 1003 ParseSpecifierQualifierList(D.getMutableDeclSpec()); 1004 D.SetSourceRange(D.getDeclSpec().getSourceRange()); 1005 ParseDeclarator(D); 1006 return D.isInvalidType(); 1007 } 1008 1009 // It's not a type, it has to be an expression list. 1010 // Discard the comma locations - ActOnCXXNew has enough parameters. 1011 CommaLocsTy CommaLocs; 1012 return ParseExpressionList(PlacementArgs, CommaLocs); 1013} 1014 1015/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 1016/// to free memory allocated by new. 1017/// 1018/// This method is called to parse the 'delete' expression after the optional 1019/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 1020/// and "Start" is its location. Otherwise, "Start" is the location of the 1021/// 'delete' token. 1022/// 1023/// delete-expression: 1024/// '::'[opt] 'delete' cast-expression 1025/// '::'[opt] 'delete' '[' ']' cast-expression 1026Parser::OwningExprResult 1027Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 1028 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 1029 ConsumeToken(); // Consume 'delete' 1030 1031 // Array delete? 1032 bool ArrayDelete = false; 1033 if (Tok.is(tok::l_square)) { 1034 ArrayDelete = true; 1035 SourceLocation LHS = ConsumeBracket(); 1036 SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 1037 if (RHS.isInvalid()) 1038 return ExprError(); 1039 } 1040 1041 OwningExprResult Operand(ParseCastExpression(false)); 1042 if (Operand.isInvalid()) 1043 return move(Operand); 1044 1045 return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand)); 1046} 1047 1048static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) 1049{ 1050 switch(kind) { 1051 default: assert(false && "Not a known unary type trait."); 1052 case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 1053 case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 1054 case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 1055 case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 1056 case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 1057 case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; 1058 case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 1059 case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 1060 case tok::kw___is_abstract: return UTT_IsAbstract; 1061 case tok::kw___is_class: return UTT_IsClass; 1062 case tok::kw___is_empty: return UTT_IsEmpty; 1063 case tok::kw___is_enum: return UTT_IsEnum; 1064 case tok::kw___is_pod: return UTT_IsPOD; 1065 case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 1066 case tok::kw___is_union: return UTT_IsUnion; 1067 } 1068} 1069 1070/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 1071/// pseudo-functions that allow implementation of the TR1/C++0x type traits 1072/// templates. 1073/// 1074/// primary-expression: 1075/// [GNU] unary-type-trait '(' type-id ')' 1076/// 1077Parser::OwningExprResult Parser::ParseUnaryTypeTrait() 1078{ 1079 UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 1080 SourceLocation Loc = ConsumeToken(); 1081 1082 SourceLocation LParen = Tok.getLocation(); 1083 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) 1084 return ExprError(); 1085 1086 // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 1087 // there will be cryptic errors about mismatched parentheses and missing 1088 // specifiers. 1089 TypeResult Ty = ParseTypeName(); 1090 1091 SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); 1092 1093 if (Ty.isInvalid()) 1094 return ExprError(); 1095 1096 return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen); 1097} 1098 1099/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 1100/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 1101/// based on the context past the parens. 1102Parser::OwningExprResult 1103Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 1104 TypeTy *&CastTy, 1105 SourceLocation LParenLoc, 1106 SourceLocation &RParenLoc) { 1107 assert(getLang().CPlusPlus && "Should only be called for C++!"); 1108 assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 1109 assert(isTypeIdInParens() && "Not a type-id!"); 1110 1111 OwningExprResult Result(Actions, true); 1112 CastTy = 0; 1113 1114 // We need to disambiguate a very ugly part of the C++ syntax: 1115 // 1116 // (T())x; - type-id 1117 // (T())*x; - type-id 1118 // (T())/x; - expression 1119 // (T()); - expression 1120 // 1121 // The bad news is that we cannot use the specialized tentative parser, since 1122 // it can only verify that the thing inside the parens can be parsed as 1123 // type-id, it is not useful for determining the context past the parens. 1124 // 1125 // The good news is that the parser can disambiguate this part without 1126 // making any unnecessary Action calls. 1127 // 1128 // It uses a scheme similar to parsing inline methods. The parenthesized 1129 // tokens are cached, the context that follows is determined (possibly by 1130 // parsing a cast-expression), and then we re-introduce the cached tokens 1131 // into the token stream and parse them appropriately. 1132 1133 ParenParseOption ParseAs; 1134 CachedTokens Toks; 1135 1136 // Store the tokens of the parentheses. We will parse them after we determine 1137 // the context that follows them. 1138 if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) { 1139 // We didn't find the ')' we expected. 1140 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1141 return ExprError(); 1142 } 1143 1144 if (Tok.is(tok::l_brace)) { 1145 ParseAs = CompoundLiteral; 1146 } else { 1147 bool NotCastExpr; 1148 // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 1149 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 1150 NotCastExpr = true; 1151 } else { 1152 // Try parsing the cast-expression that may follow. 1153 // If it is not a cast-expression, NotCastExpr will be true and no token 1154 // will be consumed. 1155 Result = ParseCastExpression(false/*isUnaryExpression*/, 1156 false/*isAddressofOperand*/, 1157 NotCastExpr); 1158 } 1159 1160 // If we parsed a cast-expression, it's really a type-id, otherwise it's 1161 // an expression. 1162 ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 1163 } 1164 1165 // The current token should go after the cached tokens. 1166 Toks.push_back(Tok); 1167 // Re-enter the stored parenthesized tokens into the token stream, so we may 1168 // parse them now. 1169 PP.EnterTokenStream(Toks.data(), Toks.size(), 1170 true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 1171 // Drop the current token and bring the first cached one. It's the same token 1172 // as when we entered this function. 1173 ConsumeAnyToken(); 1174 1175 if (ParseAs >= CompoundLiteral) { 1176 TypeResult Ty = ParseTypeName(); 1177 1178 // Match the ')'. 1179 if (Tok.is(tok::r_paren)) 1180 RParenLoc = ConsumeParen(); 1181 else 1182 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1183 1184 if (ParseAs == CompoundLiteral) { 1185 ExprType = CompoundLiteral; 1186 return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc); 1187 } 1188 1189 // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 1190 assert(ParseAs == CastExpr); 1191 1192 if (Ty.isInvalid()) 1193 return ExprError(); 1194 1195 CastTy = Ty.get(); 1196 1197 // Result is what ParseCastExpression returned earlier. 1198 if (!Result.isInvalid()) 1199 Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result)); 1200 return move(Result); 1201 } 1202 1203 // Not a compound literal, and not followed by a cast-expression. 1204 assert(ParseAs == SimpleExpr); 1205 1206 ExprType = SimpleExpr; 1207 Result = ParseExpression(); 1208 if (!Result.isInvalid() && Tok.is(tok::r_paren)) 1209 Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result)); 1210 1211 // Match the ')'. 1212 if (Result.isInvalid()) { 1213 SkipUntil(tok::r_paren); 1214 return ExprError(); 1215 } 1216 1217 if (Tok.is(tok::r_paren)) 1218 RParenLoc = ConsumeParen(); 1219 else 1220 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1221 1222 return move(Result); 1223} 1224