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