DeclBase.cpp revision 3478eb6872d836600caf45b0f81c2065d685d6e0
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) StatSwitch = true;
59  return StatSwitch;
60}
61
62void Decl::PrintStats() {
63  fprintf(stderr, "*** Decl Stats:\n");
64
65  int totalDecls = 0;
66#define DECL(Derived, Base) totalDecls += n##Derived##s;
67#include "clang/AST/DeclNodes.def"
68  fprintf(stderr, "  %d decls total.\n", totalDecls);
69
70  int totalBytes = 0;
71#define DECL(Derived, Base)                                             \
72  if (n##Derived##s > 0) {                                              \
73    totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl));         \
74    fprintf(stderr, "    %d " #Derived " decls, %d each (%d bytes)\n",  \
75            n##Derived##s, (int)sizeof(Derived##Decl),                  \
76            (int)(n##Derived##s * sizeof(Derived##Decl)));              \
77  }
78#include "clang/AST/DeclNodes.def"
79
80  fprintf(stderr, "Total bytes = %d\n", totalBytes);
81}
82
83void Decl::addDeclKind(Kind k) {
84  switch (k) {
85  default: assert(0 && "Declaration not in DeclNodes.def!");
86#define DECL(Derived, Base) case Derived: ++n##Derived##s; break;
87#include "clang/AST/DeclNodes.def"
88  }
89}
90
91bool Decl::isTemplateParameterPack() const {
92  if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
93    return TTP->isParameterPack();
94
95  return false;
96}
97
98bool Decl::isFunctionOrFunctionTemplate() const {
99  if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
100    return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
101
102  return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
103}
104
105bool Decl::isDefinedOutsideFunctionOrMethod() const {
106  for (const DeclContext *DC = getDeclContext();
107       DC && !DC->isTranslationUnit();
108       DC = DC->getParent())
109    if (DC->isFunctionOrMethod())
110      return false;
111
112  return true;
113}
114
115
116//===----------------------------------------------------------------------===//
117// PrettyStackTraceDecl Implementation
118//===----------------------------------------------------------------------===//
119
120void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
121  SourceLocation TheLoc = Loc;
122  if (TheLoc.isInvalid() && TheDecl)
123    TheLoc = TheDecl->getLocation();
124
125  if (TheLoc.isValid()) {
126    TheLoc.print(OS, SM);
127    OS << ": ";
128  }
129
130  OS << Message;
131
132  if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
133    OS << " '" << DN->getQualifiedNameAsString() << '\'';
134  OS << '\n';
135}
136
137//===----------------------------------------------------------------------===//
138// Decl Implementation
139//===----------------------------------------------------------------------===//
140
141// Out-of-line virtual method providing a home for Decl.
142Decl::~Decl() {
143  assert(!HasAttrs && "attributes should have been freed by Destroy");
144}
145
146void Decl::setDeclContext(DeclContext *DC) {
147  if (isOutOfSemaDC())
148    delete getMultipleDC();
149
150  DeclCtx = DC;
151}
152
153void Decl::setLexicalDeclContext(DeclContext *DC) {
154  if (DC == getLexicalDeclContext())
155    return;
156
157  if (isInSemaDC()) {
158    MultipleDC *MDC = new (getASTContext()) MultipleDC();
159    MDC->SemanticDC = getDeclContext();
160    MDC->LexicalDC = DC;
161    DeclCtx = MDC;
162  } else {
163    getMultipleDC()->LexicalDC = DC;
164  }
165}
166
167bool Decl::isInAnonymousNamespace() const {
168  const DeclContext *DC = getDeclContext();
169  do {
170    if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
171      if (ND->isAnonymousNamespace())
172        return true;
173  } while ((DC = DC->getParent()));
174
175  return false;
176}
177
178TranslationUnitDecl *Decl::getTranslationUnitDecl() {
179  if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
180    return TUD;
181
182  DeclContext *DC = getDeclContext();
183  assert(DC && "This decl is not contained in a translation unit!");
184
185  while (!DC->isTranslationUnit()) {
186    DC = DC->getParent();
187    assert(DC && "This decl is not contained in a translation unit!");
188  }
189
190  return cast<TranslationUnitDecl>(DC);
191}
192
193ASTContext &Decl::getASTContext() const {
194  return getTranslationUnitDecl()->getASTContext();
195}
196
197unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
198  switch (DeclKind) {
199    case Function:
200    case CXXMethod:
201    case CXXConstructor:
202    case CXXDestructor:
203    case CXXConversion:
204    case Typedef:
205    case EnumConstant:
206    case Var:
207    case ImplicitParam:
208    case ParmVar:
209    case NonTypeTemplateParm:
210    case ObjCMethod:
211    case ObjCContainer:
212    case ObjCInterface:
213    case ObjCProperty:
214    case ObjCCompatibleAlias:
215      return IDNS_Ordinary;
216
217    case UsingShadow:
218      return 0; // we'll actually overwrite this later
219
220    case UnresolvedUsingValue:
221    case UnresolvedUsingTypename:
222      return IDNS_Ordinary | IDNS_Using;
223
224    case Using:
225      return IDNS_Using;
226
227    case ObjCProtocol:
228      return IDNS_ObjCProtocol;
229
230    case ObjCImplementation:
231      return IDNS_ObjCImplementation;
232
233    case ObjCCategory:
234    case ObjCCategoryImpl:
235      return IDNS_ObjCCategoryName;
236
237    case Field:
238    case ObjCAtDefsField:
239    case ObjCIvar:
240      return IDNS_Member;
241
242    case Record:
243    case CXXRecord:
244    case Enum:
245    case TemplateTypeParm:
246      return IDNS_Tag;
247
248    case Namespace:
249    case Template:
250    case FunctionTemplate:
251    case ClassTemplate:
252    case TemplateTemplateParm:
253    case NamespaceAlias:
254      return IDNS_Tag | IDNS_Ordinary;
255
256    // Never have names.
257    case Friend:
258    case FriendTemplate:
259    case LinkageSpec:
260    case FileScopeAsm:
261    case StaticAssert:
262    case ObjCClass:
263    case ObjCPropertyImpl:
264    case ObjCForwardProtocol:
265    case Block:
266    case TranslationUnit:
267
268    // Aren't looked up?
269    case UsingDirective:
270    case ClassTemplateSpecialization:
271    case ClassTemplatePartialSpecialization:
272      return 0;
273  }
274
275  return 0;
276}
277
278void Decl::addAttr(Attr *NewAttr) {
279  Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
280
281  NewAttr->setNext(ExistingAttr);
282  ExistingAttr = NewAttr;
283
284  HasAttrs = true;
285}
286
287void Decl::invalidateAttrs() {
288  if (!HasAttrs) return;
289
290  HasAttrs = false;
291  getASTContext().eraseDeclAttrs(this);
292}
293
294const Attr *Decl::getAttrsImpl() const {
295  assert(HasAttrs && "getAttrs() should verify this!");
296  return getASTContext().getDeclAttrs(this);
297}
298
299void Decl::swapAttrs(Decl *RHS) {
300  bool HasLHSAttr = this->HasAttrs;
301  bool HasRHSAttr = RHS->HasAttrs;
302
303  // Usually, neither decl has attrs, nothing to do.
304  if (!HasLHSAttr && !HasRHSAttr) return;
305
306  // If 'this' has no attrs, swap the other way.
307  if (!HasLHSAttr)
308    return RHS->swapAttrs(this);
309
310  ASTContext &Context = getASTContext();
311
312  // Handle the case when both decls have attrs.
313  if (HasRHSAttr) {
314    std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS));
315    return;
316  }
317
318  // Otherwise, LHS has an attr and RHS doesn't.
319  Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this);
320  Context.eraseDeclAttrs(this);
321  this->HasAttrs = false;
322  RHS->HasAttrs = true;
323}
324
325
326void Decl::Destroy(ASTContext &C) {
327  // Free attributes for this decl.
328  if (HasAttrs) {
329    C.getDeclAttrs(this)->Destroy(C);
330    invalidateAttrs();
331    HasAttrs = false;
332  }
333
334#if 0
335  // FIXME: Once ownership is fully understood, we can enable this code
336  if (DeclContext *DC = dyn_cast<DeclContext>(this))
337    DC->decls_begin()->Destroy(C);
338
339  // Observe the unrolled recursion.  By setting N->NextDeclInContext = 0x0
340  // within the loop, only the Destroy method for the first Decl
341  // will deallocate all of the Decls in a chain.
342
343  Decl* N = getNextDeclInContext();
344
345  while (N) {
346    Decl* Tmp = N->getNextDeclInContext();
347    N->NextDeclInContext = 0;
348    N->Destroy(C);
349    N = Tmp;
350  }
351
352  if (isOutOfSemaDC())
353    delete (C) getMultipleDC();
354
355  this->~Decl();
356  C.Deallocate((void *)this);
357#endif
358}
359
360Decl *Decl::castFromDeclContext (const DeclContext *D) {
361  Decl::Kind DK = D->getDeclKind();
362  switch(DK) {
363#define DECL_CONTEXT(Name) \
364    case Decl::Name:     \
365      return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
366#define DECL_CONTEXT_BASE(Name)
367#include "clang/AST/DeclNodes.def"
368    default:
369#define DECL_CONTEXT_BASE(Name)                                   \
370      if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
371        return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
372#include "clang/AST/DeclNodes.def"
373      assert(false && "a decl that inherits DeclContext isn't handled");
374      return 0;
375  }
376}
377
378DeclContext *Decl::castToDeclContext(const Decl *D) {
379  Decl::Kind DK = D->getKind();
380  switch(DK) {
381#define DECL_CONTEXT(Name) \
382    case Decl::Name:     \
383      return static_cast<Name##Decl*>(const_cast<Decl*>(D));
384#define DECL_CONTEXT_BASE(Name)
385#include "clang/AST/DeclNodes.def"
386    default:
387#define DECL_CONTEXT_BASE(Name)                                   \
388      if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
389        return static_cast<Name##Decl*>(const_cast<Decl*>(D));
390#include "clang/AST/DeclNodes.def"
391      assert(false && "a decl that inherits DeclContext isn't handled");
392      return 0;
393  }
394}
395
396CompoundStmt* Decl::getCompoundBody() const {
397  return dyn_cast_or_null<CompoundStmt>(getBody());
398}
399
400SourceLocation Decl::getBodyRBrace() const {
401  Stmt *Body = getBody();
402  if (!Body)
403    return SourceLocation();
404  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
405    return CS->getRBracLoc();
406  assert(isa<CXXTryStmt>(Body) &&
407         "Body can only be CompoundStmt or CXXTryStmt");
408  return cast<CXXTryStmt>(Body)->getSourceRange().getEnd();
409}
410
411#ifndef NDEBUG
412void Decl::CheckAccessDeclContext() const {
413  // Suppress this check if any of the following hold:
414  // 1. this is the translation unit (and thus has no parent)
415  // 2. this is a template parameter (and thus doesn't belong to its context)
416  // 3. this is a ParmVarDecl (which can be in a record context during
417  //    the brief period between its creation and the creation of the
418  //    FunctionDecl)
419  // 4. the context is not a record
420  if (isa<TranslationUnitDecl>(this) ||
421      !isa<CXXRecordDecl>(getDeclContext()))
422    return;
423
424  assert(Access != AS_none &&
425         "Access specifier is AS_none inside a record decl");
426}
427
428#endif
429
430//===----------------------------------------------------------------------===//
431// DeclContext Implementation
432//===----------------------------------------------------------------------===//
433
434bool DeclContext::classof(const Decl *D) {
435  switch (D->getKind()) {
436#define DECL_CONTEXT(Name) case Decl::Name:
437#define DECL_CONTEXT_BASE(Name)
438#include "clang/AST/DeclNodes.def"
439      return true;
440    default:
441#define DECL_CONTEXT_BASE(Name)                   \
442      if (D->getKind() >= Decl::Name##First &&  \
443          D->getKind() <= Decl::Name##Last)     \
444        return true;
445#include "clang/AST/DeclNodes.def"
446      return false;
447  }
448}
449
450DeclContext::~DeclContext() {
451  // FIXME: Currently ~ASTContext will delete the StoredDeclsMaps because
452  // ~DeclContext() is not guaranteed to be called when ASTContext uses
453  // a BumpPtrAllocator.
454  // delete static_cast<StoredDeclsMap*>(LookupPtr);
455}
456
457void DeclContext::DestroyDecls(ASTContext &C) {
458  for (decl_iterator D = decls_begin(); D != decls_end(); )
459    (*D++)->Destroy(C);
460}
461
462/// \brief Find the parent context of this context that will be
463/// used for unqualified name lookup.
464///
465/// Generally, the parent lookup context is the semantic context. However, for
466/// a friend function the parent lookup context is the lexical context, which
467/// is the class in which the friend is declared.
468DeclContext *DeclContext::getLookupParent() {
469  // FIXME: Find a better way to identify friends
470  if (isa<FunctionDecl>(this))
471    if (getParent()->getLookupContext()->isFileContext() &&
472        getLexicalParent()->getLookupContext()->isRecord())
473      return getLexicalParent();
474
475  return getParent();
476}
477
478bool DeclContext::isDependentContext() const {
479  if (isFileContext())
480    return false;
481
482  if (isa<ClassTemplatePartialSpecializationDecl>(this))
483    return true;
484
485  if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
486    if (Record->getDescribedClassTemplate())
487      return true;
488
489  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this))
490    if (Function->getDescribedFunctionTemplate())
491      return true;
492
493  return getParent() && getParent()->isDependentContext();
494}
495
496bool DeclContext::isTransparentContext() const {
497  if (DeclKind == Decl::Enum)
498    return true; // FIXME: Check for C++0x scoped enums
499  else if (DeclKind == Decl::LinkageSpec)
500    return true;
501  else if (DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast)
502    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
503  else if (DeclKind == Decl::Namespace)
504    return false; // FIXME: Check for C++0x inline namespaces
505
506  return false;
507}
508
509bool DeclContext::Encloses(DeclContext *DC) {
510  if (getPrimaryContext() != this)
511    return getPrimaryContext()->Encloses(DC);
512
513  for (; DC; DC = DC->getParent())
514    if (DC->getPrimaryContext() == this)
515      return true;
516  return false;
517}
518
519DeclContext *DeclContext::getPrimaryContext() {
520  switch (DeclKind) {
521  case Decl::TranslationUnit:
522  case Decl::LinkageSpec:
523  case Decl::Block:
524    // There is only one DeclContext for these entities.
525    return this;
526
527  case Decl::Namespace:
528    // The original namespace is our primary context.
529    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
530
531  case Decl::ObjCMethod:
532    return this;
533
534  case Decl::ObjCInterface:
535  case Decl::ObjCProtocol:
536  case Decl::ObjCCategory:
537    // FIXME: Can Objective-C interfaces be forward-declared?
538    return this;
539
540  case Decl::ObjCImplementation:
541  case Decl::ObjCCategoryImpl:
542    return this;
543
544  default:
545    if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
546      // If this is a tag type that has a definition or is currently
547      // being defined, that definition is our primary context.
548      if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAs<TagType>())
549        if (TagT->isBeingDefined() ||
550            (TagT->getDecl() && TagT->getDecl()->isDefinition()))
551          return TagT->getDecl();
552      return this;
553    }
554
555    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
556          "Unknown DeclContext kind");
557    return this;
558  }
559}
560
561DeclContext *DeclContext::getNextContext() {
562  switch (DeclKind) {
563  case Decl::Namespace:
564    // Return the next namespace
565    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
566
567  default:
568    return 0;
569  }
570}
571
572/// \brief Load the declarations within this lexical storage from an
573/// external source.
574void
575DeclContext::LoadLexicalDeclsFromExternalStorage() const {
576  ExternalASTSource *Source = getParentASTContext().getExternalSource();
577  assert(hasExternalLexicalStorage() && Source && "No external storage?");
578
579  llvm::SmallVector<uint32_t, 64> Decls;
580  if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this),
581                                          Decls))
582    return;
583
584  // There is no longer any lexical storage in this context
585  ExternalLexicalStorage = false;
586
587  if (Decls.empty())
588    return;
589
590  // Resolve all of the declaration IDs into declarations, building up
591  // a chain of declarations via the Decl::NextDeclInContext field.
592  Decl *FirstNewDecl = 0;
593  Decl *PrevDecl = 0;
594  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
595    Decl *D = Source->GetDecl(Decls[I]);
596    if (PrevDecl)
597      PrevDecl->NextDeclInContext = D;
598    else
599      FirstNewDecl = D;
600
601    PrevDecl = D;
602  }
603
604  // Splice the newly-read declarations into the beginning of the list
605  // of declarations.
606  PrevDecl->NextDeclInContext = FirstDecl;
607  FirstDecl = FirstNewDecl;
608  if (!LastDecl)
609    LastDecl = PrevDecl;
610}
611
612void
613DeclContext::LoadVisibleDeclsFromExternalStorage() const {
614  DeclContext *This = const_cast<DeclContext *>(this);
615  ExternalASTSource *Source = getParentASTContext().getExternalSource();
616  assert(hasExternalVisibleStorage() && Source && "No external storage?");
617
618  llvm::SmallVector<VisibleDeclaration, 64> Decls;
619  if (Source->ReadDeclsVisibleInContext(This, Decls))
620    return;
621
622  // There is no longer any visible storage in this context
623  ExternalVisibleStorage = false;
624
625  // Load the declaration IDs for all of the names visible in this
626  // context.
627  assert(!LookupPtr && "Have a lookup map before de-serialization?");
628  StoredDeclsMap *Map =
629    (StoredDeclsMap*) getParentASTContext().CreateStoredDeclsMap();
630  LookupPtr = Map;
631  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
632    (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
633  }
634}
635
636DeclContext::decl_iterator DeclContext::decls_begin() const {
637  if (hasExternalLexicalStorage())
638    LoadLexicalDeclsFromExternalStorage();
639
640  // FIXME: Check whether we need to load some declarations from
641  // external storage.
642  return decl_iterator(FirstDecl);
643}
644
645DeclContext::decl_iterator DeclContext::decls_end() const {
646  if (hasExternalLexicalStorage())
647    LoadLexicalDeclsFromExternalStorage();
648
649  return decl_iterator();
650}
651
652bool DeclContext::decls_empty() const {
653  if (hasExternalLexicalStorage())
654    LoadLexicalDeclsFromExternalStorage();
655
656  return !FirstDecl;
657}
658
659void DeclContext::removeDecl(Decl *D) {
660  assert(D->getLexicalDeclContext() == this &&
661         "decl being removed from non-lexical context");
662  assert((D->NextDeclInContext || D == LastDecl) &&
663         "decl is not in decls list");
664
665  // Remove D from the decl chain.  This is O(n) but hopefully rare.
666  if (D == FirstDecl) {
667    if (D == LastDecl)
668      FirstDecl = LastDecl = 0;
669    else
670      FirstDecl = D->NextDeclInContext;
671  } else {
672    for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) {
673      assert(I && "decl not found in linked list");
674      if (I->NextDeclInContext == D) {
675        I->NextDeclInContext = D->NextDeclInContext;
676        if (D == LastDecl) LastDecl = I;
677        break;
678      }
679    }
680  }
681
682  // Mark that D is no longer in the decl chain.
683  D->NextDeclInContext = 0;
684
685  // Remove D from the lookup table if necessary.
686  if (isa<NamedDecl>(D)) {
687    NamedDecl *ND = cast<NamedDecl>(D);
688
689    void *OpaqueMap = getPrimaryContext()->LookupPtr;
690    if (!OpaqueMap) return;
691
692    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(OpaqueMap);
693    StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
694    assert(Pos != Map->end() && "no lookup entry for decl");
695    Pos->second.remove(ND);
696  }
697}
698
699void DeclContext::addHiddenDecl(Decl *D) {
700  assert(D->getLexicalDeclContext() == this &&
701         "Decl inserted into wrong lexical context");
702  assert(!D->getNextDeclInContext() && D != LastDecl &&
703         "Decl already inserted into a DeclContext");
704
705  if (FirstDecl) {
706    LastDecl->NextDeclInContext = D;
707    LastDecl = D;
708  } else {
709    FirstDecl = LastDecl = D;
710  }
711}
712
713void DeclContext::addDecl(Decl *D) {
714  addHiddenDecl(D);
715
716  if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
717    ND->getDeclContext()->makeDeclVisibleInContext(ND);
718}
719
720/// buildLookup - Build the lookup data structure with all of the
721/// declarations in DCtx (and any other contexts linked to it or
722/// transparent contexts nested within it).
723void DeclContext::buildLookup(DeclContext *DCtx) {
724  for (; DCtx; DCtx = DCtx->getNextContext()) {
725    for (decl_iterator D = DCtx->decls_begin(),
726                    DEnd = DCtx->decls_end();
727         D != DEnd; ++D) {
728      // Insert this declaration into the lookup structure, but only
729      // if it's semantically in its decl context.  During non-lazy
730      // lookup building, this is implicitly enforced by addDecl.
731      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
732        if (D->getDeclContext() == DCtx)
733          makeDeclVisibleInContextImpl(ND);
734
735      // Insert any forward-declared Objective-C interfaces into the lookup
736      // data structure.
737      if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
738        for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
739             I != IEnd; ++I)
740          makeDeclVisibleInContextImpl(I->getInterface());
741
742      // If this declaration is itself a transparent declaration context,
743      // add its members (recursively).
744      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
745        if (InnerCtx->isTransparentContext())
746          buildLookup(InnerCtx->getPrimaryContext());
747    }
748  }
749}
750
751DeclContext::lookup_result
752DeclContext::lookup(DeclarationName Name) {
753  DeclContext *PrimaryContext = getPrimaryContext();
754  if (PrimaryContext != this)
755    return PrimaryContext->lookup(Name);
756
757  if (hasExternalVisibleStorage())
758    LoadVisibleDeclsFromExternalStorage();
759
760  /// If there is no lookup data structure, build one now by walking
761  /// all of the linked DeclContexts (in declaration order!) and
762  /// inserting their values.
763  if (!LookupPtr) {
764    buildLookup(this);
765
766    if (!LookupPtr)
767      return lookup_result(0, 0);
768  }
769
770  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr);
771  StoredDeclsMap::iterator Pos = Map->find(Name);
772  if (Pos == Map->end())
773    return lookup_result(0, 0);
774  return Pos->second.getLookupResult(getParentASTContext());
775}
776
777DeclContext::lookup_const_result
778DeclContext::lookup(DeclarationName Name) const {
779  return const_cast<DeclContext*>(this)->lookup(Name);
780}
781
782DeclContext *DeclContext::getLookupContext() {
783  DeclContext *Ctx = this;
784  // Skip through transparent contexts.
785  while (Ctx->isTransparentContext())
786    Ctx = Ctx->getParent();
787  return Ctx;
788}
789
790DeclContext *DeclContext::getEnclosingNamespaceContext() {
791  DeclContext *Ctx = this;
792  // Skip through non-namespace, non-translation-unit contexts.
793  while (!Ctx->isFileContext() || Ctx->isTransparentContext())
794    Ctx = Ctx->getParent();
795  return Ctx->getPrimaryContext();
796}
797
798void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
799  // FIXME: This feels like a hack. Should DeclarationName support
800  // template-ids, or is there a better way to keep specializations
801  // from being visible?
802  if (isa<ClassTemplateSpecializationDecl>(D))
803    return;
804  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
805    if (FD->isFunctionTemplateSpecialization())
806      return;
807
808  DeclContext *PrimaryContext = getPrimaryContext();
809  if (PrimaryContext != this) {
810    PrimaryContext->makeDeclVisibleInContext(D, Recoverable);
811    return;
812  }
813
814  // If we already have a lookup data structure, perform the insertion
815  // into it. Otherwise, be lazy and don't build that structure until
816  // someone asks for it.
817  if (LookupPtr || !Recoverable)
818    makeDeclVisibleInContextImpl(D);
819
820  // If we are a transparent context, insert into our parent context,
821  // too. This operation is recursive.
822  if (isTransparentContext())
823    getParent()->makeDeclVisibleInContext(D, Recoverable);
824}
825
826void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
827  // Skip unnamed declarations.
828  if (!D->getDeclName())
829    return;
830
831  // FIXME: This feels like a hack. Should DeclarationName support
832  // template-ids, or is there a better way to keep specializations
833  // from being visible?
834  if (isa<ClassTemplateSpecializationDecl>(D))
835    return;
836
837  ASTContext *C = 0;
838  if (!LookupPtr) {
839    C = &getParentASTContext();
840    LookupPtr = (StoredDeclsMap*) C->CreateStoredDeclsMap();
841  }
842
843  // Insert this declaration into the map.
844  StoredDeclsMap &Map = *static_cast<StoredDeclsMap*>(LookupPtr);
845  StoredDeclsList &DeclNameEntries = Map[D->getDeclName()];
846  if (DeclNameEntries.isNull()) {
847    DeclNameEntries.setOnlyValue(D);
848    return;
849  }
850
851  // If it is possible that this is a redeclaration, check to see if there is
852  // already a decl for which declarationReplaces returns true.  If there is
853  // one, just replace it and return.
854  if (!C)
855    C = &getParentASTContext();
856
857  if (DeclNameEntries.HandleRedeclaration(*C, D))
858    return;
859
860  // Put this declaration into the appropriate slot.
861  DeclNameEntries.AddSubsequentDecl(D);
862}
863
864/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
865/// this context.
866DeclContext::udir_iterator_range
867DeclContext::getUsingDirectives() const {
868  lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
869  return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
870                             reinterpret_cast<udir_iterator>(Result.second));
871}
872
873void StoredDeclsList::materializeDecls(ASTContext &Context) {
874  if (isNull())
875    return;
876
877  switch ((DataKind)(Data & 0x03)) {
878  case DK_Decl:
879  case DK_Decl_Vector:
880    break;
881
882  case DK_DeclID: {
883    // Resolve this declaration ID to an actual declaration by
884    // querying the external AST source.
885    unsigned DeclID = Data >> 2;
886
887    ExternalASTSource *Source = Context.getExternalSource();
888    assert(Source && "No external AST source available!");
889
890    Data = reinterpret_cast<uintptr_t>(Source->GetDecl(DeclID));
891    break;
892  }
893
894  case DK_ID_Vector: {
895    // We have a vector of declaration IDs. Resolve all of them to
896    // actual declarations.
897    VectorTy &Vector = *getAsVector();
898    ExternalASTSource *Source = Context.getExternalSource();
899    assert(Source && "No external AST source available!");
900
901    for (unsigned I = 0, N = Vector.size(); I != N; ++I)
902      Vector[I] = reinterpret_cast<uintptr_t>(Source->GetDecl(Vector[I]));
903
904    Data = (Data & ~0x03) | DK_Decl_Vector;
905    break;
906  }
907  }
908}
909
910//===----------------------------------------------------------------------===//
911// Creation and Destruction of StoredDeclsMaps.                               //
912//===----------------------------------------------------------------------===//
913
914void *ASTContext::CreateStoredDeclsMap() {
915  StoredDeclsMap *M = new StoredDeclsMap();
916  SDMs.push_back(M);
917  return M;
918}
919
920void ASTContext::ReleaseDeclContextMaps() {
921  for (std::vector<void*>::iterator I = SDMs.begin(), E = SDMs.end(); I!=E; ++I)
922    delete (StoredDeclsMap*) *I;
923}
924