[cfe-commits] r148181 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/DeclTemplate.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp

Douglas Gregor dgregor at apple.com
Sat Jan 14 07:13:50 PST 2012


Author: dgregor
Date: Sat Jan 14 09:13:49 2012
New Revision: 148181

URL: http://llvm.org/viewvc/llvm-project?rev=148181&view=rev
Log:
Reimplement RedeclarableTemplateDecl in terms of
Redeclarable<RedeclarableTemplateDecl>, eliminating a bunch of
redeclaration-chain logic both in RedeclarableTemplateDecl and
especially in its (de-)serialization.

As part of this, eliminate the RedeclarableTemplate<> class template,
which was an abstraction that didn't actually save anything.

Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=148181&r1=148180&r2=148181&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Sat Jan 14 09:13:49 2012
@@ -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 <limits>
@@ -478,23 +479,12 @@
 };
 
 /// Declaration of a redeclarable template.
-class RedeclarableTemplateDecl : public TemplateDecl {
-
-  RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
-    return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
-  }
-
-  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<RedeclarableTemplateDecl> 
+{
+  typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
+  virtual RedeclarableTemplateDecl *getNextRedeclaration() {
+    return RedeclLink.getNext();
   }
 
 protected:
@@ -564,15 +554,12 @@
     /// was explicitly specialized.
     llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
       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<CommonBase*, RedeclarableTemplateDecl*> 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 @@
   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 <class decl_type> 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<RedeclarableTemplateDecl*>(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<RedeclarableTemplateDecl*>(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<RedeclarableTemplateDecl*>(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 @@
   /// \brief Retrieve the previous declaration of this template, or
   /// NULL if no such declaration exists.
   RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
-    return getInstantiatedFromMemberTemplateImpl();
+    return getCommonPtr()->InstantiatedFromMember.getPointer();
+  }
+
+  void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
+    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
   }
 
-  virtual RedeclarableTemplateDecl *getNextRedeclaration();
+  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 @@
     return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
   }
 
+  friend class ASTReader;
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
 };
 
