summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/inline-functions.cpp
blob: f1169f91913e44aef798940e377e76e1fc2929c5 (plain)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NORMAL
// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -triple=x86_64-pc-win32 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSVCCOMPAT
// CHECK: ; ModuleID 

struct A {
    inline void f();
};

// NORMAL-NOT: define void @_ZN1A1fEv
// MSVCCOMPAT-NOT: define void @"\01?f@A@@QEAAXXZ"
void A::f() { }

template<typename> struct B { };

template<> struct B<char> {
  inline void f();
};

// NORMAL-NOT: _ZN1BIcE1fEv
// MSVCCOMPAT-NOT: @"\01?f@?$B@D@@QEAAXXZ"
void B<char>::f() { }

// We need a final CHECK line here.

// NORMAL-LABEL: define void @_Z1fv
// MSVCCOMPAT-LABEL: define void @"\01?f@@YAXXZ"
void f() { }

// <rdar://problem/8740363>
inline void f1(int);

// NORMAL-LABEL: define linkonce_odr void @_Z2f1i
// MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?f1@@YAXH@Z"
void f1(int) { }

void test_f1() { f1(17); }

// PR8789
namespace test1 {
  template <typename T> class ClassTemplate {
  private:
    friend void T::func();
    void g() {}
  };

  // NORMAL-LABEL: define linkonce_odr void @_ZN5test11C4funcEv(
  // MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?func@C@test1@@QEAAXXZ"(

  class C {
  public:
    void func() {
      ClassTemplate<C> ct;
      ct.g();
    }
  };

  void f() {
    C c;
    c.func();
  }
}

// PR13252
namespace test2 {
  struct A;
  void f(const A& a);
  struct A {
    friend void f(const A& a) { } 
  };
  void g() {
    A a;
    f(a);
  }
  // NORMAL-LABEL: define linkonce_odr void @_ZN5test21fERKNS_1AE
  // MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?f@test2@@YAXAEBUA@1@@Z"
}

// NORMAL-NOT: _Z17ExternAndInlineFnv
// MSVCCOMPAT-LABEL: define weak_odr void @"\01?ExternAndInlineFn@@YAXXZ"
extern inline void ExternAndInlineFn() {}

// NORMAL-NOT: _Z18InlineThenExternFnv
// MSVCCOMPAT-LABEL: define weak_odr void @"\01?InlineThenExternFn@@YAXXZ"
inline void InlineThenExternFn() {}
extern void InlineThenExternFn();

// NORMAL-LABEL: define void @_Z18ExternThenInlineFnv
// MSVCCOMPAT-LABEL: define void @"\01?ExternThenInlineFn@@YAXXZ"
extern void ExternThenInlineFn() {}

// NORMAL-NOT: _Z25ExternThenInlineThenDefFnv
// MSVCCOMPAT-LABEL: define weak_odr void @"\01?ExternThenInlineThenDefFn@@YAXXZ"
extern void ExternThenInlineThenDefFn();
inline void ExternThenInlineThenDefFn();
void ExternThenInlineThenDefFn() {}

// NORMAL-NOT: _Z25InlineThenExternThenDefFnv
// MSVCCOMPAT-LABEL: define weak_odr void @"\01?InlineThenExternThenDefFn@@YAXXZ"
inline void InlineThenExternThenDefFn();
extern void InlineThenExternThenDefFn();
void InlineThenExternThenDefFn() {}

// NORMAL-NOT: _Z17ExternAndConstexprFnv
// MSVCCOMPAT-LABEL: define weak_odr i32 @"\01?ExternAndConstexprFn@@YAHXZ"
extern constexpr int ExternAndConstexprFn() { return 0; }

// NORMAL-NOT: _Z11ConstexprFnv
// MSVCCOMPAT-NOT: @"\01?ConstexprFn@@YAHXZ"
constexpr int ConstexprFn() { return 0; }

template <typename T>
extern inline void ExternInlineOnPrimaryTemplate(T);

// NORMAL-LABEL: define void @_Z29ExternInlineOnPrimaryTemplateIiEvT_
// MSVCCOMPAT-LABEL: define void @"\01??$ExternInlineOnPrimaryTemplate@H@@YAXH@Z"
template <>
void ExternInlineOnPrimaryTemplate(int) {}

template <typename T>
extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(T);

// NORMAL-NOT: _Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_
// MSVCCOMPAT-LABEL: define weak_odr void @"\01??$ExternInlineOnPrimaryTemplateAndSpecialization@H@@YAXH@Z"
template <>
extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(int) {}

struct TypeWithInlineMethods {
  // NORMAL-NOT: _ZN21TypeWithInlineMethods9StaticFunEv
  // MSVCCOMPAT-NOT: @"\01?StaticFun@TypeWithInlineMethods@@SAXXZ"
  static void StaticFun() {}
  // NORMAL-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv
  // MSVCCOMPAT-NOT: @"\01?NonStaticFun@TypeWithInlineMethods@@QEAAXXZ"
  void NonStaticFun() { StaticFun(); }
};

namespace PR22959 {
template <typename>
struct S;

S<int> Foo();

template <typename>
struct S {
  friend S<int> Foo();
};

__attribute__((used)) inline S<int> Foo() { return S<int>(); }
// NORMAL-LABEL: define linkonce_odr void @_ZN7PR229593FooEv(
// MSVCCOMPAT-LABEL: define linkonce_odr i8 @"\01?Foo@PR22959@@YA?AU?$S@H@1@XZ"(
}