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