aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-06-21 10:57:41 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-06-21 10:57:41 +0000
commit5bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26a (patch)
treeccefb836f9c7c2fc75d94c7782b64fa8a2fbc62d
parent4be54302da40d3e7cba3d93115f312d2fcca1879 (diff)
Combine ClassTemplateDecl's PreviousDeclaration with CommonPtr, as in FunctionTemplateDecl.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106412 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclTemplate.h66
-rw-r--r--lib/AST/DeclTemplate.cpp47
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp5
3 files changed, 53 insertions, 65 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index cf42fa03fa..3e4966e84d 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -1295,25 +1295,19 @@ protected:
llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
};
- // FIXME: Combine PreviousDeclaration with CommonPtr, as in
- // FunctionTemplateDecl.
-
- /// \brief Previous declaration of this class template.
- ClassTemplateDecl *PreviousDeclaration;
+ /// \brief A pointer to the previous declaration (if this is a redeclaration)
+ /// or to the data that is common to all declarations of this class template.
+ llvm::PointerUnion<Common*, ClassTemplateDecl*> CommonOrPrev;
- /// \brief Pointer to the data that is common to all of the
- /// declarations of this class template.
- ///
- /// The first declaration of a class template (e.g., the declaration
- /// with no "previous declaration") owns this pointer.
- Common *CommonPtr;
+ /// \brief Retrieves the "common" pointer shared by all
+ /// (re-)declarations of the same class template. Calling this routine
+ /// may implicitly allocate memory for the common pointer.
+ Common *getCommonPtr();
ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
- PreviousDeclaration(0), CommonPtr(0) { }
-
- ~ClassTemplateDecl();
+ CommonOrPrev((Common*)0) { }
public:
/// Get the underlying class declarations of the template.
@@ -1321,14 +1315,23 @@ public:
return static_cast<CXXRecordDecl *>(TemplatedDecl);
}
- /// \brief Retrieve the previous declaration of this template.
- ClassTemplateDecl *getPreviousDeclaration() const {
- return PreviousDeclaration;
+ /// \brief Retrieve the previous declaration of this class template, or
+ /// NULL if no such declaration exists.
+ const ClassTemplateDecl *getPreviousDeclaration() const {
+ return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ ClassTemplateDecl *getPreviousDeclaration() {
+ return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
}
- /// \brief Initialize the previous declaration. Only valid to call on a
- /// ClassTemplateDecl that is created using ClassTemplateDecl::CreateEmpty.
- void initPreviousDeclaration(ASTContext &C, ClassTemplateDecl *PrevDecl);
+ /// \brief Set the previous declaration of this class template.
+ void setPreviousDeclaration(ClassTemplateDecl *Prev) {
+ if (Prev)
+ CommonOrPrev = Prev;
+ }
virtual ClassTemplateDecl *getCanonicalDecl();
@@ -1340,21 +1343,16 @@ public:
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl);
- /// \brief Create an empty class template node. Mainly used for PCH reading.
- static ClassTemplateDecl *CreateEmpty(ASTContext &C) {
- return new (C) ClassTemplateDecl(0,SourceLocation(),DeclarationName(),0,0);
- }
-
/// \brief Retrieve the set of specializations of this class template.
llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
- return CommonPtr->Specializations;
+ return getCommonPtr()->Specializations;
}
/// \brief Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations() {
- return CommonPtr->PartialSpecializations;
+ return getCommonPtr()->PartialSpecializations;
}
/// \brief Retrieve the partial specializations as an ordered list.
@@ -1407,13 +1405,13 @@ public:
/// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
///
/// \returns null if this is not an instantiation of a member class template.
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return CommonPtr->InstantiatedFromMember.getPointer();
+ ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return getCommonPtr()->InstantiatedFromMember.getPointer();
}
void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
- assert(!CommonPtr->InstantiatedFromMember.getPointer());
- CommonPtr->InstantiatedFromMember.setPointer(CTD);
+ assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+ getCommonPtr()->InstantiatedFromMember.setPointer(CTD);
}
/// \brief Determines whether this template was a specialization of a
@@ -1432,14 +1430,14 @@ public:
/// struct X<int>::Inner { /* ... */ };
/// \endcode
bool isMemberSpecialization() {
- return CommonPtr->InstantiatedFromMember.getInt();
+ return getCommonPtr()->InstantiatedFromMember.getInt();
}
/// \brief Note that this member template is a specialization.
void setMemberSpecialization() {
- assert(CommonPtr->InstantiatedFromMember.getPointer() &&
+ assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
- CommonPtr->InstantiatedFromMember.setInt(true);
+ getCommonPtr()->InstantiatedFromMember.setInt(true);
}
// Implement isa/cast/dyncast support
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 1fcf92309b..a318de656f 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -155,21 +155,6 @@ ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
return Template;
}
-void ClassTemplateDecl::initPreviousDeclaration(ASTContext &C,
- ClassTemplateDecl *PrevDecl) {
- assert(PreviousDeclaration == 0 && "PreviousDeclaration already set!");
- assert(CommonPtr == 0 && "initPreviousDeclaration already called!");
-
- PreviousDeclaration = PrevDecl;
-
- if (PrevDecl)
- CommonPtr = PrevDecl->CommonPtr;
- else {
- CommonPtr = new (C) Common;
- C.AddDeallocation(DeallocateCommon, CommonPtr);
- }
-}
-
ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
@@ -178,29 +163,18 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl) {
ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
- New->initPreviousDeclaration(C, PrevDecl);
+ New->setPreviousDeclaration(PrevDecl);
return New;
}
-ClassTemplateDecl::~ClassTemplateDecl() {
- assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
-}
-
void ClassTemplateDecl::Destroy(ASTContext& C) {
- if (!PreviousDeclaration) {
- CommonPtr->~Common();
- C.Deallocate((void*)CommonPtr);
- }
- CommonPtr = 0;
-
- this->~ClassTemplateDecl();
- C.Deallocate((void*)this);
+ Decl::Destroy(C);
}
void ClassTemplateDecl::getPartialSpecializations(
llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
- = CommonPtr->PartialSpecializations;
+ = getPartialSpecializations();
PS.clear();
PS.resize(PartialSpecs.size());
for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
@@ -228,6 +202,7 @@ ClassTemplateDecl::findPartialSpecialization(QualType T) {
QualType
ClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
+ Common *CommonPtr = getCommonPtr();
if (!CommonPtr->InjectedClassNameType.isNull())
return CommonPtr->InjectedClassNameType;
@@ -264,6 +239,20 @@ ClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
return CommonPtr->InjectedClassNameType;
}
+ClassTemplateDecl::Common *ClassTemplateDecl::getCommonPtr() {
+ // Find the first declaration of this function template.
+ ClassTemplateDecl *First = this;
+ while (First->getPreviousDeclaration())
+ First = First->getPreviousDeclaration();
+
+ if (First->CommonOrPrev.isNull()) {
+ Common *CommonPtr = new (getASTContext()) Common;
+ getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+ First->CommonOrPrev = CommonPtr;
+ }
+ return First->CommonOrPrev.get<Common*>();
+}
+
//===----------------------------------------------------------------------===//
// TemplateTypeParm Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 2968aea93e..d84eb085cf 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -671,7 +671,7 @@ void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
ClassTemplateDecl *PrevDecl =
cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
- D->initPreviousDeclaration(*Reader.getContext(), PrevDecl);
+ D->setPreviousDeclaration(PrevDecl);
if (PrevDecl == 0) {
// This ClassTemplateDecl owns a CommonPtr; read it.
@@ -1085,7 +1085,8 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
assert(false && "cannot read FriendTemplateDecl");
break;
case pch::DECL_CLASS_TEMPLATE:
- D = ClassTemplateDecl::CreateEmpty(*Context);
+ D = ClassTemplateDecl::Create(*Context, 0, SourceLocation(),
+ DeclarationName(), 0, 0, 0);
break;
case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
assert(false && "cannot read ClasstemplateSpecializationDecl");