1022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck %s
28e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s
3d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
4d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonnamespace Test1 {
5d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
6d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson// Check that we emit a non-virtual thunk for C::f.
7d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
8d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct A {
9d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
10d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
11d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
12d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct B {
13d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
14d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
15d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
16d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct C : A, B {
17d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void c();
18d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
19d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
20d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
21d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
2293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define void @_ZThn8_N5Test11C1fEv(
23d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonvoid C::f() { }
24d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
25d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson}
26d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
27d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonnamespace Test2 {
28d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
29d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson// Check that we emit a thunk for B::f since it's overriding a virtual base.
30d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
31d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct A {
32d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
33d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
34d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
35d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct B : virtual A {
36d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void b();
37d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
38d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
39d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
4093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define void @_ZTv0_n24_N5Test21B1fEv(
41d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonvoid B::f() { }
42d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
43d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson}
44d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
45d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonnamespace Test3 {
46d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
47d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson// Check that we emit a covariant thunk for B::f.
48d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
49d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct V1 { };
50d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct V2 : virtual V1 { };
51d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
52d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct A {
53d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual V1 *f();
54d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
55d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
56d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct B : A {
57d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void b();
58d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
59d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual V2 *f();
60d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
61d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
62ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv(
63d63fed48fa958ca7d9a432dab1010c272c19f215Anders CarlssonV2 *B::f() { return 0; }
64d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
65d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson}
66d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
67d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonnamespace Test4 {
68d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
69d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson// Check that the thunk for 'C::f' has the same visibility as the function itself.
70d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
71d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct A {
72d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
73d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
74d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
75d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct B {
76d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
77d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
78d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
79d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonstruct __attribute__((visibility("protected"))) C : A, B {
80d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void c();
81d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
82d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson  virtual void f();
83d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson};
84d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
8593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// CHECK-LABEL: define protected void @_ZThn8_N5Test41C1fEv(
86d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlssonvoid C::f() { }
87d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
88d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson}
89d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
90d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson// Check that the thunk gets internal linkage.
9115e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCallnamespace Test4B {
9215e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  struct A {
9315e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall    virtual void f();
9415e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  };
95d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
9615e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  struct B {
9715e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall    virtual void f();
9815e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  };
99d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
10015e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  namespace {
10115e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall    struct C : A, B {
10215e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall      virtual void c();
10315e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall      virtual void f();
10415e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall    };
10515e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  }
10615e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  void C::c() {}
10715e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  void C::f() {}
108d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson
10915e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  // Force C::f to be used.
11015e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  void f() {
11115e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall    C c;
11215e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall    c.f();
11315e310a3b970b64a84cb30f0005bc396b4d978cbJohn McCall  }
114d63fed48fa958ca7d9a432dab1010c272c19f215Anders Carlsson}
115ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson
116ada087c4518a18f844ecc051b07039064016a4baAnders Carlssonnamespace Test5 {
117ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson
118ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson// Check that the thunk for 'B::f' gets the same linkage as the function itself.
119ada087c4518a18f844ecc051b07039064016a4baAnders Carlssonstruct A {
120ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson  virtual void f();
121ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson};
122ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson
123ada087c4518a18f844ecc051b07039064016a4baAnders Carlssonstruct B : virtual A {
124ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson  virtual void f() { }
125ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson};
126ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson
127ada087c4518a18f844ecc051b07039064016a4baAnders Carlssonvoid f(B b) {
128ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson  b.f();
129ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson}
130ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson}
131ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson
132cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregornamespace Test6 {
133cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  struct X {
134cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    X();
135cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    X(const X&);
136cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    X &operator=(const X&);
137cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    ~X();
138cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  };
139cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
140cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  struct P {
141cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    P();
142cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    P(const P&);
143cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    ~P();
144cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    X first;
145cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    X second;
146cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  };
147cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
148cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  P getP();
149cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
150cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  struct Base1 {
151cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    int i;
152cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
153cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    virtual X f() { return X(); }
154cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  };
155cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
156cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  struct Base2 {
157cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    float real;
158ada087c4518a18f844ecc051b07039064016a4baAnders Carlsson
159cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    virtual X f() { return X(); }
160cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  };
161cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
162cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  struct Thunks : Base1, Base2 {
163cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    long l;
164cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
165cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor    virtual X f();
166cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  };
167cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
16893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CHECK-LABEL: define void @_ZThn16_N5Test66Thunks1fEv
169cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  // CHECK-NOT: memcpy
170cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  // CHECK: {{call void @_ZN5Test66Thunks1fEv.*sret}}
171cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  // CHECK: ret void
172cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor  X Thunks::f() { return X(); }
173cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor}
174cb359df81b83dd4f938d05cb9cf5c34bd20068bdDouglas Gregor
175663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregornamespace Test7 {
176663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  // PR7188
177663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  struct X {
178663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    X();
179663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    X(const X&);
180663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    X &operator=(const X&);
181663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    ~X();
182663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  };
183663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
184663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  struct Small { short s; };
185663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  struct Large {
186663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    char array[1024];
187663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  };
188663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
189663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  class A {
190663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  protected:
191663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    virtual void foo() = 0;
192663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  };
193663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
194663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  class B : public A {
195663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  protected:
196663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    virtual void bar() = 0;
197663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  };
198663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
199663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  class C : public A  {
200663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  protected:
201663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    virtual void baz(X, X&, _Complex float, Small, Small&, Large) = 0;
202663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  };
203663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
204663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  class D : public B,
205663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor            public C {
206663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
207663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    void foo() {}
208663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    void bar() {}
209663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor    void baz(X, X&, _Complex float, Small, Small&, Large);
210663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  };
211663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
212663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  void D::baz(X, X&, _Complex float, Small, Small&, Large) { }
213663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
21493ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CHECK-LABEL: define void @_ZThn8_N5Test71D3bazENS_1XERS1_CfNS_5SmallERS4_NS_5LargeE(
215663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  // CHECK-NOT: memcpy
216663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  // CHECK: ret void
217663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor  void testD() { D d; }
218663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor}
219663218b576d8d79dea546c5726d7c90c216b1358Douglas Gregor
2202736071ea3a46f90e65c93418961611d96c10ab9John McCallnamespace Test8 {
2212736071ea3a46f90e65c93418961611d96c10ab9John McCall  struct NonPOD { ~NonPOD(); int x, y, z; };
2222736071ea3a46f90e65c93418961611d96c10ab9John McCall  struct A { virtual void foo(); };
2232736071ea3a46f90e65c93418961611d96c10ab9John McCall  struct B { virtual void bar(NonPOD); };
2242736071ea3a46f90e65c93418961611d96c10ab9John McCall  struct C : A, B { virtual void bar(NonPOD); static void helper(NonPOD); };
2252736071ea3a46f90e65c93418961611d96c10ab9John McCall
2262736071ea3a46f90e65c93418961611d96c10ab9John McCall  // CHECK: define void @_ZN5Test81C6helperENS_6NonPODE([[NONPODTYPE:%.*]]*
2272736071ea3a46f90e65c93418961611d96c10ab9John McCall  void C::helper(NonPOD var) {}
2282736071ea3a46f90e65c93418961611d96c10ab9John McCall
22993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CHECK-LABEL: define void @_ZThn8_N5Test81C3barENS_6NonPODE(
2303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NOT: load [[NONPODTYPE]], [[NONPODTYPE]]*
2312736071ea3a46f90e65c93418961611d96c10ab9John McCall  // CHECK-NOT: memcpy
2322736071ea3a46f90e65c93418961611d96c10ab9John McCall  // CHECK: ret void
2332736071ea3a46f90e65c93418961611d96c10ab9John McCall  void C::bar(NonPOD var) {}
2342736071ea3a46f90e65c93418961611d96c10ab9John McCall}
2352736071ea3a46f90e65c93418961611d96c10ab9John McCall
236e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall// PR7241: Emitting thunks for a method shouldn't require the vtable for
237e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall// that class to be emitted.
238e21323588b32caf674213c9897dd12e2f0ea3cc5John McCallnamespace Test9 {
239e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall  struct A { virtual ~A() { } };
240e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall  struct B : A { virtual void test() const {} };
241e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall  struct C : B { C(); ~C(); };
242e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall  struct D : C { D() {} };
243e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall  void test() {
244e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall    D d;
245e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall  }
246e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall}
247e21323588b32caf674213c9897dd12e2f0ea3cc5John McCall
24865005536dee9216b14e2361153a14ddd8a7cd50aJohn McCallnamespace Test10 {
24965005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall  struct A { virtual void foo(); };
25065005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall  struct B { virtual void foo(); };
25165005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall  struct C : A, B { void foo() {} };
25265005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Test later.
25465005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall  void test() {
25565005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall    C c;
25665005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall  }
25765005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall}
25865005536dee9216b14e2361153a14ddd8a7cd50aJohn McCall
2594e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall// PR7611
2604e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCallnamespace Test11 {
2614e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  struct A {             virtual A* f(); };
2624e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  struct B : virtual A { virtual A* f(); };
2634e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  struct C : B         { virtual C* f(); };
2644e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  C* C::f() { return 0; }
2654e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall
2667dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  //  C::f itself.
2677dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  // CHECK: define {{.*}} @_ZN6Test111C1fEv(
2687dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman
2694e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  //  The this-adjustment and return-adjustment thunk required when
2704e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  //  C::f appears in a vtable where A is at a nonzero offset from C.
2714e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  // CHECK: define {{.*}} @_ZTcv0_n24_v0_n32_N6Test111C1fEv(
2724e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall
2734e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  //  The return-adjustment thunk required when C::f appears in a vtable
2744e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  //  where A is at a zero offset from C.
2754e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall  // CHECK: define {{.*}} @_ZTch0_v0_n32_N6Test111C1fEv(
2764e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall}
2774e3b17c9ce4a198eaeac4355b12e4b523185ecb5John McCall
2787dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman// Varargs thunk test.
2797dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedmannamespace Test12 {
2807dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  struct A {
2817dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman    virtual A* f(int x, ...);
2827dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  };
2837dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  struct B {
2847dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman    virtual B* f(int x, ...);
2857dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  };
2867dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  struct C : A, B {
2877dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman    virtual void c();
2887dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman    virtual C* f(int x, ...);
2897dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  };
2907dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  C* C::f(int x, ...) { return this; }
2917dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman
2927dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  // C::f
2937dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  // CHECK: define {{.*}} @_ZN6Test121C1fEiz
2947dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman
2957dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  // Varargs thunk; check that both the this and covariant adjustments
2967dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  // are generated.
2977dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman  // CHECK: define {{.*}} @_ZTchn8_h8_N6Test121C1fEiz
2983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -8
2993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 8
3007dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman}
3017dcdf5ba9324a9577461eae302e88fdd52e310c5Eli Friedman
30282bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman// PR13832
30382bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedmannamespace Test13 {
30482bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  struct B1 {
30582bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman    virtual B1 &foo1();
30682bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  };
30782bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  struct Pad1 {
30882bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman    virtual ~Pad1();
30982bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  };
31082bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  struct Proxy1 : Pad1, B1 {
31182bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman    virtual ~Proxy1();
31282bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  };
31382bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  struct D : virtual Proxy1 {
31482bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman    virtual ~D();
31582bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman    virtual D &foo1();
31682bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  };
31782bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  D& D::foo1() {
31882bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman    return *this;
31982bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  }
32082bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  // CHECK: define {{.*}} @_ZTcvn8_n32_v8_n24_N6Test131D4foo1Ev
3213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -8
3223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -32
3233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -24
3243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 8
32582bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman  // CHECK: ret %"struct.Test13::D"*
32682bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman}
32782bad6bbb6c04ec6e34562988d0d1f9e450a7279Eli Friedman
328022301b85823fc474965ce487fc9d61a156287e2Rafael Espindolanamespace Test14 {
329022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  class A {
330022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola    virtual void f();
331022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  };
332022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  class B {
333022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola    virtual void f();
334022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  };
335022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  class C : public A, public B  {
336022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola    virtual void f();
337022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  };
338022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  void C::f() {
339022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola  }
340899245792776dd219a3c36eb19b42272e270bc0cBill Wendling  // CHECK: define void @_ZThn8_N6Test141C1fEv({{.*}}) unnamed_addr [[NUW:#[0-9]+]]
341022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola}
342022301b85823fc474965ce487fc9d61a156287e2Rafael Espindola
3438e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling// Varargs non-covariant thunk test.
3448e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling// PR18098
3458e3eec5fed242ef730b4ea023051650420e9c443Bill Wendlingnamespace Test15 {
3468e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  struct A {
3478e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling    virtual ~A();
3488e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  };
3498e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  struct B {
3508e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling    virtual void f(int x, ...);
3518e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  };
3528e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  struct C : A, B {
3538e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling    virtual void c();
3548e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling    virtual void f(int x, ...);
3558e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  };
3568e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  void C::c() {}
3578e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling
3588e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  // C::c
3598e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  // CHECK: declare void @_ZN6Test151C1fEiz
3608e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  // non-virtual thunk to C::f
3618e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling  // CHECK: declare void @_ZThn8_N6Test151C1fEiz
3628e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling}
3638e3eec5fed242ef730b4ea023051650420e9c443Bill Wendling
3642736071ea3a46f90e65c93418961611d96c10ab9John McCall/**** The following has to go at the end of the file ****/
3652736071ea3a46f90e65c93418961611d96c10ab9John McCall
3660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// This is from Test5:
3670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(
3680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
3690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This is from Test10:
371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
374899245792776dd219a3c36eb19b42272e270bc0cBill Wendling// CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} }
375