diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-30 17:50:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-30 17:50:56 +0000 |
commit | c5b8c9b6607de7ce25a28f26a34f43efa5728cb7 (patch) | |
tree | 0722fdea4616cac8f0d50fc41c69ff26e6660809 | |
parent | 426cc3828ce07a2cff15c9837f5958e6fc4b7739 (diff) |
What luck! Clang obtains support for refering to members of the
current instantiation when that current instantiation is a class
template partial specialization.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77609 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 3 | ||||
-rw-r--r-- | test/SemaTemplate/current-instantiation.cpp | 73 |
2 files changed, 75 insertions, 1 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 1580e721d3..076685b808 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -189,7 +189,8 @@ CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) { // list of the partial specialization enclosed in <>. If // the nth template parameter is a parameter pack, the nth // template argument is a pack expansion (14.6.3) whose - // pattern is the name of the parameter pack. (FIXME) + // pattern is the name of the parameter pack. + // (FIXME: parameter packs) // // All of these options come down to having the // nested-name-specifier type that is equivalent to the diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp index 603c14016f..a1d9fcb537 100644 --- a/test/SemaTemplate/current-instantiation.cpp +++ b/test/SemaTemplate/current-instantiation.cpp @@ -69,3 +69,76 @@ struct X0 { 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}} + }; +}; |