зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
426cc3828c
Коммит
c5b8c9b660
|
@ -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
|
||||
|
|
|
@ -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}}
|
||||
};
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче