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