From b1fe2c90016197752ca86bf8ef18086dcf2cf96c Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 7 Apr 2009 17:20:56 +0000 Subject: [PATCH] Move the internal DeclContext data structures into a separate header. Simplify the addition of a case statement to a switch. Fix -print-stats for attribute-qualified types. llvm-svn: 68522 --- clang/include/clang/AST/Decl.h | 3 + clang/include/clang/AST/DeclBase.h | 13 +- .../include/clang/AST/DeclContextInternals.h | 135 ++++++++++++++++++ clang/include/clang/AST/DeclVisitor.h | 3 + clang/include/clang/AST/Stmt.h | 5 +- clang/lib/AST/ASTContext.cpp | 9 +- clang/lib/AST/DeclBase.cpp | 110 +------------- 7 files changed, 160 insertions(+), 118 deletions(-) create mode 100644 clang/include/clang/AST/DeclContextInternals.h diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 39a990a2dbc6..a2ad29015e0b 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -870,6 +870,9 @@ protected: : NamedDecl(DK, DC, L, Id), TypeForDecl(0) {} public: + // Low-level accessor + Type *getTypeForDecl() const { return TypeForDecl; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= TypeFirst && D->getKind() <= TypeLast; diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index abdb10dcbc50..4194ba045977 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -375,10 +375,6 @@ class DeclContext { /// another pointer. Decl *LastDecl; - /// isLookupMap - Determine if the lookup structure is a - /// DenseMap. Othewise, it is an array. - bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; } - protected: DeclContext(Decl::Kind K) : DeclKind(K), LookupPtr(), FirstDecl(0), LastDecl(0) { } @@ -761,6 +757,15 @@ public: return getUsingDirectives().second; } + // Low-level accessors + + /// \brief Determine if the lookup structure is a + /// DenseMap. Othewise, it is an array. + bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; } + + /// \brief Retrieve the internal representation of the lookup structure. + llvm::PointerIntPair getLookupPtr() const { return LookupPtr; } + static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } #define DECL_CONTEXT(Name) \ diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h new file mode 100644 index 000000000000..0aa50a1f98f9 --- /dev/null +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -0,0 +1,135 @@ +//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the data structures used in the implementation +// of DeclContext. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H +#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H + +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclarationName.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/SmallVector.h" + +namespace clang { + +/// StoredDeclsList - This is an array of decls optimized a common case of only +/// containing one entry. +struct StoredDeclsList { + /// VectorTy - When in vector form, this is what the Data pointer points to. + typedef llvm::SmallVector VectorTy; + + /// Data - Union of NamedDecl*/VectorTy*. + llvm::PointerUnion Data; +public: + StoredDeclsList() {} + StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { + if (isVector()) + Data = new VectorTy(*Data.get()); + } + + ~StoredDeclsList() { + // If this is a vector-form, free the vector. + if (isVector()) + delete Data.get(); + } + + StoredDeclsList &operator=(const StoredDeclsList &RHS) { + if (isVector()) + delete Data.get(); + Data = RHS.Data; + if (isVector()) + Data = new VectorTy(*Data.get()); + return *this; + } + + bool isVector() const { return Data.is(); } + bool isInline() const { return Data.is(); } + bool isNull() const { return Data.isNull(); } + + void setOnlyValue(NamedDecl *ND) { + assert(isInline() && "Not inline"); + Data = ND; + } + + /// getLookupResult - Return an array of all the decls that this list + /// represents. + DeclContext::lookup_result getLookupResult() { + // If we have a single inline unit, return it. + if (isInline()) { + assert(!isNull() && "Empty list isn't allowed"); + + // Data is a raw pointer to a NamedDecl*, return it. + void *Ptr = &Data; + return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); + } + + // Otherwise, we have a range result. + VectorTy &V = *Data.get(); + return DeclContext::lookup_result(&V[0], &V[0]+V.size()); + } + + /// HandleRedeclaration - If this is a redeclaration of an existing decl, + /// replace the old one with D and return true. Otherwise return false. + bool HandleRedeclaration(NamedDecl *D) { + // Most decls only have one entry in their list, special case it. + if (isInline()) { + if (!D->declarationReplaces(Data.get())) + return false; + setOnlyValue(D); + return true; + } + + // Determine if this declaration is actually a redeclaration. + VectorTy &Vec = *Data.get(); + VectorTy::iterator RDI + = std::find_if(Vec.begin(), Vec.end(), + std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces), + D)); + if (RDI == Vec.end()) + return false; + *RDI = D; + return true; + } + + /// AddSubsequentDecl - This is called on the second and later decl when it is + /// not a redeclaration to merge it into the appropriate place in our list. + /// + void AddSubsequentDecl(NamedDecl *D) { + // If this is the second decl added to the list, convert this to vector + // form. + if (isInline()) { + NamedDecl *OldD = Data.get(); + VectorTy *VT = new VectorTy(); + VT->push_back(OldD); + Data = VT; + } + + VectorTy &Vec = *Data.get(); + if (isa(D) || + D->getIdentifierNamespace() == Decl::IDNS_Tag) + Vec.push_back(D); + else if (Vec.back()->getIdentifierNamespace() == Decl::IDNS_Tag) { + NamedDecl *TagD = Vec.back(); + Vec.back() = D; + Vec.push_back(TagD); + } else + Vec.push_back(D); + } +}; + +typedef llvm::DenseMap StoredDeclsMap; + + +} // end namespace clang + +#endif diff --git a/clang/include/clang/AST/DeclVisitor.h b/clang/include/clang/AST/DeclVisitor.h index 28c10c7e182f..9423c319c3e3 100644 --- a/clang/include/clang/AST/DeclVisitor.h +++ b/clang/include/clang/AST/DeclVisitor.h @@ -13,6 +13,9 @@ #ifndef LLVM_CLANG_AST_DECLVISITOR_H #define LLVM_CLANG_AST_DECLVISITOR_H +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" namespace clang { diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 11023234b040..c99f0a9b2fa8 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -587,9 +587,8 @@ public: SwitchLoc = SL; } void addSwitchCase(SwitchCase *SC) { - if (FirstCase) - SC->setNextSwitchCase(FirstCase); - + assert(!SC->getNextSwitchCase() && "case/default already added to a switch"); + SC->setNextSwitchCase(FirstCase); FirstCase = SC; } virtual SourceRange getSourceRange() const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 99de7cbf59bd..307c0e4454af 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -103,7 +103,8 @@ void ASTContext::PrintStats() const { unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0; unsigned NumObjCQualifiedIds = 0; unsigned NumTypeOfTypes = 0, NumTypeOfExprTypes = 0; - + unsigned NumExtQual = 0; + for (unsigned i = 0, e = Types.size(); i != e; ++i) { Type *T = Types[i]; if (isa(T)) @@ -149,6 +150,8 @@ void ASTContext::PrintStats() const { ++NumTypeOfTypes; else if (isa(T)) ++NumTypeOfExprTypes; + else if (isa(T)) + ++NumExtQual; else { QualType(T, 0).dump(); assert(0 && "Unknown type!"); @@ -179,6 +182,7 @@ void ASTContext::PrintStats() const { NumObjCQualifiedIds); fprintf(stderr, " %d typeof types\n", NumTypeOfTypes); fprintf(stderr, " %d typeof exprs\n", NumTypeOfExprTypes); + fprintf(stderr, " %d attribute-qualified types\n", NumExtQual); fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+ NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+ @@ -189,7 +193,8 @@ void ASTContext::PrintStats() const { NumFunctionP*sizeof(FunctionProtoType)+ NumFunctionNP*sizeof(FunctionNoProtoType)+ NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+ - NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprTypes*sizeof(TypeOfExprType))); + NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprTypes*sizeof(TypeOfExprType)+ + NumExtQual*sizeof(ExtQualType))); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 0abe047a80c8..615bf00087b4 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -13,6 +13,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" @@ -363,115 +364,6 @@ bool DeclContext::classof(const Decl *D) { } } -/// StoredDeclsList - This is an array of decls optimized a common case of only -/// containing one entry. -struct StoredDeclsList { - /// VectorTy - When in vector form, this is what the Data pointer points to. - typedef llvm::SmallVector VectorTy; - - /// Data - Union of NamedDecl*/VectorTy*. - llvm::PointerUnion Data; -public: - StoredDeclsList() {} - StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { - if (isVector()) - Data = new VectorTy(*Data.get()); - } - - ~StoredDeclsList() { - // If this is a vector-form, free the vector. - if (isVector()) - delete Data.get(); - } - - StoredDeclsList &operator=(const StoredDeclsList &RHS) { - if (isVector()) - delete Data.get(); - Data = RHS.Data; - if (isVector()) - Data = new VectorTy(*Data.get()); - return *this; - } - - bool isVector() const { return Data.is(); } - bool isInline() const { return Data.is(); } - bool isNull() const { return Data.isNull(); } - - void setOnlyValue(NamedDecl *ND) { - assert(isInline() && "Not inline"); - Data = ND; - } - - /// getLookupResult - Return an array of all the decls that this list - /// represents. - DeclContext::lookup_result getLookupResult() { - // If we have a single inline unit, return it. - if (isInline()) { - assert(!isNull() && "Empty list isn't allowed"); - - // Data is a raw pointer to a NamedDecl*, return it. - void *Ptr = &Data; - return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); - } - - // Otherwise, we have a range result. - VectorTy &V = *Data.get(); - return DeclContext::lookup_result(&V[0], &V[0]+V.size()); - } - - /// HandleRedeclaration - If this is a redeclaration of an existing decl, - /// replace the old one with D and return true. Otherwise return false. - bool HandleRedeclaration(NamedDecl *D) { - // Most decls only have one entry in their list, special case it. - if (isInline()) { - if (!D->declarationReplaces(Data.get())) - return false; - setOnlyValue(D); - return true; - } - - // Determine if this declaration is actually a redeclaration. - VectorTy &Vec = *Data.get(); - VectorTy::iterator RDI - = std::find_if(Vec.begin(), Vec.end(), - std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces), - D)); - if (RDI == Vec.end()) - return false; - *RDI = D; - return true; - } - - /// AddSubsequentDecl - This is called on the second and later decl when it is - /// not a redeclaration to merge it into the appropriate place in our list. - /// - void AddSubsequentDecl(NamedDecl *D) { - // If this is the second decl added to the list, convert this to vector - // form. - if (isInline()) { - NamedDecl *OldD = Data.get(); - VectorTy *VT = new VectorTy(); - VT->push_back(OldD); - Data = VT; - } - - VectorTy &Vec = *Data.get(); - if (isa(D) || - D->getIdentifierNamespace() == Decl::IDNS_Tag) - Vec.push_back(D); - else if (Vec.back()->getIdentifierNamespace() == Decl::IDNS_Tag) { - NamedDecl *TagD = Vec.back(); - Vec.back() = D; - Vec.push_back(TagD); - } else - Vec.push_back(D); - } -}; - - - -typedef llvm::DenseMap StoredDeclsMap; - DeclContext::~DeclContext() { if (isLookupMap()) delete static_cast(LookupPtr.getPointer());