DeclBase.cpp revision 3daed52a57d03765223021f5f921bdc280c8f3cc
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/DeclCXX.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/AST/ASTContext.h" 20#include "clang/AST/Type.h" 21#include "llvm/ADT/DenseMap.h" 22#include <algorithm> 23#include <cstdio> 24#include <functional> 25#include <vector> 26using namespace clang; 27 28//===----------------------------------------------------------------------===// 29// Statistics 30//===----------------------------------------------------------------------===// 31 32#define DECL(Derived, Base) static int n##Derived##s = 0; 33#include "clang/AST/DeclNodes.def" 34 35static bool StatSwitch = false; 36 37// This keeps track of all decl attributes. Since so few decls have attrs, we 38// keep them in a hash map instead of wasting space in the Decl class. 39typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy; 40 41static DeclAttrMapTy *DeclAttrs = 0; 42 43const char *Decl::getDeclKindName() const { 44 switch (DeclKind) { 45 default: assert(0 && "Declaration not in DeclNodes.def!"); 46#define DECL(Derived, Base) case Derived: return #Derived; 47#include "clang/AST/DeclNodes.def" 48 } 49} 50 51const char *DeclContext::getDeclKindName() const { 52 switch (DeclKind) { 53 default: assert(0 && "Declaration context not in DeclNodes.def!"); 54#define DECL(Derived, Base) case Decl::Derived: return #Derived; 55#include "clang/AST/DeclNodes.def" 56 } 57} 58 59bool Decl::CollectingStats(bool Enable) { 60 if (Enable) 61 StatSwitch = true; 62 return StatSwitch; 63} 64 65void Decl::PrintStats() { 66 fprintf(stderr, "*** Decl Stats:\n"); 67 68 int totalDecls = 0; 69#define DECL(Derived, Base) totalDecls += n##Derived##s; 70#include "clang/AST/DeclNodes.def" 71 fprintf(stderr, " %d decls total.\n", totalDecls); 72 73 int totalBytes = 0; 74#define DECL(Derived, Base) \ 75 if (n##Derived##s > 0) { \ 76 totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl)); \ 77 fprintf(stderr, " %d " #Derived " decls, %d each (%d bytes)\n", \ 78 n##Derived##s, (int)sizeof(Derived##Decl), \ 79 (int)(n##Derived##s * sizeof(Derived##Decl))); \ 80 } 81#include "clang/AST/DeclNodes.def" 82 83 fprintf(stderr, "Total bytes = %d\n", totalBytes); 84} 85 86void Decl::addDeclKind(Kind k) { 87 switch (k) { 88 default: assert(0 && "Declaration not in DeclNodes.def!"); 89#define DECL(Derived, Base) case Derived: ++n##Derived##s; break; 90#include "clang/AST/DeclNodes.def" 91 } 92} 93 94//===----------------------------------------------------------------------===// 95// Decl Implementation 96//===----------------------------------------------------------------------===// 97 98void Decl::setDeclContext(DeclContext *DC) { 99 if (isOutOfSemaDC()) 100 delete getMultipleDC(); 101 102 DeclCtx = reinterpret_cast<uintptr_t>(DC); 103} 104 105void Decl::setLexicalDeclContext(DeclContext *DC) { 106 if (DC == getLexicalDeclContext()) 107 return; 108 109 if (isInSemaDC()) { 110 MultipleDC *MDC = new MultipleDC(); 111 MDC->SemanticDC = getDeclContext(); 112 MDC->LexicalDC = DC; 113 DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1; 114 } else { 115 getMultipleDC()->LexicalDC = DC; 116 } 117} 118 119// Out-of-line virtual method providing a home for Decl. 120Decl::~Decl() { 121 if (isOutOfSemaDC()) 122 delete getMultipleDC(); 123 124 if (!HasAttrs) 125 return; 126 127 DeclAttrMapTy::iterator it = DeclAttrs->find(this); 128 assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!"); 129 130 // release attributes. 131 delete it->second; 132 invalidateAttrs(); 133} 134 135void Decl::addAttr(Attr *NewAttr) { 136 if (!DeclAttrs) 137 DeclAttrs = new DeclAttrMapTy(); 138 139 Attr *&ExistingAttr = (*DeclAttrs)[this]; 140 141 NewAttr->setNext(ExistingAttr); 142 ExistingAttr = NewAttr; 143 144 HasAttrs = true; 145} 146 147void Decl::invalidateAttrs() { 148 if (!HasAttrs) return; 149 150 HasAttrs = false; 151 (*DeclAttrs)[this] = 0; 152 DeclAttrs->erase(this); 153 154 if (DeclAttrs->empty()) { 155 delete DeclAttrs; 156 DeclAttrs = 0; 157 } 158} 159 160const Attr *Decl::getAttrs() const { 161 if (!HasAttrs) 162 return 0; 163 164 return (*DeclAttrs)[this]; 165} 166 167void Decl::swapAttrs(Decl *RHS) { 168 bool HasLHSAttr = this->HasAttrs; 169 bool HasRHSAttr = RHS->HasAttrs; 170 171 // Usually, neither decl has attrs, nothing to do. 172 if (!HasLHSAttr && !HasRHSAttr) return; 173 174 // If 'this' has no attrs, swap the other way. 175 if (!HasLHSAttr) 176 return RHS->swapAttrs(this); 177 178 // Handle the case when both decls have attrs. 179 if (HasRHSAttr) { 180 std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]); 181 return; 182 } 183 184 // Otherwise, LHS has an attr and RHS doesn't. 185 (*DeclAttrs)[RHS] = (*DeclAttrs)[this]; 186 (*DeclAttrs).erase(this); 187 this->HasAttrs = false; 188 RHS->HasAttrs = true; 189} 190 191 192void Decl::Destroy(ASTContext& C) { 193#if 0 194 // FIXME: Once ownership is fully understood, we can enable this code 195 if (DeclContext *DC = dyn_cast<DeclContext>(this)) 196 DC->decls_begin()->Destroy(C); 197 198 // Observe the unrolled recursion. By setting N->NextDeclInScope = 0x0 199 // within the loop, only the Destroy method for the first Decl 200 // will deallocate all of the Decls in a chain. 201 202 Decl* N = NextDeclInScope; 203 204 while (N) { 205 Decl* Tmp = N->NextDeclInScope; 206 N->NextDeclInScope = 0; 207 N->Destroy(C); 208 N = Tmp; 209 } 210 211 this->~Decl(); 212 C.Deallocate((void *)this); 213#endif 214} 215 216Decl *Decl::castFromDeclContext (const DeclContext *D) { 217 Decl::Kind DK = D->getDeclKind(); 218 switch(DK) { 219#define DECL_CONTEXT(Name) \ 220 case Decl::Name: \ 221 return static_cast<Name##Decl*>(const_cast<DeclContext*>(D)); 222#define DECL_CONTEXT_BASE(Name) 223#include "clang/AST/DeclNodes.def" 224 default: 225#define DECL_CONTEXT_BASE(Name) \ 226 if (DK >= Decl::Name##First && DK <= Decl::Name##Last) \ 227 return static_cast<Name##Decl*>(const_cast<DeclContext*>(D)); 228#include "clang/AST/DeclNodes.def" 229 assert(false && "a decl that inherits DeclContext isn't handled"); 230 return 0; 231 } 232} 233 234DeclContext *Decl::castToDeclContext(const Decl *D) { 235 Decl::Kind DK = D->getKind(); 236 switch(DK) { 237#define DECL_CONTEXT(Name) \ 238 case Decl::Name: \ 239 return static_cast<Name##Decl*>(const_cast<Decl*>(D)); 240#define DECL_CONTEXT_BASE(Name) 241#include "clang/AST/DeclNodes.def" 242 default: 243#define DECL_CONTEXT_BASE(Name) \ 244 if (DK >= Decl::Name##First && DK <= Decl::Name##Last) \ 245 return static_cast<Name##Decl*>(const_cast<Decl*>(D)); 246#include "clang/AST/DeclNodes.def" 247 assert(false && "a decl that inherits DeclContext isn't handled"); 248 return 0; 249 } 250} 251 252//===----------------------------------------------------------------------===// 253// DeclContext Implementation 254//===----------------------------------------------------------------------===// 255 256bool DeclContext::classof(const Decl *D) { 257 switch (D->getKind()) { 258#define DECL_CONTEXT(Name) case Decl::Name: 259#define DECL_CONTEXT_BASE(Name) 260#include "clang/AST/DeclNodes.def" 261 return true; 262 default: 263#define DECL_CONTEXT_BASE(Name) \ 264 if (D->getKind() >= Decl::Name##First && \ 265 D->getKind() <= Decl::Name##Last) \ 266 return true; 267#include "clang/AST/DeclNodes.def" 268 return false; 269 } 270} 271 272/// StoredDeclsList - This is an array of decls optimized a common case of only 273/// containing one entry. 274struct StoredDeclsList { 275 /// Data - If the integer is 0, then the pointer is a NamedDecl*. If the 276 /// integer is 1, then it is a VectorTy; 277 llvm::PointerIntPair<void*, 1, bool> Data; 278 279 /// VectorTy - When in vector form, this is what the Data pointer points to. 280 typedef llvm::SmallVector<NamedDecl*, 4> VectorTy; 281public: 282 StoredDeclsList() {} 283 StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { 284 if (isVector()) 285 Data.setPointer(new VectorTy(getVector())); 286 } 287 288 ~StoredDeclsList() { 289 // If this is a vector-form, free the vector. 290 if (isVector()) 291 delete &getVector(); 292 } 293 294 StoredDeclsList &operator=(const StoredDeclsList &RHS) { 295 if (isVector()) 296 delete &getVector(); 297 Data = RHS.Data; 298 if (isVector()) 299 Data.setPointer(new VectorTy(getVector())); 300 return *this; 301 } 302 303 bool isVector() const { return Data.getInt() != 0; } 304 bool isInline() const { return Data.getInt() == 0; } 305 bool isNull() const { return Data.getPointer() == 0; } 306 307 void setOnlyValue(NamedDecl *ND) { 308 assert(isInline() && "Not inline"); 309 Data.setPointer(ND); 310 } 311 312 /// getLookupResult - Return an array of all the decls that this list 313 /// represents. 314 DeclContext::lookup_result getLookupResult() { 315 // If we have a single inline unit, return it. 316 if (isInline()) { 317 assert(!isNull() && "Empty list isn't allowed"); 318 319 // Data is a raw pointer to a NamedDecl*, return it. 320 void *Ptr = &Data; 321 return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); 322 } 323 324 // Otherwise, we have a range result. 325 VectorTy &V = getVector(); 326 return DeclContext::lookup_result(&V[0], &V[0]+V.size()); 327 } 328 329 /// HandleRedeclaration - If this is a redeclaration of an existing decl, 330 /// replace the old one with D and return true. Otherwise return false. 331 bool HandleRedeclaration(NamedDecl *D) { 332 // Most decls only have one entry in their list, special case it. 333 if (isInline()) { 334 if (!D->declarationReplaces(getInlineValue())) 335 return false; 336 setOnlyValue(D); 337 return true; 338 } 339 340 // Determine if this declaration is actually a redeclaration. 341 VectorTy &Vec = getVector(); 342 VectorTy::iterator RDI 343 = std::find_if(Vec.begin(), Vec.end(), 344 std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces), 345 D)); 346 if (RDI == Vec.end()) 347 return false; 348 *RDI = D; 349 return true; 350 } 351 352 /// AddSubsequentDecl - This is called on the second and later decl when it is 353 /// not a redeclaration to merge it into the appropriate place in our list. 354 /// 355 void AddSubsequentDecl(NamedDecl *D) { 356 // If this is the second decl added to the list, convert this to vector 357 // form. 358 if (isInline()) { 359 NamedDecl *OldD = getInlineValue(); 360 Data.setInt(1); 361 VectorTy *VT = new VectorTy(); 362 VT->push_back(OldD); 363 Data.setPointer(VT); 364 } 365 366 VectorTy &Vec = getVector(); 367 if (isa<UsingDirectiveDecl>(D) || 368 D->getIdentifierNamespace() == Decl::IDNS_Tag) 369 Vec.push_back(D); 370 else if (Vec.back()->getIdentifierNamespace() == Decl::IDNS_Tag) { 371 NamedDecl *TagD = Vec.back(); 372 Vec.back() = D; 373 Vec.push_back(TagD); 374 } else 375 Vec.push_back(D); 376 } 377 378 379private: 380 VectorTy &getVector() const { 381 assert(isVector() && "Not in vector form"); 382 return *static_cast<VectorTy*>(Data.getPointer()); 383 } 384 385 NamedDecl *getInlineValue() const { 386 assert(isInline() && "Not in inline form"); 387 return (NamedDecl*)Data.getPointer(); 388 } 389}; 390 391 392 393typedef llvm::DenseMap<DeclarationName, StoredDeclsList> StoredDeclsMap; 394 395DeclContext::~DeclContext() { 396 unsigned Size = LookupPtr.getInt(); 397 if (Size == LookupIsMap) 398 delete static_cast<StoredDeclsMap*>(LookupPtr.getPointer()); 399 else 400 delete [] static_cast<NamedDecl**>(LookupPtr.getPointer()); 401} 402 403void DeclContext::DestroyDecls(ASTContext &C) { 404 for (decl_iterator D = decls_begin(); D != decls_end(); ) 405 (*D++)->Destroy(C); 406} 407 408bool DeclContext::isTransparentContext() const { 409 if (DeclKind == Decl::Enum) 410 return true; // FIXME: Check for C++0x scoped enums 411 else if (DeclKind == Decl::LinkageSpec) 412 return true; 413 else if (DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast) 414 return cast<RecordDecl>(this)->isAnonymousStructOrUnion(); 415 else if (DeclKind == Decl::Namespace) 416 return false; // FIXME: Check for C++0x inline namespaces 417 418 return false; 419} 420 421DeclContext *DeclContext::getPrimaryContext() { 422 switch (DeclKind) { 423 case Decl::TranslationUnit: 424 case Decl::LinkageSpec: 425 case Decl::Block: 426 // There is only one DeclContext for these entities. 427 return this; 428 429 case Decl::Namespace: 430 // The original namespace is our primary context. 431 return static_cast<NamespaceDecl*>(this)->getOriginalNamespace(); 432 433 case Decl::ObjCMethod: 434 return this; 435 436 case Decl::ObjCInterface: 437 case Decl::ObjCProtocol: 438 case Decl::ObjCCategory: 439 // FIXME: Can Objective-C interfaces be forward-declared? 440 return this; 441 442 case Decl::ObjCImplementation: 443 case Decl::ObjCCategoryImpl: 444 return this; 445 446 default: 447 if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) { 448 // If this is a tag type that has a definition or is currently 449 // being defined, that definition is our primary context. 450 if (const TagType *TagT = cast<TagDecl>(this)->TypeForDecl->getAsTagType()) 451 if (TagT->isBeingDefined() || 452 (TagT->getDecl() && TagT->getDecl()->isDefinition())) 453 return TagT->getDecl(); 454 return this; 455 } 456 457 assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast && 458 "Unknown DeclContext kind"); 459 return this; 460 } 461} 462 463DeclContext *DeclContext::getNextContext() { 464 switch (DeclKind) { 465 case Decl::Namespace: 466 // Return the next namespace 467 return static_cast<NamespaceDecl*>(this)->getNextNamespace(); 468 469 default: 470 return 0; 471 } 472} 473 474void DeclContext::addDecl(Decl *D) { 475 assert(D->getLexicalDeclContext() == this && 476 "Decl inserted into wrong lexical context"); 477 assert(!D->NextDeclInScope && D != LastDecl && 478 "Decl already inserted into a DeclContext"); 479 480 if (FirstDecl) { 481 LastDecl->NextDeclInScope = D; 482 LastDecl = D; 483 } else { 484 FirstDecl = LastDecl = D; 485 } 486 487 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 488 ND->getDeclContext()->makeDeclVisibleInContext(ND); 489} 490 491/// buildLookup - Build the lookup data structure with all of the 492/// declarations in DCtx (and any other contexts linked to it or 493/// transparent contexts nested within it). 494void DeclContext::buildLookup(DeclContext *DCtx) { 495 for (; DCtx; DCtx = DCtx->getNextContext()) { 496 for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end(); 497 D != DEnd; ++D) { 498 // Insert this declaration into the lookup structure 499 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) 500 makeDeclVisibleInContextImpl(ND); 501 502 // If this declaration is itself a transparent declaration context, 503 // add its members (recursively). 504 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) 505 if (InnerCtx->isTransparentContext()) 506 buildLookup(InnerCtx->getPrimaryContext()); 507 } 508 } 509} 510 511DeclContext::lookup_result 512DeclContext::lookup(DeclarationName Name) { 513 DeclContext *PrimaryContext = getPrimaryContext(); 514 if (PrimaryContext != this) 515 return PrimaryContext->lookup(Name); 516 517 /// If there is no lookup data structure, build one now by walking 518 /// all of the linked DeclContexts (in declaration order!) and 519 /// inserting their values. 520 if (LookupPtr.getPointer() == 0) 521 buildLookup(this); 522 523 if (isLookupMap()) { 524 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer()); 525 StoredDeclsMap::iterator Pos = Map->find(Name); 526 if (Pos == Map->end()) 527 return lookup_result(0, 0); 528 return Pos->second.getLookupResult(); 529 } 530 531 // We have a small array. Look into it. 532 unsigned Size = LookupPtr.getInt(); 533 NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer()); 534 for (unsigned Idx = 0; Idx != Size; ++Idx) 535 if (Array[Idx]->getDeclName() == Name) { 536 unsigned Last = Idx + 1; 537 while (Last != Size && Array[Last]->getDeclName() == Name) 538 ++Last; 539 return lookup_result(&Array[Idx], &Array[Last]); 540 } 541 542 return lookup_result(0, 0); 543} 544 545DeclContext::lookup_const_result 546DeclContext::lookup(DeclarationName Name) const { 547 return const_cast<DeclContext*>(this)->lookup(Name); 548} 549 550const DeclContext *DeclContext::getLookupContext() const { 551 const DeclContext *Ctx = this; 552 // Skip through transparent contexts. 553 while (Ctx->isTransparentContext()) 554 Ctx = Ctx->getParent(); 555 return Ctx; 556} 557 558DeclContext *DeclContext::getEnclosingNamespaceContext() { 559 DeclContext *Ctx = this; 560 // Skip through non-namespace, non-translation-unit contexts. 561 while (!Ctx->isFileContext() || Ctx->isTransparentContext()) 562 Ctx = Ctx->getParent(); 563 return Ctx->getPrimaryContext(); 564} 565 566void DeclContext::makeDeclVisibleInContext(NamedDecl *D) { 567 // FIXME: This feels like a hack. Should DeclarationName support 568 // template-ids, or is there a better way to keep specializations 569 // from being visible? 570 if (isa<ClassTemplateSpecializationDecl>(D)) 571 return; 572 573 DeclContext *PrimaryContext = getPrimaryContext(); 574 if (PrimaryContext != this) { 575 PrimaryContext->makeDeclVisibleInContext(D); 576 return; 577 } 578 579 // If we already have a lookup data structure, perform the insertion 580 // into it. Otherwise, be lazy and don't build that structure until 581 // someone asks for it. 582 if (LookupPtr.getPointer()) 583 makeDeclVisibleInContextImpl(D); 584 585 // If we are a transparent context, insert into our parent context, 586 // too. This operation is recursive. 587 if (isTransparentContext()) 588 getParent()->makeDeclVisibleInContext(D); 589} 590 591void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { 592 // Skip unnamed declarations. 593 if (!D->getDeclName()) 594 return; 595 596 // FIXME: This feels like a hack. Should DeclarationName support 597 // template-ids, or is there a better way to keep specializations 598 // from being visible? 599 if (isa<ClassTemplateSpecializationDecl>(D)) 600 return; 601 602 bool MayBeRedeclaration = true; 603 604 if (!isLookupMap()) { 605 unsigned Size = LookupPtr.getInt(); 606 607 // The lookup data is stored as an array. Search through the array 608 // to find the insertion location. 609 NamedDecl **Array; 610 if (Size == 0) { 611 Array = new NamedDecl*[LookupIsMap - 1]; 612 LookupPtr.setPointer(Array); 613 } else { 614 Array = static_cast<NamedDecl **>(LookupPtr.getPointer()); 615 } 616 617 // We always keep declarations of the same name next to each other 618 // in the array, so that it is easy to return multiple results 619 // from lookup(). 620 unsigned FirstMatch; 621 for (FirstMatch = 0; FirstMatch != Size; ++FirstMatch) 622 if (Array[FirstMatch]->getDeclName() == D->getDeclName()) 623 break; 624 625 unsigned InsertPos = FirstMatch; 626 if (FirstMatch != Size) { 627 // We found another declaration with the same name. First 628 // determine whether this is a redeclaration of an existing 629 // declaration in this scope, in which case we will replace the 630 // existing declaration. 631 unsigned LastMatch = FirstMatch; 632 for (; LastMatch != Size; ++LastMatch) { 633 if (Array[LastMatch]->getDeclName() != D->getDeclName()) 634 break; 635 636 if (D->declarationReplaces(Array[LastMatch])) { 637 // D is a redeclaration of an existing element in the 638 // array. Replace that element with D. 639 Array[LastMatch] = D; 640 return; 641 } 642 } 643 644 // [FirstMatch, LastMatch) contains the set of declarations that 645 // have the same name as this declaration. Determine where the 646 // declaration D will be inserted into this range. 647 if (D->getKind() == Decl::UsingDirective || 648 D->getIdentifierNamespace() == Decl::IDNS_Tag) 649 InsertPos = LastMatch; 650 else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag) 651 InsertPos = LastMatch - 1; 652 else 653 InsertPos = LastMatch; 654 } 655 656 if (Size < LookupIsMap - 1) { 657 // The new declaration will fit in the array. Insert the new 658 // declaration at the position Match in the array. 659 for (unsigned Idx = Size; Idx > InsertPos; --Idx) 660 Array[Idx] = Array[Idx-1]; 661 662 Array[InsertPos] = D; 663 LookupPtr.setInt(Size + 1); 664 return; 665 } 666 667 // We've reached capacity in this array. Create a map and copy in 668 // all of the declarations that were stored in the array. 669 StoredDeclsMap *Map = new StoredDeclsMap(16); 670 LookupPtr.setPointer(Map); 671 LookupPtr.setInt(LookupIsMap); 672 for (unsigned Idx = 0; Idx != LookupIsMap - 1; ++Idx) 673 makeDeclVisibleInContextImpl(Array[Idx]); 674 delete [] Array; 675 676 // Fall through to perform insertion into the map. 677 MayBeRedeclaration = false; 678 } 679 680 // Insert this declaration into the map. 681 StoredDeclsMap &Map = *static_cast<StoredDeclsMap*>(LookupPtr.getPointer()); 682 StoredDeclsList &DeclNameEntries = Map[D->getDeclName()]; 683 if (DeclNameEntries.isNull()) { 684 DeclNameEntries.setOnlyValue(D); 685 return; 686 } 687 688 // If it is possible that this is a redeclaration, check to see if there is 689 // already a decl for which declarationReplaces returns true. If there is 690 // one, just replace it and return. 691 if (MayBeRedeclaration && DeclNameEntries.HandleRedeclaration(D)) 692 return; 693 694 // Put this declaration into the appropriate slot. 695 DeclNameEntries.AddSubsequentDecl(D); 696} 697 698/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within 699/// this context. 700DeclContext::udir_iterator_range DeclContext::getUsingDirectives() const { 701 lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); 702 return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first), 703 reinterpret_cast<udir_iterator>(Result.second)); 704} 705 706