summaryrefslogtreecommitdiff
path: root/clang/test/SemaTemplate/current-instantiation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaTemplate/current-instantiation.cpp')
-rw-r--r--clang/test/SemaTemplate/current-instantiation.cpp237
1 files changed, 237 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/current-instantiation.cpp b/clang/test/SemaTemplate/current-instantiation.cpp
new file mode 100644
index 0000000..ccef811
--- /dev/null
+++ b/clang/test/SemaTemplate/current-instantiation.cpp
@@ -0,0 +1,237 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test concerns the identity of dependent types within the
+// canonical type system, specifically focusing on the difference
+// between members of the current instantiation and membmers of an
+// unknown specialization. This considers C++ [temp.type], which
+// specifies type equivalence within a template, and C++0x
+// [temp.dep.type], which defines what it means to be a member of the
+// current instantiation.
+
+template<typename T, typename U>
+struct X0 {
+ typedef T T_type;
+ typedef U U_type;
+
+ void f0(T&); // expected-note{{previous}}
+ void f0(typename X0::U_type&);
+ void f0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void f1(T&); // expected-note{{previous}}
+ void f1(typename X0::U_type&);
+ void f1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
+
+ void f2(T&); // expected-note{{previous}}
+ void f2(typename X0::U_type&);
+ void f2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ void f3(T&); // expected-note{{previous}}
+ void f3(typename X0::U_type&);
+ void f3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ struct X1 {
+ typedef T my_T_type;
+
+ void g0(T&); // expected-note{{previous}}
+ void g0(typename X0::U_type&);
+ void g0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void g1(T&); // expected-note{{previous}}
+ void g1(typename X0::U_type&);
+ void g1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
+
+ void g2(T&); // expected-note{{previous}}
+ void g2(typename X0::U_type&);
+ void g2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ void g3(T&); // expected-note{{previous}}
+ void g3(typename X0::U_type&);
+ void g3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ void g4(T&); // expected-note{{previous}}
+ void g4(typename X0::U_type&);
+ void g4(typename X1::my_T_type&); // expected-error{{redecl}}
+
+ void g5(T&); // expected-note{{previous}}
+ void g5(typename X0::U_type&);
+ void g5(typename X0::X1::my_T_type&); // expected-error{{redecl}}
+
+ void g6(T&); // expected-note{{previous}}
+ void g6(typename X0::U_type&);
+ void g6(typename X0<T, U>::X1::my_T_type&); // expected-error{{redecl}}
+
+ void g7(T&); // expected-note{{previous}}
+ void g7(typename X0::U_type&);
+ void g7(typename ::X0<typename X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
+
+ void g8(T&); // expected-note{{previous}}
+ void g8(typename X0<U, T_type>::T_type&);
+ void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
+ };
+};
+
+
+template<typename T, typename U>
+struct X0<T*, U*> {
+ typedef T T_type;
+ typedef U U_type;
+ typedef T* Tptr;
+ typedef U* Uptr;
+
+ void f0(T&); // expected-note{{previous}}
+ void f0(typename X0::U_type&);
+ void f0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void f1(T&); // expected-note{{previous}}
+ void f1(typename X0::U_type&);
+ void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
+
+ void f2(T&); // expected-note{{previous}}
+ void f2(typename X0::U_type&);
+ void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void f3(T&); // expected-note{{previous}}
+ void f3(typename X0::U_type&);
+ void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void f4(T&); // expected-note{{previous}}
+ void f4(typename X0::U_type&);
+ void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}}
+
+ void f5(X0*); // expected-note{{previous}}
+ void f5(::X0<T, U>*);
+ void f5(::X0<T*, U*>*); // expected-error{{redecl}}
+
+ struct X2 {
+ typedef T my_T_type;
+
+ void g0(T&); // expected-note{{previous}}
+ void g0(typename X0::U_type&);
+ void g0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void g1(T&); // expected-note{{previous}}
+ void g1(typename X0::U_type&);
+ void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
+
+ void g2(T&); // expected-note{{previous}}
+ void g2(typename X0::U_type&);
+ void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void g3(T&); // expected-note{{previous}}
+ void g3(typename X0::U_type&);
+ void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void g4(T&); // expected-note{{previous}}
+ void g4(typename X0::U_type&);
+ void g4(typename X2::my_T_type&); // expected-error{{redecl}}
+
+ void g5(T&); // expected-note{{previous}}
+ void g5(typename X0::U_type&);
+ void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}}
+
+ void g6(T&); // expected-note{{previous}}
+ void g6(typename X0::U_type&);
+ void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}}
+
+ void g7(T&); // expected-note{{previous}}
+ void g7(typename X0::U_type&);
+ void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
+
+ void g8(T&); // expected-note{{previous}}
+ void g8(typename X0<U, T_type>::T_type&);
+ void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
+ };
+};
+
+template<typename T>
+struct X1 {
+ static int *a;
+ void f(float *b) {
+ X1<T>::a = b; // expected-error{{incompatible}}
+ X1<T*>::a = b;
+ }
+};
+
+namespace ConstantInCurrentInstantiation {
+ template<typename T>
+ struct X {
+ static const int value = 2;
+ static int array[value];
+ };
+
+ template<typename T> const int X<T>::value;
+
+ template<typename T>
+ int X<T>::array[X<T>::value] = { 1, 2 };
+}
+
+namespace Expressions {
+ template <bool b>
+ struct Bool {
+ enum anonymous_enum { value = b };
+ };
+ struct True : public Bool<true> {};
+ struct False : public Bool<false> {};
+
+ template <typename T1, typename T2>
+ struct Is_Same : public False {};
+ template <typename T>
+ struct Is_Same<T, T> : public True {};
+
+ template <bool b, typename T = void>
+ struct Enable_If {};
+ template <typename T>
+ struct Enable_If<true, T> {
+ typedef T type;
+ };
+
+ template <typename T>
+ class Class {
+ public:
+ template <typename U>
+ typename Enable_If<Is_Same<U, Class>::value, void>::type
+ foo();
+ };
+
+
+ template <typename T>
+ template <typename U>
+ typename Enable_If<Is_Same<U, Class<T> >::value, void>::type
+ Class<T>::foo() {}
+}
+
+namespace PR9255 {
+ template<typename T>
+ class X0 {
+ public:
+ class Inner1;
+
+ class Inner2 {
+ public:
+ void f()
+ {
+ Inner1::f.g();
+ }
+ };
+ };
+}
+
+namespace rdar10194295 {
+ template<typename XT>
+ class X {
+ public:
+ enum Enum { Yes, No };
+ template<Enum> void foo();
+ template<Enum> class Inner;
+ };
+
+ template<typename XT>
+ template<typename X<XT>::Enum>
+ void X<XT>::foo()
+ {
+ }
+
+ template<typename XT>
+ template<typename X<XT>::Enum>
+ class X<XT>::Inner { };
+}