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