diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-06-21 10:57:41 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-06-21 10:57:41 +0000 |
commit | 5bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26a (patch) | |
tree | ccefb836f9c7c2fc75d94c7782b64fa8a2fbc62d | |
parent | 4be54302da40d3e7cba3d93115f312d2fcca1879 (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.h | 66 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 47 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 5 |
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"); |