ParseDeclCXX.cpp revision ef65f06e8e440aec541442cfd73a8a836e9bc842
1//===--- ParseDeclCXX.cpp - C++ Declaration 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 C++ Declaration portions of the Parser interfaces. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Parse/Parser.h" 15#include "clang/Parse/ParseDiagnostic.h" 16#include "clang/Parse/DeclSpec.h" 17#include "clang/Parse/Scope.h" 18#include "ExtensionRAIIObject.h" 19using namespace clang; 20 21/// ParseNamespace - We know that the current token is a namespace keyword. This 22/// may either be a top level namespace or a block-level namespace alias. 23/// 24/// namespace-definition: [C++ 7.3: basic.namespace] 25/// named-namespace-definition 26/// unnamed-namespace-definition 27/// 28/// unnamed-namespace-definition: 29/// 'namespace' attributes[opt] '{' namespace-body '}' 30/// 31/// named-namespace-definition: 32/// original-namespace-definition 33/// extension-namespace-definition 34/// 35/// original-namespace-definition: 36/// 'namespace' identifier attributes[opt] '{' namespace-body '}' 37/// 38/// extension-namespace-definition: 39/// 'namespace' original-namespace-name '{' namespace-body '}' 40/// 41/// namespace-alias-definition: [C++ 7.3.2: namespace.alias] 42/// 'namespace' identifier '=' qualified-namespace-specifier ';' 43/// 44Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, 45 SourceLocation &DeclEnd) { 46 assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); 47 SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. 48 49 SourceLocation IdentLoc; 50 IdentifierInfo *Ident = 0; 51 52 if (Tok.is(tok::identifier)) { 53 Ident = Tok.getIdentifierInfo(); 54 IdentLoc = ConsumeToken(); // eat the identifier. 55 } 56 57 // Read label attributes, if present. 58 Action::AttrTy *AttrList = 0; 59 if (Tok.is(tok::kw___attribute)) 60 // FIXME: save these somewhere. 61 AttrList = ParseAttributes(); 62 63 if (Tok.is(tok::equal)) 64 // FIXME: Verify no attributes were present. 65 return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); 66 67 if (Tok.isNot(tok::l_brace)) { 68 Diag(Tok, Ident ? diag::err_expected_lbrace : 69 diag::err_expected_ident_lbrace); 70 return DeclPtrTy(); 71 } 72 73 SourceLocation LBrace = ConsumeBrace(); 74 75 // Enter a scope for the namespace. 76 ParseScope NamespaceScope(this, Scope::DeclScope); 77 78 DeclPtrTy NamespcDecl = 79 Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace); 80 81 PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions, 82 PP.getSourceManager(), 83 "parsing namespace"); 84 85 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) 86 ParseExternalDeclaration(); 87 88 // Leave the namespace scope. 89 NamespaceScope.Exit(); 90 91 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace); 92 Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc); 93 94 DeclEnd = RBraceLoc; 95 return NamespcDecl; 96} 97 98/// ParseNamespaceAlias - Parse the part after the '=' in a namespace 99/// alias definition. 100/// 101Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, 102 SourceLocation AliasLoc, 103 IdentifierInfo *Alias, 104 SourceLocation &DeclEnd) { 105 assert(Tok.is(tok::equal) && "Not equal token"); 106 107 ConsumeToken(); // eat the '='. 108 109 CXXScopeSpec SS; 110 // Parse (optional) nested-name-specifier. 111 ParseOptionalCXXScopeSpecifier(SS); 112 113 if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 114 Diag(Tok, diag::err_expected_namespace_name); 115 // Skip to end of the definition and eat the ';'. 116 SkipUntil(tok::semi); 117 return DeclPtrTy(); 118 } 119 120 // Parse identifier. 121 IdentifierInfo *Ident = Tok.getIdentifierInfo(); 122 SourceLocation IdentLoc = ConsumeToken(); 123 124 // Eat the ';'. 125 DeclEnd = Tok.getLocation(); 126 ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 127 "namespace name", tok::semi); 128 129 return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias, 130 SS, IdentLoc, Ident); 131} 132 133/// ParseLinkage - We know that the current token is a string_literal 134/// and just before that, that extern was seen. 135/// 136/// linkage-specification: [C++ 7.5p2: dcl.link] 137/// 'extern' string-literal '{' declaration-seq[opt] '}' 138/// 'extern' string-literal declaration 139/// 140Parser::DeclPtrTy Parser::ParseLinkage(unsigned Context) { 141 assert(Tok.is(tok::string_literal) && "Not a string literal!"); 142 llvm::SmallVector<char, 8> LangBuffer; 143 // LangBuffer is guaranteed to be big enough. 144 LangBuffer.resize(Tok.getLength()); 145 const char *LangBufPtr = &LangBuffer[0]; 146 unsigned StrSize = PP.getSpelling(Tok, LangBufPtr); 147 148 SourceLocation Loc = ConsumeStringToken(); 149 150 ParseScope LinkageScope(this, Scope::DeclScope); 151 DeclPtrTy LinkageSpec 152 = Actions.ActOnStartLinkageSpecification(CurScope, 153 /*FIXME: */SourceLocation(), 154 Loc, LangBufPtr, StrSize, 155 Tok.is(tok::l_brace)? Tok.getLocation() 156 : SourceLocation()); 157 158 if (Tok.isNot(tok::l_brace)) { 159 ParseDeclarationOrFunctionDefinition(); 160 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, 161 SourceLocation()); 162 } 163 164 SourceLocation LBrace = ConsumeBrace(); 165 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 166 ParseExternalDeclaration(); 167 } 168 169 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 170 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace); 171} 172 173/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 174/// using-directive. Assumes that current token is 'using'. 175Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, 176 SourceLocation &DeclEnd) { 177 assert(Tok.is(tok::kw_using) && "Not using token"); 178 179 // Eat 'using'. 180 SourceLocation UsingLoc = ConsumeToken(); 181 182 if (Tok.is(tok::kw_namespace)) 183 // Next token after 'using' is 'namespace' so it must be using-directive 184 return ParseUsingDirective(Context, UsingLoc, DeclEnd); 185 186 // Otherwise, it must be using-declaration. 187 return ParseUsingDeclaration(Context, UsingLoc, DeclEnd); 188} 189 190/// ParseUsingDirective - Parse C++ using-directive, assumes 191/// that current token is 'namespace' and 'using' was already parsed. 192/// 193/// using-directive: [C++ 7.3.p4: namespace.udir] 194/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 195/// namespace-name ; 196/// [GNU] using-directive: 197/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 198/// namespace-name attributes[opt] ; 199/// 200Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context, 201 SourceLocation UsingLoc, 202 SourceLocation &DeclEnd) { 203 assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 204 205 // Eat 'namespace'. 206 SourceLocation NamespcLoc = ConsumeToken(); 207 208 CXXScopeSpec SS; 209 // Parse (optional) nested-name-specifier. 210 ParseOptionalCXXScopeSpecifier(SS); 211 212 AttributeList *AttrList = 0; 213 IdentifierInfo *NamespcName = 0; 214 SourceLocation IdentLoc = SourceLocation(); 215 216 // Parse namespace-name. 217 if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 218 Diag(Tok, diag::err_expected_namespace_name); 219 // If there was invalid namespace name, skip to end of decl, and eat ';'. 220 SkipUntil(tok::semi); 221 // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 222 return DeclPtrTy(); 223 } 224 225 // Parse identifier. 226 NamespcName = Tok.getIdentifierInfo(); 227 IdentLoc = ConsumeToken(); 228 229 // Parse (optional) attributes (most likely GNU strong-using extension). 230 if (Tok.is(tok::kw___attribute)) 231 AttrList = ParseAttributes(); 232 233 // Eat ';'. 234 DeclEnd = Tok.getLocation(); 235 ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 236 AttrList ? "attributes list" : "namespace name", tok::semi); 237 238 return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS, 239 IdentLoc, NamespcName, AttrList); 240} 241 242/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that 243/// 'using' was already seen. 244/// 245/// using-declaration: [C++ 7.3.p3: namespace.udecl] 246/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 247/// unqualified-id [TODO] 248/// 'using' :: unqualified-id [TODO] 249/// 250Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, 251 SourceLocation UsingLoc, 252 SourceLocation &DeclEnd) { 253 assert(false && "Not implemented"); 254 // FIXME: Implement parsing. 255 return DeclPtrTy(); 256} 257 258/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion. 259/// 260/// static_assert-declaration: 261/// static_assert ( constant-expression , string-literal ) ; 262/// 263Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ 264 assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration"); 265 SourceLocation StaticAssertLoc = ConsumeToken(); 266 267 if (Tok.isNot(tok::l_paren)) { 268 Diag(Tok, diag::err_expected_lparen); 269 return DeclPtrTy(); 270 } 271 272 SourceLocation LParenLoc = ConsumeParen(); 273 274 OwningExprResult AssertExpr(ParseConstantExpression()); 275 if (AssertExpr.isInvalid()) { 276 SkipUntil(tok::semi); 277 return DeclPtrTy(); 278 } 279 280 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) 281 return DeclPtrTy(); 282 283 if (Tok.isNot(tok::string_literal)) { 284 Diag(Tok, diag::err_expected_string_literal); 285 SkipUntil(tok::semi); 286 return DeclPtrTy(); 287 } 288 289 OwningExprResult AssertMessage(ParseStringLiteralExpression()); 290 if (AssertMessage.isInvalid()) 291 return DeclPtrTy(); 292 293 MatchRHSPunctuation(tok::r_paren, LParenLoc); 294 295 DeclEnd = Tok.getLocation(); 296 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert); 297 298 return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr), 299 move(AssertMessage)); 300} 301 302/// ParseClassName - Parse a C++ class-name, which names a class. Note 303/// that we only check that the result names a type; semantic analysis 304/// will need to verify that the type names a class. The result is 305/// either a type or NULL, depending on whether a type name was 306/// found. 307/// 308/// class-name: [C++ 9.1] 309/// identifier 310/// simple-template-id 311/// 312Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, 313 const CXXScopeSpec *SS) { 314 // Check whether we have a template-id that names a type. 315 if (Tok.is(tok::annot_template_id)) { 316 TemplateIdAnnotation *TemplateId 317 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 318 if (TemplateId->Kind == TNK_Type_template) { 319 AnnotateTemplateIdTokenAsType(SS); 320 321 assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 322 TypeTy *Type = Tok.getAnnotationValue(); 323 EndLocation = Tok.getAnnotationEndLoc(); 324 ConsumeToken(); 325 326 if (Type) 327 return Type; 328 return true; 329 } 330 331 // Fall through to produce an error below. 332 } 333 334 if (Tok.isNot(tok::identifier)) { 335 Diag(Tok, diag::err_expected_class_name); 336 return true; 337 } 338 339 // We have an identifier; check whether it is actually a type. 340 TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), 341 Tok.getLocation(), CurScope, SS); 342 if (!Type) { 343 Diag(Tok, diag::err_expected_class_name); 344 return true; 345 } 346 347 // Consume the identifier. 348 EndLocation = ConsumeToken(); 349 return Type; 350} 351 352/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 353/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 354/// until we reach the start of a definition or see a token that 355/// cannot start a definition. 356/// 357/// class-specifier: [C++ class] 358/// class-head '{' member-specification[opt] '}' 359/// class-head '{' member-specification[opt] '}' attributes[opt] 360/// class-head: 361/// class-key identifier[opt] base-clause[opt] 362/// class-key nested-name-specifier identifier base-clause[opt] 363/// class-key nested-name-specifier[opt] simple-template-id 364/// base-clause[opt] 365/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 366/// [GNU] class-key attributes[opt] nested-name-specifier 367/// identifier base-clause[opt] 368/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 369/// simple-template-id base-clause[opt] 370/// class-key: 371/// 'class' 372/// 'struct' 373/// 'union' 374/// 375/// elaborated-type-specifier: [C++ dcl.type.elab] 376/// class-key ::[opt] nested-name-specifier[opt] identifier 377/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 378/// simple-template-id 379/// 380/// Note that the C++ class-specifier and elaborated-type-specifier, 381/// together, subsume the C99 struct-or-union-specifier: 382/// 383/// struct-or-union-specifier: [C99 6.7.2.1] 384/// struct-or-union identifier[opt] '{' struct-contents '}' 385/// struct-or-union identifier 386/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 387/// '}' attributes[opt] 388/// [GNU] struct-or-union attributes[opt] identifier 389/// struct-or-union: 390/// 'struct' 391/// 'union' 392void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, 393 SourceLocation StartLoc, DeclSpec &DS, 394 const ParsedTemplateInfo &TemplateInfo, 395 AccessSpecifier AS) { 396 DeclSpec::TST TagType; 397 if (TagTokKind == tok::kw_struct) 398 TagType = DeclSpec::TST_struct; 399 else if (TagTokKind == tok::kw_class) 400 TagType = DeclSpec::TST_class; 401 else { 402 assert(TagTokKind == tok::kw_union && "Not a class specifier"); 403 TagType = DeclSpec::TST_union; 404 } 405 406 AttributeList *Attr = 0; 407 // If attributes exist after tag, parse them. 408 if (Tok.is(tok::kw___attribute)) 409 Attr = ParseAttributes(); 410 411 // If declspecs exist after tag, parse them. 412 if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) 413 FuzzyParseMicrosoftDeclSpec(); 414 415 // Parse the (optional) nested-name-specifier. 416 CXXScopeSpec SS; 417 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS)) 418 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 419 Diag(Tok, diag::err_expected_ident); 420 421 // Parse the (optional) class name or simple-template-id. 422 IdentifierInfo *Name = 0; 423 SourceLocation NameLoc; 424 TemplateIdAnnotation *TemplateId = 0; 425 if (Tok.is(tok::identifier)) { 426 Name = Tok.getIdentifierInfo(); 427 NameLoc = ConsumeToken(); 428 } else if (Tok.is(tok::annot_template_id)) { 429 TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 430 NameLoc = ConsumeToken(); 431 432 if (TemplateId->Kind != TNK_Type_template) { 433 // The template-name in the simple-template-id refers to 434 // something other than a class template. Give an appropriate 435 // error message and skip to the ';'. 436 SourceRange Range(NameLoc); 437 if (SS.isNotEmpty()) 438 Range.setBegin(SS.getBeginLoc()); 439 440 Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 441 << Name << static_cast<int>(TemplateId->Kind) << Range; 442 443 DS.SetTypeSpecError(); 444 SkipUntil(tok::semi, false, true); 445 TemplateId->Destroy(); 446 return; 447 } 448 } 449 450 // There are three options here. If we have 'struct foo;', then 451 // this is a forward declaration. If we have 'struct foo {...' or 452 // 'struct foo :...' then this is a definition. Otherwise we have 453 // something like 'struct foo xyz', a reference. 454 Action::TagKind TK; 455 if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) 456 TK = Action::TK_Definition; 457 else if (Tok.is(tok::semi) && !DS.isFriendSpecified()) 458 TK = Action::TK_Declaration; 459 else 460 TK = Action::TK_Reference; 461 462 if (!Name && !TemplateId && TK != Action::TK_Definition) { 463 // We have a declaration or reference to an anonymous class. 464 Diag(StartLoc, diag::err_anon_type_definition) 465 << DeclSpec::getSpecifierName(TagType); 466 467 // Skip the rest of this declarator, up until the comma or semicolon. 468 SkipUntil(tok::comma, true); 469 470 if (TemplateId) 471 TemplateId->Destroy(); 472 return; 473 } 474 475 // Create the tag portion of the class or class template. 476 Action::DeclResult TagOrTempResult; 477 TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 478 479 // FIXME: When TK == TK_Reference and we have a template-id, we need 480 // to turn that template-id into a type. 481 482 bool Owned = false; 483 if (TemplateId && TK != Action::TK_Reference) { 484 // Explicit specialization, class template partial specialization, 485 // or explicit instantiation. 486 ASTTemplateArgsPtr TemplateArgsPtr(Actions, 487 TemplateId->getTemplateArgs(), 488 TemplateId->getTemplateArgIsType(), 489 TemplateId->NumArgs); 490 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 491 TK == Action::TK_Declaration) { 492 // This is an explicit instantiation of a class template. 493 TagOrTempResult 494 = Actions.ActOnExplicitInstantiation(CurScope, 495 TemplateInfo.TemplateLoc, 496 TagType, 497 StartLoc, 498 SS, 499 TemplateTy::make(TemplateId->Template), 500 TemplateId->TemplateNameLoc, 501 TemplateId->LAngleLoc, 502 TemplateArgsPtr, 503 TemplateId->getTemplateArgLocations(), 504 TemplateId->RAngleLoc, 505 Attr); 506 } else { 507 // This is an explicit specialization or a class template 508 // partial specialization. 509 TemplateParameterLists FakedParamLists; 510 511 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 512 // This looks like an explicit instantiation, because we have 513 // something like 514 // 515 // template class Foo<X> 516 // 517 // but it actually has a definition. Most likely, this was 518 // meant to be an explicit specialization, but the user forgot 519 // the '<>' after 'template'. 520 assert(TK == Action::TK_Definition && "Expected a definition here"); 521 522 SourceLocation LAngleLoc 523 = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 524 Diag(TemplateId->TemplateNameLoc, 525 diag::err_explicit_instantiation_with_definition) 526 << SourceRange(TemplateInfo.TemplateLoc) 527 << CodeModificationHint::CreateInsertion(LAngleLoc, "<>"); 528 529 // Create a fake template parameter list that contains only 530 // "template<>", so that we treat this construct as a class 531 // template specialization. 532 FakedParamLists.push_back( 533 Actions.ActOnTemplateParameterList(0, SourceLocation(), 534 TemplateInfo.TemplateLoc, 535 LAngleLoc, 536 0, 0, 537 LAngleLoc)); 538 TemplateParams = &FakedParamLists; 539 } 540 541 // Build the class template specialization. 542 TagOrTempResult 543 = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK, 544 StartLoc, SS, 545 TemplateTy::make(TemplateId->Template), 546 TemplateId->TemplateNameLoc, 547 TemplateId->LAngleLoc, 548 TemplateArgsPtr, 549 TemplateId->getTemplateArgLocations(), 550 TemplateId->RAngleLoc, 551 Attr, 552 Action::MultiTemplateParamsArg(Actions, 553 TemplateParams? &(*TemplateParams)[0] : 0, 554 TemplateParams? TemplateParams->size() : 0)); 555 } 556 TemplateId->Destroy(); 557 } else if (TemplateParams && TK != Action::TK_Reference) { 558 // Class template declaration or definition. 559 TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK, 560 StartLoc, SS, Name, NameLoc, 561 Attr, 562 Action::MultiTemplateParamsArg(Actions, 563 &(*TemplateParams)[0], 564 TemplateParams->size()), 565 AS); 566 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 567 TK == Action::TK_Declaration) { 568 // Explicit instantiation of a member of a class template 569 // specialization, e.g., 570 // 571 // template struct Outer<int>::Inner; 572 // 573 TagOrTempResult 574 = Actions.ActOnExplicitInstantiation(CurScope, 575 TemplateInfo.TemplateLoc, 576 TagType, StartLoc, SS, Name, 577 NameLoc, Attr); 578 } else { 579 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 580 TK == Action::TK_Definition) { 581 // FIXME: Diagnose this particular error. 582 } 583 584 // Declaration or definition of a class type 585 TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, 586 Name, NameLoc, Attr, AS, Owned); 587 } 588 589 // Parse the optional base clause (C++ only). 590 if (getLang().CPlusPlus && Tok.is(tok::colon)) 591 ParseBaseClause(TagOrTempResult.get()); 592 593 // If there is a body, parse it and inform the actions module. 594 if (Tok.is(tok::l_brace)) 595 if (getLang().CPlusPlus) 596 ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get()); 597 else 598 ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); 599 else if (TK == Action::TK_Definition) { 600 // FIXME: Complain that we have a base-specifier list but no 601 // definition. 602 Diag(Tok, diag::err_expected_lbrace); 603 } 604 605 const char *PrevSpec = 0; 606 if (TagOrTempResult.isInvalid()) { 607 DS.SetTypeSpecError(); 608 return; 609 } 610 611 if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, 612 TagOrTempResult.get().getAs<void>(), Owned)) 613 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; 614 615 if (DS.isFriendSpecified()) 616 Actions.ActOnFriendDecl(CurScope, DS.getFriendSpecLoc(), 617 TagOrTempResult.get()); 618} 619 620/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 621/// 622/// base-clause : [C++ class.derived] 623/// ':' base-specifier-list 624/// base-specifier-list: 625/// base-specifier '...'[opt] 626/// base-specifier-list ',' base-specifier '...'[opt] 627void Parser::ParseBaseClause(DeclPtrTy ClassDecl) { 628 assert(Tok.is(tok::colon) && "Not a base clause"); 629 ConsumeToken(); 630 631 // Build up an array of parsed base specifiers. 632 llvm::SmallVector<BaseTy *, 8> BaseInfo; 633 634 while (true) { 635 // Parse a base-specifier. 636 BaseResult Result = ParseBaseSpecifier(ClassDecl); 637 if (Result.isInvalid()) { 638 // Skip the rest of this base specifier, up until the comma or 639 // opening brace. 640 SkipUntil(tok::comma, tok::l_brace, true, true); 641 } else { 642 // Add this to our array of base specifiers. 643 BaseInfo.push_back(Result.get()); 644 } 645 646 // If the next token is a comma, consume it and keep reading 647 // base-specifiers. 648 if (Tok.isNot(tok::comma)) break; 649 650 // Consume the comma. 651 ConsumeToken(); 652 } 653 654 // Attach the base specifiers 655 Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size()); 656} 657 658/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 659/// one entry in the base class list of a class specifier, for example: 660/// class foo : public bar, virtual private baz { 661/// 'public bar' and 'virtual private baz' are each base-specifiers. 662/// 663/// base-specifier: [C++ class.derived] 664/// ::[opt] nested-name-specifier[opt] class-name 665/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] 666/// class-name 667/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] 668/// class-name 669Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) { 670 bool IsVirtual = false; 671 SourceLocation StartLoc = Tok.getLocation(); 672 673 // Parse the 'virtual' keyword. 674 if (Tok.is(tok::kw_virtual)) { 675 ConsumeToken(); 676 IsVirtual = true; 677 } 678 679 // Parse an (optional) access specifier. 680 AccessSpecifier Access = getAccessSpecifierIfPresent(); 681 if (Access) 682 ConsumeToken(); 683 684 // Parse the 'virtual' keyword (again!), in case it came after the 685 // access specifier. 686 if (Tok.is(tok::kw_virtual)) { 687 SourceLocation VirtualLoc = ConsumeToken(); 688 if (IsVirtual) { 689 // Complain about duplicate 'virtual' 690 Diag(VirtualLoc, diag::err_dup_virtual) 691 << CodeModificationHint::CreateRemoval(SourceRange(VirtualLoc)); 692 } 693 694 IsVirtual = true; 695 } 696 697 // Parse optional '::' and optional nested-name-specifier. 698 CXXScopeSpec SS; 699 ParseOptionalCXXScopeSpecifier(SS); 700 701 // The location of the base class itself. 702 SourceLocation BaseLoc = Tok.getLocation(); 703 704 // Parse the class-name. 705 SourceLocation EndLocation; 706 TypeResult BaseType = ParseClassName(EndLocation, &SS); 707 if (BaseType.isInvalid()) 708 return true; 709 710 // Find the complete source range for the base-specifier. 711 SourceRange Range(StartLoc, EndLocation); 712 713 // Notify semantic analysis that we have parsed a complete 714 // base-specifier. 715 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, 716 BaseType.get(), BaseLoc); 717} 718 719/// getAccessSpecifierIfPresent - Determine whether the next token is 720/// a C++ access-specifier. 721/// 722/// access-specifier: [C++ class.derived] 723/// 'private' 724/// 'protected' 725/// 'public' 726AccessSpecifier Parser::getAccessSpecifierIfPresent() const 727{ 728 switch (Tok.getKind()) { 729 default: return AS_none; 730 case tok::kw_private: return AS_private; 731 case tok::kw_protected: return AS_protected; 732 case tok::kw_public: return AS_public; 733 } 734} 735 736/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 737/// 738/// member-declaration: 739/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 740/// function-definition ';'[opt] 741/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 742/// using-declaration [TODO] 743/// [C++0x] static_assert-declaration 744/// template-declaration 745/// [GNU] '__extension__' member-declaration 746/// 747/// member-declarator-list: 748/// member-declarator 749/// member-declarator-list ',' member-declarator 750/// 751/// member-declarator: 752/// declarator pure-specifier[opt] 753/// declarator constant-initializer[opt] 754/// identifier[opt] ':' constant-expression 755/// 756/// pure-specifier: 757/// '= 0' 758/// 759/// constant-initializer: 760/// '=' constant-expression 761/// 762void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { 763 // static_assert-declaration 764 if (Tok.is(tok::kw_static_assert)) { 765 SourceLocation DeclEnd; 766 ParseStaticAssertDeclaration(DeclEnd); 767 return; 768 } 769 770 if (Tok.is(tok::kw_template)) { 771 SourceLocation DeclEnd; 772 ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd, 773 AS); 774 return; 775 } 776 777 // Handle: member-declaration ::= '__extension__' member-declaration 778 if (Tok.is(tok::kw___extension__)) { 779 // __extension__ silences extension warnings in the subexpression. 780 ExtensionRAIIObject O(Diags); // Use RAII to do this. 781 ConsumeToken(); 782 return ParseCXXClassMemberDeclaration(AS); 783 } 784 785 SourceLocation DSStart = Tok.getLocation(); 786 // decl-specifier-seq: 787 // Parse the common declaration-specifiers piece. 788 DeclSpec DS; 789 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS); 790 791 if (Tok.is(tok::semi)) { 792 ConsumeToken(); 793 // C++ 9.2p7: The member-declarator-list can be omitted only after a 794 // class-specifier or an enum-specifier or in a friend declaration. 795 // FIXME: Friend declarations. 796 switch (DS.getTypeSpecType()) { 797 case DeclSpec::TST_struct: 798 case DeclSpec::TST_union: 799 case DeclSpec::TST_class: 800 case DeclSpec::TST_enum: 801 Actions.ParsedFreeStandingDeclSpec(CurScope, DS); 802 return; 803 default: 804 Diag(DSStart, diag::err_no_declarators); 805 return; 806 } 807 } 808 809 Declarator DeclaratorInfo(DS, Declarator::MemberContext); 810 811 if (Tok.isNot(tok::colon)) { 812 // Parse the first declarator. 813 ParseDeclarator(DeclaratorInfo); 814 // Error parsing the declarator? 815 if (!DeclaratorInfo.hasName()) { 816 // If so, skip until the semi-colon or a }. 817 SkipUntil(tok::r_brace, true); 818 if (Tok.is(tok::semi)) 819 ConsumeToken(); 820 return; 821 } 822 823 // function-definition: 824 if (Tok.is(tok::l_brace) 825 || (DeclaratorInfo.isFunctionDeclarator() && 826 (Tok.is(tok::colon) || Tok.is(tok::kw_try)))) { 827 if (!DeclaratorInfo.isFunctionDeclarator()) { 828 Diag(Tok, diag::err_func_def_no_params); 829 ConsumeBrace(); 830 SkipUntil(tok::r_brace, true); 831 return; 832 } 833 834 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 835 Diag(Tok, diag::err_function_declared_typedef); 836 // This recovery skips the entire function body. It would be nice 837 // to simply call ParseCXXInlineMethodDef() below, however Sema 838 // assumes the declarator represents a function, not a typedef. 839 ConsumeBrace(); 840 SkipUntil(tok::r_brace, true); 841 return; 842 } 843 844 ParseCXXInlineMethodDef(AS, DeclaratorInfo); 845 return; 846 } 847 } 848 849 // member-declarator-list: 850 // member-declarator 851 // member-declarator-list ',' member-declarator 852 853 llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup; 854 OwningExprResult BitfieldSize(Actions); 855 OwningExprResult Init(Actions); 856 bool Deleted = false; 857 858 while (1) { 859 860 // member-declarator: 861 // declarator pure-specifier[opt] 862 // declarator constant-initializer[opt] 863 // identifier[opt] ':' constant-expression 864 865 if (Tok.is(tok::colon)) { 866 ConsumeToken(); 867 BitfieldSize = ParseConstantExpression(); 868 if (BitfieldSize.isInvalid()) 869 SkipUntil(tok::comma, true, true); 870 } 871 872 // pure-specifier: 873 // '= 0' 874 // 875 // constant-initializer: 876 // '=' constant-expression 877 // 878 // defaulted/deleted function-definition: 879 // '=' 'default' [TODO] 880 // '=' 'delete' 881 882 if (Tok.is(tok::equal)) { 883 ConsumeToken(); 884 if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) { 885 ConsumeToken(); 886 Deleted = true; 887 } else { 888 Init = ParseInitializer(); 889 if (Init.isInvalid()) 890 SkipUntil(tok::comma, true, true); 891 } 892 } 893 894 // If attributes exist after the declarator, parse them. 895 if (Tok.is(tok::kw___attribute)) { 896 SourceLocation Loc; 897 AttributeList *AttrList = ParseAttributes(&Loc); 898 DeclaratorInfo.AddAttributes(AttrList, Loc); 899 } 900 901 // NOTE: If Sema is the Action module and declarator is an instance field, 902 // this call will *not* return the created decl; It will return null. 903 // See Sema::ActOnCXXMemberDeclarator for details. 904 DeclPtrTy ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS, 905 DeclaratorInfo, 906 BitfieldSize.release(), 907 Init.release(), 908 Deleted); 909 if (ThisDecl) 910 DeclsInGroup.push_back(ThisDecl); 911 912 if (DeclaratorInfo.isFunctionDeclarator() && 913 DeclaratorInfo.getDeclSpec().getStorageClassSpec() 914 != DeclSpec::SCS_typedef) { 915 // We just declared a member function. If this member function 916 // has any default arguments, we'll need to parse them later. 917 LateParsedMethodDeclaration *LateMethod = 0; 918 DeclaratorChunk::FunctionTypeInfo &FTI 919 = DeclaratorInfo.getTypeObject(0).Fun; 920 for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 921 if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 922 if (!LateMethod) { 923 // Push this method onto the stack of late-parsed method 924 // declarations. 925 getCurrentClass().MethodDecls.push_back( 926 LateParsedMethodDeclaration(ThisDecl)); 927 LateMethod = &getCurrentClass().MethodDecls.back(); 928 929 // Add all of the parameters prior to this one (they don't 930 // have default arguments). 931 LateMethod->DefaultArgs.reserve(FTI.NumArgs); 932 for (unsigned I = 0; I < ParamIdx; ++I) 933 LateMethod->DefaultArgs.push_back( 934 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param)); 935 } 936 937 // Add this parameter to the list of parameters (it or may 938 // not have a default argument). 939 LateMethod->DefaultArgs.push_back( 940 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 941 FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 942 } 943 } 944 } 945 946 // If we don't have a comma, it is either the end of the list (a ';') 947 // or an error, bail out. 948 if (Tok.isNot(tok::comma)) 949 break; 950 951 // Consume the comma. 952 ConsumeToken(); 953 954 // Parse the next declarator. 955 DeclaratorInfo.clear(); 956 BitfieldSize = 0; 957 Init = 0; 958 Deleted = false; 959 960 // Attributes are only allowed on the second declarator. 961 if (Tok.is(tok::kw___attribute)) { 962 SourceLocation Loc; 963 AttributeList *AttrList = ParseAttributes(&Loc); 964 DeclaratorInfo.AddAttributes(AttrList, Loc); 965 } 966 967 if (Tok.isNot(tok::colon)) 968 ParseDeclarator(DeclaratorInfo); 969 } 970 971 if (Tok.is(tok::semi)) { 972 ConsumeToken(); 973 Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(), 974 DeclsInGroup.size()); 975 return; 976 } 977 978 Diag(Tok, diag::err_expected_semi_decl_list); 979 // Skip to end of block or statement 980 SkipUntil(tok::r_brace, true, true); 981 if (Tok.is(tok::semi)) 982 ConsumeToken(); 983 return; 984} 985 986/// ParseCXXMemberSpecification - Parse the class definition. 987/// 988/// member-specification: 989/// member-declaration member-specification[opt] 990/// access-specifier ':' member-specification[opt] 991/// 992void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 993 unsigned TagType, DeclPtrTy TagDecl) { 994 assert((TagType == DeclSpec::TST_struct || 995 TagType == DeclSpec::TST_union || 996 TagType == DeclSpec::TST_class) && "Invalid TagType!"); 997 998 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions, 999 PP.getSourceManager(), 1000 "parsing struct/union/class body"); 1001 1002 SourceLocation LBraceLoc = ConsumeBrace(); 1003 1004 // Determine whether this is a top-level (non-nested) class. 1005 bool TopLevelClass = ClassStack.empty() || 1006 CurScope->isInCXXInlineMethodScope(); 1007 1008 // Enter a scope for the class. 1009 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 1010 1011 // Note that we are parsing a new (potentially-nested) class definition. 1012 ParsingClassDefinition ParsingDef(*this, TagDecl, TopLevelClass); 1013 1014 if (TagDecl) 1015 Actions.ActOnTagStartDefinition(CurScope, TagDecl); 1016 else { 1017 SkipUntil(tok::r_brace, false, false); 1018 return; 1019 } 1020 1021 // C++ 11p3: Members of a class defined with the keyword class are private 1022 // by default. Members of a class defined with the keywords struct or union 1023 // are public by default. 1024 AccessSpecifier CurAS; 1025 if (TagType == DeclSpec::TST_class) 1026 CurAS = AS_private; 1027 else 1028 CurAS = AS_public; 1029 1030 // While we still have something to read, read the member-declarations. 1031 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 1032 // Each iteration of this loop reads one member-declaration. 1033 1034 // Check for extraneous top-level semicolon. 1035 if (Tok.is(tok::semi)) { 1036 Diag(Tok, diag::ext_extra_struct_semi); 1037 ConsumeToken(); 1038 continue; 1039 } 1040 1041 AccessSpecifier AS = getAccessSpecifierIfPresent(); 1042 if (AS != AS_none) { 1043 // Current token is a C++ access specifier. 1044 CurAS = AS; 1045 ConsumeToken(); 1046 ExpectAndConsume(tok::colon, diag::err_expected_colon); 1047 continue; 1048 } 1049 1050 // Parse all the comma separated declarators. 1051 ParseCXXClassMemberDeclaration(CurAS); 1052 } 1053 1054 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 1055 1056 AttributeList *AttrList = 0; 1057 // If attributes exist after class contents, parse them. 1058 if (Tok.is(tok::kw___attribute)) 1059 AttrList = ParseAttributes(); // FIXME: where should I put them? 1060 1061 Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl, 1062 LBraceLoc, RBraceLoc); 1063 1064 // C++ 9.2p2: Within the class member-specification, the class is regarded as 1065 // complete within function bodies, default arguments, 1066 // exception-specifications, and constructor ctor-initializers (including 1067 // such things in nested classes). 1068 // 1069 // FIXME: Only function bodies and constructor ctor-initializers are 1070 // parsed correctly, fix the rest. 1071 if (TopLevelClass) { 1072 // We are not inside a nested class. This class and its nested classes 1073 // are complete and we can parse the delayed portions of method 1074 // declarations and the lexed inline method definitions. 1075 ParseLexedMethodDeclarations(getCurrentClass()); 1076 ParseLexedMethodDefs(getCurrentClass()); 1077 } 1078 1079 // Leave the class scope. 1080 ParsingDef.Pop(); 1081 ClassScope.Exit(); 1082 1083 Actions.ActOnTagFinishDefinition(CurScope, TagDecl); 1084} 1085 1086/// ParseConstructorInitializer - Parse a C++ constructor initializer, 1087/// which explicitly initializes the members or base classes of a 1088/// class (C++ [class.base.init]). For example, the three initializers 1089/// after the ':' in the Derived constructor below: 1090/// 1091/// @code 1092/// class Base { }; 1093/// class Derived : Base { 1094/// int x; 1095/// float f; 1096/// public: 1097/// Derived(float f) : Base(), x(17), f(f) { } 1098/// }; 1099/// @endcode 1100/// 1101/// [C++] ctor-initializer: 1102/// ':' mem-initializer-list 1103/// 1104/// [C++] mem-initializer-list: 1105/// mem-initializer 1106/// mem-initializer , mem-initializer-list 1107void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) { 1108 assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 1109 1110 SourceLocation ColonLoc = ConsumeToken(); 1111 1112 llvm::SmallVector<MemInitTy*, 4> MemInitializers; 1113 1114 do { 1115 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 1116 if (!MemInit.isInvalid()) 1117 MemInitializers.push_back(MemInit.get()); 1118 1119 if (Tok.is(tok::comma)) 1120 ConsumeToken(); 1121 else if (Tok.is(tok::l_brace)) 1122 break; 1123 else { 1124 // Skip over garbage, until we get to '{'. Don't eat the '{'. 1125 Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma); 1126 SkipUntil(tok::l_brace, true, true); 1127 break; 1128 } 1129 } while (true); 1130 1131 Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, 1132 MemInitializers.data(), MemInitializers.size()); 1133} 1134 1135/// ParseMemInitializer - Parse a C++ member initializer, which is 1136/// part of a constructor initializer that explicitly initializes one 1137/// member or base class (C++ [class.base.init]). See 1138/// ParseConstructorInitializer for an example. 1139/// 1140/// [C++] mem-initializer: 1141/// mem-initializer-id '(' expression-list[opt] ')' 1142/// 1143/// [C++] mem-initializer-id: 1144/// '::'[opt] nested-name-specifier[opt] class-name 1145/// identifier 1146Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) { 1147 // FIXME: parse '::'[opt] nested-name-specifier[opt] 1148 1149 if (Tok.isNot(tok::identifier)) { 1150 Diag(Tok, diag::err_expected_member_or_base_name); 1151 return true; 1152 } 1153 1154 // Get the identifier. This may be a member name or a class name, 1155 // but we'll let the semantic analysis determine which it is. 1156 IdentifierInfo *II = Tok.getIdentifierInfo(); 1157 SourceLocation IdLoc = ConsumeToken(); 1158 1159 // Parse the '('. 1160 if (Tok.isNot(tok::l_paren)) { 1161 Diag(Tok, diag::err_expected_lparen); 1162 return true; 1163 } 1164 SourceLocation LParenLoc = ConsumeParen(); 1165 1166 // Parse the optional expression-list. 1167 ExprVector ArgExprs(Actions); 1168 CommaLocsTy CommaLocs; 1169 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 1170 SkipUntil(tok::r_paren); 1171 return true; 1172 } 1173 1174 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1175 1176 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc, 1177 LParenLoc, ArgExprs.take(), 1178 ArgExprs.size(), CommaLocs.data(), 1179 RParenLoc); 1180} 1181 1182/// ParseExceptionSpecification - Parse a C++ exception-specification 1183/// (C++ [except.spec]). 1184/// 1185/// exception-specification: 1186/// 'throw' '(' type-id-list [opt] ')' 1187/// [MS] 'throw' '(' '...' ')' 1188/// 1189/// type-id-list: 1190/// type-id 1191/// type-id-list ',' type-id 1192/// 1193bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc, 1194 llvm::SmallVector<TypeTy*, 2> 1195 &Exceptions, 1196 llvm::SmallVector<SourceRange, 2> 1197 &Ranges, 1198 bool &hasAnyExceptionSpec) { 1199 assert(Tok.is(tok::kw_throw) && "expected throw"); 1200 1201 SourceLocation ThrowLoc = ConsumeToken(); 1202 1203 if (!Tok.is(tok::l_paren)) { 1204 return Diag(Tok, diag::err_expected_lparen_after) << "throw"; 1205 } 1206 SourceLocation LParenLoc = ConsumeParen(); 1207 1208 // Parse throw(...), a Microsoft extension that means "this function 1209 // can throw anything". 1210 if (Tok.is(tok::ellipsis)) { 1211 hasAnyExceptionSpec = true; 1212 SourceLocation EllipsisLoc = ConsumeToken(); 1213 if (!getLang().Microsoft) 1214 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 1215 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1216 return false; 1217 } 1218 1219 // Parse the sequence of type-ids. 1220 SourceRange Range; 1221 while (Tok.isNot(tok::r_paren)) { 1222 TypeResult Res(ParseTypeName(&Range)); 1223 if (!Res.isInvalid()) { 1224 Exceptions.push_back(Res.get()); 1225 Ranges.push_back(Range); 1226 } 1227 if (Tok.is(tok::comma)) 1228 ConsumeToken(); 1229 else 1230 break; 1231 } 1232 1233 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1234 return false; 1235} 1236 1237/// \brief We have just started parsing the definition of a new class, 1238/// so push that class onto our stack of classes that is currently 1239/// being parsed. 1240void Parser::PushParsingClass(DeclPtrTy ClassDecl, bool TopLevelClass) { 1241 assert((TopLevelClass || !ClassStack.empty()) && 1242 "Nested class without outer class"); 1243 ClassStack.push(new ParsingClass(ClassDecl, TopLevelClass)); 1244} 1245 1246/// \brief Deallocate the given parsed class and all of its nested 1247/// classes. 1248void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) { 1249 for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I) 1250 DeallocateParsedClasses(Class->NestedClasses[I]); 1251 delete Class; 1252} 1253 1254/// \brief Pop the top class of the stack of classes that are 1255/// currently being parsed. 1256/// 1257/// This routine should be called when we have finished parsing the 1258/// definition of a class, but have not yet popped the Scope 1259/// associated with the class's definition. 1260/// 1261/// \returns true if the class we've popped is a top-level class, 1262/// false otherwise. 1263void Parser::PopParsingClass() { 1264 assert(!ClassStack.empty() && "Mismatched push/pop for class parsing"); 1265 1266 ParsingClass *Victim = ClassStack.top(); 1267 ClassStack.pop(); 1268 if (Victim->TopLevelClass) { 1269 // Deallocate all of the nested classes of this class, 1270 // recursively: we don't need to keep any of this information. 1271 DeallocateParsedClasses(Victim); 1272 return; 1273 } 1274 assert(!ClassStack.empty() && "Missing top-level class?"); 1275 1276 if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() && 1277 Victim->NestedClasses.empty()) { 1278 // The victim is a nested class, but we will not need to perform 1279 // any processing after the definition of this class since it has 1280 // no members whose handling was delayed. Therefore, we can just 1281 // remove this nested class. 1282 delete Victim; 1283 return; 1284 } 1285 1286 // This nested class has some members that will need to be processed 1287 // after the top-level class is completely defined. Therefore, add 1288 // it to the list of nested classes within its parent. 1289 assert(CurScope->isClassScope() && "Nested class outside of class scope?"); 1290 ClassStack.top()->NestedClasses.push_back(Victim); 1291 Victim->TemplateScope = CurScope->getParent()->isTemplateParamScope(); 1292} 1293