Decl.cpp revision 082d936a5b8323ac2c04558d8bca277a647831a3
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 subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Decl.h"
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/DeclObjC.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/Stmt.h"
19#include "clang/AST/Expr.h"
20#include "clang/Basic/IdentifierTable.h"
21#include <vector>
22
23using namespace clang;
24
25void Attr::Destroy(ASTContext &C) {
26  if (Next) {
27    Next->Destroy(C);
28    Next = 0;
29  }
30  this->~Attr();
31  C.Deallocate((void*)this);
32}
33
34
35//===----------------------------------------------------------------------===//
36// Decl Allocation/Deallocation Method Implementations
37//===----------------------------------------------------------------------===//
38
39
40TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
41  return new (C) TranslationUnitDecl();
42}
43
44NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
45                                     SourceLocation L, IdentifierInfo *Id) {
46  return new (C) NamespaceDecl(DC, L, Id);
47}
48
49void NamespaceDecl::Destroy(ASTContext& C) {
50  // NamespaceDecl uses "NextDeclarator" to chain namespace declarations
51  // together. They are all top-level Decls.
52
53  this->~NamespaceDecl();
54  C.Deallocate((void *)this);
55}
56
57
58ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
59    SourceLocation L, IdentifierInfo *Id, QualType T) {
60  return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T);
61}
62
63ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
64                                 SourceLocation L, IdentifierInfo *Id,
65                                 QualType T, StorageClass S,
66                                 Expr *DefArg) {
67  return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg);
68}
69
70QualType ParmVarDecl::getOriginalType() const {
71  if (const OriginalParmVarDecl *PVD =
72      dyn_cast<OriginalParmVarDecl>(this))
73    return PVD->OriginalType;
74  return getType();
75}
76
77bool VarDecl::isExternC(ASTContext &Context) const {
78  if (!Context.getLangOptions().CPlusPlus)
79    return (getDeclContext()->isTranslationUnit() &&
80            getStorageClass() != Static) ||
81      (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
82
83  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
84       DC = DC->getParent()) {
85    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
86      if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
87        return getStorageClass() != Static;
88
89      break;
90    }
91
92    if (DC->isFunctionOrMethod())
93      return false;
94  }
95
96  return false;
97}
98
99OriginalParmVarDecl *OriginalParmVarDecl::Create(
100                                 ASTContext &C, DeclContext *DC,
101                                 SourceLocation L, IdentifierInfo *Id,
102                                 QualType T, QualType OT, StorageClass S,
103                                 Expr *DefArg) {
104  return new (C) OriginalParmVarDecl(DC, L, Id, T, OT, S, DefArg);
105}
106
107FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
108                                   SourceLocation L,
109                                   DeclarationName N, QualType T,
110                                   StorageClass S, bool isInline,
111                                   bool hasPrototype,
112                                   SourceLocation TypeSpecStartLoc) {
113  FunctionDecl *New
114    = new (C) FunctionDecl(Function, DC, L, N, T, S, isInline,
115                           TypeSpecStartLoc);
116  New->HasPrototype = hasPrototype;
117  return New;
118}
119
120BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
121  return new (C) BlockDecl(DC, L);
122}
123
124FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
125                             IdentifierInfo *Id, QualType T, Expr *BW,
126                             bool Mutable) {
127  return new (C) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable);
128}
129
130bool FieldDecl::isAnonymousStructOrUnion() const {
131  if (!isImplicit() || getDeclName())
132    return false;
133
134  if (const RecordType *Record = getType()->getAsRecordType())
135    return Record->getDecl()->isAnonymousStructOrUnion();
136
137  return false;
138}
139
140EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
141                                           SourceLocation L,
142                                           IdentifierInfo *Id, QualType T,
143                                           Expr *E, const llvm::APSInt &V) {
144  return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
145}
146
147void EnumConstantDecl::Destroy(ASTContext& C) {
148  if (Init) Init->Destroy(C);
149  Decl::Destroy(C);
150}
151
152TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
153                                 SourceLocation L,
154                                 IdentifierInfo *Id, QualType T) {
155  return new (C) TypedefDecl(DC, L, Id, T);
156}
157
158EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
159                           IdentifierInfo *Id,
160                           EnumDecl *PrevDecl) {
161  EnumDecl *Enum = new (C) EnumDecl(DC, L, Id);
162  C.getTypeDeclType(Enum, PrevDecl);
163  return Enum;
164}
165
166void EnumDecl::Destroy(ASTContext& C) {
167  Decl::Destroy(C);
168}
169
170void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) {
171  assert(!isDefinition() && "Cannot redefine enums!");
172  IntegerType = NewType;
173  TagDecl::completeDefinition();
174}
175
176FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
177                                           SourceLocation L,
178                                           StringLiteral *Str) {
179  return new (C) FileScopeAsmDecl(DC, L, Str);
180}
181
182//===----------------------------------------------------------------------===//
183// NamedDecl Implementation
184//===----------------------------------------------------------------------===//
185
186std::string NamedDecl::getQualifiedNameAsString() const {
187  std::vector<std::string> Names;
188  std::string QualName;
189  const DeclContext *Ctx = getDeclContext();
190
191  if (Ctx->isFunctionOrMethod())
192    return getNameAsString();
193
194  while (Ctx) {
195    if (Ctx->isFunctionOrMethod())
196      // FIXME: That probably will happen, when D was member of local
197      // scope class/struct/union. How do we handle this case?
198      break;
199
200    if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
201      Names.push_back(ND->getNameAsString());
202    else
203      break;
204
205    Ctx = Ctx->getParent();
206  }
207
208  std::vector<std::string>::reverse_iterator
209    I = Names.rbegin(),
210    End = Names.rend();
211
212  for (; I!=End; ++I)
213    QualName += *I + "::";
214
215  QualName += getNameAsString();
216
217  return QualName;
218}
219
220
221bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
222  assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
223
224  // UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
225  // We want to keep it, unless it nominates same namespace.
226  if (getKind() == Decl::UsingDirective) {
227    return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() ==
228           cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace();
229  }
230
231  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
232    // For function declarations, we keep track of redeclarations.
233    return FD->getPreviousDeclaration() == OldD;
234
235  // For method declarations, we keep track of redeclarations.
236  if (isa<ObjCMethodDecl>(this))
237    return false;
238
239  // For non-function declarations, if the declarations are of the
240  // same kind then this must be a redeclaration, or semantic analysis
241  // would not have given us the new declaration.
242  return this->getKind() == OldD->getKind();
243}
244
245bool NamedDecl::hasLinkage() const {
246  if (const VarDecl *VD = dyn_cast<VarDecl>(this))
247    return VD->hasExternalStorage() || VD->isFileVarDecl();
248
249  if (isa<FunctionDecl>(this) && !isa<CXXMethodDecl>(this))
250    return true;
251
252  return false;
253}
254
255//===----------------------------------------------------------------------===//
256// VarDecl Implementation
257//===----------------------------------------------------------------------===//
258
259VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
260                         IdentifierInfo *Id, QualType T, StorageClass S,
261                         SourceLocation TypeSpecStartLoc) {
262  return new (C) VarDecl(Var, DC, L, Id, T, S, TypeSpecStartLoc);
263}
264
265void VarDecl::Destroy(ASTContext& C) {
266  Expr *Init = getInit();
267  if (Init)
268    Init->Destroy(C);
269  this->~VarDecl();
270  C.Deallocate((void *)this);
271}
272
273VarDecl::~VarDecl() {
274}
275
276bool VarDecl::isTentativeDefinition(ASTContext &Context) const {
277  if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus)
278    return false;
279
280  return (!getInit() &&
281          (getStorageClass() == None || getStorageClass() == Static));
282}
283
284const Expr *VarDecl::getDefinition(const VarDecl *&Def) const {
285  Def = this;
286  while (Def && !Def->getInit())
287    Def = Def->getPreviousDeclaration();
288
289  return Def? Def->getInit() : 0;
290}
291
292//===----------------------------------------------------------------------===//
293// FunctionDecl Implementation
294//===----------------------------------------------------------------------===//
295
296void FunctionDecl::Destroy(ASTContext& C) {
297  if (Body)
298    Body->Destroy(C);
299
300  for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
301    (*I)->Destroy(C);
302
303  C.Deallocate(ParamInfo);
304
305  Decl::Destroy(C);
306}
307
308
309CompoundStmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
310  for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) {
311    if (FD->Body) {
312      Definition = FD;
313      return cast<CompoundStmt>(FD->Body);
314    }
315  }
316
317  return 0;
318}
319
320bool FunctionDecl::isMain() const {
321  return getDeclContext()->getLookupContext()->isTranslationUnit() &&
322    getIdentifier() && getIdentifier()->isStr("main");
323}
324
325bool FunctionDecl::isExternC(ASTContext &Context) const {
326  // In C, any non-static, non-overloadable function has external
327  // linkage.
328  if (!Context.getLangOptions().CPlusPlus)
329    return getStorageClass() != Static && !getAttr<OverloadableAttr>();
330
331  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
332       DC = DC->getParent()) {
333    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
334      if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
335        return getStorageClass() != Static && !getAttr<OverloadableAttr>();
336
337      break;
338    }
339  }
340
341  return false;
342}
343
344/// \brief Returns a value indicating whether this function
345/// corresponds to a builtin function.
346///
347/// The function corresponds to a built-in function if it is
348/// declared at translation scope or within an extern "C" block and
349/// its name matches with the name of a builtin. The returned value
350/// will be 0 for functions that do not correspond to a builtin, a
351/// value of type \c Builtin::ID if in the target-independent range
352/// \c [1,Builtin::First), or a target-specific builtin value.
353unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const {
354  if (!getIdentifier() || !getIdentifier()->getBuiltinID())
355    return 0;
356
357  unsigned BuiltinID = getIdentifier()->getBuiltinID();
358  if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
359    return BuiltinID;
360
361  // This function has the name of a known C library
362  // function. Determine whether it actually refers to the C library
363  // function or whether it just has the same name.
364
365  // If this is a static function, it's not a builtin.
366  if (getStorageClass() == Static)
367    return 0;
368
369  // If this function is at translation-unit scope and we're not in
370  // C++, it refers to the C library function.
371  if (!Context.getLangOptions().CPlusPlus &&
372      getDeclContext()->isTranslationUnit())
373    return BuiltinID;
374
375  // If the function is in an extern "C" linkage specification and is
376  // not marked "overloadable", it's the real function.
377  if (isa<LinkageSpecDecl>(getDeclContext()) &&
378      cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
379        == LinkageSpecDecl::lang_c &&
380      !getAttr<OverloadableAttr>())
381    return BuiltinID;
382
383  // Not a builtin
384  return 0;
385}
386
387
388// Helper function for FunctionDecl::getNumParams and FunctionDecl::setParams()
389static unsigned getNumTypeParams(QualType T) {
390  const FunctionType *FT = T->getAsFunctionType();
391  if (isa<FunctionNoProtoType>(FT))
392    return 0;
393  return cast<FunctionProtoType>(FT)->getNumArgs();
394}
395
396unsigned FunctionDecl::getNumParams() const {
397  // Can happen if a FunctionDecl is declared using typeof(some_other_func) bar;
398  if (!ParamInfo)
399    return 0;
400
401  return getNumTypeParams(getType());
402}
403
404void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo,
405                             unsigned NumParams) {
406  assert(ParamInfo == 0 && "Already has param info!");
407  assert(NumParams == getNumTypeParams(getType()) &&
408         "Parameter count mismatch!");
409
410  // Zero params -> null pointer.
411  if (NumParams) {
412    void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
413    ParamInfo = new (Mem) ParmVarDecl*[NumParams];
414    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
415  }
416}
417
418/// getMinRequiredArguments - Returns the minimum number of arguments
419/// needed to call this function. This may be fewer than the number of
420/// function parameters, if some of the parameters have default
421/// arguments (in C++).
422unsigned FunctionDecl::getMinRequiredArguments() const {
423  unsigned NumRequiredArgs = getNumParams();
424  while (NumRequiredArgs > 0
425         && getParamDecl(NumRequiredArgs-1)->getDefaultArg())
426    --NumRequiredArgs;
427
428  return NumRequiredArgs;
429}
430
431/// getOverloadedOperator - Which C++ overloaded operator this
432/// function represents, if any.
433OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
434  if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
435    return getDeclName().getCXXOverloadedOperator();
436  else
437    return OO_None;
438}
439
440//===----------------------------------------------------------------------===//
441// TagDecl Implementation
442//===----------------------------------------------------------------------===//
443
444void TagDecl::startDefinition() {
445  TagType *TagT = const_cast<TagType *>(TypeForDecl->getAsTagType());
446  TagT->decl.setPointer(this);
447  TagT->getAsTagType()->decl.setInt(1);
448}
449
450void TagDecl::completeDefinition() {
451  assert((!TypeForDecl ||
452          TypeForDecl->getAsTagType()->decl.getPointer() == this) &&
453         "Attempt to redefine a tag definition?");
454  IsDefinition = true;
455  TagType *TagT = const_cast<TagType *>(TypeForDecl->getAsTagType());
456  TagT->decl.setPointer(this);
457  TagT->decl.setInt(0);
458}
459
460TagDecl* TagDecl::getDefinition(ASTContext& C) const {
461  QualType T = C.getTypeDeclType(const_cast<TagDecl*>(this));
462  TagDecl* D = cast<TagDecl>(T->getAsTagType()->getDecl());
463  return D->isDefinition() ? D : 0;
464}
465
466//===----------------------------------------------------------------------===//
467// RecordDecl Implementation
468//===----------------------------------------------------------------------===//
469
470RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
471                       IdentifierInfo *Id)
472  : TagDecl(DK, TK, DC, L, Id) {
473  HasFlexibleArrayMember = false;
474  AnonymousStructOrUnion = false;
475  assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
476}
477
478RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
479                               SourceLocation L, IdentifierInfo *Id,
480                               RecordDecl* PrevDecl) {
481
482  RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id);
483  C.getTypeDeclType(R, PrevDecl);
484  return R;
485}
486
487RecordDecl::~RecordDecl() {
488}
489
490void RecordDecl::Destroy(ASTContext& C) {
491  TagDecl::Destroy(C);
492}
493
494/// completeDefinition - Notes that the definition of this type is now
495/// complete.
496void RecordDecl::completeDefinition(ASTContext& C) {
497  assert(!isDefinition() && "Cannot redefine record!");
498  TagDecl::completeDefinition();
499}
500
501//===----------------------------------------------------------------------===//
502// BlockDecl Implementation
503//===----------------------------------------------------------------------===//
504
505BlockDecl::~BlockDecl() {
506}
507
508void BlockDecl::Destroy(ASTContext& C) {
509  if (Body)
510    Body->Destroy(C);
511
512  for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
513    (*I)->Destroy(C);
514
515  C.Deallocate(ParamInfo);
516  Decl::Destroy(C);
517}
518
519void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo,
520                          unsigned NParms) {
521  assert(ParamInfo == 0 && "Already has param info!");
522
523  // Zero params -> null pointer.
524  if (NParms) {
525    NumParams = NParms;
526    void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
527    ParamInfo = new (Mem) ParmVarDecl*[NumParams];
528    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
529  }
530}
531
532unsigned BlockDecl::getNumParams() const {
533  return NumParams;
534}
535