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