DeclBase.cpp revision 7f0be13b435ad110f99af83a24a50f43225f3083
1//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Decl and DeclContext classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclBase.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/ASTContext.h"
20#include "clang/AST/Type.h"
21#include "llvm/ADT/DenseMap.h"
22#include <algorithm>
23#include <functional>
24#include <vector>
25using namespace clang;
26
27//===----------------------------------------------------------------------===//
28//  Statistics
29//===----------------------------------------------------------------------===//
30
31#define DECL(Derived, Base) static int n##Derived##s = 0;
32#include "clang/AST/DeclNodes.def"
33
34static bool StatSwitch = false;
35
36// This keeps track of all decl attributes. Since so few decls have attrs, we
37// keep them in a hash map instead of wasting space in the Decl class.
38typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
39
40static DeclAttrMapTy *DeclAttrs = 0;
41
42const char *Decl::getDeclKindName() const {
43  switch (DeclKind) {
44  default: assert(0 && "Declaration not in DeclNodes.def!");
45#define DECL(Derived, Base) case Derived: return #Derived;
46#include "clang/AST/DeclNodes.def"
47  }
48}
49
50const char *DeclContext::getDeclKindName() const {
51  switch (DeclKind) {
52  default: assert(0 && "Declaration context not in DeclNodes.def!");
53#define DECL(Derived, Base) case Decl::Derived: return #Derived;
54#include "clang/AST/DeclNodes.def"
55  }
56}
57
58bool Decl::CollectingStats(bool Enable) {
59  if (Enable)
60    StatSwitch = true;
61  return StatSwitch;
62}
63
64void Decl::PrintStats() {
65  fprintf(stderr, "*** Decl Stats:\n");
66
67  int totalDecls = 0;
68#define DECL(Derived, Base) totalDecls += n##Derived##s;
69#include "clang/AST/DeclNodes.def"
70  fprintf(stderr, "  %d decls total.\n", totalDecls);
71
72  int totalBytes = 0;
73#define DECL(Derived, Base)                                             \
74  if (n##Derived##s > 0) {                                              \
75    totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl));         \
76    fprintf(stderr, "    %d " #Derived " decls, %d each (%d bytes)\n",  \
77            n##Derived##s, (int)sizeof(Derived##Decl),                  \
78            (int)(n##Derived##s * sizeof(Derived##Decl)));              \
79  }
80#include "clang/AST/DeclNodes.def"
81
82  fprintf(stderr, "Total bytes = %d\n", totalBytes);
83}
84
85void Decl::addDeclKind(Kind k) {
86  switch (k) {
87  default: assert(0 && "Declaration not in DeclNodes.def!");
88#define DECL(Derived, Base) case Derived: ++n##Derived##s; break;
89#include "clang/AST/DeclNodes.def"
90  }
91}
92
93//===----------------------------------------------------------------------===//
94// Decl Implementation
95//===----------------------------------------------------------------------===//
96
97void Decl::setDeclContext(DeclContext *DC) {
98  if (isOutOfSemaDC())
99    delete getMultipleDC();
100
101  DeclCtx = reinterpret_cast<uintptr_t>(DC);
102}
103
104void Decl::setLexicalDeclContext(DeclContext *DC) {
105  if (DC == getLexicalDeclContext())
106    return;
107
108  if (isInSemaDC()) {
109    MultipleDC *MDC = new MultipleDC();
110    MDC->SemanticDC = getDeclContext();
111    MDC->LexicalDC = DC;
112    DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1;
113  } else {
114    getMultipleDC()->LexicalDC = DC;
115  }
116}
117
118// Out-of-line virtual method providing a home for Decl.
119Decl::~Decl() {
120  if (isOutOfSemaDC())
121    delete getMultipleDC();
122
123  if (!HasAttrs)
124    return;
125
126  DeclAttrMapTy::iterator it = DeclAttrs->find(this);
127  assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
128
129  // release attributes.
130  delete it->second;
131  invalidateAttrs();
132}
133
134void Decl::addAttr(Attr *NewAttr) {
135  if (!DeclAttrs)
136    DeclAttrs = new DeclAttrMapTy();
137
138  Attr *&ExistingAttr = (*DeclAttrs)[this];
139
140  NewAttr->setNext(ExistingAttr);
141  ExistingAttr = NewAttr;
142
143  HasAttrs = true;
144}
145
146void Decl::invalidateAttrs() {
147  if (!HasAttrs) return;
148
149  HasAttrs = false;
150  (*DeclAttrs)[this] = 0;
151  DeclAttrs->erase(this);
152
153  if (DeclAttrs->empty()) {
154    delete DeclAttrs;
155    DeclAttrs = 0;
156  }
157}
158
159const Attr *Decl::getAttrs() const {
160  if (!HasAttrs)
161    return 0;
162
163  return (*DeclAttrs)[this];
164}
165
166void Decl::swapAttrs(Decl *RHS) {
167  bool HasLHSAttr = this->HasAttrs;
168  bool HasRHSAttr = RHS->HasAttrs;
169
170  // Usually, neither decl has attrs, nothing to do.
171  if (!HasLHSAttr && !HasRHSAttr) return;
172
173  // If 'this' has no attrs, swap the other way.
174  if (!HasLHSAttr)
175    return RHS->swapAttrs(this);
176
177  // Handle the case when both decls have attrs.
178  if (HasRHSAttr) {
179    std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
180    return;
181  }
182
183  // Otherwise, LHS has an attr and RHS doesn't.
184  (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
185  (*DeclAttrs).erase(this);
186  this->HasAttrs = false;
187  RHS->HasAttrs = true;
188}
189
190
191void Decl::Destroy(ASTContext& C) {
192#if 0
193  // FIXME: Once ownership is fully understood, we can enable this code
194  if (DeclContext *DC = dyn_cast<DeclContext>(this))
195    DC->decls_begin()->Destroy(C);
196
197  // Observe the unrolled recursion.  By setting N->NextDeclInScope = 0x0
198  // within the loop, only the Destroy method for the first Decl
199  // will deallocate all of the Decls in a chain.
200
201  Decl* N = NextDeclInScope;
202
203  while (N) {
204    Decl* Tmp = N->NextDeclInScope;
205    N->NextDeclInScope = 0;
206    N->Destroy(C);
207    N = Tmp;
208  }
209
210  this->~Decl();
211  C.Deallocate((void *)this);
212#endif
213}
214
215Decl *Decl::castFromDeclContext (const DeclContext *D) {
216  Decl::Kind DK = D->getDeclKind();
217  switch(DK) {
218#define DECL_CONTEXT(Name) \
219    case Decl::Name:     \
220      return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
221#define DECL_CONTEXT_BASE(Name)
222#include "clang/AST/DeclNodes.def"
223    default:
224#define DECL_CONTEXT_BASE(Name)                                   \
225      if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
226        return static_cast<Name##Decl*>(const_cast<DeclContext*>(D));
227#include "clang/AST/DeclNodes.def"
228      assert(false && "a decl that inherits DeclContext isn't handled");
229      return 0;
230  }
231}
232
233DeclContext *Decl::castToDeclContext(const Decl *D) {
234  Decl::Kind DK = D->getKind();
235  switch(DK) {
236#define DECL_CONTEXT(Name) \
237    case Decl::Name:     \
238      return static_cast<Name##Decl*>(const_cast<Decl*>(D));
239#define DECL_CONTEXT_BASE(Name)
240#include "clang/AST/DeclNodes.def"
241    default:
242#define DECL_CONTEXT_BASE(Name)                                   \
243      if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
244        return static_cast<Name##Decl*>(const_cast<Decl*>(D));
245#include "clang/AST/DeclNodes.def"
246      assert(false && "a decl that inherits DeclContext isn't handled");
247      return 0;
248  }
249}
250
251//===----------------------------------------------------------------------===//
252// DeclContext Implementation
253//===----------------------------------------------------------------------===//
254
255bool DeclContext::classof(const Decl *D) {
256  switch (D->getKind()) {
257#define DECL_CONTEXT(Name) case Decl::Name:
258#define DECL_CONTEXT_BASE(Name)
259#include "clang/AST/DeclNodes.def"
260      return true;
261    default:
262#define DECL_CONTEXT_BASE(Name)                   \
263      if (D->getKind() >= Decl::Name##First &&  \
264          D->getKind() <= Decl::Name##Last)     \
265        return true;
266#include "clang/AST/DeclNodes.def"
267      return false;
268  }
269}
270
271// FIXME: We really want to use a DenseSet here to eliminate the
272// redundant storage of the declaration names, but (1) it doesn't give
273// us the ability to search based on DeclarationName, (2) we really
274// need something more like a DenseMultiSet, and (3) it's
275// implemented in terms of DenseMap anyway. However, this data
276// structure is really space-inefficient, so we'll have to do
277// something.
278typedef llvm::DenseMap<DeclarationName, std::vector<NamedDecl*> >
279  StoredDeclsMap;
280
281DeclContext::~DeclContext() {
282  unsigned Size = LookupPtr.getInt();
283  if (Size == LookupIsMap)
284    delete static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
285  else
286    delete [] static_cast<NamedDecl**>(LookupPtr.getPointer());
287}
288
289void DeclContext::DestroyDecls(ASTContext &C) {
290  for (decl_iterator D = decls_begin(); D != decls_end(); )
291    (*D++)->Destroy(C);
292}
293
294bool DeclContext::isTransparentContext() const {
295  if (DeclKind == Decl::Enum)
296    return true; // FIXME: Check for C++0x scoped enums
297  else if (DeclKind == Decl::LinkageSpec)
298    return true;
299  else if (DeclKind == Decl::Record || DeclKind == Decl::CXXRecord)
300    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
301  else if (DeclKind == Decl::Namespace)
302    return false; // FIXME: Check for C++0x inline namespaces
303
304  return false;
305}
306
307DeclContext *DeclContext::getPrimaryContext() {
308  switch (DeclKind) {
309  case Decl::TranslationUnit:
310  case Decl::LinkageSpec:
311  case Decl::Block:
312    // There is only one DeclContext for these entities.
313    return this;
314
315  case Decl::Namespace:
316    // The original namespace is our primary context.
317    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
318
319  case Decl::ObjCMethod:
320    return this;
321
322  case Decl::ObjCInterface:
323  case Decl::ObjCProtocol:
324  case Decl::ObjCCategory:
325    // FIXME: Can Objective-C interfaces be forward-declared?
326    return this;
327
328  case Decl::ObjCImplementation:
329  case Decl::ObjCCategoryImpl:
330    return this;
331
332  default:
333    if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
334      // If this is a tag type that has a definition or is currently
335      // being defined, that definition is our primary context.
336      if (TagType *TagT
337            = cast_or_null<TagType>(cast<TagDecl>(this)->TypeForDecl))
338        if (TagT->isBeingDefined() ||
339            (TagT->getDecl() && TagT->getDecl()->isDefinition()))
340          return TagT->getDecl();
341      return this;
342    }
343
344    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
345          "Unknown DeclContext kind");
346    return this;
347  }
348}
349
350DeclContext *DeclContext::getNextContext() {
351  switch (DeclKind) {
352  case Decl::Namespace:
353    // Return the next namespace
354    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
355
356  default:
357    return 0;
358  }
359}
360
361void DeclContext::addDecl(Decl *D) {
362  assert(D->getLexicalDeclContext() == this &&
363         "Decl inserted into wrong lexical context");
364  assert(!D->NextDeclInScope && D != LastDecl &&
365         "Decl already inserted into a DeclContext");
366
367  if (FirstDecl) {
368    LastDecl->NextDeclInScope = D;
369    LastDecl = D;
370  } else {
371    FirstDecl = LastDecl = D;
372  }
373
374  if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
375    ND->getDeclContext()->makeDeclVisibleInContext(ND);
376}
377
378/// buildLookup - Build the lookup data structure with all of the
379/// declarations in DCtx (and any other contexts linked to it or
380/// transparent contexts nested within it).
381void DeclContext::buildLookup(DeclContext *DCtx) {
382  for (; DCtx; DCtx = DCtx->getNextContext()) {
383    for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end();
384         D != DEnd; ++D) {
385      // Insert this declaration into the lookup structure
386      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
387        makeDeclVisibleInContextImpl(ND);
388
389      // If this declaration is itself a transparent declaration context,
390      // add its members (recursively).
391      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
392        if (InnerCtx->isTransparentContext())
393          buildLookup(InnerCtx->getPrimaryContext());
394    }
395  }
396}
397
398DeclContext::lookup_result
399DeclContext::lookup(DeclarationName Name) {
400  DeclContext *PrimaryContext = getPrimaryContext();
401  if (PrimaryContext != this)
402    return PrimaryContext->lookup(Name);
403
404  /// If there is no lookup data structure, build one now by walking
405  /// all of the linked DeclContexts (in declaration order!) and
406  /// inserting their values.
407  if (LookupPtr.getPointer() == 0)
408    buildLookup(this);
409
410  if (isLookupMap()) {
411    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
412    StoredDeclsMap::iterator Pos = Map->find(Name);
413    if (Pos == Map->end())
414      return lookup_result(0, 0);
415
416    return lookup_result(&Pos->second.front(),
417                         &Pos->second.front() + Pos->second.size());
418  }
419
420  // We have a small array. Look into it.
421  unsigned Size = LookupPtr.getInt();
422  NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
423  for (unsigned Idx = 0; Idx != Size; ++Idx)
424    if (Array[Idx]->getDeclName() == Name) {
425      unsigned Last = Idx + 1;
426      while (Last != Size && Array[Last]->getDeclName() == Name)
427        ++Last;
428      return lookup_result(&Array[Idx], &Array[Last]);
429    }
430
431  return lookup_result(0, 0);
432}
433
434DeclContext::lookup_const_result
435DeclContext::lookup(DeclarationName Name) const {
436  return const_cast<DeclContext*>(this)->lookup(Name);
437}
438
439const DeclContext *DeclContext::getLookupContext() const {
440  const DeclContext *Ctx = this;
441  // Skip through transparent contexts.
442  while (Ctx->isTransparentContext())
443    Ctx = Ctx->getParent();
444  return Ctx;
445}
446
447void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
448  // FIXME: This feels like a hack. Should DeclarationName support
449  // template-ids, or is there a better way to keep specializations
450  // from being visible?
451  if (isa<ClassTemplateSpecializationDecl>(D))
452    return;
453
454  DeclContext *PrimaryContext = getPrimaryContext();
455  if (PrimaryContext != this) {
456    PrimaryContext->makeDeclVisibleInContext(D);
457    return;
458  }
459
460  // If we already have a lookup data structure, perform the insertion
461  // into it. Otherwise, be lazy and don't build that structure until
462  // someone asks for it.
463  if (LookupPtr.getPointer())
464    makeDeclVisibleInContextImpl(D);
465
466  // If we are a transparent context, insert into our parent context,
467  // too. This operation is recursive.
468  if (isTransparentContext())
469    getParent()->makeDeclVisibleInContext(D);
470}
471
472void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
473  // Skip unnamed declarations.
474  if (!D->getDeclName())
475    return;
476
477  // FIXME: This feels like a hack. Should DeclarationName support
478  // template-ids, or is there a better way to keep specializations
479  // from being visible?
480  if (isa<ClassTemplateSpecializationDecl>(D))
481    return;
482
483  bool MayBeRedeclaration = true;
484
485  if (!isLookupMap()) {
486    unsigned Size = LookupPtr.getInt();
487
488    // The lookup data is stored as an array. Search through the array
489    // to find the insertion location.
490    NamedDecl **Array;
491    if (Size == 0) {
492      Array = new NamedDecl*[LookupIsMap - 1];
493      LookupPtr.setPointer(Array);
494    } else {
495      Array = static_cast<NamedDecl **>(LookupPtr.getPointer());
496    }
497
498    // We always keep declarations of the same name next to each other
499    // in the array, so that it is easy to return multiple results
500    // from lookup().
501    unsigned FirstMatch;
502    for (FirstMatch = 0; FirstMatch != Size; ++FirstMatch)
503      if (Array[FirstMatch]->getDeclName() == D->getDeclName())
504        break;
505
506    unsigned InsertPos = FirstMatch;
507    if (FirstMatch != Size) {
508      // We found another declaration with the same name. First
509      // determine whether this is a redeclaration of an existing
510      // declaration in this scope, in which case we will replace the
511      // existing declaration.
512      unsigned LastMatch = FirstMatch;
513      for (; LastMatch != Size; ++LastMatch) {
514        if (Array[LastMatch]->getDeclName() != D->getDeclName())
515          break;
516
517        if (D->declarationReplaces(Array[LastMatch])) {
518          // D is a redeclaration of an existing element in the
519          // array. Replace that element with D.
520          Array[LastMatch] = D;
521          return;
522        }
523      }
524
525      // [FirstMatch, LastMatch) contains the set of declarations that
526      // have the same name as this declaration. Determine where the
527      // declaration D will be inserted into this range.
528      if (D->getKind() == Decl::UsingDirective ||
529          D->getIdentifierNamespace() == Decl::IDNS_Tag)
530        InsertPos = LastMatch;
531      else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag)
532        InsertPos = LastMatch - 1;
533      else
534        InsertPos = LastMatch;
535    }
536
537    if (Size < LookupIsMap - 1) {
538      // The new declaration will fit in the array. Insert the new
539      // declaration at the position Match in the array.
540      for (unsigned Idx = Size; Idx > InsertPos; --Idx)
541       Array[Idx] = Array[Idx-1];
542
543      Array[InsertPos] = D;
544      LookupPtr.setInt(Size + 1);
545      return;
546    }
547
548    // We've reached capacity in this array. Create a map and copy in
549    // all of the declarations that were stored in the array.
550    StoredDeclsMap *Map = new StoredDeclsMap(16);
551    LookupPtr.setPointer(Map);
552    LookupPtr.setInt(LookupIsMap);
553    for (unsigned Idx = 0; Idx != LookupIsMap - 1; ++Idx)
554      makeDeclVisibleInContextImpl(Array[Idx]);
555    delete [] Array;
556
557    // Fall through to perform insertion into the map.
558    MayBeRedeclaration = false;
559  }
560
561  // Insert this declaration into the map.
562  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
563  std::vector<NamedDecl *> &DeclNameEntries = (*Map)[D->getDeclName()];
564  if (DeclNameEntries.empty()) {
565    DeclNameEntries.push_back(D);
566    return;
567  }
568
569  if (MayBeRedeclaration) {
570    // Determine if this declaration is actually a redeclaration.
571    std::vector<NamedDecl *>::iterator Redecl
572      = std::find_if(DeclNameEntries.begin(), DeclNameEntries.end(),
573                   std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
574                                D));
575    if (Redecl != DeclNameEntries.end()) {
576      *Redecl = D;
577      return;
578    }
579  }
580
581  // Put this declaration into the appropriate slot.
582  if (isa<UsingDirectiveDecl>(D) ||
583      D->getIdentifierNamespace() == Decl::IDNS_Tag)
584    DeclNameEntries.push_back(D);
585  else if (DeclNameEntries.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
586    NamedDecl *TagD = DeclNameEntries.back();
587    DeclNameEntries.back() = D;
588    DeclNameEntries.push_back(TagD);
589  } else
590    DeclNameEntries.push_back(D);
591}
592
593/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
594/// this context.
595DeclContext::udir_iterator_range DeclContext::getUsingDirectives() const {
596  lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
597  return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
598                             reinterpret_cast<udir_iterator>(Result.second));
599}
600
601