[cfe-commits] r85209 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h test/CXX/temp/temp.spec/temp.explicit/p3.cpp test/SemaTemplate/class-template-spec.cpp

Douglas Gregor dgregor at apple.com
Mon Oct 26 23:26:26 PDT 2009


Author: dgregor
Date: Tue Oct 27 01:26:26 2009
New Revision: 85209

URL: http://llvm.org/viewvc/llvm-project?rev=85209&view=rev
Log:
Only set the point of instantiation for an implicit or explicit
instantiation once we have committed to performing the
instantiation. As part of this, make our makeshift
template-instantiation location information suck slightly less.

Fixes PR5264.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
    cfe/trunk/test/SemaTemplate/class-template-spec.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Oct 27 01:26:26 2009
@@ -3189,7 +3189,7 @@
                    bool Complain = true);
 
   bool
-  InstantiateClassTemplateSpecialization(
+  InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
                            ClassTemplateSpecializationDecl *ClassTemplateSpec,
                            TemplateSpecializationKind TSK,
                            bool Complain = true);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Oct 27 01:26:26 2009
@@ -3726,8 +3726,6 @@
   Specialization->setLexicalDeclContext(CurContext);
   CurContext->addDecl(Specialization);
 
-  Specialization->setPointOfInstantiation(TemplateNameLoc);
-
   // C++ [temp.explicit]p3:
   //   A definition of a class template or class member template
   //   shall be in scope at the point of the explicit instantiation of
@@ -3739,7 +3737,7 @@
     = cast_or_null<ClassTemplateSpecializationDecl>(
                                         Specialization->getDefinition(Context));
   if (!Def)
-    InstantiateClassTemplateSpecialization(Specialization, TSK);
+    InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
   else // Instantiate the members of this class template specialization.
     InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
 
@@ -4280,6 +4278,13 @@
     /// \brief Returns the name of the entity whose type is being rebuilt.
     DeclarationName getBaseEntity() { return Entity; }
 
+    /// \brief Sets the "base" location and entity when that
+    /// information is known based on another transformation.
+    void setBase(SourceLocation Loc, DeclarationName Entity) {
+      this->Loc = Loc;
+      this->Entity = Entity;
+    }
+      
     /// \brief Transforms an expression by returning the expression itself
     /// (an identity function).
     ///

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Oct 27 01:26:26 2009
@@ -392,6 +392,13 @@
     /// \brief Returns the name of the entity being instantiated, if any.
     DeclarationName getBaseEntity() { return Entity; }
 
+    /// \brief Sets the "base" location and entity when that
+    /// information is known based on another transformation.
+    void setBase(SourceLocation Loc, DeclarationName Entity) {
+      this->Loc = Loc;
+      this->Entity = Entity;
+    }
+      
     /// \brief Transform the given declaration by instantiating a reference to
     /// this declaration.
     Decl *TransformDecl(Decl *D);
@@ -849,6 +856,10 @@
         = Instantiation->getMemberSpecializationInfo()) {
     MSInfo->setTemplateSpecializationKind(TSK);
     MSInfo->setPointOfInstantiation(PointOfInstantiation);
+  } else if (ClassTemplateSpecializationDecl *Spec 
+               = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
+    Spec->setTemplateSpecializationKind(TSK);
+    Spec->setPointOfInstantiation(PointOfInstantiation);
   }
   
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
@@ -915,6 +926,7 @@
 
 bool
 Sema::InstantiateClassTemplateSpecialization(
+                           SourceLocation PointOfInstantiation,
                            ClassTemplateSpecializationDecl *ClassTemplateSpec,
                            TemplateSpecializationKind TSK,
                            bool Complain) {
@@ -932,10 +944,9 @@
       // declaration (C++0x [temp.explicit]p10); go ahead and perform the
       // explicit instantiation.
       ClassTemplateSpec->setSpecializationKind(TSK);
-      InstantiateClassTemplateSpecializationMembers(
-                        /*FIXME?*/ClassTemplateSpec->getPointOfInstantiation(), 
-                                  ClassTemplateSpec,
-                                  TSK);
+      InstantiateClassTemplateSpecializationMembers(PointOfInstantiation,
+                                                    ClassTemplateSpec,
+                                                    TSK);
       return false;
     }
     
@@ -1019,8 +1030,7 @@
     if (Ambiguous) {
       // Partial ordering did not produce a clear winner. Complain.
       ClassTemplateSpec->setInvalidDecl();
-      Diag(ClassTemplateSpec->getPointOfInstantiation(),
-           diag::err_partial_spec_ordering_ambiguous)
+      Diag(PointOfInstantiation, diag::err_partial_spec_ordering_ambiguous)
         << ClassTemplateSpec;
       
       // Print the matching partial specializations.
@@ -1053,12 +1063,9 @@
     Pattern = OrigTemplate->getTemplatedDecl();
   }
 
