Decl.cpp revision 7a7be65a7801addae8205fd68323cecd70df1635
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/ASTContext.h" 17#include "clang/AST/Stmt.h" 18#include "clang/AST/Expr.h" 19#include "clang/Basic/IdentifierTable.h" 20 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Decl Allocation/Deallocation Method Implementations 25//===----------------------------------------------------------------------===// 26 27TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { 28 return new (C) TranslationUnitDecl(); 29} 30 31NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, 32 SourceLocation L, IdentifierInfo *Id) { 33 return new (C) NamespaceDecl(DC, L, Id); 34} 35 36void NamespaceDecl::Destroy(ASTContext& C) { 37 // NamespaceDecl uses "NextDeclarator" to chain namespace declarations 38 // together. They are all top-level Decls. 39 40 this->~NamespaceDecl(); 41 C.Deallocate((void *)this); 42} 43 44 45ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, 46 SourceLocation L, IdentifierInfo *Id, QualType T) { 47 return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); 48} 49 50ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, 51 SourceLocation L, IdentifierInfo *Id, 52 QualType T, StorageClass S, 53 Expr *DefArg) { 54 return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg); 55} 56 57QualType ParmVarDecl::getOriginalType() const { 58 if (const OriginalParmVarDecl *PVD = 59 dyn_cast<OriginalParmVarDecl>(this)) 60 return PVD->OriginalType; 61 return getType(); 62} 63 64OriginalParmVarDecl *OriginalParmVarDecl::Create( 65 ASTContext &C, DeclContext *DC, 66 SourceLocation L, IdentifierInfo *Id, 67 QualType T, QualType OT, StorageClass S, 68 Expr *DefArg) { 69 return new (C) OriginalParmVarDecl(DC, L, Id, T, OT, S, DefArg); 70} 71 72FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, 73 SourceLocation L, 74 DeclarationName N, QualType T, 75 StorageClass S, bool isInline, 76 SourceLocation TypeSpecStartLoc) { 77 return new (C) FunctionDecl(Function, DC, L, N, T, S, isInline, 78 TypeSpecStartLoc); 79} 80 81BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { 82 return new (C) BlockDecl(DC, L); 83} 84 85FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 86 IdentifierInfo *Id, QualType T, Expr *BW, 87 bool Mutable) { 88 return new (C) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable); 89} 90 91bool FieldDecl::isAnonymousStructOrUnion() const { 92 if (!isImplicit() || getDeclName()) 93 return false; 94 95 if (const RecordType *Record = getType()->getAsRecordType()) 96 return Record->getDecl()->isAnonymousStructOrUnion(); 97 98 return false; 99} 100 101EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, 102 SourceLocation L, 103 IdentifierInfo *Id, QualType T, 104 Expr *E, const llvm::APSInt &V) { 105 return new (C) EnumConstantDecl(CD, L, Id, T, E, V); 106} 107 108void EnumConstantDecl::Destroy(ASTContext& C) { 109 if (Init) Init->Destroy(C); 110 Decl::Destroy(C); 111} 112 113TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, 114 SourceLocation L, 115 IdentifierInfo *Id, QualType T) { 116 return new (C) TypedefDecl(DC, L, Id, T); 117} 118 119EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 120 IdentifierInfo *Id, 121 EnumDecl *PrevDecl) { 122 EnumDecl *Enum = new (C) EnumDecl(DC, L, Id); 123 C.getTypeDeclType(Enum, PrevDecl); 124 return Enum; 125} 126 127void EnumDecl::Destroy(ASTContext& C) { 128 Decl::Destroy(C); 129} 130 131void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) { 132 assert(!isDefinition() && "Cannot redefine enums!"); 133 IntegerType = NewType; 134 TagDecl::completeDefinition(); 135} 136 137FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, 138 SourceLocation L, 139 StringLiteral *Str) { 140 return new (C) FileScopeAsmDecl(DC, L, Str); 141} 142 143//===----------------------------------------------------------------------===// 144// NamedDecl Implementation 145//===----------------------------------------------------------------------===// 146 147bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { 148 assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); 149 150 // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. 151 // We want to keep it, unless it nominates same namespace. 152 if (getKind() == Decl::UsingDirective) { 153 return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() == 154 cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace(); 155 } 156 157 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) 158 // For function declarations, we keep track of redeclarations. 159 return FD->getPreviousDeclaration() == OldD; 160 161 // For non-function declarations, if the declarations are of the 162 // same kind then this must be a redeclaration, or semantic analysis 163 // would not have given us the new declaration. 164 return this->getKind() == OldD->getKind(); 165} 166 167 168//===----------------------------------------------------------------------===// 169// VarDecl Implementation 170//===----------------------------------------------------------------------===// 171 172VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 173 IdentifierInfo *Id, QualType T, StorageClass S, 174 SourceLocation TypeSpecStartLoc) { 175 return new (C) VarDecl(Var, DC, L, Id, T, S, TypeSpecStartLoc); 176} 177 178void VarDecl::Destroy(ASTContext& C) { 179 this->~VarDecl(); 180 C.Deallocate((void *)this); 181} 182 183VarDecl::~VarDecl() { 184 delete getInit(); 185} 186 187//===----------------------------------------------------------------------===// 188// FunctionDecl Implementation 189//===----------------------------------------------------------------------===// 190 191void FunctionDecl::Destroy(ASTContext& C) { 192 if (Body) 193 Body->Destroy(C); 194 195 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 196 (*I)->Destroy(C); 197 198 C.Deallocate(ParamInfo); 199 200 Decl::Destroy(C); 201} 202 203 204Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { 205 for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) { 206 if (FD->Body) { 207 Definition = FD; 208 return FD->Body; 209 } 210 } 211 212 return 0; 213} 214 215// Helper function for FunctionDecl::getNumParams and FunctionDecl::setParams() 216static unsigned getNumTypeParams(QualType T) { 217 const FunctionType *FT = T->getAsFunctionType(); 218 if (isa<FunctionTypeNoProto>(FT)) 219 return 0; 220 return cast<FunctionTypeProto>(FT)->getNumArgs(); 221} 222 223unsigned FunctionDecl::getNumParams() const { 224 // Can happen if a FunctionDecl is declared using typeof(some_other_func) bar; 225 if (!ParamInfo) 226 return 0; 227 228 return getNumTypeParams(getType()); 229} 230 231void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, 232 unsigned NumParams) { 233 assert(ParamInfo == 0 && "Already has param info!"); 234 assert(NumParams == getNumTypeParams(getType()) && 235 "Parameter count mismatch!"); 236 237 // Zero params -> null pointer. 238 if (NumParams) { 239 void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); 240 ParamInfo = new (Mem) ParmVarDecl*[NumParams]; 241 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 242 } 243} 244 245/// getMinRequiredArguments - Returns the minimum number of arguments 246/// needed to call this function. This may be fewer than the number of 247/// function parameters, if some of the parameters have default 248/// arguments (in C++). 249unsigned FunctionDecl::getMinRequiredArguments() const { 250 unsigned NumRequiredArgs = getNumParams(); 251 while (NumRequiredArgs > 0 252 && getParamDecl(NumRequiredArgs-1)->getDefaultArg()) 253 --NumRequiredArgs; 254 255 return NumRequiredArgs; 256} 257 258/// getOverloadedOperator - Which C++ overloaded operator this 259/// function represents, if any. 260OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { 261 if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName) 262 return getDeclName().getCXXOverloadedOperator(); 263 else 264 return OO_None; 265} 266 267//===----------------------------------------------------------------------===// 268// TagDecl Implementation 269//===----------------------------------------------------------------------===// 270 271void TagDecl::startDefinition() { 272 cast<TagType>(TypeForDecl)->decl.setPointer(this); 273 cast<TagType>(TypeForDecl)->decl.setInt(1); 274} 275 276void TagDecl::completeDefinition() { 277 assert((!TypeForDecl || 278 cast<TagType>(TypeForDecl)->decl.getPointer() == this) && 279 "Attempt to redefine a tag definition?"); 280 IsDefinition = true; 281 cast<TagType>(TypeForDecl)->decl.setPointer(this); 282 cast<TagType>(TypeForDecl)->decl.setInt(0); 283} 284 285TagDecl* TagDecl::getDefinition(ASTContext& C) const { 286 QualType T = C.getTypeDeclType(const_cast<TagDecl*>(this)); 287 TagDecl* D = cast<TagDecl>(cast<TagType>(T)->getDecl()); 288 return D->isDefinition() ? D : 0; 289} 290 291//===----------------------------------------------------------------------===// 292// RecordDecl Implementation 293//===----------------------------------------------------------------------===// 294 295RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, 296 IdentifierInfo *Id) 297 : TagDecl(DK, TK, DC, L, Id) { 298 HasFlexibleArrayMember = false; 299 AnonymousStructOrUnion = false; 300 assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); 301} 302 303RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 304 SourceLocation L, IdentifierInfo *Id, 305 RecordDecl* PrevDecl) { 306 307 RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id); 308 C.getTypeDeclType(R, PrevDecl); 309 return R; 310} 311 312RecordDecl::~RecordDecl() { 313} 314 315void RecordDecl::Destroy(ASTContext& C) { 316 TagDecl::Destroy(C); 317} 318 319/// completeDefinition - Notes that the definition of this type is now 320/// complete. 321void RecordDecl::completeDefinition(ASTContext& C) { 322 assert(!isDefinition() && "Cannot redefine record!"); 323 TagDecl::completeDefinition(); 324} 325 326//===----------------------------------------------------------------------===// 327// BlockDecl Implementation 328//===----------------------------------------------------------------------===// 329 330BlockDecl::~BlockDecl() { 331} 332 333void BlockDecl::Destroy(ASTContext& C) { 334 if (Body) 335 Body->Destroy(C); 336 337 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 338 (*I)->Destroy(C); 339 340 Decl::Destroy(C); 341} 342