r209472 - If a class template specialization from one module has its definition

Richard Smith richard-llvm at metafoo.co.uk
Thu May 22 13:59:29 PDT 2014


Author: rsmith
Date: Thu May 22 15:59:29 2014
New Revision: 209472

URL: http://llvm.org/viewvc/llvm-project?rev=209472&view=rev
Log:
If a class template specialization from one module has its definition
instantiated in another module, and the instantiation uses a partial
specialization, include the partial specialization and its template arguments
in the update record. We'll need them if someone imports the second module and
tries to instantiate a member of the template.

Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-common.h
    cfe/trunk/test/Modules/cxx-templates.cpp

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=209472&r1=209471&r2=209472&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu May 22 15:59:29 2014
@@ -3201,6 +3201,16 @@ void ASTDeclReader::UpdateDecl(Decl *D,
             cast<ClassTemplateSpecializationDecl>(RD);
         Spec->setTemplateSpecializationKind(TSK);
         Spec->setPointOfInstantiation(POI);
+
+        if (Record[Idx++]) {
+          auto PartialSpec =
+              ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx);
+          SmallVector<TemplateArgument, 8> TemplArgs;
+          Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+          auto *TemplArgList = TemplateArgumentList::CreateCopy(
+              Reader.getContext(), TemplArgs.data(), TemplArgs.size());
+          Spec->setInstantiationOf(PartialSpec, TemplArgList);
+        }
       }
 
       RD->setTagKind((TagTypeKind)Record[Idx++]);

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=209472&r1=209471&r2=209472&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu May 22 15:59:29 2014
@@ -4531,6 +4531,19 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
           auto *Spec = cast<ClassTemplateSpecializationDecl>(RD);
           Record.push_back(Spec->getTemplateSpecializationKind());
           AddSourceLocation(Spec->getPointOfInstantiation(), Record);
+
+          // The instantiation might have been resolved to a partial
+          // specialization. If so, record which one.
+          auto From = Spec->getInstantiatedFrom();
+          if (auto PartialSpec =
+                From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
+            Record.push_back(true);
+            AddDeclRef(PartialSpec, Record);
+            AddTemplateArgumentList(&Spec->getTemplateInstantiationArgs(),
+                                    Record);
+          } else {
+            Record.push_back(false);
+          }
         }
         Record.push_back(RD->getTagKind());
         AddSourceLocation(RD->getLocation(), Record);

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-a.h?rev=209472&r1=209471&r2=209472&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-a.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-a.h Thu May 22 15:59:29 2014
@@ -50,3 +50,9 @@ template<> struct MergeSpecializations<c
 };
 
 void InstantiateWithFriend(Std::WithFriend<int> wfi) {}
+
+template<typename T> struct WithPartialSpecialization<T*> {
+  typedef int type;
+  T &f() { static T t; return t; }
+};
+typedef WithPartialSpecializationUse::type WithPartialSpecializationInstantiate;

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-common.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-common.h?rev=209472&r1=209471&r2=209472&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-common.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-common.h Thu May 22 15:59:29 2014
@@ -30,3 +30,6 @@ template<typename T> struct Outer {
     void g();
   };
 };
+
+template<typename T> struct WithPartialSpecialization {};
+typedef WithPartialSpecialization<int*> WithPartialSpecializationUse;

Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=209472&r1=209471&r2=209472&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Thu May 22 15:59:29 2014
@@ -102,6 +102,8 @@ void g() {
   TemplateInstantiationVisibility<char[3]> tiv3; // expected-error {{must be imported from module 'cxx_templates_b_impl'}}
   // expected-note at cxx-templates-b-impl.h:10 {{previous definition is here}}
   TemplateInstantiationVisibility<char[4]> tiv4;
+
+  int &p = WithPartialSpecializationUse().f();
 }
 
 RedeclaredAsFriend<int> raf1;





More information about the cfe-commits mailing list