1 // RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s 2 // RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s 3 // RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s 4 // RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s 5 6 // RUN: %clang_cc1 -triple i686-pc-win32 -O1 -mconstructor-aliases -std=c++1y -emit-llvm -o - %s | FileCheck %s --check-prefix=MSC --check-prefix=M32 7 8 // Helper structs to make templates more expressive. 9 struct ImplicitInst_Exported {}; 10 struct ExplicitDecl_Exported {}; 11 struct ExplicitInst_Exported {}; 12 struct ExplicitSpec_Exported {}; 13 struct ExplicitSpec_Def_Exported {}; 14 struct ExplicitSpec_InlineDef_Exported {}; 15 struct ExplicitSpec_NotExported {}; 16 struct External { int v; }; 17 18 #define JOIN2(x, y) x##y 19 #define JOIN(x, y) JOIN2(x, y) 20 #define UNIQ(name) JOIN(name, __LINE__) 21 #define USEVAR(var) int UNIQ(use)() { return var; } 22 #define USE(func) void UNIQ(use)() { func(); } 23 #define INSTVAR(var) template int var; 24 #define INST(func) template void func(); 25 26 27 //===----------------------------------------------------------------------===// 28 // Globals 29 //===----------------------------------------------------------------------===// 30 31 // Declarations are not exported. 32 // MSC-NOT: @"\01?ExternGlobalDecl@@3HA" 33 // GNU-NOT: @ExternGlobalDecl 34 __declspec(dllexport) extern int ExternGlobalDecl; 35 36 // dllexport implies a definition. 37 // MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4 38 // GNU-DAG: @GlobalDef = dllexport global i32 0, align 4 39 __declspec(dllexport) int GlobalDef; 40 41 // Export definition. 42 // MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4 43 // GNU-DAG: @GlobalInit1 = dllexport global i32 1, align 4 44 __declspec(dllexport) int GlobalInit1 = 1; 45 46 // MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4 47 // GNU-DAG: @GlobalInit2 = dllexport global i32 1, align 4 48 int __declspec(dllexport) GlobalInit2 = 1; 49 50 // Declare, then export definition. 51 // MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4 52 // GNU-DAG: @GlobalDeclInit = dllexport global i32 1, align 4 53 __declspec(dllexport) extern int GlobalDeclInit; 54 int GlobalDeclInit = 1; 55 56 // Redeclarations 57 // MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4 58 // GNU-DAG: @GlobalRedecl1 = dllexport global i32 0, align 4 59 __declspec(dllexport) extern int GlobalRedecl1; 60 __declspec(dllexport) int GlobalRedecl1; 61 62 // MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4 63 // GNU-DAG: @GlobalRedecl2 = dllexport global i32 0, align 4 64 __declspec(dllexport) extern int GlobalRedecl2; 65 int GlobalRedecl2; 66 67 // MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = dllexport global i32 0, align 4 68 // GNU-DAG: @_ZN2ns14ExternalGlobalE = dllexport global i32 0, align 4 69 namespace ns { __declspec(dllexport) int ExternalGlobal; } 70 71 // MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4 72 // GNU-DAG: @ExternalAutoTypeGlobal = dllexport global %struct.External zeroinitializer, align 4 73 __declspec(dllexport) auto ExternalAutoTypeGlobal = External(); 74 75 int f(); 76 // MSC-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0 77 // MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0 78 int __declspec(dllexport) nonInlineStaticLocalsFunc() { 79 static int x = f(); 80 return x++; 81 }; 82 83 // MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0 84 // MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0 85 // Note: MinGW doesn't seem to export the static local here. 86 inline int __declspec(dllexport) inlineStaticLocalsFunc() { 87 static int x = f(); 88 return x++; 89 } 90 91 92 93 //===----------------------------------------------------------------------===// 94 // Variable templates 95 //===----------------------------------------------------------------------===// 96 97 // Declarations are not exported. 98 99 // dllexport implies a definition. 100 // MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA" 101 // GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE 102 template<typename T> __declspec(dllexport) int VarTmplDef; 103 INSTVAR(VarTmplDef<ExplicitInst_Exported>) 104 105 // MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global 106 // GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external dllexport global 107 template<typename T> __declspec(dllexport) int VarTmplImplicitDef; 108 USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>) 109 110 // Export definition. 111 // MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 112 // GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 113 template<typename T> __declspec(dllexport) int VarTmplInit1 = 1; 114 INSTVAR(VarTmplInit1<ExplicitInst_Exported>) 115 116 // MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 117 // GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 118 template<typename T> int __declspec(dllexport) VarTmplInit2 = 1; 119 INSTVAR(VarTmplInit2<ExplicitInst_Exported>) 120 121 // Declare, then export definition. 122 // MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 123 // GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 124 template<typename T> __declspec(dllexport) extern int VarTmplDeclInit; 125 template<typename T> int VarTmplDeclInit = 1; 126 INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>) 127 128 // Redeclarations 129 // MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 130 // GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 131 template<typename T> __declspec(dllexport) extern int VarTmplRedecl1; 132 template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1; 133 INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>) 134 135 // MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 136 // GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 137 template<typename T> __declspec(dllexport) extern int VarTmplRedecl2; 138 template<typename T> int VarTmplRedecl2 = 1; 139 INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>) 140 141 // MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4 142 // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, align 4 143 namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; } 144 INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>) 145 146 // MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4 147 // GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, align 4 148 template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External(); 149 template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>; 150 151 152 template<typename T> int VarTmpl = 1; 153 template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1; 154 155 // Export implicit instantiation of an exported variable template. 156 // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 157 // GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 158 USEVAR(ExportedVarTmpl<ImplicitInst_Exported>) 159 160 // Export explicit instantiation declaration of an exported variable template. 161 // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 162 // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4 163 extern template int ExportedVarTmpl<ExplicitDecl_Exported>; 164 template int ExportedVarTmpl<ExplicitDecl_Exported>; 165 166 // Export explicit instantiation definition of an exported variable template. 167 // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 168 // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 169 template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>; 170 171 // Export specialization of an exported variable template. 172 // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4 173 // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE = dllexport global i32 0, align 4 174 template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>; 175 176 // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4 177 // GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE = dllexport global i32 1, align 4 178 template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1; 179 180 // Not exporting specialization of an exported variable template without 181 // explicit dllexport. 182 // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4 183 // GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE = global i32 0, align 4 184 template<> int ExportedVarTmpl<ExplicitSpec_NotExported>; 185 186 187 // Export explicit instantiation declaration of a non-exported variable template. 188 // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 189 // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4 190 extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>; 191 template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>; 192 193 // Export explicit instantiation definition of a non-exported variable template. 194 // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 195 // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 196 template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>; 197 198 // Export specialization of a non-exported variable template. 199 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4 200 // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE = dllexport global i32 0, align 4 201 template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>; 202 203 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4 204 // GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE = dllexport global i32 1, align 4 205 template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1; 206 207 208 209 //===----------------------------------------------------------------------===// 210 // Functions 211 //===----------------------------------------------------------------------===// 212 213 // Declarations are not exported. 214 215 // Export function definition. 216 // MSC-DAG: define dllexport void @"\01?def@@YAXXZ"() 217 // GNU-DAG: define dllexport void @_Z3defv() 218 __declspec(dllexport) void def() {} 219 220 // extern "C" 221 // MSC-DAG: define dllexport void @externC() 222 // GNU-DAG: define dllexport void @externC() 223 extern "C" __declspec(dllexport) void externC() {} 224 225 // Export inline function. 226 // MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"() 227 // GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv() 228 __declspec(dllexport) inline void inlineFunc() {} 229 230 // MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"() 231 // GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv() 232 __declspec(dllexport) inline void inlineDecl(); 233 void inlineDecl() {} 234 235 // MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"() 236 // GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv() 237 __declspec(dllexport) void inlineDef(); 238 inline void inlineDef() {} 239 240 // Redeclarations 241 // MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"() 242 // GNU-DAG: define dllexport void @_Z7redecl1v() 243 __declspec(dllexport) void redecl1(); 244 __declspec(dllexport) void redecl1() {} 245 246 // MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"() 247 // GNU-DAG: define dllexport void @_Z7redecl2v() 248 __declspec(dllexport) void redecl2(); 249 void redecl2() {} 250 251 // Friend functions 252 // MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"() 253 // GNU-DAG: define dllexport void @_Z7friend1v() 254 // MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"() 255 // GNU-DAG: define dllexport void @_Z7friend2v() 256 struct FuncFriend { 257 friend __declspec(dllexport) void friend1(); 258 friend __declspec(dllexport) void friend2(); 259 }; 260 __declspec(dllexport) void friend1() {} 261 void friend2() {} 262 263 // Implicit declarations can be redeclared with dllexport. 264 // MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"( 265 // GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}( 266 void* alloc(__SIZE_TYPE__ n); 267 __declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); } 268 269 // MSC-DAG: define dllexport void @"\01?externalFunc@ns@@YAXXZ"() 270 // GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv() 271 namespace ns { __declspec(dllexport) void externalFunc() {} } 272 273 274 275 //===----------------------------------------------------------------------===// 276 // Function templates 277 //===----------------------------------------------------------------------===// 278 279 // Export function template definition. 280 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"() 281 // GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv() 282 template<typename T> __declspec(dllexport) void funcTmplDef() {} 283 INST(funcTmplDef<ExplicitInst_Exported>) 284 285 // Export inline function template. 286 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"() 287 // GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv() 288 template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {} 289 INST(inlineFuncTmpl1<ExplicitInst_Exported>) 290 291 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"() 292 // GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv() 293 template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {} 294 INST(inlineFuncTmpl2<ExplicitInst_Exported>) 295 296 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"() 297 // GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv() 298 template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl(); 299 template<typename T> void inlineFuncTmplDecl() {} 300 INST(inlineFuncTmplDecl<ExplicitInst_Exported>) 301 302 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"() 303 // GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv() 304 template<typename T> __declspec(dllexport) void inlineFuncTmplDef(); 305 template<typename T> inline void inlineFuncTmplDef() {} 306 INST(inlineFuncTmplDef<ExplicitInst_Exported>) 307 308 309 // Redeclarations 310 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"() 311 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv() 312 template<typename T> __declspec(dllexport) void funcTmplRedecl1(); 313 template<typename T> __declspec(dllexport) void funcTmplRedecl1() {} 314 INST(funcTmplRedecl1<ExplicitInst_Exported>) 315 316 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"() 317 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv() 318 template<typename T> __declspec(dllexport) void funcTmplRedecl2(); 319 template<typename T> void funcTmplRedecl2() {} 320 INST(funcTmplRedecl2<ExplicitInst_Exported>) 321 322 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"() 323 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv() 324 template<typename T> __declspec(dllexport) void funcTmplRedecl3(); 325 template<typename T> void funcTmplRedecl3() {} 326 INST(funcTmplRedecl3<ExplicitInst_Exported>) 327 328 329 // Function template friends 330 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"() 331 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv() 332 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"() 333 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv() 334 struct FuncTmplFriend { 335 template<typename T> friend __declspec(dllexport) void funcTmplFriend1(); 336 template<typename T> friend __declspec(dllexport) void funcTmplFriend2(); 337 }; 338 template<typename T> __declspec(dllexport) void funcTmplFriend1() {} 339 template<typename T> void funcTmplFriend2() {} 340 INST(funcTmplFriend1<ExplicitInst_Exported>) 341 INST(funcTmplFriend2<ExplicitInst_Exported>) 342 343 // MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"() 344 // GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv() 345 namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} } 346 INST(ns::externalFuncTmpl<ExplicitInst_Exported>) 347 348 349 template<typename T> void funcTmpl() {} 350 template<typename T> __declspec(dllexport) void exportedFuncTmpl() {} 351 352 // Export implicit instantiation of an exported function template. 353 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"() 354 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv() 355 USE(exportedFuncTmpl<ImplicitInst_Exported>) 356 357 // Export explicit instantiation declaration of an exported function template. 358 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"() 359 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv() 360 extern template void exportedFuncTmpl<ExplicitDecl_Exported>(); 361 template void exportedFuncTmpl<ExplicitDecl_Exported>(); 362 363 // Export explicit instantiation definition of an exported function template. 364 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"() 365 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv() 366 template void exportedFuncTmpl<ExplicitInst_Exported>(); 367 368 // Export specialization of an exported function template. 369 // MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"() 370 // GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv() 371 template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {} 372 373 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"() 374 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv() 375 template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {} 376 377 // Not exporting specialization of an exported function template without 378 // explicit dllexport. 379 // MSC-DAG: define void @"\01??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"() 380 // GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv() 381 template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {} 382 383 384 // Export explicit instantiation declaration of a non-exported function template. 385 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"() 386 // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv() 387 extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>(); 388 template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>(); 389 390 // Export explicit instantiation definition of a non-exported function template. 391 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"() 392 // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv() 393 template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>(); 394 395 // Export specialization of a non-exported function template. 396 // MSC-DAG: define dllexport void @"\01??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"() 397 // GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv() 398 template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {} 399 400 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"() 401 // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv() 402 template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {} 403 404 405 406 //===----------------------------------------------------------------------===// 407 // Precedence 408 //===----------------------------------------------------------------------===// 409 410 // dllexport takes precedence over the dllimport if both are specified. 411 // MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4 412 // MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4 413 // GNU-DAG: @PrecedenceGlobal1A = dllexport global i32 0, align 4 414 // GNU-DAG: @PrecedenceGlobal1B = dllexport global i32 0, align 4 415 __attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // dllimport ignored 416 __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored 417 418 // MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4 419 // MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4 420 // GNU-DAG: @PrecedenceGlobal2A = dllexport global i32 0, align 4 421 // GNU-DAG: @PrecedenceGlobal2B = dllexport global i32 0, align 4 422 __attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // dllimport ignored 423 __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored 424 425 // MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4 426 // GNU-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4 427 __declspec(dllexport) extern int PrecedenceGlobalRedecl1; 428 __declspec(dllimport) int PrecedenceGlobalRedecl1 = 0; 429 430 // MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4 431 // GNU-DAG: @PrecedenceGlobalRedecl2 = dllexport global i32 0, align 4 432 __declspec(dllimport) extern int PrecedenceGlobalRedecl2; 433 __declspec(dllexport) int PrecedenceGlobalRedecl2; 434 435 // MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4 436 // GNU-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 0, align 4 437 __attribute__((dllexport)) extern int PrecedenceGlobalMixed1; 438 __declspec(dllimport) int PrecedenceGlobalMixed1 = 0; 439 440 // MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4 441 // GNU-DAG: @PrecedenceGlobalMixed2 = dllexport global i32 0, align 4 442 __attribute__((dllimport)) extern int PrecedenceGlobalMixed2; 443 __declspec(dllexport) int PrecedenceGlobalMixed2; 444 445 // MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ" 446 // MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ" 447 // GNU-DAG: define dllexport void @_Z12precedence1Av() 448 // GNU-DAG: define dllexport void @_Z12precedence1Bv() 449 void __attribute__((dllimport, dllexport)) precedence1A() {} 450 void __declspec(dllimport) __declspec(dllexport) precedence1B() {} 451 452 // MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ" 453 // MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ" 454 // GNU-DAG: define dllexport void @_Z12precedence2Av() 455 // GNU-DAG: define dllexport void @_Z12precedence2Bv() 456 void __attribute__((dllexport, dllimport)) precedence2A() {} 457 void __declspec(dllexport) __declspec(dllimport) precedence2B() {} 458 459 // MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ" 460 // GNU-DAG: define dllexport void @_Z17precedenceRedecl1v() 461 void __declspec(dllimport) precedenceRedecl1(); 462 void __declspec(dllexport) precedenceRedecl1() {} 463 464 // MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ" 465 // GNU-DAG: define dllexport void @_Z17precedenceRedecl2v() 466 void __declspec(dllexport) precedenceRedecl2(); 467 void __declspec(dllimport) precedenceRedecl2() {} 468 469 470 471 //===----------------------------------------------------------------------===// 472 // Classes 473 //===----------------------------------------------------------------------===// 474 475 struct S { 476 void __declspec(dllexport) a() {} 477 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ" 478 479 struct T { 480 void __declspec(dllexport) a() {} 481 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ" 482 }; 483 }; 484 485 486 struct __declspec(dllexport) T { 487 // Copy assignment operator: 488 // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z" 489 490 // Explicitly defaulted copy constructur: 491 T(const T&) = default; 492 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z" 493 494 void a() {} 495 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ" 496 497 static int b; 498 // M32-DAG: @"\01?b@T@@2HA" = external dllexport global i32 499 500 static int c; 501 // M32-DAG: @"\01?c@T@@2HA" = dllexport global i32 0, align 4 502 }; 503 504 USEVAR(T::b) 505 int T::c; 506 507 template <typename T> struct __declspec(dllexport) U { void foo() {} }; 508 // The U<int> specialization below must cause the following to be emitted: 509 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ" 510 // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z" 511 struct __declspec(dllexport) V : public U<int> { }; 512 513 514 struct __declspec(dllexport) W { virtual void foo() {} }; 515 // Default ctor: 516 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ" 517 // Copy ctor: 518 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z" 519 // vftable: 520 // M32-DAG: @"\01??_7W@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)] 521 // G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] 522 523 struct __declspec(dllexport) X : public virtual W {}; 524 // vbtable: 525 // M32-DAG: @"\01??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4] 526 527 struct __declspec(dllexport) Y { 528 // Move assignment operator: 529 // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z" 530 531 int x; 532 }; 533 534 struct __declspec(dllexport) Z { virtual ~Z() {} }; 535 // The scalar deleting dtor does not get exported: 536 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_GZ@@UAEPAXI@Z" 537 538 539 // The user-defined dtor does get exported: 540 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1Z@@UAE@XZ" 541 542 namespace DontUseDtorAlias { 543 struct __declspec(dllexport) A { ~A(); }; 544 struct __declspec(dllexport) B : A { ~B(); }; 545 A::~A() { } 546 B::~B() { } 547 // Emit a real definition of B's constructor; don't alias it to A's. 548 // M32-DAG: define dllexport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ" 549 } 550 551 struct __declspec(dllexport) DefaultedCtorsDtors { 552 DefaultedCtorsDtors() = default; 553 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ" 554 ~DefaultedCtorsDtors() = default; 555 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ" 556 }; 557 558 namespace ReferencedInlineMethodInNestedClass { 559 struct __declspec(dllexport) S { 560 void foo() { 561 t->bar(); 562 } 563 struct T { 564 void bar() {} 565 }; 566 T *t; 567 }; 568 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ" 569 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ" 570 } 571