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