Decl.cpp revision f009795057dc8ca254f5618c80a0a90f07cd44b4
1//===--- Decl.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 class and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Decl.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Attr.h"
17#include "clang/Basic/IdentifierTable.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 nEnumConst = 0;
31static unsigned nEnumDecls = 0;
32static unsigned nTypedef = 0;
33static unsigned nFieldDecls = 0;
34static unsigned nInterfaceDecls = 0;
35static unsigned nClassDecls = 0;
36static unsigned nMethodDecls = 0;
37static unsigned nProtocolDecls = 0;
38static unsigned nForwardProtocolDecls = 0;
39static unsigned nCategoryDecls = 0;
40static unsigned nIvarDecls = 0;
41static unsigned nObjCImplementationDecls = 0;
42static unsigned nObjCCategoryImpl = 0;
43static unsigned nObjCCompatibleAlias = 0;
44static unsigned nObjCPropertyDecl = 0;
45static unsigned nObjCPropertyImplDecl = 0;
46static unsigned nLinkageSpecDecl = 0;
47static unsigned nFileScopeAsmDecl = 0;
48
49static bool StatSwitch = false;
50
51// This keeps track of all decl attributes. Since so few decls have attrs, we
52// keep them in a hash map instead of wasting space in the Decl class.
53typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
54
55static DeclAttrMapTy *DeclAttrs = 0;
56
57const char *Decl::getDeclKindName() const {
58  switch (DeclKind) {
59  default: assert(0 && "Unknown decl kind!");
60  case Typedef:             return "Typedef";
61  case Function:            return "Function";
62  case Var:                 return "Var";
63  case ParmVar:             return "ParmVar";
64  case EnumConstant:        return "EnumConstant";
65  case ObjCInterface:       return "ObjCInterface";
66  case ObjCClass:           return "ObjCClass";
67  case ObjCMethod:          return "ObjCMethod";
68  case ObjCProtocol:        return "ObjCProtocol";
69  case ObjCForwardProtocol: return "ObjCForwardProtocol";
70  case Struct:              return "Struct";
71  case Union:               return "Union";
72  case Class:               return "Class";
73  case Enum:                return "Enum";
74  }
75}
76
77bool Decl::CollectingStats(bool Enable) {
78  if (Enable)
79    StatSwitch = true;
80  return StatSwitch;
81}
82
83void Decl::PrintStats() {
84  fprintf(stderr, "*** Decl Stats:\n");
85  fprintf(stderr, "  %d decls total.\n",
86          int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+
87              nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
88              nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls));
89  fprintf(stderr, "    %d function decls, %d each (%d bytes)\n",
90          nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
91  fprintf(stderr, "    %d variable decls, %d each (%d bytes)\n",
92          nVars, (int)sizeof(VarDecl),
93          int(nVars*sizeof(VarDecl)));
94  fprintf(stderr, "    %d parameter variable decls, %d each (%d bytes)\n",
95          nParmVars, (int)sizeof(ParmVarDecl),
96          int(nParmVars*sizeof(ParmVarDecl)));
97  fprintf(stderr, "    %d field decls, %d each (%d bytes)\n",
98          nFieldDecls, (int)sizeof(FieldDecl),
99          int(nFieldDecls*sizeof(FieldDecl)));
100  fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n",
101          nSUC, (int)sizeof(RecordDecl),
102          int(nSUC*sizeof(RecordDecl)));
103  fprintf(stderr, "    %d enum decls, %d each (%d bytes)\n",
104          nEnumDecls, (int)sizeof(EnumDecl),
105          int(nEnumDecls*sizeof(EnumDecl)));
106  fprintf(stderr, "    %d enum constant decls, %d each (%d bytes)\n",
107          nEnumConst, (int)sizeof(EnumConstantDecl),
108          int(nEnumConst*sizeof(EnumConstantDecl)));
109  fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n",
110          nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
111  // Objective-C decls...
112  fprintf(stderr, "    %d interface decls, %d each (%d bytes)\n",
113          nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
114          int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
115  fprintf(stderr, "    %d instance variable decls, %d each (%d bytes)\n",
116          nIvarDecls, (int)sizeof(ObjCIvarDecl),
117          int(nIvarDecls*sizeof(ObjCIvarDecl)));
118  fprintf(stderr, "    %d class decls, %d each (%d bytes)\n",
119          nClassDecls, (int)sizeof(ObjCClassDecl),
120          int(nClassDecls*sizeof(ObjCClassDecl)));
121  fprintf(stderr, "    %d method decls, %d each (%d bytes)\n",
122          nMethodDecls, (int)sizeof(ObjCMethodDecl),
123          int(nMethodDecls*sizeof(ObjCMethodDecl)));
124  fprintf(stderr, "    %d protocol decls, %d each (%d bytes)\n",
125          nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
126          int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
127  fprintf(stderr, "    %d forward protocol decls, %d each (%d bytes)\n",
128          nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
129          int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
130  fprintf(stderr, "    %d category decls, %d each (%d bytes)\n",
131          nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
132          int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
133
134  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
135          nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
136          int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
137
138  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
139          nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
140          int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
141
142  fprintf(stderr, "    %d compatibility alias decls, %d each (%d bytes)\n",
143          nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
144          int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
145
146  fprintf(stderr, "    %d property decls, %d each (%d bytes)\n",
147          nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
148          int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
149
150  fprintf(stderr, "    %d property implementation decls, %d each (%d bytes)\n",
151          nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
152          int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
153
154  fprintf(stderr, "Total bytes = %d\n",
155          int(nFuncs*sizeof(FunctionDecl)+
156              nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
157              nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
158              nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
159              nTypedef*sizeof(TypedefDecl)+
160              nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
161              nIvarDecls*sizeof(ObjCIvarDecl)+
162              nClassDecls*sizeof(ObjCClassDecl)+
163              nMethodDecls*sizeof(ObjCMethodDecl)+
164              nProtocolDecls*sizeof(ObjCProtocolDecl)+
165              nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
166              nCategoryDecls*sizeof(ObjCCategoryDecl)+
167              nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
168              nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
169              nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
170              nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
171              nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
172              nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
173              nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)));
174
175}
176
177void Decl::addDeclKind(Kind k) {
178  switch (k) {
179  case Typedef:             nTypedef++; break;
180  case Function:            nFuncs++; break;
181  case Var:                 nVars++; break;
182  case ParmVar:             nParmVars++; break;
183  case EnumConstant:        nEnumConst++; break;
184  case Field:               nFieldDecls++; break;
185  case Struct: case Union: case Class: nSUC++; break;
186  case Enum:                nEnumDecls++; break;
187  case ObjCInterface:       nInterfaceDecls++; break;
188  case ObjCClass:           nClassDecls++; break;
189  case ObjCMethod:          nMethodDecls++; break;
190  case ObjCProtocol:        nProtocolDecls++; break;
191  case ObjCForwardProtocol: nForwardProtocolDecls++; break;
192  case ObjCCategory:        nCategoryDecls++; break;
193  case ObjCIvar:            nIvarDecls++; break;
194  case ObjCImplementation:  nObjCImplementationDecls++; break;
195  case ObjCCategoryImpl:    nObjCCategoryImpl++; break;
196  case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
197  case ObjCProperty:        nObjCPropertyDecl++; break;
198  case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
199  case LinkageSpec:         nLinkageSpecDecl++; break;
200  case FileScopeAsm:        nFileScopeAsmDecl++; break;
201  case TranslationUnit:     break;
202  }
203}
204
205//===----------------------------------------------------------------------===//
206// Decl Allocation/Deallocation Method Implementations
207//===----------------------------------------------------------------------===//
208
209TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
210  void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
211  return new (Mem) TranslationUnitDecl();
212}
213
214VarDecl *VarDecl::Create(ASTContext &C, DeclContext *CD,
215                         SourceLocation L,
216                         IdentifierInfo *Id, QualType T,
217                         StorageClass S, ScopedDecl *PrevDecl) {
218  void *Mem = C.getAllocator().Allocate<VarDecl>();
219  return new (Mem) VarDecl(Var, CD, L, Id, T, S, PrevDecl);
220}
221
222ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *CD,
223                                 SourceLocation L, IdentifierInfo *Id,
224                                 QualType T, StorageClass S,
225                                 Expr *DefArg, ScopedDecl *PrevDecl) {
226  void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
227  return new (Mem) ParmVarDecl(CD, L, Id, T, S, DefArg, PrevDecl);
228}
229
230FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *CD,
231                                   SourceLocation L,
232                                   IdentifierInfo *Id, QualType T,
233                                   StorageClass S, bool isInline,
234                                   ScopedDecl *PrevDecl) {
235  void *Mem = C.getAllocator().Allocate<FunctionDecl>();
236  return new (Mem) FunctionDecl(CD, L, Id, T, S, isInline, PrevDecl);
237}
238
239FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
240                             IdentifierInfo *Id, QualType T, Expr *BW) {
241  void *Mem = C.getAllocator().Allocate<FieldDecl>();
242  return new (Mem) FieldDecl(L, Id, T, BW);
243}
244
245
246EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
247                                           SourceLocation L,
248                                           IdentifierInfo *Id, QualType T,
249                                           Expr *E, const llvm::APSInt &V,
250                                           ScopedDecl *PrevDecl){
251  void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
252  return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
253}
254
255TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *CD,
256                                 SourceLocation L,
257                                 IdentifierInfo *Id, QualType T,
258                                 ScopedDecl *PD) {
259  void *Mem = C.getAllocator().Allocate<TypedefDecl>();
260  return new (Mem) TypedefDecl(CD, L, Id, T, PD);
261}
262
263EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *CD, SourceLocation L,
264                           IdentifierInfo *Id,
265                           ScopedDecl *PrevDecl) {
266  void *Mem = C.getAllocator().Allocate<EnumDecl>();
267  return new (Mem) EnumDecl(CD, L, Id, PrevDecl);
268}
269
270RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, DeclContext *CD,
271                               SourceLocation L, IdentifierInfo *Id,
272                               ScopedDecl *PrevDecl) {
273  void *Mem = C.getAllocator().Allocate<RecordDecl>();
274  return new (Mem) RecordDecl(DK, CD, L, Id, PrevDecl);
275}
276
277FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
278                                           SourceLocation L,
279                                           StringLiteral *Str) {
280  void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
281  return new (Mem) FileScopeAsmDecl(L, Str);
282}
283
284LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
285                                         SourceLocation L,
286                                         LanguageIDs Lang, Decl *D) {
287  void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
288  return new (Mem) LinkageSpecDecl(L, Lang, D);
289}
290
291//===----------------------------------------------------------------------===//
292// Decl Implementation
293//===----------------------------------------------------------------------===//
294
295// Out-of-line virtual method providing a home for Decl.
296Decl::~Decl() {
297  if (!HasAttrs)
298    return;
299
300  DeclAttrMapTy::iterator it = DeclAttrs->find(this);
301  assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
302
303  delete it->second;
304  DeclAttrs->erase(it);
305  if (DeclAttrs->empty()) {
306    delete DeclAttrs;
307    DeclAttrs = 0;
308  }
309}
310
311void Decl::addAttr(Attr *NewAttr) {
312  if (!DeclAttrs)
313    DeclAttrs = new DeclAttrMapTy();
314
315  Attr *&ExistingAttr = (*DeclAttrs)[this];
316
317  NewAttr->setNext(ExistingAttr);
318  ExistingAttr = NewAttr;
319
320  HasAttrs = true;
321}
322
323const Attr *Decl::getAttrs() const {
324  if (!HasAttrs)
325    return 0;
326
327  return (*DeclAttrs)[this];
328}
329
330#define CASE(KIND) \
331  case KIND: \
332    static_cast<KIND##Decl *>(const_cast<Decl *>(this))->~KIND##Decl(); \
333    break
334
335void Decl::Destroy(ASTContext& C) const {
336  switch (getKind()) {
337  CASE(TranslationUnit);
338  CASE(Field);
339  CASE(ObjCIvar);
340  CASE(ObjCCategory);
341  CASE(ObjCCategoryImpl);
342  CASE(ObjCImplementation);
343  CASE(ObjCProtocol);
344  CASE(ObjCProperty);
345  CASE(Typedef);
346  CASE(Enum);
347  CASE(EnumConstant);
348  CASE(Function);
349  CASE(Var);
350  CASE(ParmVar);
351  CASE(ObjCInterface);
352  CASE(ObjCCompatibleAlias);
353  CASE(ObjCMethod);
354  CASE(ObjCClass);
355  CASE(ObjCForwardProtocol);
356  CASE(LinkageSpec);
357
358  case Struct: case Union: case Class:
359    static_cast<RecordDecl *>(const_cast<Decl *>(this))->~RecordDecl();
360    break;
361
362  default: assert(0 && "Unknown decl kind!");
363  }
364
365  C.getAllocator().Deallocate((void *)this);
366}
367
368#undef CASE
369
370//===----------------------------------------------------------------------===//
371// DeclContext Implementation
372//===----------------------------------------------------------------------===//
373
374DeclContext *DeclContext::getParent() const {
375  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
376    return SD->getDeclContext();
377  else
378    return NULL;
379}
380
381Decl *DeclContext::ToDecl (const DeclContext *D) {
382  return CastTo<Decl>(D);
383}
384
385DeclContext *DeclContext::FromDecl (const Decl *D) {
386  return CastTo<DeclContext>(D);
387}
388
389//===----------------------------------------------------------------------===//
390// NamedDecl Implementation
391//===----------------------------------------------------------------------===//
392
393const char *NamedDecl::getName() const {
394  if (const IdentifierInfo *II = getIdentifier())
395    return II->getName();
396  return "";
397}
398
399//===----------------------------------------------------------------------===//
400// FunctionDecl Implementation
401//===----------------------------------------------------------------------===//
402
403FunctionDecl::~FunctionDecl() {
404  delete[] ParamInfo;
405  delete Body;
406  delete PreviousDeclaration;
407}
408
409Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
410  for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) {
411    if (FD->Body) {
412      Definition = FD;
413      return FD->Body;
414    }
415  }
416
417  return 0;
418}
419
420unsigned FunctionDecl::getNumParams() const {
421  const FunctionType *FT = getType()->getAsFunctionType();
422  if (isa<FunctionTypeNoProto>(FT))
423    return 0;
424  return cast<FunctionTypeProto>(FT)->getNumArgs();
425}
426
427void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
428  assert(ParamInfo == 0 && "Already has param info!");
429  assert(NumParams == getNumParams() && "Parameter count mismatch!");
430
431  // Zero params -> null pointer.
432  if (NumParams) {
433    ParamInfo = new ParmVarDecl*[NumParams];
434    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
435  }
436}
437
438/// getMinRequiredArguments - Returns the minimum number of arguments
439/// needed to call this function. This may be fewer than the number of
440/// function parameters, if some of the parameters have default
441/// arguments (in C++).
442unsigned FunctionDecl::getMinRequiredArguments() const {
443  unsigned NumRequiredArgs = getNumParams();
444  while (NumRequiredArgs > 0
445         && getParamDecl(NumRequiredArgs-1)->getDefaultArg())
446    --NumRequiredArgs;
447
448  return NumRequiredArgs;
449}
450
451/// AddRedeclaration - Specifies that this function declaration has been
452/// redeclared by the function declaration FD. FD must be a
453/// redeclaration of this based on the semantics of the language being
454/// translated ("compatible" function types in C, same signatures in
455/// C++).
456void FunctionDecl::AddRedeclaration(FunctionDecl *FD) {
457  assert(FD->PreviousDeclaration == 0 &&
458         "Redeclaration already has a previous declaration!");
459
460  // Insert FD into the list of previous declarations of this
461  // function.
462  FD->PreviousDeclaration = this->PreviousDeclaration;
463  this->PreviousDeclaration = FD;
464
465  // Swap the contents of this function declaration and FD. This
466  // effectively transforms the original declaration into the most
467  // recent declaration, so that all references to this declaration
468  // remain valid (and have information from *all* declarations),
469  // while retaining all of the information about previous
470  // declarations as well.
471
472  // Swap parameters, so that the most recent parameter names and
473  // exact types (e.g., enum vs int) show up in the original
474  // declaration.
475  ParmVarDecl **thisParamInfo = this->ParamInfo;
476  this->ParamInfo = FD->ParamInfo;
477  FD->ParamInfo = thisParamInfo;
478
479  // Swap the function body: all declarations share the same function
480  // body, but we keep track of who actually defined that function
481  // body by keeping the pointer to the body stored in that node.
482  Stmt *thisBody = this->Body;
483  this->Body = FD->Body;
484  FD->Body = thisBody;
485
486  // Swap type information: this is important because in C, later
487  // declarations can provide slightly different types (enum vs. int,
488  // for example).
489  QualType thisType = this->getType();
490  this->setType(FD->getType());
491  FD->setType(thisType);
492
493  // Swap location information: this allows us to produce diagnostics
494  // later on that reference the most recent declaration (which has
495  // the most information!) while retaining the location of previous
496  // declarations (good for "redefinition" diagnostics).
497  SourceLocation thisLocation = this->getLocation();
498  this->setLocation(FD->getLocation());
499  FD->setLocation(thisLocation);
500
501  // Swap attributes. FD will have the union of the attributes from
502  // all previous declarations.
503  if (DeclAttrs) {
504    Attr *thisAttr = (*DeclAttrs)[this];
505    (*DeclAttrs)[this] = (*DeclAttrs)[FD];
506    (*DeclAttrs)[FD] = thisAttr;
507  }
508
509  // If any declaration is inline, the function is inline.
510  this->IsInline |= FD->IsInline;
511
512  // FIXME: Is this the right way to handle storage specifiers?
513  if (FD->SClass) this->SClass = FD->SClass;
514}
515
516//===----------------------------------------------------------------------===//
517// RecordDecl Implementation
518//===----------------------------------------------------------------------===//
519
520/// defineBody - When created, RecordDecl's correspond to a forward declared
521/// record.  This method is used to mark the decl as being defined, with the
522/// specified contents.
523void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
524  assert(!isDefinition() && "Cannot redefine record!");
525  setDefinition(true);
526  NumMembers = numMembers;
527  if (numMembers) {
528    Members = new FieldDecl*[numMembers];
529    memcpy(Members, members, numMembers*sizeof(Decl*));
530  }
531}
532
533FieldDecl *RecordDecl::getMember(IdentifierInfo *II) {
534  if (Members == 0 || NumMembers < 0)
535    return 0;
536
537  // Linear search.  When C++ classes come along, will likely need to revisit.
538  for (int i = 0; i != NumMembers; ++i)
539    if (Members[i]->getIdentifier() == II)
540      return Members[i];
541  return 0;
542}
543