1 // RUN: %clang_cc1 -no-opaque-pointers -triple i686-windows-msvc -emit-llvm -std=c++14 \ 2 // RUN: -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases \ 3 // RUN: -disable-llvm-passes -o - %s -w -fms-compatibility-version=19.00 | \ 4 // RUN: FileCheck %s 5 6 struct CtorWithClosure { 7 __declspec(dllexport) CtorWithClosure(...) {} 8 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 9 // CHECK: %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4 10 // CHECK: store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4 11 // CHECK: %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]] 12 // CHECK: call noundef %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* {{[^,]*}} %[[this]]) 13 // CHECK: ret void 14 }; 15 16 struct CtorWithClosureOutOfLine { 17 __declspec(dllexport) CtorWithClosureOutOfLine(...); 18 }; 19 CtorWithClosureOutOfLine::CtorWithClosureOutOfLine(...) {} 20 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorWithClosureOutOfLine@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 21 22 #define DELETE_IMPLICIT_MEMBERS(ClassName) \ 23 ClassName(ClassName &&) = delete; \ 24 ClassName(ClassName &) = delete; \ 25 ~ClassName() = delete; \ 26 ClassName &operator=(ClassName &) = delete 27 28 struct __declspec(dllexport) ClassWithClosure { 29 DELETE_IMPLICIT_MEMBERS(ClassWithClosure); 30 ClassWithClosure(...) {} 31 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 32 // CHECK: %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4 33 // CHECK: store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4 34 // CHECK: %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]] 35 // CHECK: call noundef %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* {{[^,]*}} %[[this]]) 36 // CHECK: ret void 37 }; 38 39 template <typename T> struct TemplateWithClosure { 40 TemplateWithClosure(int x = sizeof(T)) {} 41 }; 42 extern template struct TemplateWithClosure<char>; 43 template struct __declspec(dllexport) TemplateWithClosure<char>; 44 extern template struct TemplateWithClosure<int>; 45 template struct __declspec(dllexport) TemplateWithClosure<int>; 46 47 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$TemplateWithClosure@D@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 48 // CHECK: call {{.*}} @"??0?$TemplateWithClosure@D@@QAE@H@Z"({{.*}}, i32 noundef 1) 49 50 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$TemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 51 // CHECK: call {{.*}} @"??0?$TemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 noundef 4) 52 53 template <typename T> struct __declspec(dllexport) ExportedTemplateWithClosure { 54 ExportedTemplateWithClosure(int x = sizeof(T)) {} 55 }; 56 template <> ExportedTemplateWithClosure<int>::ExportedTemplateWithClosure(int); // Don't try to emit the closure for a declaration. 57 template <> ExportedTemplateWithClosure<int>::ExportedTemplateWithClosure(int) {}; 58 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$ExportedTemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 59 // CHECK: call {{.*}} @"??0?$ExportedTemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 noundef 4) 60 61 struct __declspec(dllexport) NestedOuter { 62 DELETE_IMPLICIT_MEMBERS(NestedOuter); 63 NestedOuter(void *p = 0) {} 64 struct __declspec(dllexport) NestedInner { 65 DELETE_IMPLICIT_MEMBERS(NestedInner); 66 NestedInner(void *p = 0) {} 67 }; 68 }; 69 70 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 71 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat 72 73 struct HasDtor { 74 ~HasDtor(); 75 int o; 76 }; 77 struct HasImplicitDtor1 { HasDtor o; }; 78 struct HasImplicitDtor2 { HasDtor o; }; 79 struct __declspec(dllexport) CtorClosureInline { 80 CtorClosureInline(const HasImplicitDtor1 &v = {}) {} 81 }; 82 struct __declspec(dllexport) CtorClosureOutOfLine { 83 CtorClosureOutOfLine(const HasImplicitDtor2 &v = {}); 84 }; 85 CtorClosureOutOfLine::CtorClosureOutOfLine(const HasImplicitDtor2 &v) {} 86 87 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorClosureInline@@QAEXXZ" 88 // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??1HasImplicitDtor1@@QAE@XZ" 89 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorClosureOutOfLine@@QAEXXZ" 90 // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??1HasImplicitDtor2@@QAE@XZ" 91 92 struct SomeStruct {}; 93 constexpr SomeStruct kConstexprStruct; 94 struct __declspec(dllexport) ConstexprDefaultArg { 95 ConstexprDefaultArg(SomeStruct = kConstexprStruct) {} 96 }; 97 // CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FConstexprDefaultArg@@QAEXXZ" 98