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