summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX')
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp50
1 files changed, 49 insertions, 1 deletions
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index c598880b625..d5d61f32ef9 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -544,6 +544,7 @@ struct A {
struct __declspec(dllexport) B {
B(A = 0) {}
};
+
}
//
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ"({{.*}}) comdat
@@ -611,7 +612,6 @@ namespace UseDtorAlias {
B::~B() { }
// Emit a alias definition of B's constructor.
// M32-DAG: @"\01??1B@UseDtorAlias@@QAE@XZ" = dllexport alias {{.*}} @"\01??1A@UseDtorAlias@@QAE@XZ"
-
}
struct __declspec(dllexport) DefaultedCtorsDtors {
@@ -729,6 +729,54 @@ extern template struct PR23770DerivedTemplate<int>;
template struct __declspec(dllexport) PR23770DerivedTemplate<int>;
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ"
+namespace InClassInits {
+
+struct __declspec(dllexport) S {
+ int x = 42;
+};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::S"* @"\01??0S@InClassInits@@QAE@XZ"
+
+// dllexport an already instantiated class template.
+template <typename T> struct Base {
+ int x = 42;
+};
+Base<int> base;
+struct __declspec(dllexport) T : Base<int> { };
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Base"* @"\01??0?$Base@H@InClassInits@@QAE@XZ"
+
+struct A { A(int); };
+struct __declspec(dllexport) U {
+ // Class with both default constructor closure and in-class initializer.
+ U(A = 0) {}
+ int x = 0;
+};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::U"* @"\01??0U@InClassInits@@QAE@UA@1@@Z"
+
+struct Evil {
+ template <typename T> struct Base {
+ int x = 0;
+ };
+ struct S : Base<int> {};
+ // The already instantiated Base<int> becomes dllexported below, but the
+ // in-class initializer for Base<>::x still hasn't been parsed, so emitting
+ // the default ctor must still be delayed.
+ struct __declspec(dllexport) T : Base<int> {};
+};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Evil::Base"* @"\01??0?$Base@H@Evil@InClassInits@@QAE@XZ"
+
+template <typename T> struct Foo {};
+template <typename T> struct Bar {
+ Bar<T> &operator=(Foo<T>) {}
+};
+struct __declspec(dllexport) Baz {
+ Bar<int> n;
+};
+// After parsing Baz, in ActOnFinishCXXNonNestedClass we would synthesize
+// Baz's operator=, causing instantiation of Foo<int> after which
+// ActOnFinishCXXNonNestedClass is called, and we would bite our own tail.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %"struct.InClassInits::Baz"* @"\01??4Baz@InClassInits@@QAEAAU01@ABU01@@Z"
+}
+
//===----------------------------------------------------------------------===//
// Classes with template base classes
OpenPOWER on IntegriCloud