-  // Note that this is an instantiation.
-  ClassTemplateSpec->setSpecializationKind(TSK);
-
-  bool Result = InstantiateClass(ClassTemplateSpec->getPointOfInstantiation(),
-                                 ClassTemplateSpec, Pattern,
-                              getTemplateInstantiationArgs(ClassTemplateSpec),
+  bool Result = InstantiateClass(PointOfInstantiation, ClassTemplateSpec, 
+                                 Pattern,
+                                getTemplateInstantiationArgs(ClassTemplateSpec),
                                  TSK,
                                  Complain);
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Oct 27 01:26:26 2009
@@ -1694,13 +1694,10 @@
   if (const RecordType *Record = T->getAs<RecordType>()) {
     if (ClassTemplateSpecializationDecl *ClassTemplateSpec
           = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
-      if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
-        if (Loc.isValid())
-          ClassTemplateSpec->setPointOfInstantiation(Loc);
-        return InstantiateClassTemplateSpecialization(ClassTemplateSpec,
+      if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared)
+        return InstantiateClassTemplateSpecialization(Loc, ClassTemplateSpec,
                                                       TSK_ImplicitInstantiation,
                                                       /*Complain=*/diag != 0);
-      }
     } else if (CXXRecordDecl *Rec
                  = dyn_cast<CXXRecordDecl>(Record->getDecl())) {
       if (CXXRecordDecl *Pattern = Rec->getInstantiatedFromMemberClass()) {
@@ -1708,13 +1705,11 @@
         assert(MSInfo && "Missing member specialization information?");
         // This record was instantiated from a class within a template.
         if (MSInfo->getTemplateSpecializationKind() 
-                                               != TSK_ExplicitSpecialization) {
-          MSInfo->setPointOfInstantiation(Loc);
+                                               != TSK_ExplicitSpecialization)
           return InstantiateClass(Loc, Rec, Pattern,
                                   getTemplateInstantiationArgs(Rec),
                                   TSK_ImplicitInstantiation,
                                   /*Complain=*/diag != 0);
-        }
       }
     }
   }

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Oct 27 01:26:26 2009
@@ -1884,6 +1884,7 @@
     return Arg;
 
   case TemplateArgument::Type: {
+    TemporaryBase Rebase(*this, Arg.getLocation(), DeclarationName());
     QualType T = getDerived().TransformType(Arg.getAsType());
     if (T.isNull())
       return TemplateArgument();
@@ -1891,6 +1892,10 @@
   }
 
   case TemplateArgument::Declaration: {
+    DeclarationName Name;
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
+      Name = ND->getDeclName();
+    TemporaryBase Rebase(*this, Arg.getLocation(), Name);
     Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
     if (!D)
       return TemplateArgument();

Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p3.cpp?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p3.cpp Tue Oct 27 01:26:26 2009
@@ -9,14 +9,12 @@
 // template shall be in scope at the point of the explicit instantiation of 
 // the member function template.
 struct X0; // expected-note 2{{forward declaration}}
-template<typename> struct X1; // expected-note 2{{declared here}} \
-                              // expected-note 3{{forward declaration}}
+template<typename> struct X1; // expected-note 5{{declared here}}
 
 // FIXME: Repeated diagnostics here!
 template void X0::f0<int>(int); // expected-error 2{{incomplete type}} \
   // expected-error{{invalid token after}}
-template void X1<int>::f0<int>(int); // expected-error{{implicit instantiation of undefined template}} \
-  // expected-error{{incomplete type}} \\
+template void X1<int>::f0<int>(int); // expected-error 2{{implicit instantiation of undefined template}} \
   // expected-error{{invalid token}}
 
 // A definition of a class template or class member template shall be in scope 
@@ -37,10 +35,10 @@
 // A definition of a class template shall be in scope at the point of an 
 // explicit instantiation of a member function or a static data member of the
 // class template.
-template void X1<int>::f1(int); // expected-error{{incomplete type}} \
+template void X1<int>::f1(int); // expected-error{{undefined template}} \
                                 // expected-error{{does not refer}}
 
-template int X1<int>::member; // expected-error{{incomplete type}} \
+template int X1<int>::member; // expected-error{{undefined template}} \
                               // expected-error{{does not refer}}
 
 // A definition of a member class of a class template shall be in scope at the 

Modified: cfe/trunk/test/SemaTemplate/class-template-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-spec.cpp?rev=85209&r1=85208&r2=85209&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/class-template-spec.cpp Tue Oct 27 01:26:26 2009
@@ -20,8 +20,7 @@
                           A<double> *a2)
 {
   (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
-  (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} \
-               // expected-note{{first required here}}
+  (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}}
 }
 
 typedef float FLOAT;
@@ -71,8 +70,7 @@
 }
 
 // Diagnose specialization errors
-struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} \
-                      // expected-error{{after instantiation}}
+struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
 
 template<> struct ::A<double>;
 
@@ -100,3 +98,9 @@
   int testf(int x) { return f(x); }
 };
 
+// PR5264
+template <typename T> class Foo;
+Foo<int>* v;
+Foo<int>& F() { return *v; }
+template <typename T> class Foo {};
+Foo<int> x;





More information about the cfe-commits mailing list