diff options
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 574 |
1 files changed, 0 insertions, 574 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp deleted file mode 100644 index 1a7eeca..0000000 --- a/clang/lib/AST/Decl.cpp +++ /dev/null @@ -1,574 +0,0 @@ -//===--- Decl.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 class and subclasses. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/Decl.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/Basic/IdentifierTable.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 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 Allocation/Deallocation Method Implementations -//===----------------------------------------------------------------------===// - -TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { - void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>(); - return new (Mem) TranslationUnitDecl(); -} - -NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id) { - void *Mem = C.getAllocator().Allocate<NamespaceDecl>(); - return new (Mem) NamespaceDecl(DC, L, Id); -} - -VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, QualType T, - StorageClass S, ScopedDecl *PrevDecl) { - void *Mem = C.getAllocator().Allocate<VarDecl>(); - return new (Mem) VarDecl(Var, DC, L, Id, T, S, PrevDecl); -} - -ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - QualType T, StorageClass S, - Expr *DefArg, ScopedDecl *PrevDecl) { - void *Mem = C.getAllocator().Allocate<ParmVarDecl>(); - return new (Mem) ParmVarDecl(DC, L, Id, T, S, DefArg, PrevDecl); -} - -FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, QualType T, - StorageClass S, bool isInline, - ScopedDecl *PrevDecl) { - void *Mem = C.getAllocator().Allocate<FunctionDecl>(); - return new (Mem) FunctionDecl(DC, L, Id, T, S, isInline, PrevDecl); -} - -FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L, - IdentifierInfo *Id, QualType T, Expr *BW) { - void *Mem = C.getAllocator().Allocate<FieldDecl>(); - return new (Mem) FieldDecl(L, Id, T, BW); -} - - -EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, - SourceLocation L, - IdentifierInfo *Id, QualType T, - Expr *E, const llvm::APSInt &V, - ScopedDecl *PrevDecl){ - void *Mem = C.getAllocator().Allocate<EnumConstantDecl>(); - return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl); -} - -TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, QualType T, - ScopedDecl *PD) { - void *Mem = C.getAllocator().Allocate<TypedefDecl>(); - return new (Mem) TypedefDecl(DC, L, Id, T, PD); -} - -EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, - ScopedDecl *PrevDecl) { - void *Mem = C.getAllocator().Allocate<EnumDecl>(); - return new (Mem) EnumDecl(DC, L, Id, PrevDecl); -} - -RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - ScopedDecl *PrevDecl) { - void *Mem = C.getAllocator().Allocate<RecordDecl>(); - return new (Mem) RecordDecl(DK, DC, L, Id, PrevDecl); -} - -FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, - SourceLocation L, - StringLiteral *Str) { - void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>(); - return new (Mem) FileScopeAsmDecl(L, Str); -} - -LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, - SourceLocation L, - LanguageIDs Lang, Decl *D) { - void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>(); - return new (Mem) LinkageSpecDecl(L, Lang, D); -} - -//===----------------------------------------------------------------------===// -// 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!"); - - delete it->second; - DeclAttrs->erase(it); - if (DeclAttrs->empty()) { - delete DeclAttrs; - DeclAttrs = 0; - } -} - -void Decl::addAttr(Attr *NewAttr) { - if (!DeclAttrs) - DeclAttrs = new DeclAttrMapTy(); - - Attr *&ExistingAttr = (*DeclAttrs)[this]; - - NewAttr->setNext(ExistingAttr); - ExistingAttr = NewAttr; - - HasAttrs = true; -} - -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; -} - - -#define CASE(KIND) \ - case KIND: \ - static_cast<KIND##Decl *>(const_cast<Decl *>(this))->~KIND##Decl(); \ - break - -void Decl::Destroy(ASTContext& C) const { - switch (getKind()) { - CASE(TranslationUnit); - CASE(Field); - CASE(ObjCIvar); - CASE(ObjCCategory); - CASE(ObjCCategoryImpl); - CASE(ObjCImplementation); - CASE(ObjCProtocol); - CASE(ObjCProperty); - CASE(Namespace); - CASE(Typedef); - CASE(Enum); - CASE(EnumConstant); - CASE(Function); - CASE(Var); - CASE(ParmVar); - CASE(ObjCInterface); - CASE(ObjCCompatibleAlias); - CASE(ObjCMethod); - CASE(ObjCClass); - CASE(ObjCForwardProtocol); - CASE(LinkageSpec); - - case Struct: case Union: case Class: - static_cast<RecordDecl *>(const_cast<Decl *>(this))->~RecordDecl(); - break; - - default: assert(0 && "Unknown decl kind!"); - } - - C.getAllocator().Deallocate((void *)this); -} - -#undef CASE - -//===----------------------------------------------------------------------===// -// 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); -} - -//===----------------------------------------------------------------------===// -// NamedDecl Implementation -//===----------------------------------------------------------------------===// - -const char *NamedDecl::getName() const { - if (const IdentifierInfo *II = getIdentifier()) - return II->getName(); - return ""; -} - -//===----------------------------------------------------------------------===// -// FunctionDecl Implementation -//===----------------------------------------------------------------------===// - -FunctionDecl::~FunctionDecl() { - delete[] ParamInfo; - delete Body; - delete PreviousDeclaration; -} - -Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { - for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) { - if (FD->Body) { - Definition = FD; - return FD->Body; - } - } - - return 0; -} - -unsigned FunctionDecl::getNumParams() const { - const FunctionType *FT = getType()->getAsFunctionType(); - if (isa<FunctionTypeNoProto>(FT)) - return 0; - return cast<FunctionTypeProto>(FT)->getNumArgs(); -} - -void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) { - assert(ParamInfo == 0 && "Already has param info!"); - assert(NumParams == getNumParams() && "Parameter count mismatch!"); - - // Zero params -> null pointer. - if (NumParams) { - ParamInfo = new ParmVarDecl*[NumParams]; - memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); - } -} - -/// getMinRequiredArguments - Returns the minimum number of arguments -/// needed to call this function. This may be fewer than the number of -/// function parameters, if some of the parameters have default -/// arguments (in C++). -unsigned FunctionDecl::getMinRequiredArguments() const { - unsigned NumRequiredArgs = getNumParams(); - while (NumRequiredArgs > 0 - && getParamDecl(NumRequiredArgs-1)->getDefaultArg()) - --NumRequiredArgs; - - return NumRequiredArgs; -} - -/// AddRedeclaration - Specifies that this function declaration has been -/// redeclared by the function declaration FD. FD must be a -/// redeclaration of this based on the semantics of the language being -/// translated ("compatible" function types in C, same signatures in -/// C++). -void FunctionDecl::AddRedeclaration(FunctionDecl *FD) { - assert(FD->PreviousDeclaration == 0 && - "Redeclaration already has a previous declaration!"); - - // Insert FD into the list of previous declarations of this - // function. - FD->PreviousDeclaration = this->PreviousDeclaration; - this->PreviousDeclaration = FD; - - // Swap the contents of this function declaration and FD. This - // effectively transforms the original declaration into the most - // recent declaration, so that all references to this declaration - // remain valid (and have information from *all* declarations), - // while retaining all of the information about previous - // declarations as well. - - // Swap parameters, so that the most recent parameter names and - // exact types (e.g., enum vs int) show up in the original - // declaration. - std::swap(this->ParamInfo, FD->ParamInfo); - - // Swap the function body: all declarations share the same function - // body, but we keep track of who actually defined that function - // body by keeping the pointer to the body stored in that node. - std::swap(this->Body, FD->Body); - - // Swap type information: this is important because in C, later - // declarations can provide slightly different types (enum vs. int, - // for example). - QualType thisType = this->getType(); - this->setType(FD->getType()); - FD->setType(thisType); - - // Swap location information: this allows us to produce diagnostics - // later on that reference the most recent declaration (which has - // the most information!) while retaining the location of previous - // declarations (good for "redefinition" diagnostics). - SourceLocation thisLocation = this->getLocation(); - this->setLocation(FD->getLocation()); - FD->setLocation(thisLocation); - - // Swap attributes. FD will have the union of the attributes from - // all previous declarations. - this->swapAttrs(FD); - - // If any declaration is inline, the function is inline. - this->IsInline |= FD->IsInline; - - // FIXME: Is this the right way to handle storage specifiers? - if (FD->SClass) this->SClass = FD->SClass; -} - -//===----------------------------------------------------------------------===// -// RecordDecl Implementation -//===----------------------------------------------------------------------===// - -/// defineBody - When created, RecordDecl's correspond to a forward declared -/// record. This method is used to mark the decl as being defined, with the -/// specified contents. -void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) { - assert(!isDefinition() && "Cannot redefine record!"); - setDefinition(true); - NumMembers = numMembers; - if (numMembers) { - Members = new FieldDecl*[numMembers]; - memcpy(Members, members, numMembers*sizeof(Decl*)); - } -} - -FieldDecl *RecordDecl::getMember(IdentifierInfo *II) { - if (Members == 0 || NumMembers < 0) - return 0; - - // Linear search. When C++ classes come along, will likely need to revisit. - for (int i = 0; i != NumMembers; ++i) - if (Members[i]->getIdentifier() == II) - return Members[i]; - return 0; -} |