1 // RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc       \
2 // RUN:     -disable-llvm-passes -std=c++14                             \
3 // RUN:     -fno-dllexport-inlines -emit-llvm -O1 -o - |                \
4 // RUN:     FileCheck --check-prefix=CHECK --check-prefix=NOEXPORTINLINE %s
5 
6 // RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc       \
7 // RUN:     -disable-llvm-passes -std=c++14                             \
8 // RUN:     -emit-llvm -O1 -o - |                                       \
9 // RUN:     FileCheck --check-prefix=CHECK  --check-prefix=EXPORTINLINE %s
10 
11 
12 struct __declspec(dllexport) ExportedClass {
13 
14   // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InclassDefFunc@ExportedClass@@
15   // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@ExportedClass@@
InclassDefFunc()16   void InclassDefFunc() {}
17 
18   // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ"
InclassDefFuncWithStaticVariable()19   int InclassDefFuncWithStaticVariable() {
20     // CHECK-DAG: @"?static_variable@?1??InclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
21     static int static_variable = 0;
22     ++static_variable;
23     return static_variable;
24   }
25 
26   // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFunctWithLambdaStaticVariable@ExportedClass@@QEAAHXZ"
InclassDefFunctWithLambdaStaticVariable()27   int InclassDefFunctWithLambdaStaticVariable() {
28     // CHECK-DAG: @"?static_x@?2???R<lambda_1>@?0??InclassDefFunctWithLambdaStaticVariable@ExportedClass@@QEAAHXZ@QEBA?A?<auto>@@XZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
29     return ([]() { static int static_x; return ++static_x; })();
30   }
31 
32   // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InlineOutclassDefFunc@ExportedClass@@QEAAXXZ
33   // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InlineOutclassDefFunc@ExportedClass@@QEAAXXZ
34   inline void InlineOutclassDefFunc();
35 
36   // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InlineOutclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ"
37   inline int InlineOutclassDefFuncWithStaticVariable();
38 
39   // CHECK-DAG: define dso_local dllexport void @"?OutoflineDefFunc@ExportedClass@@QEAAXXZ"
40   void OutoflineDefFunc();
41 };
42 
OutoflineDefFunc()43 void ExportedClass::OutoflineDefFunc() {}
44 
InlineOutclassDefFunc()45 inline void ExportedClass::InlineOutclassDefFunc() {}
46 
InlineOutclassDefFuncWithStaticVariable()47 inline int ExportedClass::InlineOutclassDefFuncWithStaticVariable() {
48   static int static_variable = 0;
49   return ++static_variable;
50 }
51 
ExportedClassUser()52 void ExportedClassUser() {
53   ExportedClass a;
54   a.InclassDefFunc();
55   a.InlineOutclassDefFunc();
56 }
57 
58 template<typename T>
59 struct __declspec(dllexport) TemplateExportedClass {
InclassDefFunc()60   void InclassDefFunc() {}
61 
InclassDefFuncWithStaticVariable()62   int InclassDefFuncWithStaticVariable() {
63     static int static_x = 0;
64     return ++static_x;
65   }
66 };
67 
68 class A11{};
69 class B22{};
70 
71 // CHECK-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateExportedClass@VA11@@@@QEAAXXZ"
72 // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VA11@@@@QEAAHXZ"
73 // CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VA11@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
74 template class TemplateExportedClass<A11>;
75 
76 // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InclassDefFunc@?$TemplateExportedClass@VB22@@@@QEAAXXZ"
77 // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateExportedClass@VB22@@@@QEAAXXZ
78 // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VB22@@@@QEAAHXZ"
79 // CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VB22@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
80 TemplateExportedClass<B22> b22;
81 
TemplateExportedClassUser()82 void TemplateExportedClassUser() {
83   b22.InclassDefFunc();
84   b22.InclassDefFuncWithStaticVariable();
85 }
86 
87 
88 template<typename T>
89 struct TemplateNoAttributeClass {
InclassDefFuncTemplateNoAttributeClass90   void InclassDefFunc() {}
InclassDefFuncWithStaticLocalTemplateNoAttributeClass91   int InclassDefFuncWithStaticLocal() {
92     static int static_x;
93     return ++static_x;
94   }
95 };
96 
97 // CHECK-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateNoAttributeClass@VA11@@@@QEAAXXZ"
98 // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VA11
99 // CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VA11@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
100 template class __declspec(dllexport) TemplateNoAttributeClass<A11>;
101 
102 // CHECK-DAG: define available_externally dllimport void @"?InclassDefFunc@?$TemplateNoAttributeClass@VB22@@@@QEAAXXZ"
103 // CHECK-DAG: define available_externally dllimport i32 @"?InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VB22@@@@QEAAHXZ"
104 // CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VB22@@@@QEAAHXZ@4HA" = available_externally dllimport global i32 0, align 4
105 extern template class __declspec(dllimport) TemplateNoAttributeClass<B22>;
106 
TemplateNoAttributeClassUser()107 void TemplateNoAttributeClassUser() {
108   TemplateNoAttributeClass<B22> b22;
109   b22.InclassDefFunc();
110   b22.InclassDefFuncWithStaticLocal();
111 }
112 
113 struct __declspec(dllimport) ImportedClass {
114   // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InClassDefFunc@ImportedClass@@QEAAXXZ"
115   // EXPORTINLINE-DAG: define available_externally dllimport void @"?InClassDefFunc@ImportedClass@@QEAAXXZ"
InClassDefFunc()116   void InClassDefFunc() {}
117 
118   // EXPORTINLINE-DAG: define available_externally dllimport i32 @"?InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ"
119   // NOEXPORTINLINE-DAG: define linkonce_odr dso_local i32 @"?InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ"
InClassDefFuncWithStaticVariable()120   int InClassDefFuncWithStaticVariable() {
121     // CHECK-DAG: @"?static_variable@?1??InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ@4HA" = available_externally dllimport global i32 0, align 4
122     static int static_variable = 0;
123     ++static_variable;
124     return static_variable;
125   }
126 };
127 
InClassDefFuncUser()128 int InClassDefFuncUser() {
129   // This is necessary for declare statement of ImportedClass::InClassDefFunc().
130   ImportedClass c;
131   c.InClassDefFunc();
132   return c.InClassDefFuncWithStaticVariable();
133 }
134