54 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s | FileCheck %s --check-prefix=IMPORT2// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s -DTEST_EXPORT | FileCheck %s --check-prefix=EXPORT3 4#ifndef TEST_EXPORT5#define DLLATTR __declspec(dllimport)6#else7#define DLLATTR __declspec(dllexport)8#endif9 10// PR37232: When a dllimport attribute is propagated from a derived class to a11// base class that happens to be a template specialization, it is only applied12// to template *methods*, and not static data members. If a dllexport attribute13// is propagated, it still applies to static data members.14 15// IMPORT-DAG: @"?sdm@Exporter@@2HB" = available_externally dllimport constant i32 2, align 416// IMPORT-DAG: @"?csdm@?$A@H@@2HB" = linkonce_odr dso_local constant i32 2, comdat, align 417// IMPORT-DAG: @"?sdm@?$A@H@@2HA" = linkonce_odr dso_local global i32 1, comdat, align 418// IMPORT-DAG: @"?sdm@?$B@H@@2HB" = available_externally dllimport constant i32 2, align 419// IMPORT-DAG: @"?sdm@?$C@H@@2HB" = available_externally dllimport constant i32 2, align 420 21// EXPORT-DAG: @"?sdm@Exporter@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 422// EXPORT-DAG: @"?csdm@?$A@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 423// EXPORT-DAG: @"?sdm@?$A@H@@2HA" = weak_odr dso_local dllexport global i32 1, comdat, align 424// EXPORT-DAG: @"?sdm@?$B@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 425// EXPORT-DAG: @"?sdm@?$C@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 426 27 28template <typename T> struct A {29 static constexpr int csdm = 2;30 static int sdm;31};32template <typename T> int A<T>::sdm = 1;33 34struct DLLATTR Exporter : A<int> {35 static constexpr int sdm = 2;36};37 38template <typename T> struct DLLATTR B { static constexpr int sdm = 2; };39 40template <typename T> struct DLLATTR C;41template <typename T> struct C { static constexpr int sdm = 2; };42 43void takeRef(const int &_Args) {}44 45int main() {46 takeRef(Exporter::sdm);47 takeRef(A<int>::csdm);48 takeRef(A<int>::sdm);49 takeRef(B<int>::sdm);50 takeRef(C<int>::sdm);51 52 return 1;53}54