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