Instantiation for member classes of class templates. Note that only
the declarations of member classes are instantiated when the owning
class template is instantiated. The definitions of such member classes
are instantiated when a complete type is required.
This change also introduces the injected-class-name into a class
template specialization.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67707 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp
new file mode 100644
index 0000000..26fddcf
--- /dev/null
+++ b/test/SemaTemplate/instantiate-member-class.cpp
@@ -0,0 +1,33 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T>
+class X {
+public:
+ struct C { T &foo(); };
+
+ struct D {
+ struct E { T &bar(); };
+ struct F; // expected-note{{member is declared here}}
+ };
+};
+
+X<int>::C *c1;
+X<float>::C *c2;
+
+X<int>::X *xi;
+X<float>::X *xf;
+
+void test_naming() {
+ c1 = c2; // expected-error{{incompatible type assigning 'X<float>::C *', expected 'X<int>::C *'}}
+ xi = xf; // expected-error{{incompatible type assigning}}
+ // FIXME: error above doesn't print the type X<int>::X cleanly!
+}
+
+void test_instantiation(X<double>::C *x,
+ X<float>::D::E *e,
+ X<float>::D::F *f) {
+ double &dr = x->foo();
+ float &fr = e->bar();
+ f->foo(); // expected-error{{implicit instantiation of undefined member 'struct X<float>::D::F'}}
+
+}