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