]> granicus.if.org Git - clang/commitdiff
Enter the context of the declared function template when performing
authorJohn McCall <rjmccall@apple.com>
Tue, 12 Oct 2010 19:40:14 +0000 (19:40 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 12 Oct 2010 19:40:14 +0000 (19:40 +0000)
deduction and the final substitution, but not while substituting the
explicit template arguments.  Fixes rdar://problem/8537391

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116332 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateDeduction.cpp
test/SemaTemplate/deduction.cpp

index 6237610c098d09d0da5b82ca86d9f02ab0b936f0..ce3748b901a11957d6059fc570ccf3e4fa6cff8d 100644 (file)
@@ -1218,8 +1218,6 @@ Sema::SubstituteExplicitTemplateArguments(
   if (Inst)
     return TDK_InstantiationDepth;
 
-  ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
-
   if (CheckTemplateArgumentList(FunctionTemplate,
                                 SourceLocation(),
                                 ExplicitTemplateArgs,
@@ -1238,6 +1236,12 @@ Sema::SubstituteExplicitTemplateArguments(
     = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
   Info.reset(ExplicitArgumentList);
 
+  // Template argument deduction and the final substitution should be
+  // done in the context of the templated declaration.  Explicit
+  // argument substitution, on the other hand, needs to happen in the
+  // calling context.
+  ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
+
   // Instantiate the types of each of the function parameters given the
   // explicitly-specified template arguments.
   for (FunctionDecl::param_iterator P = Function->param_begin(),
index 9400a0aba96be29b8b9df0b87e5f01e3af8d6312..cf98d6e0ac473a3ce1e89c89f6027eb8aed0e1be 100644 (file)
@@ -134,3 +134,19 @@ namespace test2 {
     f(0, p);
   }
 }
+
+// rdar://problem/8537391
+namespace test3 {
+  struct Foo {
+    template <void F(char)> static inline void foo();
+  };
+
+  class Bar {
+    template<typename T> static inline void wobble(T ch);
+
+  public:
+    static void madness() {
+      Foo::foo<wobble<char> >();
+    }
+  };
+}