diff options
Diffstat (limited to 'clang/test/SemaTemplate/instantiate-member-class.cpp')
-rw-r--r-- | clang/test/SemaTemplate/instantiate-member-class.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/instantiate-member-class.cpp b/clang/test/SemaTemplate/instantiate-member-class.cpp new file mode 100644 index 0000000..bb64276 --- /dev/null +++ b/clang/test/SemaTemplate/instantiate-member-class.cpp @@ -0,0 +1,142 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR8965 { + template<typename T> + struct X { + typedef int type; + + T field; // expected-note{{in instantiation of member class}} + }; + + template<typename T> + struct Y { + struct Inner; + + typedef typename X<Inner>::type // expected-note{{in instantiation of template class}} + type; // expected-note{{not-yet-instantiated member is declared here}} + + struct Inner { + typedef type field; // expected-error{{no member 'type' in 'PR8965::Y<int>'; it has not yet been instantiated}} + }; + }; + + Y<int> y; // expected-note{{in instantiation of template class}} +} + +template<typename T> +class X { +public: + struct C { T &foo(); }; + + struct D { + struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}} + struct F; // expected-note{{member is declared here}} + }; +}; + +X<int>::C *c1; +X<float>::C *c2; + +X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} +X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} + +void test_naming() { + c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}} + xi = xf; // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}} + // 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 'X<float>::D::F'}} + +} + + +X<void>::C *c3; // okay +X<void>::D::E *e1; // okay +X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}} + +// Redeclarations. +namespace test1 { + template <typename T> struct Registry { + struct node; + static node *Head; + struct node { + node(int v) { Head = this; } + }; + }; + void test() { + Registry<int>::node node(0); + } +} + +// Redeclarations during explicit instantiations. +namespace test2 { + template <typename T> class A { + class Foo; + class Foo { + int foo(); + }; + }; + template class A<int>; + + template <typename T> class B { + class Foo; + class Foo { + public: + typedef int X; + }; + typename Foo::X x; + class Foo; + }; + template class B<int>; + + template <typename T> class C { + class Foo; + class Foo; + }; + template <typename T> class C<T>::Foo { + int x; + }; + template class C<int>; +} + +namespace AliasTagDef { + template<typename T> + struct F { + using S = struct U { // expected-warning {{C++11}} + T g() { + return T(); + } + }; + }; + + int m = F<int>::S().g(); + int n = F<int>::U().g(); +} + +namespace rdar10397846 { + template<int I> struct A + { + struct B + { + struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + }; + }; + + template<int N> void foo() + { + class A<N>::B::C X; // expected-note{{in instantiation of member function}} + int A<N+1>::B::C::*member = 0; + } + + void bar() + { + foo<0>(); + foo<1>(); // expected-note{{in instantiation of function template}} + } +} |