r184811 - Fix deserializing of class template partial specializations. Assign sequence

Richard Smith richard-llvm at metafoo.co.uk
Mon Jun 24 18:25:16 PDT 2013


Author: rsmith
Date: Mon Jun 24 20:25:15 2013
New Revision: 184811

URL: http://llvm.org/viewvc/llvm-project?rev=184811&view=rev
Log:
Fix deserializing of class template partial specializations. Assign sequence
numbers as we deserialize class template partial specializations. We can't
assume that the old sequence numbers will work.

The sequence numbers are still deterministic, but are now a lot less
predictable for class template partial specializations in modules/PCH.

Added:
    cfe/trunk/test/Modules/Inputs/cxx-templates-common.h
Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-b.h
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/Modules/cxx-templates.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Mon Jun 24 20:25:15 2013
@@ -1711,7 +1711,8 @@ public:
   }
 
   /// \brief Get the sequence number for this class template partial
-  /// specialization.
+  /// specialization. Internal, only valid for specializations which
+  /// are in the specialized class template's folding set.
   unsigned getSequenceNumber() const { return SequenceNumber; }
 
   /// \brief Retrieve the member class template partial specialization from
@@ -1928,7 +1929,9 @@ public:
 
   /// \brief Return the next partial specialization sequence number.
   unsigned getNextPartialSpecSequenceNumber() {
-    return getPartialSpecializations().size();
+    // Do not load lazy specializations here. They get numbered as they are
+    // loaded.
+    return getCommonPtr()->PartialSpecializations.size();
   }
 
   /// \brief Retrieve the partial specializations as an ordered list.

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Jun 24 20:25:15 2013
@@ -1458,9 +1458,12 @@ ASTDeclReader::VisitClassTemplateSpecial
   if (writtenAsCanonicalDecl) {
     ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx);
     if (D->isCanonicalDecl()) { // It's kept in the folding set.
-      if (ClassTemplatePartialSpecializationDecl *Partial
-                        = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
-  CanonPattern->getCommonPtr()->PartialSpecializations.GetOrInsertNode(Partial);
+      if (ClassTemplatePartialSpecializationDecl *Partial =
+              dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
+        Partial->SequenceNumber =
+            CanonPattern->getNextPartialSpecSequenceNumber();
+        CanonPattern->getCommonPtr()->PartialSpecializations
+            .GetOrInsertNode(Partial);
       } else {
         CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
       }
@@ -1485,8 +1488,6 @@ void ASTDeclReader::VisitClassTemplatePa
       D->ArgsAsWritten[i] = Reader.ReadTemplateArgumentLoc(F, Record, Idx);
   }
 
-  D->SequenceNumber = Record[Idx++];
-
   // These are read/set from/to the first declaration.
   if (ThisDeclID == Redecl.getFirstID()) {
     D->InstantiatedFromMember.setPointer(

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Jun 24 20:25:15 2013
@@ -1174,8 +1174,6 @@ void ASTDeclWriter::VisitClassTemplatePa
   for (int i = 0, e = D->getNumTemplateArgsAsWritten(); i != e; ++i)
     Writer.AddTemplateArgumentLoc(D->getTemplateArgsAsWritten()[i], Record);
 
-  Record.push_back(D->getSequenceNumber());
-
   // These are read/set from/to the first declaration.
   if (D->getPreviousDecl() == 0) {
     Writer.AddDeclRef(D->getInstantiatedFromMember(), 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=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-a.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-a.h Mon Jun 24 20:25:15 2013
@@ -1,3 +1,5 @@
+ at import cxx_templates_common;
+
 template<typename T> T f() { return T(); }
 template<typename T> T f(T);
 namespace N {
@@ -8,3 +10,7 @@ namespace N {
 template<int N> int template_param_kinds_1();
 template<template<typename T, int, int> class> int template_param_kinds_2();
 template<template<typename T, typename U, T> class> int template_param_kinds_3();
+
+template<typename T> struct SomeTemplate<T*>;
+template<typename T> struct SomeTemplate<T*> {};
+typedef SomeTemplate<int*> SomeTemplateIntPtr;

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-b.h?rev=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-b.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-b.h Mon Jun 24 20:25:15 2013
@@ -1,3 +1,5 @@
+ at import cxx_templates_common;
+
 template<typename T> T f();
 template<typename T> T f(T t) { return t; }
 namespace N {
@@ -8,3 +10,7 @@ namespace N {
 template<typename> int template_param_kinds_1();
 template<template<typename, int, int...> class> int template_param_kinds_2();
 template<template<typename T, typename U, U> class> int template_param_kinds_3();
+
+template<typename T> struct SomeTemplate<T&> {};
+template<typename T> struct SomeTemplate<T&>;
+typedef SomeTemplate<int&> SomeTemplateIntRef;

Added: 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=184811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-common.h (added)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-common.h Mon Jun 24 20:25:15 2013
@@ -0,0 +1 @@
+template<typename T> struct SomeTemplate {};

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Mon Jun 24 20:25:15 2013
@@ -188,6 +188,10 @@ module cxx_linkage_cache {
   header "cxx-linkage-cache.h"
 }
 
+module cxx_templates_common {
+  header "cxx-templates-common.h"
+}
+
 module cxx_templates_a {
   header "cxx-templates-a.h"
 }

Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=184811&r1=184810&r2=184811&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Mon Jun 24 20:25:15 2013
@@ -17,37 +17,44 @@ void g() {
   f<double>(1.0);
   f<int>();
   f(); // expected-error {{no matching function}}
-  // expected-note at Inputs/cxx-templates-b.h:1 {{couldn't infer template argument}}
-  // expected-note at Inputs/cxx-templates-b.h:2 {{requires single argument}}
+  // expected-note at Inputs/cxx-templates-b.h:3 {{couldn't infer template argument}}
+  // expected-note at Inputs/cxx-templates-b.h:4 {{requires single argument}}
 
   N::f(0);
   N::f<double>(1.0);
   N::f<int>();
   N::f(); // expected-error {{no matching function}}
-  // expected-note at Inputs/cxx-templates-a.h:4 {{couldn't infer template argument}}
-  // expected-note at Inputs/cxx-templates-a.h:5 {{requires 1 argument, but 0 were provided}}
+  // expected-note at Inputs/cxx-templates-a.h:6 {{couldn't infer template argument}}
+  // expected-note at Inputs/cxx-templates-a.h:7 {{requires 1 argument, but 0 were provided}}
 
   template_param_kinds_1<0>(); // ok, from cxx-templates-a.h
   template_param_kinds_1<int>(); // ok, from cxx-templates-b.h
 
   template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function}}
-  // expected-note at Inputs/cxx-templates-a.h:9 {{invalid explicitly-specified argument}}
-  // expected-note at Inputs/cxx-templates-b.h:9 {{invalid explicitly-specified argument}}
+  // expected-note at Inputs/cxx-templates-a.h:11 {{invalid explicitly-specified argument}}
+  // expected-note at Inputs/cxx-templates-b.h:11 {{invalid explicitly-specified argument}}
 
   template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}}
-  // expected-note at Inputs/cxx-templates-a.h:9 {{candidate}}
-  // expected-note at Inputs/cxx-templates-b.h:9 {{candidate}}
+  // expected-note at Inputs/cxx-templates-a.h:11 {{candidate}}
+  // expected-note at Inputs/cxx-templates-b.h:11 {{candidate}}
 
   // FIXME: This should be valid, but we incorrectly match the template template
   // argument against both template template parameters.
   template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}}
-  // expected-note at Inputs/cxx-templates-a.h:10 {{candidate}}
-  // expected-note at Inputs/cxx-templates-b.h:10 {{candidate}}
+  // expected-note at Inputs/cxx-templates-a.h:12 {{candidate}}
+  // expected-note at Inputs/cxx-templates-b.h:12 {{candidate}}
   template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}}
-  // expected-note at Inputs/cxx-templates-a.h:10 {{candidate}}
-  // expected-note at Inputs/cxx-templates-b.h:10 {{candidate}}
+  // expected-note at Inputs/cxx-templates-a.h:12 {{candidate}}
+  // expected-note at Inputs/cxx-templates-b.h:12 {{candidate}}
 }
 
+ at import cxx_templates_common;
+
+typedef SomeTemplate<int*> SomeTemplateIntPtr;
+typedef SomeTemplate<int&> SomeTemplateIntRef;
+SomeTemplate<char*> some_template_char_ptr;
+SomeTemplate<char&> some_template_char_ref;
+
 // FIXME: There should only be two 'f's here.
 // CHECK-GLOBAL:      DeclarationName 'f'
 // CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'





More information about the cfe-commits mailing list