-//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//\r
-//\r
-// The LLVM Compiler Infrastructure\r
-//\r
-// This file is distributed under the University of Illinois Open Source\r
-// License. See LICENSE.TXT for details.\r
-//\r
-//===----------------------------------------------------------------------===//\r
-//\r
-// This file implements the Decl and DeclContext classes.\r
-//\r
-//===----------------------------------------------------------------------===//\r
-\r
-#include "clang/AST/DeclBase.h"\r
-#include "clang/AST/ASTContext.h"\r
-#include "llvm/ADT/DenseMap.h"\r
-using namespace clang;\r
-\r
-//===----------------------------------------------------------------------===//\r
-// Statistics\r
-//===----------------------------------------------------------------------===//\r
-\r
-// temporary statistics gathering\r
-static unsigned nFuncs = 0;\r
-static unsigned nVars = 0;\r
-static unsigned nParmVars = 0;\r
-static unsigned nSUC = 0;\r
-static unsigned nEnumConst = 0;\r
-static unsigned nEnumDecls = 0;\r
-static unsigned nNamespaces = 0;\r
-static unsigned nTypedef = 0;\r
-static unsigned nFieldDecls = 0;\r
-static unsigned nInterfaceDecls = 0;\r
-static unsigned nClassDecls = 0;\r
-static unsigned nMethodDecls = 0;\r
-static unsigned nProtocolDecls = 0;\r
-static unsigned nForwardProtocolDecls = 0;\r
-static unsigned nCategoryDecls = 0;\r
-static unsigned nIvarDecls = 0;\r
-static unsigned nObjCImplementationDecls = 0;\r
-static unsigned nObjCCategoryImpl = 0;\r
-static unsigned nObjCCompatibleAlias = 0;\r
-static unsigned nObjCPropertyDecl = 0;\r
-static unsigned nObjCPropertyImplDecl = 0;\r
-static unsigned nLinkageSpecDecl = 0;\r
-static unsigned nFileScopeAsmDecl = 0;\r
-\r
-static bool StatSwitch = false;\r
-\r
-// This keeps track of all decl attributes. Since so few decls have attrs, we\r
-// keep them in a hash map instead of wasting space in the Decl class.\r
-typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;\r
-\r
-static DeclAttrMapTy *DeclAttrs = 0;\r
-\r
-const char *Decl::getDeclKindName() const {\r
- switch (DeclKind) {\r
- default: assert(0 && "Unknown decl kind!");\r
- case Namespace: return "Namespace";\r
- case Typedef: return "Typedef";\r
- case Function: return "Function";\r
- case Var: return "Var";\r
- case ParmVar: return "ParmVar";\r
- case EnumConstant: return "EnumConstant";\r
- case ObjCIvar: return "ObjCIvar";\r
- case ObjCInterface: return "ObjCInterface";\r
- case ObjCClass: return "ObjCClass";\r
- case ObjCMethod: return "ObjCMethod";\r
- case ObjCProtocol: return "ObjCProtocol";\r
- case ObjCForwardProtocol: return "ObjCForwardProtocol"; \r
- case Struct: return "Struct";\r
- case Union: return "Union";\r
- case Class: return "Class";\r
- case Enum: return "Enum";\r
- }\r
-}\r
-\r
-bool Decl::CollectingStats(bool Enable) {\r
- if (Enable)\r
- StatSwitch = true;\r
- return StatSwitch;\r
-}\r
-\r
-void Decl::PrintStats() {\r
- fprintf(stderr, "*** Decl Stats:\n");\r
- fprintf(stderr, " %d decls total.\n", \r
- int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+\r
- nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+\r
- nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+\r
- nNamespaces));\r
- fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n", \r
- nNamespaces, (int)sizeof(NamespaceDecl), \r
- int(nNamespaces*sizeof(NamespaceDecl)));\r
- fprintf(stderr, " %d function decls, %d each (%d bytes)\n", \r
- nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));\r
- fprintf(stderr, " %d variable decls, %d each (%d bytes)\n", \r
- nVars, (int)sizeof(VarDecl), \r
- int(nVars*sizeof(VarDecl)));\r
- fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n", \r
- nParmVars, (int)sizeof(ParmVarDecl),\r
- int(nParmVars*sizeof(ParmVarDecl)));\r
- fprintf(stderr, " %d field decls, %d each (%d bytes)\n", \r
- nFieldDecls, (int)sizeof(FieldDecl),\r
- int(nFieldDecls*sizeof(FieldDecl)));\r
- fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n", \r
- nSUC, (int)sizeof(RecordDecl),\r
- int(nSUC*sizeof(RecordDecl)));\r
- fprintf(stderr, " %d enum decls, %d each (%d bytes)\n", \r
- nEnumDecls, (int)sizeof(EnumDecl), \r
- int(nEnumDecls*sizeof(EnumDecl)));\r
- fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n", \r
- nEnumConst, (int)sizeof(EnumConstantDecl),\r
- int(nEnumConst*sizeof(EnumConstantDecl)));\r
- fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n", \r
- nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));\r
- // Objective-C decls...\r
- fprintf(stderr, " %d interface decls, %d each (%d bytes)\n", \r
- nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),\r
- int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));\r
- fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n", \r
- nIvarDecls, (int)sizeof(ObjCIvarDecl),\r
- int(nIvarDecls*sizeof(ObjCIvarDecl)));\r
- fprintf(stderr, " %d class decls, %d each (%d bytes)\n", \r
- nClassDecls, (int)sizeof(ObjCClassDecl),\r
- int(nClassDecls*sizeof(ObjCClassDecl)));\r
- fprintf(stderr, " %d method decls, %d each (%d bytes)\n", \r
- nMethodDecls, (int)sizeof(ObjCMethodDecl),\r
- int(nMethodDecls*sizeof(ObjCMethodDecl)));\r
- fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n", \r
- nProtocolDecls, (int)sizeof(ObjCProtocolDecl),\r
- int(nProtocolDecls*sizeof(ObjCProtocolDecl)));\r
- fprintf(stderr, " %d forward protocol decls, %d each (%d bytes)\n", \r
- nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),\r
- int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));\r
- fprintf(stderr, " %d category decls, %d each (%d bytes)\n", \r
- nCategoryDecls, (int)sizeof(ObjCCategoryDecl),\r
- int(nCategoryDecls*sizeof(ObjCCategoryDecl)));\r
-\r
- fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n", \r
- nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),\r
- int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));\r
-\r
- fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n", \r
- nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),\r
- int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));\r
-\r
- fprintf(stderr, " %d compatibility alias decls, %d each (%d bytes)\n", \r
- nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),\r
- int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));\r
- \r
- fprintf(stderr, " %d property decls, %d each (%d bytes)\n", \r
- nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),\r
- int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));\r
- \r
- fprintf(stderr, " %d property implementation decls, %d each (%d bytes)\n", \r
- nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),\r
- int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));\r
- \r
- fprintf(stderr, "Total bytes = %d\n", \r
- int(nFuncs*sizeof(FunctionDecl)+\r
- nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+\r
- nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+\r
- nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+\r
- nTypedef*sizeof(TypedefDecl)+\r
- nInterfaceDecls*sizeof(ObjCInterfaceDecl)+\r
- nIvarDecls*sizeof(ObjCIvarDecl)+\r
- nClassDecls*sizeof(ObjCClassDecl)+\r
- nMethodDecls*sizeof(ObjCMethodDecl)+\r
- nProtocolDecls*sizeof(ObjCProtocolDecl)+\r
- nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+\r
- nCategoryDecls*sizeof(ObjCCategoryDecl)+\r
- nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+\r
- nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+\r
- nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+\r
- nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+\r
- nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+\r
- nLinkageSpecDecl*sizeof(LinkageSpecDecl)+\r
- nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+\r
- nNamespaces*sizeof(NamespaceDecl)));\r
- \r
-}\r
-\r
-void Decl::addDeclKind(Kind k) {\r
- switch (k) {\r
- case Namespace: nNamespaces++; break;\r
- case Typedef: nTypedef++; break;\r
- case Function: nFuncs++; break;\r
- case Var: nVars++; break;\r
- case ParmVar: nParmVars++; break;\r
- case EnumConstant: nEnumConst++; break;\r
- case Field: nFieldDecls++; break;\r
- case Struct: case Union: case Class: nSUC++; break;\r
- case Enum: nEnumDecls++; break;\r
- case ObjCInterface: nInterfaceDecls++; break;\r
- case ObjCClass: nClassDecls++; break;\r
- case ObjCMethod: nMethodDecls++; break;\r
- case ObjCProtocol: nProtocolDecls++; break;\r
- case ObjCForwardProtocol: nForwardProtocolDecls++; break;\r
- case ObjCCategory: nCategoryDecls++; break;\r
- case ObjCIvar: nIvarDecls++; break;\r
- case ObjCImplementation: nObjCImplementationDecls++; break;\r
- case ObjCCategoryImpl: nObjCCategoryImpl++; break;\r
- case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;\r
- case ObjCProperty: nObjCPropertyDecl++; break;\r
- case ObjCPropertyImpl: nObjCPropertyImplDecl++; break;\r
- case LinkageSpec: nLinkageSpecDecl++; break;\r
- case FileScopeAsm: nFileScopeAsmDecl++; break;\r
- case TranslationUnit: break;\r
- }\r
-}\r
-\r
-//===----------------------------------------------------------------------===//\r
-// Decl Implementation\r
-//===----------------------------------------------------------------------===//\r
-\r
-// Out-of-line virtual method providing a home for Decl.\r
-Decl::~Decl() {\r
- if (!HasAttrs)\r
- return;\r
- \r
- DeclAttrMapTy::iterator it = DeclAttrs->find(this);\r
- assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");\r
-\r
- // release attributes.\r
- delete it->second;\r
- invalidateAttrs();\r
-}\r
-\r
-void Decl::addAttr(Attr *NewAttr) {\r
- if (!DeclAttrs)\r
- DeclAttrs = new DeclAttrMapTy();\r
- \r
- Attr *&ExistingAttr = (*DeclAttrs)[this];\r
-\r
- NewAttr->setNext(ExistingAttr);\r
- ExistingAttr = NewAttr;\r
- \r
- HasAttrs = true;\r
-}\r
-\r
-void Decl::invalidateAttrs() {\r
- if (!HasAttrs) return;\r
-\r
- HasAttrs = false;\r
- (*DeclAttrs)[this] = 0;\r
- DeclAttrs->erase(this);\r
-\r
- if (DeclAttrs->empty()) {\r
- delete DeclAttrs;\r
- DeclAttrs = 0;\r
- }\r
-}\r
-\r
-const Attr *Decl::getAttrs() const {\r
- if (!HasAttrs)\r
- return 0;\r
- \r
- return (*DeclAttrs)[this];\r
-}\r
-\r
-void Decl::swapAttrs(Decl *RHS) {\r
- bool HasLHSAttr = this->HasAttrs;\r
- bool HasRHSAttr = RHS->HasAttrs;\r
- \r
- // Usually, neither decl has attrs, nothing to do.\r
- if (!HasLHSAttr && !HasRHSAttr) return;\r
- \r
- // If 'this' has no attrs, swap the other way.\r
- if (!HasLHSAttr)\r
- return RHS->swapAttrs(this);\r
- \r
- // Handle the case when both decls have attrs.\r
- if (HasRHSAttr) {\r
- std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);\r
- return;\r
- }\r
- \r
- // Otherwise, LHS has an attr and RHS doesn't.\r
- (*DeclAttrs)[RHS] = (*DeclAttrs)[this];\r
- (*DeclAttrs).erase(this);\r
- this->HasAttrs = false;\r
- RHS->HasAttrs = true;\r
-}\r
-\r
-\r
-void Decl::Destroy(ASTContext& C) {\r
-\r
- if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) { \r
-\r
- // Observe the unrolled recursion. By setting N->NextDeclarator = 0x0\r
- // within the loop, only the Destroy method for the first ScopedDecl\r
- // will deallocate all of the ScopedDecls in a chain.\r
- \r
- ScopedDecl* N = SD->getNextDeclarator();\r
- \r
- while (N) {\r
- ScopedDecl* Tmp = N->getNextDeclarator();\r
- N->NextDeclarator = 0x0;\r
- N->Destroy(C);\r
- N = Tmp;\r
- }\r
- } \r
- \r
- this->~Decl();\r
- C.getAllocator().Deallocate((void *)this);\r
-}\r
-\r
-//===----------------------------------------------------------------------===//\r
-// DeclContext Implementation\r
-//===----------------------------------------------------------------------===//\r
-\r
-DeclContext *DeclContext::getParent() const {\r
- if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))\r
- return SD->getDeclContext();\r
- else\r
- return NULL;\r
-}\r
-\r
-Decl *DeclContext::ToDecl (const DeclContext *D) {\r
- return CastTo<Decl>(D);\r
-}\r
-\r
-DeclContext *DeclContext::FromDecl (const Decl *D) {\r
- return CastTo<DeclContext>(D);\r
-}\r
+//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Decl and DeclContext classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/ADT/DenseMap.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Statistics
+//===----------------------------------------------------------------------===//
+
+// temporary statistics gathering
+static unsigned nFuncs = 0;
+static unsigned nVars = 0;
+static unsigned nParmVars = 0;
+static unsigned nSUC = 0;
+static unsigned nEnumConst = 0;
+static unsigned nEnumDecls = 0;
+static unsigned nNamespaces = 0;
+static unsigned nTypedef = 0;
+static unsigned nFieldDecls = 0;
+static unsigned nInterfaceDecls = 0;
+static unsigned nClassDecls = 0;
+static unsigned nMethodDecls = 0;
+static unsigned nProtocolDecls = 0;
+static unsigned nForwardProtocolDecls = 0;
+static unsigned nCategoryDecls = 0;
+static unsigned nIvarDecls = 0;
+static unsigned nObjCImplementationDecls = 0;
+static unsigned nObjCCategoryImpl = 0;
+static unsigned nObjCCompatibleAlias = 0;
+static unsigned nObjCPropertyDecl = 0;
+static unsigned nObjCPropertyImplDecl = 0;
+static unsigned nLinkageSpecDecl = 0;
+static unsigned nFileScopeAsmDecl = 0;
+
+static bool StatSwitch = false;
+
+// This keeps track of all decl attributes. Since so few decls have attrs, we
+// keep them in a hash map instead of wasting space in the Decl class.
+typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
+
+static DeclAttrMapTy *DeclAttrs = 0;
+
+const char *Decl::getDeclKindName() const {
+ switch (DeclKind) {
+ default: assert(0 && "Unknown decl kind!");
+ case Namespace: return "Namespace";
+ case Typedef: return "Typedef";
+ case Function: return "Function";
+ case Var: return "Var";
+ case ParmVar: return "ParmVar";
+ case EnumConstant: return "EnumConstant";
+ case ObjCIvar: return "ObjCIvar";
+ case ObjCInterface: return "ObjCInterface";
+ case ObjCClass: return "ObjCClass";
+ case ObjCMethod: return "ObjCMethod";
+ case ObjCProtocol: return "ObjCProtocol";
+ case ObjCForwardProtocol: return "ObjCForwardProtocol";
+ case Struct: return "Struct";
+ case Union: return "Union";
+ case Class: return "Class";
+ case Enum: return "Enum";
+ }
+}
+
+bool Decl::CollectingStats(bool Enable) {
+ if (Enable)
+ StatSwitch = true;
+ return StatSwitch;
+}
+
+void Decl::PrintStats() {
+ fprintf(stderr, "*** Decl Stats:\n");
+ fprintf(stderr, " %d decls total.\n",
+ int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+
+ nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
+ nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
+ nNamespaces));
+ fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n",
+ nNamespaces, (int)sizeof(NamespaceDecl),
+ int(nNamespaces*sizeof(NamespaceDecl)));
+ fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
+ nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
+ fprintf(stderr, " %d variable decls, %d each (%d bytes)\n",
+ nVars, (int)sizeof(VarDecl),
+ int(nVars*sizeof(VarDecl)));
+ fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
+ nParmVars, (int)sizeof(ParmVarDecl),
+ int(nParmVars*sizeof(ParmVarDecl)));
+ fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
+ nFieldDecls, (int)sizeof(FieldDecl),
+ int(nFieldDecls*sizeof(FieldDecl)));
+ fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
+ nSUC, (int)sizeof(RecordDecl),
+ int(nSUC*sizeof(RecordDecl)));
+ fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
+ nEnumDecls, (int)sizeof(EnumDecl),
+ int(nEnumDecls*sizeof(EnumDecl)));
+ fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
+ nEnumConst, (int)sizeof(EnumConstantDecl),
+ int(nEnumConst*sizeof(EnumConstantDecl)));
+ fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
+ nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
+ // Objective-C decls...
+ fprintf(stderr, " %d interface decls, %d each (%d bytes)\n",
+ nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
+ int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
+ fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n",
+ nIvarDecls, (int)sizeof(ObjCIvarDecl),
+ int(nIvarDecls*sizeof(ObjCIvarDecl)));
+ fprintf(stderr, " %d class decls, %d each (%d bytes)\n",
+ nClassDecls, (int)sizeof(ObjCClassDecl),
+ int(nClassDecls*sizeof(ObjCClassDecl)));
+ fprintf(stderr, " %d method decls, %d each (%d bytes)\n",
+ nMethodDecls, (int)sizeof(ObjCMethodDecl),
+ int(nMethodDecls*sizeof(ObjCMethodDecl)));
+ fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n",
+ nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
+ int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
+ fprintf(stderr, " %d forward protocol decls, %d each (%d bytes)\n",
+ nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
+ int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
+ fprintf(stderr, " %d category decls, %d each (%d bytes)\n",
+ nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
+ int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
+
+ fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n",
+ nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
+ int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
+
+ fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n",
+ nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
+ int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
+
+ fprintf(stderr, " %d compatibility alias decls, %d each (%d bytes)\n",
+ nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
+ int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
+
+ fprintf(stderr, " %d property decls, %d each (%d bytes)\n",
+ nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
+ int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
+
+ fprintf(stderr, " %d property implementation decls, %d each (%d bytes)\n",
+ nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
+ int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
+
+ fprintf(stderr, "Total bytes = %d\n",
+ int(nFuncs*sizeof(FunctionDecl)+
+ nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
+ nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
+ nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
+ nTypedef*sizeof(TypedefDecl)+
+ nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
+ nIvarDecls*sizeof(ObjCIvarDecl)+
+ nClassDecls*sizeof(ObjCClassDecl)+
+ nMethodDecls*sizeof(ObjCMethodDecl)+
+ nProtocolDecls*sizeof(ObjCProtocolDecl)+
+ nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
+ nCategoryDecls*sizeof(ObjCCategoryDecl)+
+ nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
+ nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
+ nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
+ nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
+ nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
+ nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
+ nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
+ nNamespaces*sizeof(NamespaceDecl)));
+
+}
+
+void Decl::addDeclKind(Kind k) {
+ switch (k) {
+ case Namespace: nNamespaces++; break;
+ case Typedef: nTypedef++; break;
+ case Function: nFuncs++; break;
+ case Var: nVars++; break;
+ case ParmVar: nParmVars++; break;
+ case EnumConstant: nEnumConst++; break;
+ case Field: nFieldDecls++; break;
+ case Struct: case Union: case Class: nSUC++; break;
+ case Enum: nEnumDecls++; break;
+ case ObjCInterface: nInterfaceDecls++; break;
+ case ObjCClass: nClassDecls++; break;
+ case ObjCMethod: nMethodDecls++; break;
+ case ObjCProtocol: nProtocolDecls++; break;
+ case ObjCForwardProtocol: nForwardProtocolDecls++; break;
+ case ObjCCategory: nCategoryDecls++; break;
+ case ObjCIvar: nIvarDecls++; break;
+ case ObjCImplementation: nObjCImplementationDecls++; break;
+ case ObjCCategoryImpl: nObjCCategoryImpl++; break;
+ case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
+ case ObjCProperty: nObjCPropertyDecl++; break;
+ case ObjCPropertyImpl: nObjCPropertyImplDecl++; break;
+ case LinkageSpec: nLinkageSpecDecl++; break;
+ case FileScopeAsm: nFileScopeAsmDecl++; break;
+ case TranslationUnit: break;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Decl Implementation
+//===----------------------------------------------------------------------===//
+
+// Out-of-line virtual method providing a home for Decl.
+Decl::~Decl() {
+ if (!HasAttrs)
+ return;
+
+ DeclAttrMapTy::iterator it = DeclAttrs->find(this);
+ assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
+
+ // release attributes.
+ delete it->second;
+ invalidateAttrs();
+}
+
+void Decl::addAttr(Attr *NewAttr) {
+ if (!DeclAttrs)
+ DeclAttrs = new DeclAttrMapTy();
+
+ Attr *&ExistingAttr = (*DeclAttrs)[this];
+
+ NewAttr->setNext(ExistingAttr);
+ ExistingAttr = NewAttr;
+
+ HasAttrs = true;
+}
+
+void Decl::invalidateAttrs() {
+ if (!HasAttrs) return;
+
+ HasAttrs = false;
+ (*DeclAttrs)[this] = 0;
+ DeclAttrs->erase(this);
+
+ if (DeclAttrs->empty()) {
+ delete DeclAttrs;
+ DeclAttrs = 0;
+ }
+}
+
+const Attr *Decl::getAttrs() const {
+ if (!HasAttrs)
+ return 0;
+
+ return (*DeclAttrs)[this];
+}
+
+void Decl::swapAttrs(Decl *RHS) {
+ bool HasLHSAttr = this->HasAttrs;
+ bool HasRHSAttr = RHS->HasAttrs;
+
+ // Usually, neither decl has attrs, nothing to do.
+ if (!HasLHSAttr && !HasRHSAttr) return;
+
+ // If 'this' has no attrs, swap the other way.
+ if (!HasLHSAttr)
+ return RHS->swapAttrs(this);
+
+ // Handle the case when both decls have attrs.
+ if (HasRHSAttr) {
+ std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
+ return;
+ }
+
+ // Otherwise, LHS has an attr and RHS doesn't.
+ (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
+ (*DeclAttrs).erase(this);
+ this->HasAttrs = false;
+ RHS->HasAttrs = true;
+}
+
+
+void Decl::Destroy(ASTContext& C) {
+
+ if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
+
+ // Observe the unrolled recursion. By setting N->NextDeclarator = 0x0
+ // within the loop, only the Destroy method for the first ScopedDecl
+ // will deallocate all of the ScopedDecls in a chain.
+
+ ScopedDecl* N = SD->getNextDeclarator();
+
+ while (N) {
+ ScopedDecl* Tmp = N->getNextDeclarator();
+ N->NextDeclarator = 0x0;
+ N->Destroy(C);
+ N = Tmp;
+ }
+ }
+
+ this->~Decl();
+ C.getAllocator().Deallocate((void *)this);
+}
+
+//===----------------------------------------------------------------------===//
+// DeclContext Implementation
+//===----------------------------------------------------------------------===//
+
+DeclContext *DeclContext::getParent() const {
+ if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
+ return SD->getDeclContext();
+ else
+ return NULL;
+}
+
+Decl *DeclContext::ToDecl (const DeclContext *D) {
+ return CastTo<Decl>(D);
+}
+
+DeclContext *DeclContext::FromDecl (const Decl *D) {
+ return CastTo<DeclContext>(D);
+}