diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGenCXX/dllexport.cpp | 13 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/dllimport.cpp | 49 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/explicit-instantiation.cpp | 23 | ||||
-rw-r--r-- | clang/test/SemaTemplate/extern-templates.cpp | 13 |
4 files changed, 81 insertions, 17 deletions
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index 6232f2c747e..7cef7c2d127 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -844,6 +844,11 @@ struct __declspec(dllexport) B { // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ" } +// dllexport trumps dllexport on an explicit instantiation. +template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} }; +template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>; +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ" + //===----------------------------------------------------------------------===// // Classes with template base classes @@ -958,14 +963,6 @@ template struct ExplicitInstantiationDeclTemplateBase<int>; // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ" // G32-DAG: define weak_odr x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv -template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} }; -extern template struct ExplicitInstantiationDeclTemplateBase2<int>; -struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {}; -template struct __declspec(dllimport) ExplicitInstantiationDeclTemplateBase2<int>; -USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func) -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ" -// G32-DAG: define weak_odr x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv - // PR26076 struct LayerSelectionBound; template <typename> struct Selection {}; diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp index 021de44789a..629c2b6c8ba 100644 --- a/clang/test/CodeGenCXX/dllimport.cpp +++ b/clang/test/CodeGenCXX/dllimport.cpp @@ -656,7 +656,7 @@ namespace DontUseDtorAlias { namespace Vtordisp { // Don't dllimport the vtordisp. - // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ" + // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ" class Base { virtual void f() {} @@ -667,7 +667,7 @@ namespace Vtordisp { C() {} virtual void f() {} }; - template class C<char>; + USECLASS(C<int>); } namespace ClassTemplateStaticDef { @@ -698,26 +698,31 @@ namespace PR19933 { template <typename T> struct A { static NonPOD x; }; template <typename T> NonPOD A<T>::x; template struct __declspec(dllimport) A<int>; - // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer + USEVARTYPE(NonPOD, A<int>::x); + // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = external dllimport global %"struct.PR19933::NonPOD" int f(); template <typename T> struct B { static int x; }; template <typename T> int B<T>::x = f(); template struct __declspec(dllimport) B<int>; - // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0 + USEVAR(B<int>::x); + // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = external dllimport global i32 constexpr int g() { return 42; } template <typename T> struct C { static int x; }; template <typename T> int C<T>::x = g(); template struct __declspec(dllimport) C<int>; - // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42 + USEVAR(C<int>::x); + // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = external dllimport global i32 template <int I> struct D { static int x, y; }; template <int I> int D<I>::x = I + 1; template <int I> int D<I>::y = I + f(); template struct __declspec(dllimport) D<42>; - // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43 - // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0 + USEVAR(D<42>::x); + USEVAR(D<42>::y); + // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32 + // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32 } namespace PR21355 { @@ -805,6 +810,36 @@ template struct __declspec(dllimport) PR23770DerivedTemplate<int>; USEMEMFUNC(PR23770BaseTemplate<int>, f); // M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ" +namespace PR27810 { + template <class T> + struct basic_ostream { + struct sentry { + sentry() { } + void foo() { } + }; + }; + template class __declspec(dllimport) basic_ostream<char>; + // The explicit instantiation definition acts as an explicit instantiation + // *declaration*, dllimport is not inherited by the inner class, and no + // functions are emitted unless they are used. + + USEMEMFUNC(basic_ostream<char>::sentry, foo); + // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?foo@sentry@?$basic_ostream@D@PR27810@@QAEXXZ" + // M32-NOT: ??0sentry@?$basic_ostream@D@PR27810@@QAE@XZ +} + +namespace PR27811 { + template <class T> struct codecvt { + virtual ~codecvt() { } + }; + template class __declspec(dllimport) codecvt<char>; + + // dllimport means this explicit instantiation definition gets treated as a + // declaration. Thus, the vtable should not be marked used, and in fact + // nothing for this class should be emitted at all since it's not used. + // M32-NOT: codecvt +} + //===----------------------------------------------------------------------===// // Classes with template base classes //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGenCXX/explicit-instantiation.cpp b/clang/test/CodeGenCXX/explicit-instantiation.cpp index 6076444c25b..7e00d78e483 100644 --- a/clang/test/CodeGenCXX/explicit-instantiation.cpp +++ b/clang/test/CodeGenCXX/explicit-instantiation.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-OPT // RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -O3 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT +// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK-MS // This check logically is attached to 'template int S<int>::i;' below. // CHECK: @_ZN1SIiE1iE = weak_odr global i32 @@ -103,6 +104,28 @@ int g() { return S<int>().f(); } template struct S<int>; } +namespace NestedClasses { + // Check how explicit instantiation of an outer class affects the inner class. + template <typename T> struct Outer { + struct Inner { + void f() {} + }; + }; + + // Explicit instantiation definition of Outer causes explicit instantiation + // definition of Inner. + template struct Outer<int>; + // CHECK: define weak_odr void @_ZN13NestedClasses5OuterIiE5Inner1fEv + // CHECK-MS: define weak_odr x86_thiscallcc void @"\01?f@Inner@?$Outer@H@NestedClasses@@QAEXXZ" + + // Explicit instantiation declaration of Outer causes explicit instantiation + // declaration of Inner, but not in MSVC mode. + extern template struct Outer<char>; + auto use = &Outer<char>::Inner::f; + // CHECK: {{declare|define available_externally}} void @_ZN13NestedClasses5OuterIcE5Inner1fEv + // CHECK-MS: define linkonce_odr x86_thiscallcc void @"\01?f@Inner@?$Outer@D@NestedClasses@@QAEXXZ" +} + // Check that we emit definitions from explicit instantiations even when they // occur prior to the definition itself. template <typename T> struct S { diff --git a/clang/test/SemaTemplate/extern-templates.cpp b/clang/test/SemaTemplate/extern-templates.cpp index eca64ed595e..5eb9c9db127 100644 --- a/clang/test/SemaTemplate/extern-templates.cpp +++ b/clang/test/SemaTemplate/extern-templates.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// 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 { @@ -21,12 +22,20 @@ extern template class X0<int*>; template<typename T> void X0<T>::Inner::g(T t) { - t = 17; // expected-error{{incompatible}} +#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*>; |