]> granicus.if.org Git - clang/commitdiff
Fix and test template instantiation for nested member templates.
authorDouglas Gregor <dgregor@apple.com>
Fri, 28 Aug 2009 21:09:48 +0000 (21:09 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 28 Aug 2009 21:09:48 +0000 (21:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80394 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-member-template.cpp

index 213855741cb4ebdde3b773c487008cab42605ba0..732394d867d8038cee9be960e328ce03ac0dc058 100644 (file)
@@ -947,9 +947,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
   
   // Find the function body that we'll be substituting.
   const FunctionDecl *PatternDecl = 0;
-  if (FunctionTemplateDecl *Primary = Function->getPrimaryTemplate())
+  if (FunctionTemplateDecl *Primary = Function->getPrimaryTemplate()) {
+    while (Primary->getInstantiatedFromMemberTemplate())
+      Primary = Primary->getInstantiatedFromMemberTemplate();
+    
     PatternDecl = Primary->getTemplatedDecl();
-  else 
+  else 
     PatternDecl = Function->getInstantiatedFromMemberFunction();
   Stmt *Pattern = 0;
   if (PatternDecl)
index be5665b9892ff3dc602bceb1a098c62c40b1f5d7..d72028df8a5db22f50fdc10f855ebbc3e6d44849 100644 (file)
@@ -41,9 +41,22 @@ struct X1 {
       U z; // expected-error{{void}}
     };
   };
+  
+  template<typename U>
+  struct Inner3 {
+    void f0(T t, U u) {
+      (void)(t + u); // expected-error{{invalid operands}}
+    }
+    
+    template<typename V>
+    V f1(T t, U u, V) {
+      return t + u; // expected-error{{incompatible type}}
+    }
+  };
+  
 };
 
-void test_X1() {
+void test_X1(int *ip, int i, double *dp) {
   X1<void>::Inner0<int> *xvip; // okay
   X1<void>::Inner0<int> xvi; // expected-note{{instantiation}}
   
@@ -52,4 +65,13 @@ void test_X1() {
   
   X1<int>::Inner2<void>::SuperInner *xisivp; // okay
   X1<int>::Inner2<void>::SuperInner xisiv; // expected-note{{instantiation}}
+  
+  X1<int*>::Inner3<int> id3;
+  id3.f0(ip, i);
+  id3.f0(dp, i); // expected-error{{incompatible type}}
+  id3.f1(ip, i, ip);
+  id3.f1(ip, i, dp); // expected-note{{instantiation}}
+  
+  X1<int*>::Inner3<double*> id3b;
+  id3b.f0(ip, dp); // expected-note{{instantiation}}
 }