ParseExprCXX.cpp revision 7e7eb3da052a6d80ddf2377cab0384c798f73f75
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 assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 520 "Unexpected number of commas!"); 521 return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 522 LParenLoc, move_arg(Exprs), 523 CommaLocs.data(), RParenLoc); 524} 525 526/// ParseCXXCondition - if/switch/while/for condition expression. 527/// 528/// condition: 529/// expression 530/// type-specifier-seq declarator '=' assignment-expression 531/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 532/// '=' assignment-expression 533/// 534Parser::OwningExprResult Parser::ParseCXXCondition() { 535 if (!isCXXConditionDeclaration()) 536 return ParseExpression(); // expression 537 538 SourceLocation StartLoc = Tok.getLocation(); 539 540 // type-specifier-seq 541 DeclSpec DS; 542 ParseSpecifierQualifierList(DS); 543 544 // declarator 545 Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 546 ParseDeclarator(DeclaratorInfo); 547 548 // simple-asm-expr[opt] 549 if (Tok.is(tok::kw_asm)) { 550 SourceLocation Loc; 551 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); 552 if (AsmLabel.isInvalid()) { 553 SkipUntil(tok::semi); 554 return ExprError(); 555 } 556 DeclaratorInfo.setAsmLabel(AsmLabel.release()); 557 DeclaratorInfo.SetRangeEnd(Loc); 558 } 559 560 // If attributes are present, parse them. 561 if (Tok.is(tok::kw___attribute)) { 562 SourceLocation Loc; 563 AttributeList *AttrList = ParseAttributes(&Loc); 564 DeclaratorInfo.AddAttributes(AttrList, Loc); 565 } 566 567 // '=' assignment-expression 568 if (Tok.isNot(tok::equal)) 569 return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 570 SourceLocation EqualLoc = ConsumeToken(); 571 OwningExprResult AssignExpr(ParseAssignmentExpression()); 572 if (AssignExpr.isInvalid()) 573 return ExprError(); 574 575 return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 576 DeclaratorInfo,EqualLoc, 577 move(AssignExpr)); 578} 579 580/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 581/// This should only be called when the current token is known to be part of 582/// simple-type-specifier. 583/// 584/// simple-type-specifier: 585/// '::'[opt] nested-name-specifier[opt] type-name 586/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 587/// char 588/// wchar_t 589/// bool 590/// short 591/// int 592/// long 593/// signed 594/// unsigned 595/// float 596/// double 597/// void 598/// [GNU] typeof-specifier 599/// [C++0x] auto [TODO] 600/// 601/// type-name: 602/// class-name 603/// enum-name 604/// typedef-name 605/// 606void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 607 DS.SetRangeStart(Tok.getLocation()); 608 const char *PrevSpec; 609 SourceLocation Loc = Tok.getLocation(); 610 611 switch (Tok.getKind()) { 612 case tok::identifier: // foo::bar 613 case tok::coloncolon: // ::foo::bar 614 assert(0 && "Annotation token should already be formed!"); 615 default: 616 assert(0 && "Not a simple-type-specifier token!"); 617 abort(); 618 619 // type-name 620 case tok::annot_typename: { 621 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, 622 Tok.getAnnotationValue()); 623 break; 624 } 625 626 // builtin types 627 case tok::kw_short: 628 DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 629 break; 630 case tok::kw_long: 631 DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 632 break; 633 case tok::kw_signed: 634 DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 635 break; 636 case tok::kw_unsigned: 637 DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 638 break; 639 case tok::kw_void: 640 DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 641 break; 642 case tok::kw_char: 643 DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 644 break; 645 case tok::kw_int: 646 DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 647 break; 648 case tok::kw_float: 649 DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 650 break; 651 case tok::kw_double: 652 DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 653 break; 654 case tok::kw_wchar_t: 655 DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 656 break; 657 case tok::kw_bool: 658 DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 659 break; 660 661 // GNU typeof support. 662 case tok::kw_typeof: 663 ParseTypeofSpecifier(DS); 664 DS.Finish(Diags, PP); 665 return; 666 } 667 if (Tok.is(tok::annot_typename)) 668 DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 669 else 670 DS.SetRangeEnd(Tok.getLocation()); 671 ConsumeToken(); 672 DS.Finish(Diags, PP); 673} 674 675/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 676/// [dcl.name]), which is a non-empty sequence of type-specifiers, 677/// e.g., "const short int". Note that the DeclSpec is *not* finished 678/// by parsing the type-specifier-seq, because these sequences are 679/// typically followed by some form of declarator. Returns true and 680/// emits diagnostics if this is not a type-specifier-seq, false 681/// otherwise. 682/// 683/// type-specifier-seq: [C++ 8.1] 684/// type-specifier type-specifier-seq[opt] 685/// 686bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 687 DS.SetRangeStart(Tok.getLocation()); 688 const char *PrevSpec = 0; 689 int isInvalid = 0; 690 691 // Parse one or more of the type specifiers. 692 if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) { 693 Diag(Tok, diag::err_operator_missing_type_specifier); 694 return true; 695 } 696 697 while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ; 698 699 return false; 700} 701 702/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 703/// operator name (C++ [over.oper]). If successful, returns the 704/// predefined identifier that corresponds to that overloaded 705/// operator. Otherwise, returns NULL and does not consume any tokens. 706/// 707/// operator-function-id: [C++ 13.5] 708/// 'operator' operator 709/// 710/// operator: one of 711/// new delete new[] delete[] 712/// + - * / % ^ & | ~ 713/// ! = < > += -= *= /= %= 714/// ^= &= |= << >> >>= <<= == != 715/// <= >= && || ++ -- , ->* -> 716/// () [] 717OverloadedOperatorKind 718Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) { 719 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 720 SourceLocation Loc; 721 722 OverloadedOperatorKind Op = OO_None; 723 switch (NextToken().getKind()) { 724 case tok::kw_new: 725 ConsumeToken(); // 'operator' 726 Loc = ConsumeToken(); // 'new' 727 if (Tok.is(tok::l_square)) { 728 ConsumeBracket(); // '[' 729 Loc = Tok.getLocation(); 730 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 731 Op = OO_Array_New; 732 } else { 733 Op = OO_New; 734 } 735 if (EndLoc) 736 *EndLoc = Loc; 737 return Op; 738 739 case tok::kw_delete: 740 ConsumeToken(); // 'operator' 741 Loc = ConsumeToken(); // 'delete' 742 if (Tok.is(tok::l_square)) { 743 ConsumeBracket(); // '[' 744 Loc = Tok.getLocation(); 745 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 746 Op = OO_Array_Delete; 747 } else { 748 Op = OO_Delete; 749 } 750 if (EndLoc) 751 *EndLoc = Loc; 752 return Op; 753 754#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 755 case tok::Token: Op = OO_##Name; break; 756#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 757#include "clang/Basic/OperatorKinds.def" 758 759 case tok::l_paren: 760 ConsumeToken(); // 'operator' 761 ConsumeParen(); // '(' 762 Loc = Tok.getLocation(); 763 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 764 if (EndLoc) 765 *EndLoc = Loc; 766 return OO_Call; 767 768 case tok::l_square: 769 ConsumeToken(); // 'operator' 770 ConsumeBracket(); // '[' 771 Loc = Tok.getLocation(); 772 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 773 if (EndLoc) 774 *EndLoc = Loc; 775 return OO_Subscript; 776 777 default: 778 return OO_None; 779 } 780 781 ConsumeToken(); // 'operator' 782 Loc = ConsumeAnyToken(); // the operator itself 783 if (EndLoc) 784 *EndLoc = Loc; 785 return Op; 786} 787 788/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 789/// which expresses the name of a user-defined conversion operator 790/// (C++ [class.conv.fct]p1). Returns the type that this operator is 791/// specifying a conversion for, or NULL if there was an error. 792/// 793/// conversion-function-id: [C++ 12.3.2] 794/// operator conversion-type-id 795/// 796/// conversion-type-id: 797/// type-specifier-seq conversion-declarator[opt] 798/// 799/// conversion-declarator: 800/// ptr-operator conversion-declarator[opt] 801Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) { 802 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 803 ConsumeToken(); // 'operator' 804 805 // Parse the type-specifier-seq. 806 DeclSpec DS; 807 if (ParseCXXTypeSpecifierSeq(DS)) 808 return 0; 809 810 // Parse the conversion-declarator, which is merely a sequence of 811 // ptr-operators. 812 Declarator D(DS, Declarator::TypeNameContext); 813 ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 814 if (EndLoc) 815 *EndLoc = D.getSourceRange().getEnd(); 816 817 // Finish up the type. 818 Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 819 if (Result.isInvalid()) 820 return 0; 821 else 822 return Result.get(); 823} 824 825/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 826/// memory in a typesafe manner and call constructors. 827/// 828/// This method is called to parse the new expression after the optional :: has 829/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 830/// is its location. Otherwise, "Start" is the location of the 'new' token. 831/// 832/// new-expression: 833/// '::'[opt] 'new' new-placement[opt] new-type-id 834/// new-initializer[opt] 835/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 836/// new-initializer[opt] 837/// 838/// new-placement: 839/// '(' expression-list ')' 840/// 841/// new-type-id: 842/// type-specifier-seq new-declarator[opt] 843/// 844/// new-declarator: 845/// ptr-operator new-declarator[opt] 846/// direct-new-declarator 847/// 848/// new-initializer: 849/// '(' expression-list[opt] ')' 850/// [C++0x] braced-init-list [TODO] 851/// 852Parser::OwningExprResult 853Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 854 assert(Tok.is(tok::kw_new) && "expected 'new' token"); 855 ConsumeToken(); // Consume 'new' 856 857 // A '(' now can be a new-placement or the '(' wrapping the type-id in the 858 // second form of new-expression. It can't be a new-type-id. 859 860 ExprVector PlacementArgs(Actions); 861 SourceLocation PlacementLParen, PlacementRParen; 862 863 bool ParenTypeId; 864 DeclSpec DS; 865 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 866 if (Tok.is(tok::l_paren)) { 867 // If it turns out to be a placement, we change the type location. 868 PlacementLParen = ConsumeParen(); 869 if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 870 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 871 return ExprError(); 872 } 873 874 PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 875 if (PlacementRParen.isInvalid()) { 876 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 877 return ExprError(); 878 } 879 880 if (PlacementArgs.empty()) { 881 // Reset the placement locations. There was no placement. 882 PlacementLParen = PlacementRParen = SourceLocation(); 883 ParenTypeId = true; 884 } else { 885 // We still need the type. 886 if (Tok.is(tok::l_paren)) { 887 SourceLocation LParen = ConsumeParen(); 888 ParseSpecifierQualifierList(DS); 889 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 890 ParseDeclarator(DeclaratorInfo); 891 MatchRHSPunctuation(tok::r_paren, LParen); 892 ParenTypeId = true; 893 } else { 894 if (ParseCXXTypeSpecifierSeq(DS)) 895 DeclaratorInfo.setInvalidType(true); 896 else { 897 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 898 ParseDeclaratorInternal(DeclaratorInfo, 899 &Parser::ParseDirectNewDeclarator); 900 } 901 ParenTypeId = false; 902 } 903 } 904 } else { 905 // A new-type-id is a simplified type-id, where essentially the 906 // direct-declarator is replaced by a direct-new-declarator. 907 if (ParseCXXTypeSpecifierSeq(DS)) 908 DeclaratorInfo.setInvalidType(true); 909 else { 910 DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 911 ParseDeclaratorInternal(DeclaratorInfo, 912 &Parser::ParseDirectNewDeclarator); 913 } 914 ParenTypeId = false; 915 } 916 if (DeclaratorInfo.isInvalidType()) { 917 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 918 return ExprError(); 919 } 920 921 ExprVector ConstructorArgs(Actions); 922 SourceLocation ConstructorLParen, ConstructorRParen; 923 924 if (Tok.is(tok::l_paren)) { 925 ConstructorLParen = ConsumeParen(); 926 if (Tok.isNot(tok::r_paren)) { 927 CommaLocsTy CommaLocs; 928 if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 929 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 930 return ExprError(); 931 } 932 } 933 ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 934 if (ConstructorRParen.isInvalid()) { 935 SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 936 return ExprError(); 937 } 938 } 939 940 return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 941 move_arg(PlacementArgs), PlacementRParen, 942 ParenTypeId, DeclaratorInfo, ConstructorLParen, 943 move_arg(ConstructorArgs), ConstructorRParen); 944} 945 946/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 947/// passed to ParseDeclaratorInternal. 948/// 949/// direct-new-declarator: 950/// '[' expression ']' 951/// direct-new-declarator '[' constant-expression ']' 952/// 953void Parser::ParseDirectNewDeclarator(Declarator &D) { 954 // Parse the array dimensions. 955 bool first = true; 956 while (Tok.is(tok::l_square)) { 957 SourceLocation LLoc = ConsumeBracket(); 958 OwningExprResult Size(first ? ParseExpression() 959 : ParseConstantExpression()); 960 if (Size.isInvalid()) { 961 // Recover 962 SkipUntil(tok::r_square); 963 return; 964 } 965 first = false; 966 967 SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc); 968 D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 969 Size.release(), LLoc, RLoc), 970 RLoc); 971 972 if (RLoc.isInvalid()) 973 return; 974 } 975} 976 977/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 978/// This ambiguity appears in the syntax of the C++ new operator. 979/// 980/// new-expression: 981/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 982/// new-initializer[opt] 983/// 984/// new-placement: 985/// '(' expression-list ')' 986/// 987bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 988 Declarator &D) { 989 // The '(' was already consumed. 990 if (isTypeIdInParens()) { 991 ParseSpecifierQualifierList(D.getMutableDeclSpec()); 992 D.SetSourceRange(D.getDeclSpec().getSourceRange()); 993 ParseDeclarator(D); 994 return D.isInvalidType(); 995 } 996 997 // It's not a type, it has to be an expression list. 998 // Discard the comma locations - ActOnCXXNew has enough parameters. 999 CommaLocsTy CommaLocs; 1000 return ParseExpressionList(PlacementArgs, CommaLocs); 1001} 1002 1003/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 1004/// to free memory allocated by new. 1005/// 1006/// This method is called to parse the 'delete' expression after the optional 1007/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 1008/// and "Start" is its location. Otherwise, "Start" is the location of the 1009/// 'delete' token. 1010/// 1011/// delete-expression: 1012/// '::'[opt] 'delete' cast-expression 1013/// '::'[opt] 'delete' '[' ']' cast-expression 1014Parser::OwningExprResult 1015Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 1016 assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 1017 ConsumeToken(); // Consume 'delete' 1018 1019 // Array delete? 1020 bool ArrayDelete = false; 1021 if (Tok.is(tok::l_square)) { 1022 ArrayDelete = true; 1023 SourceLocation LHS = ConsumeBracket(); 1024 SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 1025 if (RHS.isInvalid()) 1026 return ExprError(); 1027 } 1028 1029 OwningExprResult Operand(ParseCastExpression(false)); 1030 if (Operand.isInvalid()) 1031 return move(Operand); 1032 1033 return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand)); 1034} 1035 1036static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) 1037{ 1038 switch(kind) { 1039 default: assert(false && "Not a known unary type trait."); 1040 case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 1041 case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 1042 case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 1043 case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 1044 case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 1045 case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; 1046 case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 1047 case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 1048 case tok::kw___is_abstract: return UTT_IsAbstract; 1049 case tok::kw___is_class: return UTT_IsClass; 1050 case tok::kw___is_empty: return UTT_IsEmpty; 1051 case tok::kw___is_enum: return UTT_IsEnum; 1052 case tok::kw___is_pod: return UTT_IsPOD; 1053 case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 1054 case tok::kw___is_union: return UTT_IsUnion; 1055 } 1056} 1057 1058/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 1059/// pseudo-functions that allow implementation of the TR1/C++0x type traits 1060/// templates. 1061/// 1062/// primary-expression: 1063/// [GNU] unary-type-trait '(' type-id ')' 1064/// 1065Parser::OwningExprResult Parser::ParseUnaryTypeTrait() 1066{ 1067 UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 1068 SourceLocation Loc = ConsumeToken(); 1069 1070 SourceLocation LParen = Tok.getLocation(); 1071 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) 1072 return ExprError(); 1073 1074 // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 1075 // there will be cryptic errors about mismatched parentheses and missing 1076 // specifiers. 1077 TypeResult Ty = ParseTypeName(); 1078 1079 SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); 1080 1081 if (Ty.isInvalid()) 1082 return ExprError(); 1083 1084 return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen); 1085} 1086 1087/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 1088/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 1089/// based on the context past the parens. 1090Parser::OwningExprResult 1091Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 1092 TypeTy *&CastTy, 1093 SourceLocation LParenLoc, 1094 SourceLocation &RParenLoc) { 1095 assert(getLang().CPlusPlus && "Should only be called for C++!"); 1096 assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 1097 assert(isTypeIdInParens() && "Not a type-id!"); 1098 1099 OwningExprResult Result(Actions, true); 1100 CastTy = 0; 1101 1102 // We need to disambiguate a very ugly part of the C++ syntax: 1103 // 1104 // (T())x; - type-id 1105 // (T())*x; - type-id 1106 // (T())/x; - expression 1107 // (T()); - expression 1108 // 1109 // The bad news is that we cannot use the specialized tentative parser, since 1110 // it can only verify that the thing inside the parens can be parsed as 1111 // type-id, it is not useful for determining the context past the parens. 1112 // 1113 // The good news is that the parser can disambiguate this part without 1114 // making any unnecessary Action calls. 1115 // 1116 // It uses a scheme similar to parsing inline methods. The parenthesized 1117 // tokens are cached, the context that follows is determined (possibly by 1118 // parsing a cast-expression), and then we re-introduce the cached tokens 1119 // into the token stream and parse them appropriately. 1120 1121 ParenParseOption ParseAs; 1122 CachedTokens Toks; 1123 1124 // Store the tokens of the parentheses. We will parse them after we determine 1125 // the context that follows them. 1126 if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) { 1127 // We didn't find the ')' we expected. 1128 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1129 return ExprError(); 1130 } 1131 1132 if (Tok.is(tok::l_brace)) { 1133 ParseAs = CompoundLiteral; 1134 } else { 1135 bool NotCastExpr; 1136 // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 1137 if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 1138 NotCastExpr = true; 1139 } else { 1140 // Try parsing the cast-expression that may follow. 1141 // If it is not a cast-expression, NotCastExpr will be true and no token 1142 // will be consumed. 1143 Result = ParseCastExpression(false/*isUnaryExpression*/, 1144 false/*isAddressofOperand*/, 1145 NotCastExpr); 1146 } 1147 1148 // If we parsed a cast-expression, it's really a type-id, otherwise it's 1149 // an expression. 1150 ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 1151 } 1152 1153 // The current token should go after the cached tokens. 1154 Toks.push_back(Tok); 1155 // Re-enter the stored parenthesized tokens into the token stream, so we may 1156 // parse them now. 1157 PP.EnterTokenStream(Toks.data(), Toks.size(), 1158 true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 1159 // Drop the current token and bring the first cached one. It's the same token 1160 // as when we entered this function. 1161 ConsumeAnyToken(); 1162 1163 if (ParseAs >= CompoundLiteral) { 1164 TypeResult Ty = ParseTypeName(); 1165 1166 // Match the ')'. 1167 if (Tok.is(tok::r_paren)) 1168 RParenLoc = ConsumeParen(); 1169 else 1170 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1171 1172 if (ParseAs == CompoundLiteral) { 1173 ExprType = CompoundLiteral; 1174 return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc); 1175 } 1176 1177 // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 1178 assert(ParseAs == CastExpr); 1179 1180 if (Ty.isInvalid()) 1181 return ExprError(); 1182 1183 CastTy = Ty.get(); 1184 1185 // Result is what ParseCastExpression returned earlier. 1186 if (!Result.isInvalid()) 1187 Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result)); 1188 return move(Result); 1189 } 1190 1191 // Not a compound literal, and not followed by a cast-expression. 1192 assert(ParseAs == SimpleExpr); 1193 1194 ExprType = SimpleExpr; 1195 Result = ParseExpression(); 1196 if (!Result.isInvalid() && Tok.is(tok::r_paren)) 1197 Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result)); 1198 1199 // Match the ')'. 1200 if (Result.isInvalid()) { 1201 SkipUntil(tok::r_paren); 1202 return ExprError(); 1203 } 1204 1205 if (Tok.is(tok::r_paren)) 1206 RParenLoc = ConsumeParen(); 1207 else 1208 MatchRHSPunctuation(tok::r_paren, LParenLoc); 1209 1210 return move(Result); 1211} 1212