DeclBase.cpp revision 77407b802130b1c44b1f63b855722a5376f57bca
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/DeclObjC.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/ASTContext.h"
18#include "llvm/ADT/DenseMap.h"
19using namespace clang;
20
21//===----------------------------------------------------------------------===//
22//  Statistics
23//===----------------------------------------------------------------------===//
24
25// temporary statistics gathering
26static unsigned nFuncs = 0;
27static unsigned nVars = 0;
28static unsigned nParmVars = 0;
29static unsigned nSUC = 0;
30static unsigned nCXXSUC = 0;
31static unsigned nEnumConst = 0;
32static unsigned nEnumDecls = 0;
33static unsigned nNamespaces = 0;
34static unsigned nOverFuncs = 0;
35static unsigned nTypedef = 0;
36static unsigned nFieldDecls = 0;
37static unsigned nCXXFieldDecls = 0;
38static unsigned nInterfaceDecls = 0;
39static unsigned nClassDecls = 0;
40static unsigned nMethodDecls = 0;
41static unsigned nProtocolDecls = 0;
42static unsigned nForwardProtocolDecls = 0;
43static unsigned nCategoryDecls = 0;
44static unsigned nIvarDecls = 0;
45static unsigned nAtDefsFieldDecls = 0;
46static unsigned nObjCImplementationDecls = 0;
47static unsigned nObjCCategoryImpl = 0;
48static unsigned nObjCCompatibleAlias = 0;
49static unsigned nObjCPropertyDecl = 0;
50static unsigned nObjCPropertyImplDecl = 0;
51static unsigned nLinkageSpecDecl = 0;
52static unsigned nFileScopeAsmDecl = 0;
53static unsigned nBlockDecls = 0;
54
55static bool StatSwitch = false;
56
57// This keeps track of all decl attributes. Since so few decls have attrs, we
58// keep them in a hash map instead of wasting space in the Decl class.
59typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
60
61static DeclAttrMapTy *DeclAttrs = 0;
62
63const char *Decl::getDeclKindName() const {
64  switch (DeclKind) {
65  default: assert(0 && "Unknown decl kind!");
66  case Namespace:           return "Namespace";
67  case OverloadedFunction:  return "OverloadedFunction";
68  case Typedef:             return "Typedef";
69  case Function:            return "Function";
70  case Var:                 return "Var";
71  case ParmVar:             return "ParmVar";
72  case EnumConstant:        return "EnumConstant";
73  case ObjCIvar:            return "ObjCIvar";
74  case ObjCInterface:       return "ObjCInterface";
75  case ObjCClass:           return "ObjCClass";
76  case ObjCMethod:          return "ObjCMethod";
77  case ObjCProtocol:        return "ObjCProtocol";
78  case ObjCForwardProtocol: return "ObjCForwardProtocol";
79  case Record:              return "Record";
80  case CXXRecord:           return "CXXRecord";
81  case Enum:                return "Enum";
82  case Block:               return "Block";
83  }
84}
85
86bool Decl::CollectingStats(bool Enable) {
87  if (Enable)
88    StatSwitch = true;
89  return StatSwitch;
90}
91
92void Decl::PrintStats() {
93  fprintf(stderr, "*** Decl Stats:\n");
94  fprintf(stderr, "  %d decls total.\n",
95          int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXFieldDecls+nCXXSUC+
96              nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
97              nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
98              nAtDefsFieldDecls+nNamespaces+nOverFuncs));
99  fprintf(stderr, "    %d namespace decls, %d each (%d bytes)\n",
100          nNamespaces, (int)sizeof(NamespaceDecl),
101          int(nNamespaces*sizeof(NamespaceDecl)));
102  fprintf(stderr, "    %d overloaded function decls, %d each (%d bytes)\n",
103          nOverFuncs, (int)sizeof(OverloadedFunctionDecl),
104          int(nOverFuncs*sizeof(OverloadedFunctionDecl)));
105  fprintf(stderr, "    %d function decls, %d each (%d bytes)\n",
106          nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
107  fprintf(stderr, "    %d variable decls, %d each (%d bytes)\n",
108          nVars, (int)sizeof(VarDecl),
109          int(nVars*sizeof(VarDecl)));
110  fprintf(stderr, "    %d parameter variable decls, %d each (%d bytes)\n",
111          nParmVars, (int)sizeof(ParmVarDecl),
112          int(nParmVars*sizeof(ParmVarDecl)));
113  fprintf(stderr, "    %d field decls, %d each (%d bytes)\n",
114          nFieldDecls, (int)sizeof(FieldDecl),
115          int(nFieldDecls*sizeof(FieldDecl)));
116  fprintf(stderr, "    %d @defs generated field decls, %d each (%d bytes)\n",
117          nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl),
118          int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl)));
119  fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n",
120          nSUC, (int)sizeof(RecordDecl),
121          int(nSUC*sizeof(RecordDecl)));
122  fprintf(stderr, "    %d C++ field decls, %d each (%d bytes)\n",
123          nCXXFieldDecls, (int)sizeof(CXXFieldDecl),
124          int(nCXXFieldDecls*sizeof(CXXFieldDecl)));
125  fprintf(stderr, "    %d C++ struct/union/class decls, %d each (%d bytes)\n",
126          nCXXSUC, (int)sizeof(CXXRecordDecl),
127          int(nCXXSUC*sizeof(CXXRecordDecl)));
128  fprintf(stderr, "    %d enum decls, %d each (%d bytes)\n",
129          nEnumDecls, (int)sizeof(EnumDecl),
130          int(nEnumDecls*sizeof(EnumDecl)));
131  fprintf(stderr, "    %d enum constant decls, %d each (%d bytes)\n",
132          nEnumConst, (int)sizeof(EnumConstantDecl),
133          int(nEnumConst*sizeof(EnumConstantDecl)));
134  fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n",
135          nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
136  // Objective-C decls...
137  fprintf(stderr, "    %d interface decls, %d each (%d bytes)\n",
138          nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
139          int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
140  fprintf(stderr, "    %d instance variable decls, %d each (%d bytes)\n",
141          nIvarDecls, (int)sizeof(ObjCIvarDecl),
142          int(nIvarDecls*sizeof(ObjCIvarDecl)));
143  fprintf(stderr, "    %d class decls, %d each (%d bytes)\n",
144          nClassDecls, (int)sizeof(ObjCClassDecl),
145          int(nClassDecls*sizeof(ObjCClassDecl)));
146  fprintf(stderr, "    %d method decls, %d each (%d bytes)\n",
147          nMethodDecls, (int)sizeof(ObjCMethodDecl),
148          int(nMethodDecls*sizeof(ObjCMethodDecl)));
149  fprintf(stderr, "    %d protocol decls, %d each (%d bytes)\n",
150          nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
151          int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
152  fprintf(stderr, "    %d forward protocol decls, %d each (%d bytes)\n",
153          nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
154          int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
155  fprintf(stderr, "    %d category decls, %d each (%d bytes)\n",
156          nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
157          int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
158
159  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
160          nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
161          int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
162
163  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
164          nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
165          int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
166
167  fprintf(stderr, "    %d compatibility alias decls, %d each (%d bytes)\n",
168          nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
169          int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
170
171  fprintf(stderr, "    %d property decls, %d each (%d bytes)\n",
172          nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
173          int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
174
175  fprintf(stderr, "    %d property implementation decls, %d each (%d bytes)\n",
176          nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
177          int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
178
179  fprintf(stderr, "Total bytes = %d\n",
180          int(nFuncs*sizeof(FunctionDecl)+
181              nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
182              nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
183              nCXXFieldDecls*sizeof(CXXFieldDecl)+nCXXSUC*sizeof(CXXRecordDecl)+
184              nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
185              nTypedef*sizeof(TypedefDecl)+
186              nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
187              nIvarDecls*sizeof(ObjCIvarDecl)+
188              nClassDecls*sizeof(ObjCClassDecl)+
189              nMethodDecls*sizeof(ObjCMethodDecl)+
190              nProtocolDecls*sizeof(ObjCProtocolDecl)+
191              nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
192              nCategoryDecls*sizeof(ObjCCategoryDecl)+
193              nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
194              nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
195              nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
196              nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
197              nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
198              nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
199              nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
200              nNamespaces*sizeof(NamespaceDecl)+
201              nOverFuncs*sizeof(OverloadedFunctionDecl)));
202
203}
204
205void Decl::addDeclKind(Kind k) {
206  switch (k) {
207  case Namespace:           nNamespaces++; break;
208  case OverloadedFunction:  nOverFuncs++; break;
209  case Typedef:             nTypedef++; break;
210  case Function:            nFuncs++; break;
211  case Var:                 nVars++; break;
212  case ParmVar:             nParmVars++; break;
213  case EnumConstant:        nEnumConst++; break;
214  case Field:               nFieldDecls++; break;
215  case Record:              nSUC++; break;
216  case Enum:                nEnumDecls++; break;
217  case ObjCInterface:       nInterfaceDecls++; break;
218  case ObjCClass:           nClassDecls++; break;
219  case ObjCMethod:          nMethodDecls++; break;
220  case ObjCProtocol:        nProtocolDecls++; break;
221  case ObjCForwardProtocol: nForwardProtocolDecls++; break;
222  case ObjCCategory:        nCategoryDecls++; break;
223  case ObjCIvar:            nIvarDecls++; break;
224  case ObjCAtDefsField:     nAtDefsFieldDecls++; break;
225  case ObjCImplementation:  nObjCImplementationDecls++; break;
226  case ObjCCategoryImpl:    nObjCCategoryImpl++; break;
227  case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
228  case ObjCProperty:        nObjCPropertyDecl++; break;
229  case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
230  case LinkageSpec:         nLinkageSpecDecl++; break;
231  case FileScopeAsm:        nFileScopeAsmDecl++; break;
232  case Block:               nBlockDecls++; break;
233  case ImplicitParam:
234  case TranslationUnit:     break;
235
236  case CXXField:            nCXXFieldDecls++; break;
237  case CXXRecord:           nCXXSUC++; break;
238  // FIXME: Statistics for C++ decls.
239  case CXXMethod:
240  case CXXConstructor:
241  case CXXDestructor:
242  case CXXConversion:
243  case CXXClassVar:
244    break;
245  }
246}
247
248//===----------------------------------------------------------------------===//
249// Decl Implementation
250//===----------------------------------------------------------------------===//
251
252// Out-of-line virtual method providing a home for Decl.
253Decl::~Decl() {
254  if (!HasAttrs)
255    return;
256
257  DeclAttrMapTy::iterator it = DeclAttrs->find(this);
258  assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
259
260  // release attributes.
261  delete it->second;
262  invalidateAttrs();
263}
264
265void Decl::addAttr(Attr *NewAttr) {
266  if (!DeclAttrs)
267    DeclAttrs = new DeclAttrMapTy();
268
269  Attr *&ExistingAttr = (*DeclAttrs)[this];
270
271  NewAttr->setNext(ExistingAttr);
272  ExistingAttr = NewAttr;
273
274  HasAttrs = true;
275}
276
277void Decl::invalidateAttrs() {
278  if (!HasAttrs) return;
279
280  HasAttrs = false;
281  (*DeclAttrs)[this] = 0;
282  DeclAttrs->erase(this);
283
284  if (DeclAttrs->empty()) {
285    delete DeclAttrs;
286    DeclAttrs = 0;
287  }
288}
289
290const Attr *Decl::getAttrs() const {
291  if (!HasAttrs)
292    return 0;
293
294  return (*DeclAttrs)[this];
295}
296
297void Decl::swapAttrs(Decl *RHS) {
298  bool HasLHSAttr = this->HasAttrs;
299  bool HasRHSAttr = RHS->HasAttrs;
300
301  // Usually, neither decl has attrs, nothing to do.
302  if (!HasLHSAttr && !HasRHSAttr) return;
303
304  // If 'this' has no attrs, swap the other way.
305  if (!HasLHSAttr)
306    return RHS->swapAttrs(this);
307
308  // Handle the case when both decls have attrs.
309  if (HasRHSAttr) {
310    std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
311    return;
312  }
313
314  // Otherwise, LHS has an attr and RHS doesn't.
315  (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
316  (*DeclAttrs).erase(this);
317  this->HasAttrs = false;
318  RHS->HasAttrs = true;
319}
320
321
322void Decl::Destroy(ASTContext& C) {
323
324  if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
325
326    // Observe the unrolled recursion.  By setting N->NextDeclarator = 0x0
327    // within the loop, only the Destroy method for the first ScopedDecl
328    // will deallocate all of the ScopedDecls in a chain.
329
330    ScopedDecl* N = SD->getNextDeclarator();
331
332    while (N) {
333      ScopedDecl* Tmp = N->getNextDeclarator();
334      N->NextDeclarator = 0x0;
335      N->Destroy(C);
336      N = Tmp;
337    }
338  }
339
340  this->~Decl();
341  C.getAllocator().Deallocate((void *)this);
342}
343
344Decl *Decl::castFromDeclContext (const DeclContext *D) {
345  return DeclContext::CastTo<Decl>(D);
346}
347
348DeclContext *Decl::castToDeclContext(const Decl *D) {
349  return DeclContext::CastTo<DeclContext>(D);
350}
351
352//===----------------------------------------------------------------------===//
353// DeclContext Implementation
354//===----------------------------------------------------------------------===//
355
356const DeclContext *DeclContext::getParent() const {
357  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
358    return SD->getDeclContext();
359  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
360    return BD->getParentContext();
361  else
362    return NULL;
363}
364
365const DeclContext *DeclContext::getLexicalParent() const {
366  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
367    return SD->getLexicalDeclContext();
368  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
369    return BD->getParentContext();
370  else
371    return NULL;
372}
373