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