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