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