reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc  -fms-extensions -emit-llvm -o - | FileCheck %s

struct S {
  S();
  ~S();
};

template <typename T> struct __declspec(dllexport) ExportedTemplate {
  static S s;
};
template <typename T> S ExportedTemplate<T>::s;
void useExportedTemplate(ExportedTemplate<int> x) {
  (void)x.s;
}
int f();
namespace selectany_init {
// MS don't put selectany static var in the linker directive, init routine
// f() is not getting called if x is not referenced.
int __declspec(selectany) x = f();
inline int __declspec(selectany) x1 = f();
}

namespace explicit_template_instantiation {
template <typename T> struct A { static  int x; };
template <typename T> int A<T>::x = f();
template struct A<int>;
}

namespace implicit_template_instantiation {
template <typename T> struct A { static  int x; };
template <typename T>  int A<T>::x = f();
int g() { return A<int>::x; }
}


template <class T>
struct X_ {
  static T ioo;
  static T init();
};
template <class T> T X_<T>::ioo = X_<T>::init();
template struct X_<int>;

template <class T>
struct X {
  static T ioo;
  static T init();
};
// template specialized static data don't need in llvm.used,
// the static init routine get call from _GLOBAL__sub_I_ routines.
template <> int X<int>::ioo = X<int>::init();
template struct X<int>;
class a {
public:
  a();
};
// For the static var inside unnamed namespace, the object is local to TU.
// No need to put static var in the linker directive.
// The static init routine is called before main.
namespace {
template <int> class aj {
public:
  static a al;
};
template <int am> a aj<am>::al;
class b : aj<3> {
  void c();
};
void b::c() { al; }
}

// C++17, inline static data member also need to use
struct A
{
  A();
  ~A();
};

struct S1
{
  inline static A aoo; // C++17 inline variable, thus also a definition
};

int foo();
inline int zoo = foo();
inline static int boo = foo();


// CHECK: @llvm.used = appending global [7 x i8*] [i8* bitcast (i32* @"?x1@selectany_init@@3HA" to i8*), i8* bitcast (i32* @"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* @"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.A, %struct.A* @"?aoo@S1@@2UA@@A", i32 0, i32 0), i8* bitcast (i32* @"?zoo@@3HA" to i8*), i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section "llvm.metadata"