1// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NORMAL
2// 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
3// CHECK: ; ModuleID
4
5struct A {
6    inline void f();
7};
8
9// NORMAL-NOT: define void @_ZN1A1fEv
10// MSVCCOMPAT-NOT: define void @"\01?f@A@@QEAAXXZ"
11void A::f() { }
12
13template<typename> struct B { };
14
15template<> struct B<char> {
16  inline void f();
17};
18
19// NORMAL-NOT: _ZN1BIcE1fEv
20// MSVCCOMPAT-NOT: @"\01?f@?$B@D@@QEAAXXZ"
21void B<char>::f() { }
22
23// We need a final CHECK line here.
24
25// NORMAL-LABEL: define void @_Z1fv
26// MSVCCOMPAT-LABEL: define void @"\01?f@@YAXXZ"
27void f() { }
28
29// <rdar://problem/8740363>
30inline void f1(int);
31
32// NORMAL-LABEL: define linkonce_odr void @_Z2f1i
33// MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?f1@@YAXH@Z"
34void f1(int) { }
35
36void test_f1() { f1(17); }
37
38// PR8789
39namespace test1 {
40  template <typename T> class ClassTemplate {
41  private:
42    friend void T::func();
43    void g() {}
44  };
45
46  // NORMAL-LABEL: define linkonce_odr void @_ZN5test11C4funcEv(
47  // MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?func@C@test1@@QEAAXXZ"(
48
49  class C {
50  public:
51    void func() {
52      ClassTemplate<C> ct;
53      ct.g();
54    }
55  };
56
57  void f() {
58    C c;
59    c.func();
60  }
61}
62
63// PR13252
64namespace test2 {
65  struct A;
66  void f(const A& a);
67  struct A {
68    friend void f(const A& a) { }
69  };
70  void g() {
71    A a;
72    f(a);
73  }
74  // NORMAL-LABEL: define linkonce_odr void @_ZN5test21fERKNS_1AE
75  // MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?f@test2@@YAXAEBUA@1@@Z"
76}
77
78// NORMAL-NOT: _Z17ExternAndInlineFnv
79// MSVCCOMPAT-LABEL: define weak_odr void @"\01?ExternAndInlineFn@@YAXXZ"
80extern inline void ExternAndInlineFn() {}
81
82// NORMAL-NOT: _Z18InlineThenExternFnv
83// MSVCCOMPAT-LABEL: define weak_odr void @"\01?InlineThenExternFn@@YAXXZ"
84inline void InlineThenExternFn() {}
85extern void InlineThenExternFn();
86
87// NORMAL-LABEL: define void @_Z18ExternThenInlineFnv
88// MSVCCOMPAT-LABEL: define void @"\01?ExternThenInlineFn@@YAXXZ"
89extern void ExternThenInlineFn() {}
90
91// NORMAL-NOT: _Z25ExternThenInlineThenDefFnv
92// MSVCCOMPAT-LABEL: define weak_odr void @"\01?ExternThenInlineThenDefFn@@YAXXZ"
93extern void ExternThenInlineThenDefFn();
94inline void ExternThenInlineThenDefFn();
95void ExternThenInlineThenDefFn() {}
96
97// NORMAL-NOT: _Z25InlineThenExternThenDefFnv
98// MSVCCOMPAT-LABEL: define weak_odr void @"\01?InlineThenExternThenDefFn@@YAXXZ"
99inline void InlineThenExternThenDefFn();
100extern void InlineThenExternThenDefFn();
101void InlineThenExternThenDefFn() {}
102
103// NORMAL-NOT: _Z17ExternAndConstexprFnv
104// MSVCCOMPAT-LABEL: define weak_odr i32 @"\01?ExternAndConstexprFn@@YAHXZ"
105extern constexpr int ExternAndConstexprFn() { return 0; }
106
107// NORMAL-NOT: _Z11ConstexprFnv
108// MSVCCOMPAT-NOT: @"\01?ConstexprFn@@YAHXZ"
109constexpr int ConstexprFn() { return 0; }
110
111template <typename T>
112extern inline void ExternInlineOnPrimaryTemplate(T);
113
114// NORMAL-LABEL: define void @_Z29ExternInlineOnPrimaryTemplateIiEvT_
115// MSVCCOMPAT-LABEL: define void @"\01??$ExternInlineOnPrimaryTemplate@H@@YAXH@Z"
116template <>
117void ExternInlineOnPrimaryTemplate(int) {}
118
119template <typename T>
120extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(T);
121
122// NORMAL-NOT: _Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_
123// MSVCCOMPAT-LABEL: define weak_odr void @"\01??$ExternInlineOnPrimaryTemplateAndSpecialization@H@@YAXH@Z"
124template <>
125extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(int) {}
126
127struct TypeWithInlineMethods {
128  // NORMAL-NOT: _ZN21TypeWithInlineMethods9StaticFunEv
129  // MSVCCOMPAT-NOT: @"\01?StaticFun@TypeWithInlineMethods@@SAXXZ"
130  static void StaticFun() {}
131  // NORMAL-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv
132  // MSVCCOMPAT-NOT: @"\01?NonStaticFun@TypeWithInlineMethods@@QEAAXXZ"
133  void NonStaticFun() { StaticFun(); }
134};
135
136namespace PR22959 {
137template <typename>
138struct S;
139
140S<int> Foo();
141
142template <typename>
143struct S {
144  friend S<int> Foo();
145};
146
147__attribute__((used)) inline S<int> Foo() { return S<int>(); }
148// NORMAL-LABEL: define linkonce_odr void @_ZN7PR229593FooEv(
149// MSVCCOMPAT-LABEL: define linkonce_odr i8 @"\01?Foo@PR22959@@YA?AU?$S@H@1@XZ"(
150}
151