aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-08-28 21:09:48 +0000
committerDouglas Gregor <dgregor@apple.com>2009-08-28 21:09:48 +0000
commit5ec178ff237d77e7acf5e747c19bf4f2de77a779 (patch)
treef3d0a24c570d3aa228bec174a79f87ed3c8f2745
parent357bbd022c1d340c8e255aea7a684ddb34bc76e5 (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.cpp7
-rw-r--r--test/SemaTemplate/instantiate-member-template.cpp24
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}}
}