[cfe-commits] r99509 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/instantiate-function-params.cpp

Douglas Gregor dgregor at apple.com
Thu Mar 25 08:38:42 PDT 2010


Author: dgregor
Date: Thu Mar 25 10:38:42 2010
New Revision: 99509

URL: http://llvm.org/viewvc/llvm-project?rev=99509&view=rev
Log:
Improve our handling of local instantiation scopes in two related ways:

  - When substituting template arguments as part of template argument
    deduction, introduce a new local instantiation scope.
  - When substituting into a function prototype type, introduce a new
    "temporary" local instantiation scope that merges with its outer
    scope but also keeps track of any additions it makes, removing
    them when we exit that scope.

Fixes PR6700, where we were getting too much mixing of local
instantiation scopes due to template argument deduction that
substituted results into function types.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=99509&r1=99508&r2=99509&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Mar 25 10:38:42 2010
@@ -3487,15 +3487,27 @@
     /// \brief Whether we have already exited this scope.
     bool Exited;
 
+    /// \brief Whether this scope is temporary, meaning that we should
+    /// remove any additions we make once we exit this
+    /// scope. Temporary scopes are always combined with their outer
+    /// scopes.
+    bool Temporary;
+
+    /// \brief List of the declarations that we have added into this
+    /// temporary scope. They will be removed when we exit the
+    /// temporary scope.
+    llvm::SmallVector<const Decl *, 4> AddedTemporaryDecls;
+
     // This class is non-copyable
     LocalInstantiationScope(const LocalInstantiationScope &);
     LocalInstantiationScope &operator=(const LocalInstantiationScope &);
 
   public:
-    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
+    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
+                            bool Temporary = false)
       : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 
-        Exited(false) {
-      if (!CombineWithOuterScope)
+        Exited(false), Temporary(Temporary) {
+      if (!CombineWithOuterScope && !Temporary)
         SemaRef.CurrentInstantiationScope = this;
       else
         assert(SemaRef.CurrentInstantiationScope && 
@@ -3503,8 +3515,11 @@
     }
 
     ~LocalInstantiationScope() {
-      if (!Exited)
+      if (!Exited) {
         SemaRef.CurrentInstantiationScope = Outer;
+        for (unsigned I = 0, N = AddedTemporaryDecls.size(); I != N; ++I)
+          LocalDecls.erase(AddedTemporaryDecls[I]);
+      }
     }
 
     /// \brief Exit this local instantiation scope early.
@@ -3537,6 +3552,10 @@
     void InstantiatedLocal(const Decl *D, Decl *Inst) {
       Decl *&Stored = LocalDecls[D];
       assert((!Stored || Stored == Inst) && "Already instantiated this local");
+
+      if (Temporary && !Stored)
+        AddedTemporaryDecls.push_back(D);
+
       Stored = Inst;
     }
   };

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=99509&r1=99508&r2=99509&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Mar 25 10:38:42 2010
@@ -987,13 +987,7 @@
       Decl *Param
         = const_cast<NamedDecl *>(
                                 Partial->getTemplateParameters()->getParam(I));
-      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
-        Info.Param = TTP;
-      else if (NonTypeTemplateParmDecl *NTTP
-                 = dyn_cast<NonTypeTemplateParmDecl>(Param))
-        Info.Param = NTTP;
-      else
-        Info.Param = cast<TemplateTemplateParmDecl>(Param);
+      Info.Param = makeTemplateParameter(Param);
       return TDK_Incomplete;
     }
 
@@ -1010,6 +1004,7 @@
   // verify that the instantiated template arguments are both valid
   // and are equivalent to the template arguments originally provided
   // to the class template.
+  Sema::LocalInstantiationScope InstScope(*this);
   ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
   const TemplateArgumentLoc *PartialTemplateArgs
     = Partial->getTemplateArgsAsWritten();
@@ -1458,6 +1453,7 @@
 
   // The types of the parameters from which we will perform template argument
   // deduction.
+  Sema::LocalInstantiationScope InstScope(*this);
   TemplateParameterList *TemplateParams
     = FunctionTemplate->getTemplateParameters();
   llvm::SmallVector<TemplateArgument, 4> Deduced;
@@ -1612,6 +1608,7 @@
   QualType FunctionType = Function->getType();
 
   // Substitute any explicit template arguments.
+  Sema::LocalInstantiationScope InstScope(*this);
   llvm::SmallVector<TemplateArgument, 4> Deduced;
   llvm::SmallVector<QualType, 4> ParamTypes;
   if (ExplicitTemplateArgs) {
@@ -1739,6 +1736,7 @@
   // modulo the various allowed differences.
 
   // Finish template argument deduction.
+  Sema::LocalInstantiationScope InstScope(*this);
   FunctionDecl *Spec = 0;
   TemplateDeductionResult Result
     = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, Spec, Info);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=99509&r1=99508&r2=99509&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Mar 25 10:38:42 2010
@@ -873,8 +873,11 @@
                                   llvm::SmallVectorImpl<QualType> &PTypes,
                                llvm::SmallVectorImpl<ParmVarDecl*> &PVars) {
   // Create a local instantiation scope for the parameters.
-  Sema::LocalInstantiationScope
-    Scope(SemaRef, SemaRef.CurrentInstantiationScope != 0);
+  // FIXME: When we implement the C++0x late-specified return type, 
+  // we will need to move this scope out to the function type itself.
+  bool IsTemporaryScope = (SemaRef.CurrentInstantiationScope != 0);
+  Sema::LocalInstantiationScope Scope(SemaRef, IsTemporaryScope, 
+                                      IsTemporaryScope);
 
   if (TreeTransform<TemplateInstantiator>::
         TransformFunctionTypeParams(TL, PTypes, PVars))

Modified: cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp?rev=99509&r1=99508&r2=99509&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp Thu Mar 25 10:38:42 2010
@@ -31,3 +31,14 @@
 };
 typedef instantiate< &requirement_<void(*)(ForwardIterator<char*> x)>::failed> boost_concept_checkX; // expected-error{{no member named}} \
 // expected-note 6{{in instantiation}}
+
+template<typename T> struct X0 { };
+template<typename R, typename A1> struct X0<R(A1 param)> { };
+
+template<typename T, typename A1, typename A2>
+void instF0(X0<T(A1)> x0a, X0<T(A2)> x0b) {
+  X0<T(A1)> x0c;
+  X0<T(A2)> x0d;
+}
+
+template void instF0<int, int, float>(X0<int(int)>, X0<int(float)>);





More information about the cfe-commits mailing list