DeclBase.cpp revision 5c0646b98b203d105c10ad8cc11be11cc99a4218
1//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===// 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 Decl and DeclContext classes. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/DeclBase.h" 15#include "clang/AST/Decl.h" 16#include "clang/AST/DeclContextInternals.h" 17#include "clang/AST/DeclCXX.h" 18#include "clang/AST/DeclFriend.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/DeclTemplate.h" 21#include "clang/AST/DependentDiagnostic.h" 22#include "clang/AST/ExternalASTSource.h" 23#include "clang/AST/ASTContext.h" 24#include "clang/AST/Type.h" 25#include "clang/AST/Stmt.h" 26#include "clang/AST/StmtCXX.h" 27#include "llvm/ADT/DenseMap.h" 28#include "llvm/Support/raw_ostream.h" 29#include <algorithm> 30#include <cstdio> 31#include <vector> 32using namespace clang; 33 34//===----------------------------------------------------------------------===// 35// Statistics 36//===----------------------------------------------------------------------===// 37 38#define DECL(DERIVED, BASE) static int n##DERIVED##s = 0; 39#define ABSTRACT_DECL(DECL) 40#include "clang/AST/DeclNodes.inc" 41 42static bool StatSwitch = false; 43 44const char *Decl::getDeclKindName() const { 45 switch (DeclKind) { 46 default: assert(0 && "Declaration not in DeclNodes.inc!"); 47#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED; 48#define ABSTRACT_DECL(DECL) 49#include "clang/AST/DeclNodes.inc" 50 } 51} 52 53void Decl::setInvalidDecl(bool Invalid) { 54 InvalidDecl = Invalid; 55 if (Invalid) { 56 // Defensive maneuver for ill-formed code: we're likely not to make it to 57 // a point where we set the access specifier, so default it to "public" 58 // to avoid triggering asserts elsewhere in the front end. 59 setAccess(AS_public); 60 } 61} 62 63const char *DeclContext::getDeclKindName() const { 64 switch (DeclKind) { 65 default: assert(0 && "Declaration context not in DeclNodes.inc!"); 66#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; 67#define ABSTRACT_DECL(DECL) 68#include "clang/AST/DeclNodes.inc" 69 } 70} 71 72bool Decl::CollectingStats(bool Enable) { 73 if (Enable) StatSwitch = true; 74 return StatSwitch; 75} 76 77void Decl::PrintStats() { 78 fprintf(stderr, "*** Decl Stats:\n"); 79 80 int totalDecls = 0; 81#define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s; 82#define ABSTRACT_DECL(DECL) 83#include "clang/AST/DeclNodes.inc" 84 fprintf(stderr, " %d decls total.\n", totalDecls); 85 86 int totalBytes = 0; 87#define DECL(DERIVED, BASE) \ 88 if (n##DERIVED##s > 0) { \ 89 totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \ 90 fprintf(stderr, " %d " #DERIVED " decls, %d each (%d bytes)\n", \ 91 n##DERIVED##s, (int)sizeof(DERIVED##Decl), \ 92 (int)(n##DERIVED##s * sizeof(DERIVED##Decl))); \ 93 } 94#define ABSTRACT_DECL(DECL) 95#include "clang/AST/DeclNodes.inc" 96 97 fprintf(stderr, "Total bytes = %d\n", totalBytes); 98} 99 100void Decl::add(Kind k) { 101 switch (k) { 102 default: assert(0 && "Declaration not in DeclNodes.inc!"); 103#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break; 104#define ABSTRACT_DECL(DECL) 105#include "clang/AST/DeclNodes.inc" 106 } 107} 108 109bool Decl::isTemplateParameterPack() const { 110 if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this)) 111 return TTP->isParameterPack(); 112 113 return false; 114} 115 116bool Decl::isFunctionOrFunctionTemplate() const { 117 if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this)) 118 return UD->getTargetDecl()->isFunctionOrFunctionTemplate(); 119 120 return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this); 121} 122 123bool Decl::isDefinedOutsideFunctionOrMethod() const { 124 for (const DeclContext *DC = getDeclContext(); 125 DC && !DC->isTranslationUnit(); 126 DC = DC->getParent()) 127 if (DC->isFunctionOrMethod()) 128 return false; 129 130 return true; 131} 132 133 134//===----------------------------------------------------------------------===// 135// PrettyStackTraceDecl Implementation 136//===----------------------------------------------------------------------===// 137 138void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const { 139 SourceLocation TheLoc = Loc; 140 if (TheLoc.isInvalid() && TheDecl) 141 TheLoc = TheDecl->getLocation(); 142 143 if (TheLoc.isValid()) { 144 TheLoc.print(OS, SM); 145 OS << ": "; 146 } 147 148 OS << Message; 149 150 if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) 151 OS << " '" << DN->getQualifiedNameAsString() << '\''; 152 OS << '\n'; 153} 154 155//===----------------------------------------------------------------------===// 156// Decl Implementation 157//===----------------------------------------------------------------------===// 158 159// Out-of-line virtual method providing a home for Decl. 160Decl::~Decl() { } 161 162void Decl::setDeclContext(DeclContext *DC) { 163 if (isOutOfSemaDC()) 164 delete getMultipleDC(); 165 166 DeclCtx = DC; 167} 168 169void Decl::setLexicalDeclContext(DeclContext *DC) { 170 if (DC == getLexicalDeclContext()) 171 return; 172 173 if (isInSemaDC()) { 174 MultipleDC *MDC = new (getASTContext()) MultipleDC(); 175 MDC->SemanticDC = getDeclContext(); 176 MDC->LexicalDC = DC; 177 DeclCtx = MDC; 178 } else { 179 getMultipleDC()->LexicalDC = DC; 180 } 181} 182 183bool Decl::isInAnonymousNamespace() const { 184 const DeclContext *DC = getDeclContext(); 185 do { 186 if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) 187 if (ND->isAnonymousNamespace()) 188 return true; 189 } while ((DC = DC->getParent())); 190 191 return false; 192} 193 194TranslationUnitDecl *Decl::getTranslationUnitDecl() { 195 if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this)) 196 return TUD; 197 198 DeclContext *DC = getDeclContext(); 199 assert(DC && "This decl is not contained in a translation unit!"); 200 201 while (!DC->isTranslationUnit()) { 202 DC = DC->getParent(); 203 assert(DC && "This decl is not contained in a translation unit!"); 204 } 205 206 return cast<TranslationUnitDecl>(DC); 207} 208 209ASTContext &Decl::getASTContext() const { 210 return getTranslationUnitDecl()->getASTContext(); 211} 212 213bool Decl::isUsed(bool CheckUsedAttr) const { 214 if (Used) 215 return true; 216 217 // Check for used attribute. 218 if (CheckUsedAttr && hasAttr<UsedAttr>()) 219 return true; 220 221 // Check redeclarations for used attribute. 222 for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { 223 if ((CheckUsedAttr && I->hasAttr<UsedAttr>()) || I->Used) 224 return true; 225 } 226 227 return false; 228} 229 230 231unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { 232 switch (DeclKind) { 233 case Function: 234 case CXXMethod: 235 case CXXConstructor: 236 case CXXDestructor: 237 case CXXConversion: 238 case EnumConstant: 239 case Var: 240 case ImplicitParam: 241 case ParmVar: 242 case NonTypeTemplateParm: 243 case ObjCMethod: 244 case ObjCProperty: 245 return IDNS_Ordinary; 246 247 case ObjCCompatibleAlias: 248 case ObjCInterface: 249 return IDNS_Ordinary | IDNS_Type; 250 251 case Typedef: 252 case UnresolvedUsingTypename: 253 case TemplateTypeParm: 254 return IDNS_Ordinary | IDNS_Type; 255 256 case UsingShadow: 257 return 0; // we'll actually overwrite this later 258 259 case UnresolvedUsingValue: 260 return IDNS_Ordinary | IDNS_Using; 261 262 case Using: 263 return IDNS_Using; 264 265 case ObjCProtocol: 266 return IDNS_ObjCProtocol; 267 268 case Field: 269 case ObjCAtDefsField: 270 case ObjCIvar: 271 return IDNS_Member; 272 273 case Record: 274 case CXXRecord: 275 case Enum: 276 return IDNS_Tag | IDNS_Type; 277 278 case Namespace: 279 case NamespaceAlias: 280 return IDNS_Namespace; 281 282 case FunctionTemplate: 283 return IDNS_Ordinary; 284 285 case ClassTemplate: 286 case TemplateTemplateParm: 287 return IDNS_Ordinary | IDNS_Tag | IDNS_Type; 288 289 // Never have names. 290 case Friend: 291 case FriendTemplate: 292 case AccessSpec: 293 case LinkageSpec: 294 case FileScopeAsm: 295 case StaticAssert: 296 case ObjCClass: 297 case ObjCPropertyImpl: 298 case ObjCForwardProtocol: 299 case Block: 300 case TranslationUnit: 301 302 case UsingDirective: 303 case ClassTemplateSpecialization: 304 case ClassTemplatePartialSpecialization: 305 case ObjCImplementation: 306 case ObjCCategory: 307 case ObjCCategoryImpl: 308 // Never looked up by name. 309 return 0; 310 } 311 312 return 0; 313} 314 315void Decl::setAttrs(const AttrVec &attrs) { 316 assert(!HasAttrs && "Decl already contains attrs."); 317 318 AttrVec &AttrBlank = getASTContext().getDeclAttrs(this); 319 assert(AttrBlank.empty() && "HasAttrs was wrong?"); 320 321 AttrBlank = attrs; 322 HasAttrs = true; 323} 324 325void Decl::dropAttrs() { 326 if (!HasAttrs) return; 327 328 HasAttrs = false; 329 getASTContext().eraseDeclAttrs(this); 330} 331 332const AttrVec &Decl::getAttrs() const { 333 assert(HasAttrs && "No attrs to get!"); 334 return getASTContext().getDeclAttrs(this); 335} 336 337void Decl::swapAttrs(Decl *RHS) { 338 bool HasLHSAttr = this->HasAttrs; 339 bool HasRHSAttr = RHS->HasAttrs; 340 341 // Usually, neither decl has attrs, nothing to do. 342 if (!HasLHSAttr && !HasRHSAttr) return; 343 344 // If 'this' has no attrs, swap the other way. 345 if (!HasLHSAttr) 346 return RHS->swapAttrs(this); 347 348 ASTContext &Context = getASTContext(); 349 350 // Handle the case when both decls have attrs. 351 if (HasRHSAttr) { 352 std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS)); 353 return; 354 } 355 356 // Otherwise, LHS has an attr and RHS doesn't. 357 Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this); 358 Context.eraseDeclAttrs(this); 359 this->HasAttrs = false; 360 RHS->HasAttrs = true; 361} 362 363Decl *Decl::castFromDeclContext (const DeclContext *D) { 364 Decl::Kind DK = D->getDeclKind(); 365 switch(DK) { 366#define DECL(NAME, BASE) 367#define DECL_CONTEXT(NAME) \ 368 case Decl::NAME: \ 369 return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D)); 370#define DECL_CONTEXT_BASE(NAME) 371#include "clang/AST/DeclNodes.inc" 372 default: 373#define DECL(NAME, BASE) 374#define DECL_CONTEXT_BASE(NAME) \ 375 if (DK >= first##NAME && DK <= last##NAME) \ 376 return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D)); 377#include "clang/AST/DeclNodes.inc" 378 assert(false && "a decl that inherits DeclContext isn't handled"); 379 return 0; 380 } 381} 382 383DeclContext *Decl::castToDeclContext(const Decl *D) { 384 Decl::Kind DK = D->getKind(); 385 switch(DK) { 386#define DECL(NAME, BASE) 387#define DECL_CONTEXT(NAME) \ 388 case Decl::NAME: \ 389 return static_cast<NAME##Decl*>(const_cast<Decl*>(D)); 390#define DECL_CONTEXT_BASE(NAME) 391#include "clang/AST/DeclNodes.inc" 392 default: 393#define DECL(NAME, BASE) 394#define DECL_CONTEXT_BASE(NAME) \ 395 if (DK >= first##NAME && DK <= last##NAME) \ 396 return static_cast<NAME##Decl*>(const_cast<Decl*>(D)); 397#include "clang/AST/DeclNodes.inc" 398 assert(false && "a decl that inherits DeclContext isn't handled"); 399 return 0; 400 } 401} 402 403SourceLocation Decl::getBodyRBrace() const { 404 // Special handling of FunctionDecl to avoid de-serializing the body from PCH. 405 // FunctionDecl stores EndRangeLoc for this purpose. 406 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) { 407 const FunctionDecl *Definition; 408 if (FD->hasBody(Definition)) 409 return Definition->getSourceRange().getEnd(); 410 return SourceLocation(); 411 } 412 413 if (Stmt *Body = getBody()) 414 return Body->getSourceRange().getEnd(); 415 416 return SourceLocation(); 417} 418 419#ifndef NDEBUG 420void Decl::CheckAccessDeclContext() const { 421 // Suppress this check if any of the following hold: 422 // 1. this is the translation unit (and thus has no parent) 423 // 2. this is a template parameter (and thus doesn't belong to its context) 424 // 3. this is a non-type template parameter 425 // 4. the context is not a record 426 // 5. it's invalid 427 // 6. it's a C++0x static_assert. 428 if (isa<TranslationUnitDecl>(this) || 429 isa<TemplateTypeParmDecl>(this) || 430 isa<NonTypeTemplateParmDecl>(this) || 431 !isa<CXXRecordDecl>(getDeclContext()) || 432 isInvalidDecl() || 433 isa<StaticAssertDecl>(this) || 434 // FIXME: a ParmVarDecl can have ClassTemplateSpecialization 435 // as DeclContext (?). 436 isa<ParmVarDecl>(this) || 437 // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have 438 // AS_none as access specifier. 439 isa<CXXRecordDecl>(this)) 440 return; 441 442 assert(Access != AS_none && 443 "Access specifier is AS_none inside a record decl"); 444} 445 446#endif 447 448//===----------------------------------------------------------------------===// 449// DeclContext Implementation 450//===----------------------------------------------------------------------===// 451 452bool DeclContext::classof(const Decl *D) { 453 switch (D->getKind()) { 454#define DECL(NAME, BASE) 455#define DECL_CONTEXT(NAME) case Decl::NAME: 456#define DECL_CONTEXT_BASE(NAME) 457#include "clang/AST/DeclNodes.inc" 458 return true; 459 default: 460#define DECL(NAME, BASE) 461#define DECL_CONTEXT_BASE(NAME) \ 462 if (D->getKind() >= Decl::first##NAME && \ 463 D->getKind() <= Decl::last##NAME) \ 464 return true; 465#include "clang/AST/DeclNodes.inc" 466 return false; 467 } 468} 469 470DeclContext::~DeclContext() { } 471 472/// \brief Find the parent context of this context that will be 473/// used for unqualified name lookup. 474/// 475/// Generally, the parent lookup context is the semantic context. However, for 476/// a friend function the parent lookup context is the lexical context, which 477/// is the class in which the friend is declared. 478DeclContext *DeclContext::getLookupParent() { 479 // FIXME: Find a better way to identify friends 480 if (isa<FunctionDecl>(this)) 481 if (getParent()->getRedeclContext()->isFileContext() && 482 getLexicalParent()->getRedeclContext()->isRecord()) 483 return getLexicalParent(); 484 485 return getParent(); 486} 487 488bool DeclContext::isInlineNamespace() const { 489 return isNamespace() && 490 cast<NamespaceDecl>(this)->isInline(); 491} 492 493bool DeclContext::isDependentContext() const { 494 if (isFileContext()) 495 return false; 496 497 if (isa<ClassTemplatePartialSpecializationDecl>(this)) 498 return true; 499 500 if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) 501 if (Record->getDescribedClassTemplate()) 502 return true; 503 504 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) { 505 if (Function->getDescribedFunctionTemplate()) 506 return true; 507 508 // Friend function declarations are dependent if their *lexical* 509 // context is dependent. 510 if (cast<Decl>(this)->getFriendObjectKind()) 511 return getLexicalParent()->isDependentContext(); 512 } 513 514 return getParent() && getParent()->isDependentContext(); 515} 516 517bool DeclContext::isTransparentContext() const { 518 if (DeclKind == Decl::Enum) 519 return true; // FIXME: Check for C++0x scoped enums 520 else if (DeclKind == Decl::LinkageSpec) 521 return true; 522 else if (DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord) 523 return cast<RecordDecl>(this)->isAnonymousStructOrUnion(); 524 525 return false; 526} 527 528bool DeclContext::Encloses(const DeclContext *DC) const { 529 if (getPrimaryContext() != this) 530 return getPrimaryContext()->Encloses(DC); 531 532 for (; DC; DC = DC->getParent()) 533 if (DC->getPrimaryContext() == this) 534 return true; 535 return false; 536} 537 538DeclContext *DeclContext::getPrimaryContext() { 539 switch (DeclKind) { 540 case Decl::TranslationUnit: 541 case Decl::LinkageSpec: 542 case Decl::Block: 543 // There is only one DeclContext for these entities. 544 return this; 545 546 case Decl::Namespace: 547 // The original namespace is our primary context. 548 return static_cast<NamespaceDecl*>(this)->getOriginalNamespace(); 549 550 case Decl::ObjCMethod: 551 return this; 552 553 case Decl::ObjCInterface: 554 case Decl::ObjCProtocol: 555 case Decl::ObjCCategory: 556 // FIXME: Can Objective-C interfaces be forward-declared? 557 return this; 558 559 case Decl::ObjCImplementation: 560 case Decl::ObjCCategoryImpl: 561 return this; 562 563 default: 564 if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) { 565 // If this is a tag type that has a definition or is currently 566 // being defined, that definition is our primary context. 567 TagDecl *Tag = cast<TagDecl>(this); 568 assert(isa<TagType>(Tag->TypeForDecl) || 569 isa<InjectedClassNameType>(Tag->TypeForDecl)); 570 571 if (TagDecl *Def = Tag->getDefinition()) 572 return Def; 573 574 if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) { 575 const TagType *TagTy = cast<TagType>(Tag->TypeForDecl); 576 if (TagTy->isBeingDefined()) 577 // FIXME: is it necessarily being defined in the decl 578 // that owns the type? 579 return TagTy->getDecl(); 580 } 581 582 return Tag; 583 } 584 585 assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction && 586 "Unknown DeclContext kind"); 587 return this; 588 } 589} 590 591DeclContext *DeclContext::getNextContext() { 592 switch (DeclKind) { 593 case Decl::Namespace: 594 // Return the next namespace 595 return static_cast<NamespaceDecl*>(this)->getNextNamespace(); 596 597 default: 598 return 0; 599 } 600} 601 602/// \brief Load the declarations within this lexical storage from an 603/// external source. 604void 605DeclContext::LoadLexicalDeclsFromExternalStorage() const { 606 ExternalASTSource *Source = getParentASTContext().getExternalSource(); 607 assert(hasExternalLexicalStorage() && Source && "No external storage?"); 608 609 // Notify that we have a DeclContext that is initializing. 610 ExternalASTSource::Deserializing ADeclContext(Source); 611 612 llvm::SmallVector<Decl*, 64> Decls; 613 if (Source->FindExternalLexicalDecls(this, Decls)) 614 return; 615 616 // There is no longer any lexical storage in this context 617 ExternalLexicalStorage = false; 618 619 if (Decls.empty()) 620 return; 621 622 // Resolve all of the declaration IDs into declarations, building up 623 // a chain of declarations via the Decl::NextDeclInContext field. 624 Decl *FirstNewDecl = 0; 625 Decl *PrevDecl = 0; 626 for (unsigned I = 0, N = Decls.size(); I != N; ++I) { 627 Decl *D = Decls[I]; 628 if (PrevDecl) 629 PrevDecl->NextDeclInContext = D; 630 else 631 FirstNewDecl = D; 632 633 PrevDecl = D; 634 } 635 636 // Splice the newly-read declarations into the beginning of the list 637 // of declarations. 638 PrevDecl->NextDeclInContext = FirstDecl; 639 FirstDecl = FirstNewDecl; 640 if (!LastDecl) 641 LastDecl = PrevDecl; 642} 643 644DeclContext::lookup_result 645ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC, 646 DeclarationName Name) { 647 ASTContext &Context = DC->getParentASTContext(); 648 StoredDeclsMap *Map; 649 if (!(Map = DC->LookupPtr)) 650 Map = DC->CreateStoredDeclsMap(Context); 651 652 StoredDeclsList &List = (*Map)[Name]; 653 assert(List.isNull()); 654 (void) List; 655 656 return DeclContext::lookup_result(); 657} 658 659DeclContext::lookup_result 660ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, 661 DeclarationName Name, 662 llvm::SmallVectorImpl<NamedDecl*> &Decls) { 663 ASTContext &Context = DC->getParentASTContext();; 664 665 StoredDeclsMap *Map; 666 if (!(Map = DC->LookupPtr)) 667 Map = DC->CreateStoredDeclsMap(Context); 668 669 StoredDeclsList &List = (*Map)[Name]; 670 for (unsigned I = 0, N = Decls.size(); I != N; ++I) { 671 if (List.isNull()) 672 List.setOnlyValue(Decls[I]); 673 else 674 List.AddSubsequentDecl(Decls[I]); 675 } 676 677 return List.getLookupResult(); 678} 679 680void ExternalASTSource::MaterializeVisibleDeclsForName(const DeclContext *DC, 681 DeclarationName Name, 682 llvm::SmallVectorImpl<NamedDecl*> &Decls) { 683 assert(DC->LookupPtr); 684 StoredDeclsMap &Map = *DC->LookupPtr; 685 686 // If there's an entry in the table the visible decls for this name have 687 // already been deserialized. 688 if (Map.find(Name) == Map.end()) { 689 StoredDeclsList &List = Map[Name]; 690 for (unsigned I = 0, N = Decls.size(); I != N; ++I) { 691 if (List.isNull()) 692 List.setOnlyValue(Decls[I]); 693 else 694 List.AddSubsequentDecl(Decls[I]); 695 } 696 } 697} 698 699DeclContext::decl_iterator DeclContext::noload_decls_begin() const { 700 return decl_iterator(FirstDecl); 701} 702 703DeclContext::decl_iterator DeclContext::noload_decls_end() const { 704 return decl_iterator(); 705} 706 707DeclContext::decl_iterator DeclContext::decls_begin() const { 708 if (hasExternalLexicalStorage()) 709 LoadLexicalDeclsFromExternalStorage(); 710 711 // FIXME: Check whether we need to load some declarations from 712 // external storage. 713 return decl_iterator(FirstDecl); 714} 715 716DeclContext::decl_iterator DeclContext::decls_end() const { 717 if (hasExternalLexicalStorage()) 718 LoadLexicalDeclsFromExternalStorage(); 719 720 return decl_iterator(); 721} 722 723bool DeclContext::decls_empty() const { 724 if (hasExternalLexicalStorage()) 725 LoadLexicalDeclsFromExternalStorage(); 726 727 return !FirstDecl; 728} 729 730void DeclContext::removeDecl(Decl *D) { 731 assert(D->getLexicalDeclContext() == this && 732 "decl being removed from non-lexical context"); 733 assert((D->NextDeclInContext || D == LastDecl) && 734 "decl is not in decls list"); 735 736 // Remove D from the decl chain. This is O(n) but hopefully rare. 737 if (D == FirstDecl) { 738 if (D == LastDecl) 739 FirstDecl = LastDecl = 0; 740 else 741 FirstDecl = D->NextDeclInContext; 742 } else { 743 for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) { 744 assert(I && "decl not found in linked list"); 745 if (I->NextDeclInContext == D) { 746 I->NextDeclInContext = D->NextDeclInContext; 747 if (D == LastDecl) LastDecl = I; 748 break; 749 } 750 } 751 } 752 753 // Mark that D is no longer in the decl chain. 754 D->NextDeclInContext = 0; 755 756 // Remove D from the lookup table if necessary. 757 if (isa<NamedDecl>(D)) { 758 NamedDecl *ND = cast<NamedDecl>(D); 759 760 StoredDeclsMap *Map = getPrimaryContext()->LookupPtr; 761 if (!Map) return; 762 763 StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); 764 assert(Pos != Map->end() && "no lookup entry for decl"); 765 Pos->second.remove(ND); 766 } 767} 768 769void DeclContext::addHiddenDecl(Decl *D) { 770 assert(D->getLexicalDeclContext() == this && 771 "Decl inserted into wrong lexical context"); 772 assert(!D->getNextDeclInContext() && D != LastDecl && 773 "Decl already inserted into a DeclContext"); 774 775 if (FirstDecl) { 776 LastDecl->NextDeclInContext = D; 777 LastDecl = D; 778 } else { 779 FirstDecl = LastDecl = D; 780 } 781 782 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) { 783 Decl *InnerD = D; 784 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) 785 InnerD = FunTmpl->getTemplatedDecl(); 786 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(InnerD)) 787 Record->addedConstructor(Constructor); 788 } 789} 790 791void DeclContext::addDecl(Decl *D) { 792 addHiddenDecl(D); 793 794 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 795 ND->getDeclContext()->makeDeclVisibleInContext(ND); 796} 797 798/// buildLookup - Build the lookup data structure with all of the 799/// declarations in DCtx (and any other contexts linked to it or 800/// transparent contexts nested within it). 801void DeclContext::buildLookup(DeclContext *DCtx) { 802 for (; DCtx; DCtx = DCtx->getNextContext()) { 803 for (decl_iterator D = DCtx->decls_begin(), 804 DEnd = DCtx->decls_end(); 805 D != DEnd; ++D) { 806 // Insert this declaration into the lookup structure, but only 807 // if it's semantically in its decl context. During non-lazy 808 // lookup building, this is implicitly enforced by addDecl. 809 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) 810 if (D->getDeclContext() == DCtx) 811 makeDeclVisibleInContextImpl(ND); 812 813 // Insert any forward-declared Objective-C interfaces into the lookup 814 // data structure. 815 if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D)) 816 for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); 817 I != IEnd; ++I) 818 makeDeclVisibleInContextImpl(I->getInterface()); 819 820 // If this declaration is itself a transparent declaration context or 821 // inline namespace, add its members (recursively). 822 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) 823 if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace()) 824 buildLookup(InnerCtx->getPrimaryContext()); 825 } 826 } 827} 828 829DeclContext::lookup_result 830DeclContext::lookup(DeclarationName Name) { 831 DeclContext *PrimaryContext = getPrimaryContext(); 832 if (PrimaryContext != this) 833 return PrimaryContext->lookup(Name); 834 835 if (hasExternalVisibleStorage()) { 836 // Check to see if we've already cached the lookup results. 837 if (LookupPtr) { 838 StoredDeclsMap::iterator I = LookupPtr->find(Name); 839 if (I != LookupPtr->end()) 840 return I->second.getLookupResult(); 841 } 842 843 ExternalASTSource *Source = getParentASTContext().getExternalSource(); 844 return Source->FindExternalVisibleDeclsByName(this, Name); 845 } 846 847 /// If there is no lookup data structure, build one now by walking 848 /// all of the linked DeclContexts (in declaration order!) and 849 /// inserting their values. 850 if (!LookupPtr) { 851 buildLookup(this); 852 853 if (!LookupPtr) 854 return lookup_result(lookup_iterator(0), lookup_iterator(0)); 855 } 856 857 StoredDeclsMap::iterator Pos = LookupPtr->find(Name); 858 if (Pos == LookupPtr->end()) 859 return lookup_result(lookup_iterator(0), lookup_iterator(0)); 860 return Pos->second.getLookupResult(); 861} 862 863DeclContext::lookup_const_result 864DeclContext::lookup(DeclarationName Name) const { 865 return const_cast<DeclContext*>(this)->lookup(Name); 866} 867 868DeclContext *DeclContext::getRedeclContext() { 869 DeclContext *Ctx = this; 870 // Skip through transparent contexts. 871 while (Ctx->isTransparentContext()) 872 Ctx = Ctx->getParent(); 873 return Ctx; 874} 875 876DeclContext *DeclContext::getEnclosingNamespaceContext() { 877 DeclContext *Ctx = this; 878 // Skip through non-namespace, non-translation-unit contexts. 879 while (!Ctx->isFileContext()) 880 Ctx = Ctx->getParent(); 881 return Ctx->getPrimaryContext(); 882} 883 884bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const { 885 // For non-file contexts, this is equivalent to Equals. 886 if (!isFileContext()) 887 return O->Equals(this); 888 889 do { 890 if (O->Equals(this)) 891 return true; 892 893 const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(O); 894 if (!NS || !NS->isInline()) 895 break; 896 O = NS->getParent(); 897 } while (O); 898 899 return false; 900} 901 902void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) { 903 // FIXME: This feels like a hack. Should DeclarationName support 904 // template-ids, or is there a better way to keep specializations 905 // from being visible? 906 if (isa<ClassTemplateSpecializationDecl>(D)) 907 return; 908 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 909 if (FD->isFunctionTemplateSpecialization()) 910 return; 911 912 DeclContext *PrimaryContext = getPrimaryContext(); 913 if (PrimaryContext != this) { 914 PrimaryContext->makeDeclVisibleInContext(D, Recoverable); 915 return; 916 } 917 918 // If we already have a lookup data structure, perform the insertion 919 // into it. If we haven't deserialized externally stored decls, deserialize 920 // them so we can add the decl. Otherwise, be lazy and don't build that 921 // structure until someone asks for it. 922 if (LookupPtr || !Recoverable || hasExternalVisibleStorage()) 923 makeDeclVisibleInContextImpl(D); 924 925 // If we are a transparent context or inline namespace, insert into our 926 // parent context, too. This operation is recursive. 927 if (isTransparentContext() || isInlineNamespace()) 928 getParent()->makeDeclVisibleInContext(D, Recoverable); 929} 930 931void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { 932 // Skip unnamed declarations. 933 if (!D->getDeclName()) 934 return; 935 936 // FIXME: This feels like a hack. Should DeclarationName support 937 // template-ids, or is there a better way to keep specializations 938 // from being visible? 939 if (isa<ClassTemplateSpecializationDecl>(D)) 940 return; 941 942 ASTContext *C = 0; 943 if (!LookupPtr) { 944 C = &getParentASTContext(); 945 CreateStoredDeclsMap(*C); 946 } 947 948 // If there is an external AST source, load any declarations it knows about 949 // with this declaration's name. 950 // If the lookup table contains an entry about this name it means that we 951 // have already checked the external source. 952 if (ExternalASTSource *Source = getParentASTContext().getExternalSource()) 953 if (hasExternalVisibleStorage() && 954 LookupPtr->find(D->getDeclName()) == LookupPtr->end()) 955 Source->FindExternalVisibleDeclsByName(this, D->getDeclName()); 956 957 // Insert this declaration into the map. 958 StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()]; 959 if (DeclNameEntries.isNull()) { 960 DeclNameEntries.setOnlyValue(D); 961 return; 962 } 963 964 // If it is possible that this is a redeclaration, check to see if there is 965 // already a decl for which declarationReplaces returns true. If there is 966 // one, just replace it and return. 967 if (DeclNameEntries.HandleRedeclaration(D)) 968 return; 969 970 // Put this declaration into the appropriate slot. 971 DeclNameEntries.AddSubsequentDecl(D); 972} 973 974void DeclContext::MaterializeVisibleDeclsFromExternalStorage() { 975 ExternalASTSource *Source = getParentASTContext().getExternalSource(); 976 assert(hasExternalVisibleStorage() && Source && "No external storage?"); 977 978 if (!LookupPtr) 979 CreateStoredDeclsMap(getParentASTContext()); 980 Source->MaterializeVisibleDecls(this); 981} 982 983/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within 984/// this context. 985DeclContext::udir_iterator_range 986DeclContext::getUsingDirectives() const { 987 lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); 988 return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first), 989 reinterpret_cast<udir_iterator>(Result.second)); 990} 991 992//===----------------------------------------------------------------------===// 993// Creation and Destruction of StoredDeclsMaps. // 994//===----------------------------------------------------------------------===// 995 996StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const { 997 assert(!LookupPtr && "context already has a decls map"); 998 assert(getPrimaryContext() == this && 999 "creating decls map on non-primary context"); 1000 1001 StoredDeclsMap *M; 1002 bool Dependent = isDependentContext(); 1003 if (Dependent) 1004 M = new DependentStoredDeclsMap(); 1005 else 1006 M = new StoredDeclsMap(); 1007 M->Previous = C.LastSDM; 1008 C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent); 1009 LookupPtr = M; 1010 return M; 1011} 1012 1013void ASTContext::ReleaseDeclContextMaps() { 1014 // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap 1015 // pointer because the subclass doesn't add anything that needs to 1016 // be deleted. 1017 StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt()); 1018} 1019 1020void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) { 1021 while (Map) { 1022 // Advance the iteration before we invalidate memory. 1023 llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous; 1024 1025 if (Dependent) 1026 delete static_cast<DependentStoredDeclsMap*>(Map); 1027 else 1028 delete Map; 1029 1030 Map = Next.getPointer(); 1031 Dependent = Next.getInt(); 1032 } 1033} 1034 1035DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, 1036 DeclContext *Parent, 1037 const PartialDiagnostic &PDiag) { 1038 assert(Parent->isDependentContext() 1039 && "cannot iterate dependent diagnostics of non-dependent context"); 1040 Parent = Parent->getPrimaryContext(); 1041 if (!Parent->LookupPtr) 1042 Parent->CreateStoredDeclsMap(C); 1043 1044 DependentStoredDeclsMap *Map 1045 = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr); 1046 1047 // Allocate the copy of the PartialDiagnostic via the ASTContext's 1048 // BumpPtrAllocator, rather than the ASTContext itself. 1049 PartialDiagnostic::Storage *DiagStorage = 0; 1050 if (PDiag.hasStorage()) 1051 DiagStorage = new (C) PartialDiagnostic::Storage; 1052 1053 DependentDiagnostic *DD = new (C) DependentDiagnostic(PDiag, DiagStorage); 1054 1055 // TODO: Maybe we shouldn't reverse the order during insertion. 1056 DD->NextDiagnostic = Map->FirstDiagnostic; 1057 Map->FirstDiagnostic = DD; 1058 1059 return DD; 1060} 1061