-template <class decl_type>
-class RedeclarableTemplate {
-  RedeclarableTemplateDecl *thisDecl() {
-    return static_cast<decl_type*>(this);
-  }
-
-public:
-  /// \brief Retrieve the previous declaration of this function template, or
-  /// NULL if no such declaration exists.
-  decl_type *getPreviousDeclaration() {
-    return static_cast<decl_type*>(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<RedeclarableTemplate*>(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<decl_type*>(thisDecl()->getCanonicalDeclImpl());
-  }
-
-  const decl_type *getCanonicalDecl() const {
-    return const_cast<RedeclarableTemplate*>(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 <typename T>
-  /// struct X {
-  ///   template <typename U> void f();
-  ///   template <typename U> struct A {};
-  /// };
-  /// \endcode
-  ///
-  /// X<int>::f<float> is a CXXMethodDecl (whose parent is X<int>, a
-  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
-  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
-  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
-  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
-  /// ClassTemplateDecl).
-  ///
-  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
-  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
-  /// return X<int>::A<U>, a ClassTemplateDecl (whose parent is again
-  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
-  /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
-  ///
-  /// \returns NULL if this is not an instantiation of a member template.
-  decl_type *getInstantiatedFromMemberTemplate() {
-    return static_cast<decl_type*>(
-             thisDecl()->getInstantiatedFromMemberTemplateImpl());
-  }
-
-  void setInstantiatedFromMemberTemplate(decl_type *TD) {
-    thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
-  }
-};
-
 template <> struct RedeclarableTemplateDecl::
 SpecEntryTraits<FunctionTemplateSpecializationInfo> {
   typedef FunctionDecl DeclType;
@@ -765,13 +656,10 @@
 };
 
 /// Declaration of a template function.
-class FunctionTemplateDecl : public RedeclarableTemplateDecl,
-                             public RedeclarableTemplate<FunctionTemplateDecl> {
+class FunctionTemplateDecl : public RedeclarableTemplateDecl {
   static void DeallocateCommon(void *Ptr);
 
 protected:
-  typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
-
   /// \brief Data that is common to all of the declarations of a given
   /// function template.
   struct Common : CommonBase {
@@ -834,26 +722,31 @@
                                    unsigned NumArgs, void *&InsertPos);
 
   FunctionTemplateDecl *getCanonicalDecl() {
-    return redeclarable_base::getCanonicalDecl();
+    return cast<FunctionTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
   }
   const FunctionTemplateDecl *getCanonicalDecl() const {
-    return redeclarable_base::getCanonicalDecl();
+    return cast<FunctionTemplateDecl>(
+             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<FunctionTemplateDecl>(
+             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<FunctionTemplateDecl>(
+             RedeclarableTemplateDecl::getPreviousDeclaration());
   }
 
   FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
-    return redeclarable_base::getInstantiatedFromMemberTemplate();
+    return cast_or_null<FunctionTemplateDecl>(
+             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
   }
 
   typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
@@ -1745,13 +1638,10 @@
 };
 
 /// Declaration of a class template.
-class ClassTemplateDecl : public RedeclarableTemplateDecl,
-                          public RedeclarableTemplate<ClassTemplateDecl> {
+class ClassTemplateDecl : public RedeclarableTemplateDecl {
   static void DeallocateCommon(void *Ptr);
 
 protected:
-  typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
-
   /// \brief Data that is common to all of the declarations of a given
   /// class template.
   struct Common : CommonBase {
@@ -1836,26 +1726,31 @@
   void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
 
   ClassTemplateDecl *getCanonicalDecl() {
-    return redeclarable_base::getCanonicalDecl();
+    return cast<ClassTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
   }
   const ClassTemplateDecl *getCanonicalDecl() const {
-    return redeclarable_base::getCanonicalDecl();
+    return cast<ClassTemplateDecl>(
+             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<ClassTemplateDecl>(
+             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<ClassTemplateDecl>(
+             RedeclarableTemplateDecl::getPreviousDeclaration());
   }
 
   ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
-    return redeclarable_base::getInstantiatedFromMemberTemplate();
+    return cast_or_null<ClassTemplateDecl>(
+             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
   }
 
   /// \brief Return the partial specialization with the provided arguments if it
@@ -2041,13 +1936,10 @@
 /// Declaration of an alias template.  For example:
 ///
 /// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
-class TypeAliasTemplateDecl : public RedeclarableTemplateDecl,
-                            public RedeclarableTemplate<TypeAliasTemplateDecl> {
+class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
   static void DeallocateCommon(void *Ptr);
 
 protected:
-  typedef RedeclarableTemplate<TypeAliasTemplateDecl> redeclarable_base;
-
   typedef CommonBase Common;
 
   TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
@@ -2068,26 +1960,31 @@
 
 
   TypeAliasTemplateDecl *getCanonicalDecl() {
-    return redeclarable_base::getCanonicalDecl();
+    return cast<TypeAliasTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
   }
   const TypeAliasTemplateDecl *getCanonicalDecl() const {
-    return redeclarable_base::getCanonicalDecl();
+    return cast<TypeAliasTemplateDecl>(
+             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<TypeAliasTemplateDecl>(
+             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<TypeAliasTemplateDecl>(
+             RedeclarableTemplateDecl::getPreviousDeclaration());
   }
 
   TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
-    return redeclarable_base::getInstantiatedFromMemberTemplate();
+    return cast_or_null<TypeAliasTemplateDecl>(
+             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
   }
 
 

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=148181&r1=148180&r2=148181&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Sat Jan 14 09:13:49 2012
@@ -112,42 +112,30 @@
 //===----------------------------------------------------------------------===//
 
 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
-  // Find the first declaration of this function template.
-  RedeclarableTemplateDecl *First = getCanonicalDecl();
-
-  if (First->CommonOrPrev.isNull()) {
-    CommonBase *CommonPtr = First->newCommon(getASTContext());
-    First->CommonOrPrev = CommonPtr;
-    CommonPtr->Latest = First;
-  }
-  return First->CommonOrPrev.get<CommonBase*>();
-}
-
+  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<RedeclarableTemplateDecl *, 2> PrevDecls;
+    for (RedeclarableTemplateDecl *Prev = getPreviousDeclaration(); Prev;
+         Prev = Prev->getPreviousDeclaration()) {
+      if (Prev->Common) {
+        Common = Prev->Common;
+        break;
+      }
+      
+      PrevDecls.push_back(Prev);
+    }
 
-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<CommonBase*>() && "Cannot reset TemplateDecl Prev");
+    // 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;
   }
-}
 
-RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() {
-  if (CommonOrPrev.is<RedeclarableTemplateDecl*>())
-    return CommonOrPrev.get<RedeclarableTemplateDecl*>();
-  CommonBase *Common = CommonOrPrev.get<CommonBase*>();
-  return Common ? Common->Latest : this;
+  return Common;
 }
 
 template <class EntryType>

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=148181&r1=148180&r2=148181&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Jan 14 09:13:49 2012
@@ -6152,10 +6152,10 @@
     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<Decl *, 4>::iterator D = PendingDefinitions.begin(),
                                            DEnd = PendingDefinitions.end();
        D != DEnd; ++D) {
@@ -6177,11 +6177,21 @@
       continue;
     }
     
-    ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(*D);
-    for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
-                                        REnd = PD->redecls_end();
+    if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(*D)) {
+      for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
+                                          REnd = PD->redecls_end();
+           R != REnd; ++R)
+        R->Data = PD->Data;
+      
+      continue;
+    }
+    
+    RedeclarableTemplateDecl *RTD
+      = cast<RedeclarableTemplateDecl>(*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();
 }

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=148181&r1=148180&r2=148181&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sat Jan 14 09:13:49 2012
@@ -1234,72 +1234,40 @@
 
 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;
-
-    // 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;
-    }
+  RedeclarableResult Redecl = VisitRedeclarable(D);
 
+  // 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<RedeclarableTemplateDecl>(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<RedeclarableTemplateDecl>(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<serialization::DeclID, 2> SpecIDs;
@@ -1321,6 +1289,7 @@
       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::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 @@
     ND->RedeclLink.setPointer(cast<NamespaceDecl>(previous));
   } else {
     RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
-    TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
+    TD->RedeclLink.setPointer(cast<RedeclarableTemplateDecl>(previous));
   }
 }
 
@@ -1841,7 +1810,9 @@
                                                    cast<NamespaceDecl>(Latest));
   } else {
     RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
-    TD->getCommonPtr()->Latest = cast<RedeclarableTemplateDecl>(Latest);
+    TD->RedeclLink
+      = Redeclarable<RedeclarableTemplateDecl>::LatestDeclLink(
+                                        cast<RedeclarableTemplateDecl>(Latest));
   }
 }
 

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=148181&r1=148180&r2=148181&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Sat Jan 14 09:13:49 2012
@@ -1031,38 +1031,17 @@
 }
 
 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::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   VisitRedeclarableTemplateDecl(D);
 
-  if (D->getPreviousDeclaration() == 0) {
+  if (D->isFirstDeclaration()) {
     typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
     CTSDSetTy &CTSDSet = D->getSpecializations();
     Record.push_back(CTSDSet.size());
@@ -1158,7 +1137,7 @@
 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.





More information about the cfe-commits mailing list