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