Also make explicit instantiation decls not apply to nested classes when targeting MSVC. That dll attributes are not inherited by inner classes might be the explanation for MSVC's behaviour here. llvm-svn: 270897
74 lines
1.3 KiB
C++
74 lines
1.3 KiB
C++
// RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only -verify %s -DMS
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu-pc-win32 -fsyntax-only -verify %s
|
|
|
|
template<typename T>
|
|
class X0 {
|
|
public:
|
|
void f(T t);
|
|
|
|
struct Inner {
|
|
void g(T t);
|
|
};
|
|
};
|
|
|
|
template<typename T>
|
|
void X0<T>::f(T t) {
|
|
t = 17; // expected-error{{incompatible}}
|
|
}
|
|
|
|
extern template class X0<int>;
|
|
|
|
extern template class X0<int*>;
|
|
|
|
template<typename T>
|
|
void X0<T>::Inner::g(T t) {
|
|
#ifdef MS
|
|
t = 17; // expected-error{{assigning to 'long *' from incompatible}} expected-error{{assigning to 'int *' from incompatible}}
|
|
#else
|
|
t = 17; // expected-error{{assigning to 'long *' from incompatible}}
|
|
#endif
|
|
}
|
|
|
|
void test_intptr(X0<int*> xi, X0<int*>::Inner xii) {
|
|
xi.f(0);
|
|
#ifdef MS
|
|
xii.g(0); // expected-note {{instantiation}}
|
|
#else
|
|
xii.g(0);
|
|
#endif
|
|
}
|
|
|
|
extern template class X0<long*>;
|
|
|
|
void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
|
|
xl.f(0);
|
|
xli.g(0);
|
|
}
|
|
|
|
template class X0<long*>; // expected-note 2{{instantiation}}
|
|
|
|
template<typename T>
|
|
class X1 {
|
|
public:
|
|
void f(T t) { t += 2; }
|
|
|
|
void g(T t);
|
|
};
|
|
|
|
template<typename T>
|
|
void X1<T>::g(T t) {
|
|
t += 2;
|
|
}
|
|
|
|
extern template class X1<void*>;
|
|
|
|
void g_X1(X1<void*> x1, void *ptr) {
|
|
x1.g(ptr);
|
|
}
|
|
|
|
extern template void X1<const void*>::g(const void*);
|
|
|
|
void g_X1_2(X1<const void *> x1, const void *ptr) {
|
|
x1.g(ptr);
|
|
}
|