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