Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
      2 // RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
      3 // RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -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  -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
      5 // RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
      6 // RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
      7 
      8 // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
      9 // RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC2 %s
     10 // RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU2 %s
     11 
     12 // Helper structs to make templates more expressive.
     13 struct ImplicitInst_Imported {};
     14 struct ImplicitInst_NotImported {};
     15 struct ExplicitDecl_Imported {};
     16 struct ExplicitInst_Imported {};
     17 struct ExplicitSpec_Imported {};
     18 struct ExplicitSpec_Def_Imported {};
     19 struct ExplicitSpec_InlineDef_Imported {};
     20 struct ExplicitSpec_NotImported {};
     21 
     22 #define JOIN2(x, y) x##y
     23 #define JOIN(x, y) JOIN2(x, y)
     24 #define UNIQ(name) JOIN(name, __LINE__)
     25 #define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
     26 #define USEVAR(var) USEVARTYPE(int, var)
     27 #define USE(func) void UNIQ(use)() { func(); }
     28 #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
     29 #define USECLASS(class) void UNIQ(USE)() { class x; }
     30 #define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
     31 #define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
     32 
     33 //===----------------------------------------------------------------------===//
     34 // Globals
     35 //===----------------------------------------------------------------------===//
     36 
     37 // Import declaration.
     38 // MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32
     39 // GNU-DAG: @ExternGlobalDecl            = external dllimport global i32
     40 __declspec(dllimport) extern int ExternGlobalDecl;
     41 USEVAR(ExternGlobalDecl)
     42 
     43 // dllimport implies a declaration.
     44 // MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32
     45 // GNU-DAG: @GlobalDecl            = external dllimport global i32
     46 __declspec(dllimport) int GlobalDecl;
     47 USEVAR(GlobalDecl)
     48 
     49 // Redeclarations
     50 // MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32
     51 // GNU-DAG: @GlobalRedecl1            = external dllimport global i32
     52 __declspec(dllimport) extern int GlobalRedecl1;
     53 __declspec(dllimport) extern int GlobalRedecl1;
     54 USEVAR(GlobalRedecl1)
     55 
     56 // MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32
     57 // GNU-DAG: @GlobalRedecl2a            = external dllimport global i32
     58 __declspec(dllimport) int GlobalRedecl2a;
     59 __declspec(dllimport) int GlobalRedecl2a;
     60 USEVAR(GlobalRedecl2a)
     61 
     62 // M32-DAG: @"\01?GlobalRedecl2b@@3PAHA"   = external dllimport global i32*
     63 // M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
     64 // GNU-DAG: @GlobalRedecl2b                = external dllimport global i32*
     65 int *__attribute__((dllimport)) GlobalRedecl2b;
     66 int *__attribute__((dllimport)) GlobalRedecl2b;
     67 USEVARTYPE(int*, GlobalRedecl2b)
     68 
     69 // MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32
     70 // GNU-DAG: @GlobalRedecl2c            = external dllimport global i32
     71 int GlobalRedecl2c __attribute__((dllimport));
     72 int GlobalRedecl2c __attribute__((dllimport));
     73 USEVAR(GlobalRedecl2c)
     74 
     75 // NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
     76 // and drop the dllimport with a warning.
     77 // MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32
     78 // GNU-DAG: @GlobalRedecl3            = external global i32
     79 __declspec(dllimport) extern int GlobalRedecl3;
     80                       extern int GlobalRedecl3; // dllimport ignored
     81 USEVAR(GlobalRedecl3)
     82 
     83 // MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = external dllimport global i32
     84 // GNU-DAG: @_ZN2ns14ExternalGlobalE      = external dllimport global i32
     85 namespace ns { __declspec(dllimport) int ExternalGlobal; }
     86 USEVAR(ns::ExternalGlobal)
     87 
     88 int f();
     89 // MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0
     90 // MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0
     91 inline int __declspec(dllimport) inlineStaticLocalsFunc() {
     92   static int x = f();
     93   return x++;
     94 };
     95 USE(inlineStaticLocalsFunc);
     96 
     97 // The address of a dllimport global cannot be used in constant initialization.
     98 // M32-DAG: @"\01?arr@?0??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer
     99 // GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
    100 int *initializationFunc() {
    101   static int *const arr[] = {&ExternGlobalDecl};
    102   return arr[0];
    103 }
    104 USE(initializationFunc);
    105 
    106 
    107 //===----------------------------------------------------------------------===//
    108 // Variable templates
    109 //===----------------------------------------------------------------------===//
    110 
    111 // Import declaration.
    112 // MSC-DAG: @"\01??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
    113 // GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
    114 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
    115 USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
    116 
    117 // dllimport implies a declaration.
    118 // MSC-DAG: @"\01??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
    119 // GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
    120 template<typename T> __declspec(dllimport) int VarTmplDecl;
    121 USEVAR(VarTmplDecl<ImplicitInst_Imported>)
    122 
    123 // Redeclarations
    124 // MSC-DAG: @"\01??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
    125 // GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE          = external dllimport global i32
    126 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
    127 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
    128 USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
    129 
    130 // MSC-DAG: @"\01??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
    131 // GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE          = external dllimport global i32
    132 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
    133 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
    134 USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
    135 
    136 // MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32
    137 // GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE          = external global i32
    138 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
    139 template<typename T>                       extern int VarTmplRedecl3; // dllimport ignored
    140 USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
    141 
    142 
    143 // MSC-DAG: @"\01??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
    144 // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE        = external dllimport global i32
    145 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
    146 USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
    147 
    148 
    149 template<typename T> int VarTmpl;
    150 template<typename T> __declspec(dllimport) int ImportedVarTmpl;
    151 
    152 // Import implicit instantiation of an imported variable template.
    153 // MSC-DAG: @"\01??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
    154 // GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE          = external dllimport global i32
    155 USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
    156 
    157 // Import explicit instantiation declaration of an imported variable template.
    158 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
    159 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE          = external dllimport global i32
    160 extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
    161 USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
    162 
    163 // An explicit instantiation definition of an imported variable template cannot
    164 // be imported because the template must be defined which is illegal.
    165 
    166 // Import specialization of an imported variable template.
    167 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
    168 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE          = external dllimport global i32
    169 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
    170 USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
    171 
    172 // Not importing specialization of an imported variable template without
    173 // explicit dllimport.
    174 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4
    175 // GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE          = global i32 0, align 4
    176 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
    177 USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
    178 
    179 // Import explicit instantiation declaration of a non-imported variable template.
    180 // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
    181 // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE           = external dllimport global i32
    182 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
    183 USEVAR(VarTmpl<ExplicitDecl_Imported>)
    184 
    185 // Import explicit instantiation definition of a non-imported variable template.
    186 // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32
    187 // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE           = external dllimport global i32
    188 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
    189 USEVAR(VarTmpl<ExplicitInst_Imported>)
    190 
    191 // Import specialization of a non-imported variable template.
    192 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
    193 // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE           = external dllimport global i32
    194 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
    195 USEVAR(VarTmpl<ExplicitSpec_Imported>)
    196 
    197 
    198 
    199 //===----------------------------------------------------------------------===//
    200 // Functions
    201 //===----------------------------------------------------------------------===//
    202 
    203 // Import function declaration.
    204 // MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"()
    205 // GNU-DAG: declare dllimport void @_Z4declv()
    206 __declspec(dllimport) void decl();
    207 USE(decl)
    208 
    209 // extern "C"
    210 // MSC-DAG: declare dllimport void @externC()
    211 // GNU-DAG: declare dllimport void @externC()
    212 extern "C" __declspec(dllimport) void externC();
    213 USE(externC)
    214 
    215 // Import inline function.
    216 // MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"()
    217 // GNU-DAG: declare dllimport void @_Z10inlineFuncv()
    218 // MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"()
    219 // GO1-DAG: define available_externally dllimport void @_Z10inlineFuncv()
    220 __declspec(dllimport) inline void inlineFunc() {}
    221 USE(inlineFunc)
    222 
    223 // MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"()
    224 // GNU-DAG: declare dllimport void @_Z10inlineDeclv()
    225 // MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"()
    226 // GO1-DAG: define available_externally dllimport void @_Z10inlineDeclv()
    227 __declspec(dllimport) inline void inlineDecl();
    228                              void inlineDecl() {}
    229 USE(inlineDecl)
    230 
    231 // MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"()
    232 // GNU-DAG: declare dllimport void @_Z9inlineDefv()
    233 // MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"()
    234 // GO1-DAG: define available_externally dllimport void @_Z9inlineDefv()
    235 __declspec(dllimport) void inlineDef();
    236                inline void inlineDef() {}
    237 USE(inlineDef)
    238 
    239 // inline attributes
    240 // MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"()
    241 // GNU-DAG: declare dllimport void @_Z8noinlinev()
    242 __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
    243 USE(noinline)
    244 
    245 // MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
    246 // GNU2-NOT: @_Z12alwaysInlinev()
    247 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
    248 USE(alwaysInline)
    249 
    250 // Redeclarations
    251 // MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
    252 // GNU-DAG: declare dllimport void @_Z7redecl1v()
    253 __declspec(dllimport) void redecl1();
    254 __declspec(dllimport) void redecl1();
    255 USE(redecl1)
    256 
    257 // NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
    258 // and drop the dllimport with a warning.
    259 // MSC-DAG: declare void @"\01?redecl2@@YAXXZ"()
    260 // GNU-DAG: declare void @_Z7redecl2v()
    261 __declspec(dllimport) void redecl2();
    262                       void redecl2();
    263 USE(redecl2)
    264 
    265 // MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
    266 // GNU-DAG: define void @_Z7redecl3v()
    267 __declspec(dllimport) void redecl3();
    268                       void redecl3() {} // dllimport ignored
    269 USE(redecl3)
    270 
    271 
    272 // Friend functions
    273 // MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"()
    274 // GNU-DAG: declare dllimport void @_Z7friend1v()
    275 // MSC-DAG: declare           void @"\01?friend2@@YAXXZ"()
    276 // GNU-DAG: declare           void @_Z7friend2v()
    277 // MSC-DAG: define            void @"\01?friend3@@YAXXZ"()
    278 // GNU-DAG: define            void @_Z7friend3v()
    279 struct FuncFriend {
    280   friend __declspec(dllimport) void friend1();
    281   friend __declspec(dllimport) void friend2();
    282   friend __declspec(dllimport) void friend3();
    283 };
    284 __declspec(dllimport) void friend1();
    285                       void friend2(); // dllimport ignored
    286                       void friend3() {} // dllimport ignored
    287 USE(friend1)
    288 USE(friend2)
    289 USE(friend3)
    290 
    291 // Implicit declarations can be redeclared with dllimport.
    292 // MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
    293 // GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
    294 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
    295 void UNIQ(use)() { ::operator new(42); }
    296 
    297 // MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"()
    298 // GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
    299 namespace ns { __declspec(dllimport) void externalFunc(); }
    300 USE(ns::externalFunc)
    301 
    302 
    303 
    304 //===----------------------------------------------------------------------===//
    305 // Function templates
    306 //===----------------------------------------------------------------------===//
    307 
    308 // Import function template declaration.
    309 // MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
    310 // GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
    311 template<typename T> __declspec(dllimport) void funcTmplDecl();
    312 USE(funcTmplDecl<ImplicitInst_Imported>)
    313 
    314 // Function template definitions cannot be imported.
    315 
    316 // Import inline function template.
    317 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
    318 // GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
    319 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
    320 // GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
    321 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
    322 USE(inlineFuncTmpl1<ImplicitInst_Imported>)
    323 
    324 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
    325 // GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
    326 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
    327 // GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
    328 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
    329 USE(inlineFuncTmpl2<ImplicitInst_Imported>)
    330 
    331 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
    332 // GNU-DAG: declare dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
    333 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
    334 // GO1-DAG: define available_externally dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
    335 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
    336 template<typename T>                              void inlineFuncTmplDecl() {}
    337 USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
    338 
    339 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
    340 // GNU-DAG: declare dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
    341 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
    342 // GO1-DAG: define available_externally dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
    343 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
    344 template<typename T>                inline void inlineFuncTmplDef() {}
    345 USE(inlineFuncTmplDef<ImplicitInst_Imported>)
    346 
    347 
    348 // Redeclarations
    349 // MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
    350 // GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
    351 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
    352 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
    353 USE(funcTmplRedecl1<ImplicitInst_Imported>)
    354 
    355 // MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
    356 // GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
    357 template<typename T> __declspec(dllimport) void funcTmplRedecl2();
    358 template<typename T>                       void funcTmplRedecl2(); // dllimport ignored
    359 USE(funcTmplRedecl2<ImplicitInst_NotImported>)
    360 
    361 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
    362 // GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
    363 template<typename T> __declspec(dllimport) void funcTmplRedecl3();
    364 template<typename T>                       void funcTmplRedecl3() {} // dllimport ignored
    365 USE(funcTmplRedecl3<ImplicitInst_NotImported>)
    366 
    367 
    368 // Function template friends
    369 // MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
    370 // GNU-DAG: declare dllimport   void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
    371 // MSC-DAG: declare             void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
    372 // GNU-DAG: declare             void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
    373 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
    374 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
    375 // MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
    376 // GNU-DAG: declare dllimport   void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
    377 struct FuncTmplFriend {
    378   template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
    379   template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
    380   template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
    381   template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
    382 };
    383 template<typename T> __declspec(dllimport) void funcTmplFriend1();
    384 template<typename T>                       void funcTmplFriend2(); // dllimport ignored
    385 template<typename T>                       void funcTmplFriend3() {} // dllimport ignored
    386 template<typename T>                       inline void funcTmplFriend4() {}
    387 USE(funcTmplFriend1<ImplicitInst_Imported>)
    388 USE(funcTmplFriend2<ImplicitInst_NotImported>)
    389 USE(funcTmplFriend3<ImplicitInst_NotImported>)
    390 USE(funcTmplFriend4<ImplicitInst_Imported>)
    391 
    392 // MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
    393 // GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
    394 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
    395 USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
    396 
    397 
    398 template<typename T> void funcTmpl() {}
    399 template<typename T> inline void inlineFuncTmpl() {}
    400 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
    401 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
    402 
    403 // Import implicit instantiation of an imported function template.
    404 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
    405 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
    406 USE(importedFuncTmplDecl<ImplicitInst_Imported>)
    407 
    408 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
    409 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
    410 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
    411 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
    412 USE(importedFuncTmpl<ImplicitInst_Imported>)
    413 
    414 // Import explicit instantiation declaration of an imported function template.
    415 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
    416 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
    417 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
    418 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
    419 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
    420 USE(importedFuncTmpl<ExplicitDecl_Imported>)
    421 
    422 // Import explicit instantiation definition of an imported function template.
    423 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
    424 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
    425 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
    426 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
    427 template void importedFuncTmpl<ExplicitInst_Imported>();
    428 USE(importedFuncTmpl<ExplicitInst_Imported>)
    429 
    430 
    431 // Import specialization of an imported function template.
    432 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
    433 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
    434 template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
    435 USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
    436 
    437 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
    438 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
    439 #ifdef MSABI
    440 //template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
    441 //USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
    442 #endif
    443 
    444 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
    445 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
    446 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
    447 // GO1-DAG: define available_externally dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
    448 template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
    449 USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
    450 
    451 
    452 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
    453 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
    454 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
    455 USE(importedFuncTmpl<ExplicitSpec_Imported>)
    456 
    457 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
    458 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
    459 #ifdef MSABI
    460 //template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
    461 //USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
    462 #endif
    463 
    464 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
    465 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
    466 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
    467 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
    468 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
    469 USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
    470 
    471 
    472 // Not importing specialization of an imported function template without
    473 // explicit dllimport.
    474 // MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
    475 // GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
    476 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
    477 USE(importedFuncTmpl<ExplicitSpec_NotImported>)
    478 
    479 
    480 // Import explicit instantiation declaration of a non-imported function template.
    481 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
    482 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
    483 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
    484 // GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
    485 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
    486 // GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
    487 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
    488 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
    489 USE(funcTmpl<ExplicitDecl_Imported>)
    490 USE(inlineFuncTmpl<ExplicitDecl_Imported>)
    491 
    492 
    493 // Import explicit instantiation definition of a non-imported function template.
    494 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
    495 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
    496 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
    497 // GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
    498 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
    499 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
    500 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
    501 // GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
    502 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
    503 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
    504 USE(funcTmpl<ExplicitInst_Imported>)
    505 USE(inlineFuncTmpl<ExplicitInst_Imported>)
    506 
    507 
    508 // Import specialization of a non-imported function template.
    509 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
    510 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
    511 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
    512 USE(funcTmpl<ExplicitSpec_Imported>)
    513 
    514 // MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
    515 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
    516 #ifdef MSABI
    517 //template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
    518 //USE(funcTmpl<ExplicitSpec_Def_Imported>)
    519 #endif
    520 
    521 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
    522 // GNU-DAG: declare dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
    523 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
    524 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
    525 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
    526 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
    527 
    528 
    529 
    530 //===----------------------------------------------------------------------===//
    531 // Classes
    532 //===----------------------------------------------------------------------===//
    533 
    534 struct __declspec(dllimport) T {
    535   void a() {}
    536   // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
    537 
    538   static int b;
    539   // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
    540 
    541   T& operator=(T&) = default;
    542   // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
    543 
    544   T& operator=(T&&) = default;
    545   // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
    546   // MO1-DAG: define linkonce_odr x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
    547 };
    548 USEMEMFUNC(T, a)
    549 USEVAR(T::b)
    550 USECOPYASSIGN(T)
    551 USEMOVEASSIGN(T)
    552 
    553 template <typename T> struct __declspec(dllimport) U { void foo() {} };
    554 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
    555 struct __declspec(dllimport) V : public U<int> { };
    556 USEMEMFUNC(V, foo)
    557 
    558 struct __declspec(dllimport) W { virtual void foo() {} };
    559 USECLASS(W)
    560 // vftable:
    561 // MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
    562 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
    563 
    564 struct __declspec(dllimport) KeyFuncClass {
    565   constexpr KeyFuncClass() {}
    566   virtual void foo();
    567 };
    568 constexpr KeyFuncClass keyFuncClassVar;
    569 // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
    570 
    571 struct __declspec(dllimport) X : public virtual W {};
    572 USECLASS(X)
    573 // vbtable:
    574 // MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
    575 
    576 struct __declspec(dllimport) Y {
    577   int x;
    578 };
    579 
    580 struct __declspec(dllimport) Z { virtual ~Z() {} };
    581 USECLASS(Z)
    582 // User-defined dtor:
    583 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
    584 
    585 namespace DontUseDtorAlias {
    586   struct __declspec(dllimport) A { ~A(); };
    587   struct __declspec(dllimport) B : A { ~B(); };
    588   inline A::~A() { }
    589   inline B::~B() { }
    590   // Emit a real definition of B's constructor; don't alias it to A's.
    591   // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
    592   USECLASS(B)
    593 }
    594 
    595 namespace Vtordisp {
    596   // Don't dllimport the vtordisp.
    597   // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
    598 
    599   class Base {
    600     virtual void f() {}
    601   };
    602   template <typename T>
    603   class __declspec(dllimport) C : virtual public Base {
    604   public:
    605     C() {}
    606     virtual void f() {}
    607   };
    608   template class C<char>;
    609 }
    610 
    611 namespace ClassTemplateStaticDef {
    612   // Regular template static field:
    613   template <typename T> struct __declspec(dllimport) S {
    614     static int x;
    615   };
    616   template <typename T> int S<T>::x;
    617   // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
    618   int f() { return S<int>::x; }
    619 
    620   // Partial class template specialization static field:
    621   template <typename A> struct T;
    622   template <typename A> struct __declspec(dllimport) T<A*> {
    623     static int x;
    624   };
    625   template <typename A> int T<A*>::x;
    626   // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
    627   int g() { return T<void*>::x; }
    628 }
    629 
    630 namespace PR19933 {
    631 // Don't dynamically initialize dllimport vars.
    632 // MSC2-NOT: @llvm.global_ctors
    633 // GNU2-NOT: @llvm.global_ctors
    634 
    635   struct NonPOD { NonPOD(); };
    636   template <typename T> struct A { static NonPOD x; };
    637   template <typename T> NonPOD A<T>::x;
    638   template struct __declspec(dllimport) A<int>;
    639   // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
    640 
    641   int f();
    642   template <typename T> struct B { static int x; };
    643   template <typename T> int B<T>::x = f();
    644   template struct __declspec(dllimport) B<int>;
    645   // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
    646 
    647   constexpr int g() { return 42; }
    648   template <typename T> struct C { static int x; };
    649   template <typename T> int C<T>::x = g();
    650   template struct __declspec(dllimport) C<int>;
    651   // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
    652 
    653   template <int I> struct D { static int x, y; };
    654   template <int I> int D<I>::x = I + 1;
    655   template <int I> int D<I>::y = I + f();
    656   template struct __declspec(dllimport) D<42>;
    657   // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
    658   // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
    659 }
    660 
    661 // MS ignores DLL attributes on partial specializations.
    662 template <typename T> struct PartiallySpecializedClassTemplate {};
    663 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
    664 USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
    665 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
    666 // G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
    667 
    668 template <typename T> struct ExplicitlySpecializedClassTemplate {};
    669 template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
    670 USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
    671 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
    672 // G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
    673 
    674 //===----------------------------------------------------------------------===//
    675 // Classes with template base classes
    676 //===----------------------------------------------------------------------===//
    677 
    678 template <typename T> struct ClassTemplate { void func() {} };
    679 template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
    680 template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
    681 
    682 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
    683 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
    684 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
    685 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
    686 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
    687 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
    688 
    689 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
    690 template struct ExplicitlyInstantiatedTemplate<int>;
    691 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
    692 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
    693 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
    694 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
    695 
    696 
    697 // MS: ClassTemplate<int> gets imported.
    698 struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
    699 USEMEMFUNC(ClassTemplate<int>, func)
    700 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
    701 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
    702 
    703 // ImportedTemplate is explicitly imported.
    704 struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
    705 USEMEMFUNC(ImportedClassTemplate<int>, func)
    706 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
    707 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
    708 
    709 // ExportedTemplate is explicitly exported.
    710 struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
    711 USEMEMFUNC(ExportedClassTemplate<int>, func)
    712 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
    713 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
    714 
    715 // Base class already instantiated without attribute.
    716 struct DerivedFromTemplateD : public ClassTemplate<double> {};
    717 struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
    718 USEMEMFUNC(ClassTemplate<double>, func)
    719 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
    720 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
    721 
    722 // MS: Base class already instantiated with dfferent attribute.
    723 struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
    724 struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
    725 USEMEMFUNC(ClassTemplate<bool>, func)
    726 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
    727 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
    728 
    729 // Base class already specialized without dll attribute.
    730 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
    731 USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
    732 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
    733 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
    734 
    735 // Base class alredy specialized with export attribute.
    736 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
    737 USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
    738 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
    739 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
    740 
    741 // Base class already specialized with import attribute.
    742 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
    743 USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
    744 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
    745 // G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
    746 
    747 // Base class already instantiated without dll attribute.
    748 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
    749 USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
    750 // M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
    751 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
    752 
    753 // Base class already instantiated with export attribute.
    754 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
    755 USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
    756 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
    757 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
    758 
    759 // Base class already instantiated with import attribute.
    760 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
    761 USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
    762 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
    763 // G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
    764 
    765 // MS: A dll attribute propagates through multiple levels of instantiation.
    766 template <typename T> struct TopClass { void func() {} };
    767 template <typename T> struct MiddleClass : public TopClass<T> { };
    768 struct __declspec(dllimport) BottomClas : public MiddleClass<int> { };
    769 USEMEMFUNC(TopClass<int>, func)
    770 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
    771 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
    772