diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-08-28 21:09:48 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-08-28 21:09:48 +0000 |
commit | 5ec178ff237d77e7acf5e747c19bf4f2de77a779 (patch) | |
tree | f3d0a24c570d3aa228bec174a79f87ed3c8f2745 | |
parent | 357bbd022c1d340c8e255aea7a684ddb34bc76e5 (diff) |
Fix and test template instantiation for nested member templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80394 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-member-template.cpp | 24 |
2 files changed, 28 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 213855741c..732394d867 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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) diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp index be5665b989..d72028df8a 100644 --- a/test/SemaTemplate/instantiate-member-template.cpp +++ b/test/SemaTemplate/instantiate-member-template.cpp @@ -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}} } |