diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 681765fd0080..c5fa5d308f79 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLTEMPLATE_H #include "clang/AST/DeclCXX.h" +#include "clang/AST/Redeclarable.h" #include "clang/AST/TemplateBase.h" #include "llvm/ADT/PointerUnion.h" #include @@ -478,23 +479,12 @@ public: }; /// Declaration of a redeclarable template. -class RedeclarableTemplateDecl : public TemplateDecl { - - RedeclarableTemplateDecl *getPreviousDeclarationImpl() { - return CommonOrPrev.dyn_cast(); - } - - RedeclarableTemplateDecl *getCanonicalDeclImpl(); - - void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev); - - RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() { - return getCommonPtr()->InstantiatedFromMember.getPointer(); - } - - void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) { - assert(!getCommonPtr()->InstantiatedFromMember.getPointer()); - getCommonPtr()->InstantiatedFromMember.setPointer(TD); +class RedeclarableTemplateDecl : public TemplateDecl, + public Redeclarable +{ + typedef Redeclarable redeclarable_base; + virtual RedeclarableTemplateDecl *getNextRedeclaration() { + return RedeclLink.getNext(); } protected: @@ -564,15 +554,12 @@ protected: /// was explicitly specialized. llvm::PointerIntPair InstantiatedFromMember; - - /// \brief The latest declaration of this template. - RedeclarableTemplateDecl *Latest; }; - /// \brief A pointer to the previous declaration (if this is a redeclaration) - /// or to the data that is common to all declarations of this template. - llvm::PointerUnion CommonOrPrev; - + /// \brief Pointer to the common data shared by all declarations of this + /// template. + CommonBase *Common; + /// \brief Retrieves the "common" pointer shared by all (re-)declarations of /// the same template. Calling this routine may implicitly allocate memory /// for the common pointer. @@ -584,53 +571,15 @@ protected: RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl) - : TemplateDecl(DK, DC, L, Name, Params, Decl), - CommonOrPrev((CommonBase*)0) { } + : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { } public: template friend class RedeclarableTemplate; - RedeclarableTemplateDecl *getCanonicalDecl() { - return getCanonicalDeclImpl(); - } - - /// \brief Retrieve the previous declaration of this template, or - /// NULL if no such declaration exists. - RedeclarableTemplateDecl *getPreviousDeclaration() { - return getPreviousDeclarationImpl(); - } - - /// \brief Retrieve the previous declaration of this template, or - /// NULL if no such declaration exists. - const RedeclarableTemplateDecl *getPreviousDeclaration() const { - return - const_cast(this)->getPreviousDeclaration(); - } - - /// \brief Retrieve the first declaration of this template, or itself - /// if this the first one. - RedeclarableTemplateDecl *getFirstDeclaration() { - return getCanonicalDecl(); - } - - /// \brief Retrieve the first declaration of this template, or itself - /// if this the first one. - const RedeclarableTemplateDecl *getFirstDeclaration() const { - return - const_cast(this)->getFirstDeclaration(); - } - - /// \brief Retrieve the most recent declaration of this template, or itself - /// if this the most recent one. - RedeclarableTemplateDecl *getMostRecentDeclaration() { - return getCommonPtr()->Latest; - } - - /// \brief Retrieve the most recent declaration of this template, or itself - /// if this the most recent one. - const RedeclarableTemplateDecl *getMostRecentDeclaration() const { - return - const_cast(this)->getMostRecentDeclaration(); + /// Retrieves the canonical declaration of this template. + RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); } + const RedeclarableTemplateDecl *getCanonicalDecl() const { + return getFirstDeclaration(); } /// \brief Determines whether this template was a specialization of a @@ -665,10 +614,21 @@ public: /// \brief Retrieve the previous declaration of this template, or /// NULL if no such declaration exists. RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() { - return getInstantiatedFromMemberTemplateImpl(); + return getCommonPtr()->InstantiatedFromMember.getPointer(); } - virtual RedeclarableTemplateDecl *getNextRedeclaration(); + void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) { + assert(!getCommonPtr()->InstantiatedFromMember.getPointer()); + getCommonPtr()->InstantiatedFromMember.setPointer(TD); + } + + typedef redeclarable_base::redecl_iterator redecl_iterator; + redecl_iterator redecls_begin() const { + return redeclarable_base::redecls_begin(); + } + redecl_iterator redecls_end() const { + return redeclarable_base::redecls_end(); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -680,80 +640,11 @@ public: return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; } + friend class ASTReader; friend class ASTDeclReader; friend class ASTDeclWriter; }; -template -class RedeclarableTemplate { - RedeclarableTemplateDecl *thisDecl() { - return static_cast(this); - } - -public: - /// \brief Retrieve the previous declaration of this function template, or - /// NULL if no such declaration exists. - decl_type *getPreviousDeclaration() { - return static_cast(thisDecl()->getPreviousDeclarationImpl()); - } - - /// \brief Retrieve the previous declaration of this function template, or - /// NULL if no such declaration exists. - const decl_type *getPreviousDeclaration() const { - return const_cast(this)->getPreviousDeclaration(); - } - - /// \brief Set the previous declaration of this function template. - void setPreviousDeclaration(decl_type *Prev) { - thisDecl()->setPreviousDeclarationImpl(Prev); - } - - decl_type *getCanonicalDecl() { - return static_cast(thisDecl()->getCanonicalDeclImpl()); - } - - const decl_type *getCanonicalDecl() const { - return const_cast(this)->getCanonicalDecl(); - } - - /// \brief Retrieve the member template that this template was instantiated - /// from. - /// - /// This routine will return non-NULL for member templates of - /// class templates. For example, given: - /// - /// \code - /// template - /// struct X { - /// template void f(); - /// template struct A {}; - /// }; - /// \endcode - /// - /// X::f is a CXXMethodDecl (whose parent is X, a - /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will - /// return X::f, a FunctionTemplateDecl (whose parent is again - /// X) for which getInstantiatedFromMemberTemplate() will return - /// X::f, a FunctionTemplateDecl (whose parent is X, a - /// ClassTemplateDecl). - /// - /// X::A is a ClassTemplateSpecializationDecl (whose parent - /// is X, also a CTSD) for which getSpecializedTemplate() will - /// return X::A, a ClassTemplateDecl (whose parent is again - /// X) for which getInstantiatedFromMemberTemplate() will return - /// X::A, a ClassTemplateDecl (whose parent is X, also a CTD). - /// - /// \returns NULL if this is not an instantiation of a member template. - decl_type *getInstantiatedFromMemberTemplate() { - return static_cast( - thisDecl()->getInstantiatedFromMemberTemplateImpl()); - } - - void setInstantiatedFromMemberTemplate(decl_type *TD) { - thisDecl()->setInstantiatedFromMemberTemplateImpl(TD); - } -}; - template <> struct RedeclarableTemplateDecl:: SpecEntryTraits { typedef FunctionDecl DeclType; @@ -765,13 +656,10 @@ SpecEntryTraits { }; /// Declaration of a template function. -class FunctionTemplateDecl : public RedeclarableTemplateDecl, - public RedeclarableTemplate { +class FunctionTemplateDecl : public RedeclarableTemplateDecl { static void DeallocateCommon(void *Ptr); protected: - typedef RedeclarableTemplate redeclarable_base; - /// \brief Data that is common to all of the declarations of a given /// function template. struct Common : CommonBase { @@ -834,26 +722,31 @@ public: unsigned NumArgs, void *&InsertPos); FunctionTemplateDecl *getCanonicalDecl() { - return redeclarable_base::getCanonicalDecl(); + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); } const FunctionTemplateDecl *getCanonicalDecl() const { - return redeclarable_base::getCanonicalDecl(); + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. FunctionTemplateDecl *getPreviousDeclaration() { - return redeclarable_base::getPreviousDeclaration(); + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDeclaration()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. const FunctionTemplateDecl *getPreviousDeclaration() const { - return redeclarable_base::getPreviousDeclaration(); + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDeclaration()); } FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { - return redeclarable_base::getInstantiatedFromMemberTemplate(); + return cast_or_null( + RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } typedef SpecIterator spec_iterator; @@ -1745,13 +1638,10 @@ public: }; /// Declaration of a class template. -class ClassTemplateDecl : public RedeclarableTemplateDecl, - public RedeclarableTemplate { +class ClassTemplateDecl : public RedeclarableTemplateDecl { static void DeallocateCommon(void *Ptr); protected: - typedef RedeclarableTemplate redeclarable_base; - /// \brief Data that is common to all of the declarations of a given /// class template. struct Common : CommonBase { @@ -1836,26 +1726,31 @@ public: void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos); ClassTemplateDecl *getCanonicalDecl() { - return redeclarable_base::getCanonicalDecl(); + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); } const ClassTemplateDecl *getCanonicalDecl() const { - return redeclarable_base::getCanonicalDecl(); + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); } /// \brief Retrieve the previous declaration of this class template, or /// NULL if no such declaration exists. ClassTemplateDecl *getPreviousDeclaration() { - return redeclarable_base::getPreviousDeclaration(); + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDeclaration()); } /// \brief Retrieve the previous declaration of this class template, or /// NULL if no such declaration exists. const ClassTemplateDecl *getPreviousDeclaration() const { - return redeclarable_base::getPreviousDeclaration(); + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDeclaration()); } ClassTemplateDecl *getInstantiatedFromMemberTemplate() { - return redeclarable_base::getInstantiatedFromMemberTemplate(); + return cast_or_null( + RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } /// \brief Return the partial specialization with the provided arguments if it @@ -2041,13 +1936,10 @@ public: /// Declaration of an alias template. For example: /// /// template using V = std::map>; -class TypeAliasTemplateDecl : public RedeclarableTemplateDecl, - public RedeclarableTemplate { +class TypeAliasTemplateDecl : public RedeclarableTemplateDecl { static void DeallocateCommon(void *Ptr); protected: - typedef RedeclarableTemplate redeclarable_base; - typedef CommonBase Common; TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, @@ -2068,26 +1960,31 @@ public: TypeAliasTemplateDecl *getCanonicalDecl() { - return redeclarable_base::getCanonicalDecl(); + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); } const TypeAliasTemplateDecl *getCanonicalDecl() const { - return redeclarable_base::getCanonicalDecl(); + return cast( + RedeclarableTemplateDecl::getCanonicalDecl()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. TypeAliasTemplateDecl *getPreviousDeclaration() { - return redeclarable_base::getPreviousDeclaration(); + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDeclaration()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. const TypeAliasTemplateDecl *getPreviousDeclaration() const { - return redeclarable_base::getPreviousDeclaration(); + return cast_or_null( + RedeclarableTemplateDecl::getPreviousDeclaration()); } TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() { - return redeclarable_base::getInstantiatedFromMemberTemplate(); + return cast_or_null( + RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index f505321f035f..a74552621970 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -112,42 +112,30 @@ static void AdoptTemplateParameterList(TemplateParameterList *Params, //===----------------------------------------------------------------------===// RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() { - // Find the first declaration of this function template. - RedeclarableTemplateDecl *First = getCanonicalDecl(); + if (!Common) { + // Walk the previous-declaration chain until we either find a declaration + // with a common pointer or we run out of previous declarations. + llvm::SmallVector PrevDecls; + for (RedeclarableTemplateDecl *Prev = getPreviousDeclaration(); Prev; + Prev = Prev->getPreviousDeclaration()) { + if (Prev->Common) { + Common = Prev->Common; + break; + } + + PrevDecls.push_back(Prev); + } - if (First->CommonOrPrev.isNull()) { - CommonBase *CommonPtr = First->newCommon(getASTContext()); - First->CommonOrPrev = CommonPtr; - CommonPtr->Latest = First; + // If we never found a common pointer, allocate one now. + if (!Common) + Common = newCommon(getASTContext()); + + // Update any previous declarations we saw with the common pointer. + for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) + PrevDecls[I]->Common = Common; } - return First->CommonOrPrev.get(); -} - -RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() { - RedeclarableTemplateDecl *Tmpl = this; - while (Tmpl->getPreviousDeclaration()) - Tmpl = Tmpl->getPreviousDeclaration(); - return Tmpl; -} - -void RedeclarableTemplateDecl::setPreviousDeclarationImpl( - RedeclarableTemplateDecl *Prev) { - if (Prev) { - CommonBase *Common = Prev->getCommonPtr(); - Prev = Common->Latest; - Common->Latest = this; - CommonOrPrev = Prev; - } else { - assert(CommonOrPrev.is() && "Cannot reset TemplateDecl Prev"); - } -} - -RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() { - if (CommonOrPrev.is()) - return CommonOrPrev.get(); - CommonBase *Common = CommonOrPrev.get(); - return Common ? Common->Latest : this; + return Common; } template diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index fa21bf5fdbfa..2417845ff731 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6152,10 +6152,10 @@ void ASTReader::finishPendingActions() { PendingChainedObjCCategories.clear(); } - // If we deserialized any C++ or Objective-C class definitions or any - // Objective-C protocol definitions, make sure that all redeclarations point - // to the definitions. Note that this can only happen now, after the - // redeclaration chains have been fully wired. + // If we deserialized any C++ or Objective-C class definitions, any + // Objective-C protocol definitions, or any redeclarable templates, make sure + // that all redeclarations point to the definitions. Note that this can only + // happen now, after the redeclaration chains have been fully wired. for (llvm::SmallPtrSet::iterator D = PendingDefinitions.begin(), DEnd = PendingDefinitions.end(); D != DEnd; ++D) { @@ -6177,11 +6177,21 @@ void ASTReader::finishPendingActions() { continue; } - ObjCProtocolDecl *PD = cast(*D); - for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(), - REnd = PD->redecls_end(); + if (ObjCProtocolDecl *PD = dyn_cast(*D)) { + for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(), + REnd = PD->redecls_end(); + R != REnd; ++R) + R->Data = PD->Data; + + continue; + } + + RedeclarableTemplateDecl *RTD + = cast(*D)->getCanonicalDecl(); + for (RedeclarableTemplateDecl::redecl_iterator R = RTD->redecls_begin(), + REnd = RTD->redecls_end(); R != REnd; ++R) - R->Data = PD->Data; + R->Common = RTD->Common; } PendingDefinitions.clear(); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 75c079fb65bb..21a0fb06a9c3 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1234,72 +1234,40 @@ void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { ASTDeclReader::RedeclarableResult ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { - // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr() - // can be used while this is still initializing. - enum RedeclKind { FirstDeclaration, FirstInFile, PointsToPrevious }; - RedeclKind Kind = (RedeclKind)Record[Idx++]; - - // Determine the first declaration ID. - DeclID FirstDeclID = 0; - switch (Kind) { - case FirstDeclaration: { - FirstDeclID = ThisDeclID; + RedeclarableResult Redecl = VisitRedeclarable(D); - // Since this is the first declaration of the template, fill in the - // information for the 'common' pointer. - if (D->CommonOrPrev.isNull()) { - RedeclarableTemplateDecl::CommonBase *Common - = D->newCommon(Reader.getContext()); - Common->Latest = D; - D->CommonOrPrev = Common; - } + // Make sure we've allocated the Common pointer first. We do this before + // VisitTemplateDecl so that getCommonPtr() can be used during initialization. + RedeclarableTemplateDecl *CanonD = D->getCanonicalDecl(); + if (!CanonD->Common) { + CanonD->Common = CanonD->newCommon(Reader.getContext()); + Reader.PendingDefinitions.insert(CanonD); + } + D->Common = CanonD->Common; + // If this is the first declaration of the template, fill in the information + // for the 'common' pointer. + if (ThisDeclID == Redecl.getFirstID()) { if (RedeclarableTemplateDecl *RTD = ReadDeclAs(Record, Idx)) { assert(RTD->getKind() == D->getKind() && "InstantiatedFromMemberTemplate kind mismatch"); - D->setInstantiatedFromMemberTemplateImpl(RTD); + D->setInstantiatedFromMemberTemplate(RTD); if (Record[Idx++]) D->setMemberSpecialization(); } - break; } - - case FirstInFile: - case PointsToPrevious: { - FirstDeclID = ReadDeclID(Record, Idx); - DeclID PrevDeclID = ReadDeclID(Record, Idx); - - RedeclarableTemplateDecl *FirstDecl - = cast_or_null(Reader.GetDecl(FirstDeclID)); - - // We delay loading of the redeclaration chain to avoid deeply nested calls. - // We temporarily set the first (canonical) declaration as the previous one - // which is the one that matters and mark the real previous DeclID to be - // loaded and attached later on. - D->CommonOrPrev = FirstDecl; - - if (Kind == PointsToPrevious) { - // Make a note that we need to wire up this declaration to its - // previous declaration, later. We don't need to do this for the first - // declaration in any given module file, because those will be wired - // together later. - Reader.PendingPreviousDecls.push_back(std::make_pair(D, PrevDeclID)); - } - break; - } - } - + VisitTemplateDecl(D); D->IdentifierNamespace = Record[Idx++]; - return RedeclarableResult(Reader, FirstDeclID); + return Redecl; } void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { - VisitRedeclarableTemplateDecl(D); + RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); - if (D->getPreviousDeclaration() == 0) { + if (ThisDeclID == Redecl.getFirstID()) { // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. SmallVector SpecIDs; @@ -1321,6 +1289,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { typedef serialization::DeclID DeclID; ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr(); + // FIXME: Append specializations! CommonPtr->LazySpecializations = new (Reader.getContext()) DeclID [SpecIDs.size()]; memcpy(CommonPtr->LazySpecializations, SpecIDs.data(), @@ -1415,9 +1384,9 @@ void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl( } void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { - VisitRedeclarableTemplateDecl(D); + RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); - if (D->getPreviousDeclaration() == 0) { + if (ThisDeclID == Redecl.getFirstID()) { // This FunctionTemplateDecl owns a CommonPtr; read it. // Read the function specialization declarations. @@ -1808,7 +1777,7 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) { ND->RedeclLink.setPointer(cast(previous)); } else { RedeclarableTemplateDecl *TD = cast(D); - TD->CommonOrPrev = cast(previous); + TD->RedeclLink.setPointer(cast(previous)); } } @@ -1841,7 +1810,9 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) { cast(Latest)); } else { RedeclarableTemplateDecl *TD = cast(D); - TD->getCommonPtr()->Latest = cast(Latest); + TD->RedeclLink + = Redeclarable::LatestDeclLink( + cast(Latest)); } } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index b0ba7b47c9d8..32432c0a4fcf 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1031,38 +1031,17 @@ void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) { } void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { + VisitRedeclarable(D); + // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that // getCommonPtr() can be used while this is still initializing. - enum { FirstDeclaration, FirstInFile, PointsToPrevious }; - RedeclarableTemplateDecl *Prev = D->getPreviousDeclaration(); - RedeclarableTemplateDecl *First = 0; - if (!Prev) { - Record.push_back(FirstDeclaration); - + if (D->isFirstDeclaration()) { // This declaration owns the 'common' pointer, so serialize that data now. Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record); if (D->getInstantiatedFromMemberTemplate()) Record.push_back(D->isMemberSpecialization()); - } else { - First = D->getFirstDeclaration(); - Record.push_back(Prev->isFromASTFile()? FirstInFile : PointsToPrevious); - Writer.AddDeclRef(First, Record); - Writer.AddDeclRef(Prev, Record); } - if (D->getMostRecentDeclaration() != D && (!Prev || Prev->isFromASTFile())) { - if (!First) - First = D->getFirstDeclaration(); - - // Capture the set of redeclarations in this file. - LocalRedeclarationsInfo LocalInfo = { - Writer.GetDeclRef(First), - Writer.GetDeclRef(D), - Writer.GetDeclRef(D->getMostRecentDeclaration()) - }; - Writer.LocalRedeclarations.push_back(LocalInfo); - } - VisitTemplateDecl(D); Record.push_back(D->getIdentifierNamespace()); } @@ -1070,7 +1049,7 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->getPreviousDeclaration() == 0) { + if (D->isFirstDeclaration()) { typedef llvm::FoldingSet CTSDSetTy; CTSDSetTy &CTSDSet = D->getSpecializations(); Record.push_back(CTSDSet.size()); @@ -1158,7 +1137,7 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->getPreviousDeclaration() == 0) { + if (D->isFirstDeclaration()) { // This FunctionTemplateDecl owns the CommonPtr; write it. // Write the function specialization declarations.