10b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - | FileCheck %s
2bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson
3bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlssonnamespace Test1 {
4bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson  struct A {
5f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    virtual int f() final;
6bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson  };
7bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson
8bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson  // CHECK: define i32 @_ZN5Test11fEPNS_1AE
9d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson  int f(A *a) {
10f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    // CHECK: call i32 @_ZN5Test11A1fEv
11d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson    return a->f();
12d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson  }
13d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson}
14d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson
15d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlssonnamespace Test2 {
16f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson  struct A final {
17f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    virtual int f();
18d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson  };
19d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson
20d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson  // CHECK: define i32 @_ZN5Test21fEPNS_1AE
21d66f42856539bf1c764c13fba41758228fc4cb9bAnders Carlsson  int f(A *a) {
22f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    // CHECK: call i32 @_ZN5Test21A1fEv
23bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson    return a->f();
24bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson  }
25bd2bfae2a6e5dc264e1f13183ad2ac11095766bbAnders Carlsson}
261679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson
271679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlssonnamespace Test3 {
281679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson  struct A {
291679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson    virtual int f();
301679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson  };
311679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson
321679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson  struct B final : A { };
331679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson
341679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson  // CHECK: define i32 @_ZN5Test31fEPNS_1BE
351679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson  int f(B *b) {
361679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson    // CHECK: call i32 @_ZN5Test31A1fEv
371679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson    return b->f();
381679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson  }
39268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson
40268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson  // CHECK: define i32 @_ZN5Test31fERNS_1BE
41268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson  int f(B &b) {
42268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson    // CHECK: call i32 @_ZN5Test31A1fEv
43268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson    return b.f();
44268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson  }
45268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson
46268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson  // CHECK: define i32 @_ZN5Test31fEPv
47268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson  int f(void *v) {
48268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson    // CHECK: call i32 @_ZN5Test31A1fEv
49268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson    return static_cast<B*>(v)->f();
50268ab8c6b92dc40c678d8458a335698fa34915c9Anders Carlsson  }
511679f5a84ae1e578b0de347c89eaf31e0465f33cAnders Carlsson}
520b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
530b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindolanamespace Test4 {
540b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct A {
550b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual void f();
560b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
570b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
580b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct B final : A {
590b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual void f();
600b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
610b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
620b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  // CHECK: define void @_ZN5Test41fEPNS_1BE
630b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  void f(B* d) {
640b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    // CHECK: call void @_ZN5Test41B1fEv
650b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    static_cast<A*>(d)->f();
660b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  }
670b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola}
680b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
690b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindolanamespace Test5 {
700b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct A {
710b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual void f();
720b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
730b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
740b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct B : A {
750b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual void f();
760b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
770b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
780b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct C final : B {
790b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
800b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
810b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  // CHECK: define void @_ZN5Test51fEPNS_1CE
820b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  void f(C* d) {
83ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // FIXME: It should be possible to devirtualize this case, but that is
84ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // not implemented yet.
85ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // CHECK: getelementptr
86ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // CHECK-NEXT: %[[FUNC:.*]] = load
87ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // CHECK-NEXT: call void %[[FUNC]]
880b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    static_cast<A*>(d)->f();
890b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  }
900b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola}
910b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
920b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindolanamespace Test6 {
930b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct A {
940b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual ~A();
950b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
960b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
970b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct B : public A {
980b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual ~B();
990b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
1000b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
1010b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct C {
1020b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    virtual ~C();
1030b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
1040b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
1050b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  struct D final : public C, public B {
1060b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  };
1070b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola
1080b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  // CHECK: define void @_ZN5Test61fEPNS_1DE
1090b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  void f(D* d) {
1100b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    // CHECK: call void @_ZN5Test61DD1Ev
1110b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola    static_cast<A*>(d)->~A();
1120b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola  }
1130b4fe503ef00d9f8ea330850d3e3b303e9c7c876Rafael Espindola}
114632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola
115632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindolanamespace Test7 {
116632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  struct foo {
117632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    virtual void g() {}
118632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  };
119632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola
120632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  struct bar {
121632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    virtual int f() { return 0; }
122632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  };
123632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola
124632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  struct zed final : public foo, public bar {
125632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    int z;
126632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    virtual int f() {return z;}
127632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  };
128632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola
129632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  // CHECK: define i32 @_ZN5Test71fEPNS_3zedE
130632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  int f(zed *z) {
131632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    // CHECK: alloca
132632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    // CHECK-NEXT: store
133632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    // CHECK-NEXT: load
134632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    // CHECK-NEXT: bitcast
135632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    // CHECK-NEXT: call {{.*}} @_ZN5Test73zed1fEv
136632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    // CHECK-NEXT: ret
137632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola    return static_cast<bar*>(z)->f();
138632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola  }
139632fbaa22fbed7c090eb83775731bfff786c2198Rafael Espindola}
140ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola
141ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindolanamespace Test8 {
142ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  struct A { virtual ~A() {} };
143ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  struct B {
144ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    int b;
145ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    virtual int foo() { return b; }
146ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  };
147ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  struct C final : A, B {  };
148ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  // CHECK: define i32 @_ZN5Test84testEPNS_1CE
149ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  int test(C *c) {
150ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // CHECK: %[[THIS:.*]] = phi
151ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
152ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola    return static_cast<B*>(c)->foo();
153ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola  }
154ea01d7661751e062bb670cc1a0bdfee5789cb96fRafael Espindola}
1554a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola
1564a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindolanamespace Test9 {
1574a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  struct A {
1584a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    int a;
1594a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  };
1604a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  struct B {
1614a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    int b;
1624a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  };
1634a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  struct C : public B, public A {
1644a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  };
1654a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  struct RA {
1664a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    virtual A *f() {
1674a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola      return 0;
1684a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    }
1694a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  };
1704a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  struct RC final : public RA {
1714a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    virtual C *f() {
1724a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola      C *x = new C();
1734a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola      x->a = 1;
1744a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola      x->b = 2;
1754a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola      return x;
1764a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    }
1774a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  };
1784a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
1794a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  A *f(RC *x) {
1804a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    // FIXME: It should be possible to devirtualize this case, but that is
1814a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    // not implemented yet.
1824a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    // CHECK: getelementptr
1834a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    // CHECK-NEXT: %[[FUNC:.*]] = load
1844a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    // CHECK-NEXT: bitcast
1854a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    // CHECK-NEXT: = call {{.*}} %[[FUNC]]
1864a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola    return static_cast<RA*>(x)->f();
1874a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola  }
1884a889e47bd5a8d08a705a87962a35a504728d7f6Rafael Espindola}
189