r204455 - Simplify test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp by forcing VFTableBuilder invocation with virtual function calls

Timur Iskhodzhanov timurrrr at google.com
Fri Mar 21 04:39:24 PDT 2014


Author: timurrrr
Date: Fri Mar 21 06:39:24 2014
New Revision: 204455

URL: http://llvm.org/viewvc/llvm-project?rev=204455&view=rev
Log:
Simplify test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp by forcing VFTableBuilder invocation with virtual function calls

Previously the vftables were built at the end of the TU in a reverse-to-random order

Modified:
    cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp?rev=204455&r1=204454&r2=204455&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp Fri Mar 21 06:39:24 2014
@@ -1,32 +1,17 @@
 // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o %t.ll > %t
 // RUN: FileCheck --check-prefix=EMITS-VFTABLE %s < %t.ll
 // RUN: FileCheck --check-prefix=NO-VFTABLE %s < %t.ll
-// RUN: FileCheck --check-prefix=CHECK-A %s < %t
-// RUN: FileCheck --check-prefix=CHECK-B %s < %t
-// RUN: FileCheck --check-prefix=CHECK-C %s < %t
-// RUN: FileCheck --check-prefix=CHECK-D %s < %t
-// RUN: FileCheck --check-prefix=CHECK-E %s < %t
-// RUN: FileCheck --check-prefix=CHECK-F %s < %t
-// RUN: FileCheck --check-prefix=CHECK-G %s < %t
-// RUN: FileCheck --check-prefix=CHECK-I %s < %t
-// RUN: FileCheck --check-prefix=CHECK-J %s < %t
-// RUN: FileCheck --check-prefix=CHECK-K %s < %t
-// RUN: FileCheck --check-prefix=CHECK-L %s < %t
-// RUN: FileCheck --check-prefix=CHECK-M %s < %t
-// RUN: FileCheck --check-prefix=CHECK-N %s < %t
-// RUN: FileCheck --check-prefix=CHECK-O %s < %t
-// RUN: FileCheck --check-prefix=CHECK-Q %s < %t
-// RUN: FileCheck --check-prefix=CHECK-R %s < %t
+// RUN: FileCheck %s < %t
 
 struct A {
-  // CHECK-A: VFTable for 'A' (3 entries)
-  // CHECK-A-NEXT: 0 | void A::f()
-  // CHECK-A-NEXT: 1 | void A::g()
-  // CHECK-A-NEXT: 2 | void A::h()
-  // CHECK-A: VFTable indices for 'A' (3 entries)
-  // CHECK-A-NEXT: 0 | void A::f()
-  // CHECK-A-NEXT: 1 | void A::g()
-  // CHECK-A-NEXT: 2 | void A::h()
+  // CHECK-LABEL: VFTable for 'A' (3 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-LABEL: VFTable indices for 'A' (3 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
 
   virtual void f();
   virtual void g();
@@ -35,18 +20,19 @@ struct A {
 };
 A a;
 // EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+void use(A *obj) { obj->f(); }
 
 struct B : A {
-  // CHECK-B: VFTable for 'A' in 'B' (5 entries)
-  // CHECK-B-NEXT: 0 | void B::f()
-  // CHECK-B-NEXT: 1 | void A::g()
-  // CHECK-B-NEXT: 2 | void A::h()
-  // CHECK-B-NEXT: 3 | void B::i()
-  // CHECK-B-NEXT: 4 | void B::j()
-  // CHECK-B: VFTable indices for 'B' (3 entries)
-  // CHECK-B-NEXT: 0 | void B::f()
-  // CHECK-B-NEXT: 3 | void B::i()
-  // CHECK-B-NEXT: 4 | void B::j()
+  // CHECK-LABEL: VFTable for 'A' in 'B' (5 entries)
+  // CHECK-NEXT: 0 | void B::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | void B::i()
+  // CHECK-NEXT: 4 | void B::j()
+  // CHECK-LABEL: VFTable indices for 'B' (3 entries)
+  // CHECK-NEXT: 0 | void B::f()
+  // CHECK-NEXT: 3 | void B::i()
+  // CHECK-NEXT: 4 | void B::j()
 
   virtual void f();  // overrides A::f()
   virtual void i();
@@ -54,45 +40,48 @@ struct B : A {
 };
 B b;
 // EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+void use(B *obj) { obj->f(); }
 
 struct C {
-  // CHECK-C: VFTable for 'C' (2 entries)
-  // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
-  // CHECK-C-NEXT: 1 | void C::f()
-  // CHECK-C: VFTable indices for 'C' (2 entries).
-  // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
-  // CHECK-C-NEXT: 1 | void C::f()
+  // CHECK-LABEL: VFTable for 'C' (2 entries)
+  // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+  // CHECK-NEXT: 1 | void C::f()
+  // CHECK-LABEL: VFTable indices for 'C' (2 entries).
+  // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+  // CHECK-NEXT: 1 | void C::f()
 
   virtual ~C();
   virtual void f();
 };
 void C::f() {}
 // NO-VFTABLE-NOT: @"\01??_7C@@6B@"
+void use(C *obj) { obj->f(); }
 
 struct D {
-  // CHECK-D: VFTable for 'D' (2 entries)
-  // CHECK-D-NEXT: 0 | void D::f()
-  // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
-  // CHECK-D: VFTable indices for 'D' (2 entries)
-  // CHECK-D-NEXT: 0 | void D::f()
-  // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
+  // CHECK-LABEL: VFTable for 'D' (2 entries)
+  // CHECK-NEXT: 0 | void D::f()
+  // CHECK-NEXT: 1 | D::~D() [scalar deleting]
+  // CHECK-LABEL: VFTable indices for 'D' (2 entries)
+  // CHECK-NEXT: 0 | void D::f()
+  // CHECK-NEXT: 1 | D::~D() [scalar deleting]
 
   virtual void f();
   virtual ~D();
 };
 D d;
 // EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+void use(D *obj) { obj->f(); }
 
 struct E : A {
-  // CHECK-E: VFTable for 'A' in 'E' (5 entries)
-  // CHECK-E-NEXT: 0 | void A::f()
-  // CHECK-E-NEXT: 1 | void A::g()
-  // CHECK-E-NEXT: 2 | void A::h()
-  // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
-  // CHECK-E-NEXT: 4 | void E::i()
-  // CHECK-E: VFTable indices for 'E' (2 entries).
-  // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
-  // CHECK-E-NEXT: 4 | void E::i()
+  // CHECK-LABEL: VFTable for 'A' in 'E' (5 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | E::~E() [scalar deleting]
+  // CHECK-NEXT: 4 | void E::i()
+  // CHECK-LABEL: VFTable indices for 'E' (2 entries).
+  // CHECK-NEXT: 3 | E::~E() [scalar deleting]
+  // CHECK-NEXT: 4 | void E::i()
 
   // ~E would be the key method, but it isn't used, and MS ABI has no key
   // methods.
@@ -101,36 +90,38 @@ struct E : A {
 };
 void E::i() {}
 // NO-VFTABLE-NOT: @"\01??_7E@@6B@"
+void use(E *obj) { obj->i(); }
 
 struct F : A {
-  // CHECK-F: VFTable for 'A' in 'F' (5 entries)
-  // CHECK-F-NEXT: 0 | void A::f()
-  // CHECK-F-NEXT: 1 | void A::g()
-  // CHECK-F-NEXT: 2 | void A::h()
-  // CHECK-F-NEXT: 3 | void F::i()
-  // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
-  // CHECK-F: VFTable indices for 'F' (2 entries).
-  // CHECK-F-NEXT: 3 | void F::i()
-  // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
+  // CHECK-LABEL: VFTable for 'A' in 'F' (5 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | void F::i()
+  // CHECK-NEXT: 4 | F::~F() [scalar deleting]
+  // CHECK-LABEL: VFTable indices for 'F' (2 entries).
+  // CHECK-NEXT: 3 | void F::i()
+  // CHECK-NEXT: 4 | F::~F() [scalar deleting]
 
   virtual void i();
   virtual ~F();
 };
 F f;
 // EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+void use(F *obj) { obj->i(); }
 
 struct G : E {
-  // CHECK-G: VFTable for 'A' in 'E' in 'G' (6 entries)
-  // CHECK-G-NEXT: 0 | void G::f()
-  // CHECK-G-NEXT: 1 | void A::g()
-  // CHECK-G-NEXT: 2 | void A::h()
-  // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
-  // CHECK-G-NEXT: 4 | void E::i()
-  // CHECK-G-NEXT: 5 | void G::j()
-  // CHECK-G: VFTable indices for 'G' (3 entries).
-  // CHECK-G-NEXT: 0 | void G::f()
-  // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
-  // CHECK-G-NEXT: 5 | void G::j()
+  // CHECK-LABEL: VFTable for 'A' in 'E' in 'G' (6 entries)
+  // CHECK-NEXT: 0 | void G::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | G::~G() [scalar deleting]
+  // CHECK-NEXT: 4 | void E::i()
+  // CHECK-NEXT: 5 | void G::j()
+  // CHECK-LABEL: VFTable indices for 'G' (3 entries).
+  // CHECK-NEXT: 0 | void G::f()
+  // CHECK-NEXT: 3 | G::~G() [scalar deleting]
+  // CHECK-NEXT: 5 | void G::j()
 
   virtual void f();  // overrides A::f()
   virtual ~G();
@@ -138,6 +129,7 @@ struct G : E {
 };
 void G::j() {}
 // NO-VFTABLE-NOT: @"\01??_7G@@6B@"
+void use(G *obj) { obj->j(); }
 
 // Test that the usual Itanium-style key method does not emit a vtable.
 struct H {
@@ -149,23 +141,24 @@ void H::f() {}
 struct Empty { };
 
 struct I : Empty {
-  // CHECK-I: VFTable for 'I' (2 entries)
-  // CHECK-I-NEXT: 0 | void I::f()
-  // CHECK-I-NEXT: 1 | void I::g()
+  // CHECK-LABEL: VFTable for 'I' (2 entries)
+  // CHECK-NEXT: 0 | void I::f()
+  // CHECK-NEXT: 1 | void I::g()
   virtual void f();
   virtual void g();
 };
 
 I i;
+void use(I *obj) { obj->f(); }
 
 struct J {
-  // CHECK-J: VFTable for 'J' (6 entries)
-  // CHECK-J-NEXT: 0 | void J::foo(long)
-  // CHECK-J-NEXT: 1 | void J::foo(int)
-  // CHECK-J-NEXT: 2 | void J::foo(short)
-  // CHECK-J-NEXT: 3 | void J::bar(long)
-  // CHECK-J-NEXT: 4 | void J::bar(int)
-  // CHECK-J-NEXT: 5 | void J::bar(short)
+  // CHECK-LABEL: VFTable for 'J' (6 entries)
+  // CHECK-NEXT: 0 | void J::foo(long)
+  // CHECK-NEXT: 1 | void J::foo(int)
+  // CHECK-NEXT: 2 | void J::foo(short)
+  // CHECK-NEXT: 3 | void J::bar(long)
+  // CHECK-NEXT: 4 | void J::bar(int)
+  // CHECK-NEXT: 5 | void J::bar(short)
   virtual void foo(short);
   virtual void bar(short);
   virtual void foo(int);
@@ -175,36 +168,38 @@ struct J {
 };
 
 J j;
+void use(J *obj) { obj->foo(42); }
 
 struct K : J {
-  // CHECK-K: VFTable for 'J' in 'K' (9 entries)
-  // CHECK-K-NEXT: 0 | void J::foo(long)
-  // CHECK-K-NEXT: 1 | void J::foo(int)
-  // CHECK-K-NEXT: 2 | void J::foo(short)
-  // CHECK-K-NEXT: 3 | void J::bar(long)
-  // CHECK-K-NEXT: 4 | void J::bar(int)
-  // CHECK-K-NEXT: 5 | void J::bar(short)
-  // CHECK-K-NEXT: 6 | void K::bar(double)
-  // CHECK-K-NEXT: 7 | void K::bar(float)
-  // CHECK-K-NEXT: 8 | void K::foo(float)
+  // CHECK-LABEL: VFTable for 'J' in 'K' (9 entries)
+  // CHECK-NEXT: 0 | void J::foo(long)
+  // CHECK-NEXT: 1 | void J::foo(int)
+  // CHECK-NEXT: 2 | void J::foo(short)
+  // CHECK-NEXT: 3 | void J::bar(long)
+  // CHECK-NEXT: 4 | void J::bar(int)
+  // CHECK-NEXT: 5 | void J::bar(short)
+  // CHECK-NEXT: 6 | void K::bar(double)
+  // CHECK-NEXT: 7 | void K::bar(float)
+  // CHECK-NEXT: 8 | void K::foo(float)
   virtual void bar(float);
   virtual void foo(float);
   virtual void bar(double);
 };
 
 K k;
+void use(K *obj) { obj->foo(42.0f); }
 
 struct L : J {
-  // CHECK-L: VFTable for 'J' in 'L' (9 entries)
-  // CHECK-L-NEXT: 0 | void J::foo(long)
-  // CHECK-L-NEXT: 1 | void L::foo(int)
-  // CHECK-L-NEXT: 2 | void J::foo(short)
-  // CHECK-L-NEXT: 3 | void J::bar(long)
-  // CHECK-L-NEXT: 4 | void J::bar(int)
-  // CHECK-L-NEXT: 5 | void J::bar(short)
-  // CHECK-L-NEXT: 6 | void L::foo(float)
-  // CHECK-L-NEXT: 7 | void L::bar(double)
-  // CHECK-L-NEXT: 8 | void L::bar(float)
+  // CHECK-LABEL: VFTable for 'J' in 'L' (9 entries)
+  // CHECK-NEXT: 0 | void J::foo(long)
+  // CHECK-NEXT: 1 | void L::foo(int)
+  // CHECK-NEXT: 2 | void J::foo(short)
+  // CHECK-NEXT: 3 | void J::bar(long)
+  // CHECK-NEXT: 4 | void J::bar(int)
+  // CHECK-NEXT: 5 | void J::bar(short)
+  // CHECK-NEXT: 6 | void L::foo(float)
+  // CHECK-NEXT: 7 | void L::bar(double)
+  // CHECK-NEXT: 8 | void L::bar(float)
 
   // This case is interesting. Since the J::foo(int) override is the first method in
   // the class, foo(float) precedes the bar(double) and bar(float) in the vftable.
@@ -215,20 +210,21 @@ struct L : J {
 };
 
 L l;
+void use(L *obj) { obj->foo(42.0f); }
 
 struct M : J {
-  // CHECK-M: VFTable for 'J' in 'M' (11 entries)
-  // CHECK-M-NEXT:  0 | void J::foo(long)
-  // CHECK-M-NEXT:  1 | void M::foo(int)
-  // CHECK-M-NEXT:  2 | void J::foo(short)
-  // CHECK-M-NEXT:  3 | void J::bar(long)
-  // CHECK-M-NEXT:  4 | void J::bar(int)
-  // CHECK-M-NEXT:  5 | void J::bar(short)
-  // CHECK-M-NEXT:  6 | void M::foo(float)
-  // CHECK-M-NEXT:  7 | void M::spam(long)
-  // CHECK-M-NEXT:  8 | void M::spam(int)
-  // CHECK-M-NEXT:  9 | void M::bar(double)
-  // CHECK-M-NEXT: 10 | void M::bar(float)
+  // CHECK-LABEL: VFTable for 'J' in 'M' (11 entries)
+  // CHECK-NEXT:  0 | void J::foo(long)
+  // CHECK-NEXT:  1 | void M::foo(int)
+  // CHECK-NEXT:  2 | void J::foo(short)
+  // CHECK-NEXT:  3 | void J::bar(long)
+  // CHECK-NEXT:  4 | void J::bar(int)
+  // CHECK-NEXT:  5 | void J::bar(short)
+  // CHECK-NEXT:  6 | void M::foo(float)
+  // CHECK-NEXT:  7 | void M::spam(long)
+  // CHECK-NEXT:  8 | void M::spam(int)
+  // CHECK-NEXT:  9 | void M::bar(double)
+  // CHECK-NEXT: 10 | void M::bar(float)
 
   virtual void foo(int);
   virtual void spam(int);
@@ -239,13 +235,14 @@ struct M : J {
 };
 
 M m;
+void use(M *obj) { obj->foo(42.0f); }
 
 struct N {
-  // CHECK-N: VFTable for 'N' (4 entries)
-  // CHECK-N-NEXT: 0 | void N::operator+(int)
-  // CHECK-N-NEXT: 1 | void N::operator+(short)
-  // CHECK-N-NEXT: 2 | void N::operator*(int)
-  // CHECK-N-NEXT: 3 | void N::operator*(short)
+  // CHECK-LABEL: VFTable for 'N' (4 entries)
+  // CHECK-NEXT: 0 | void N::operator+(int)
+  // CHECK-NEXT: 1 | void N::operator+(short)
+  // CHECK-NEXT: 2 | void N::operator*(int)
+  // CHECK-NEXT: 3 | void N::operator*(short)
   virtual void operator+(short);
   virtual void operator*(short);
   virtual void operator+(int);
@@ -253,20 +250,23 @@ struct N {
 };
 
 N n;
+void use(N *obj) { obj->operator+(42); }
 
 struct O { virtual A *f(); };
 struct P : O { virtual B *f(); };
 P p;
-// CHECK-O: VFTable for 'O' (1 entry)
-// CHECK-O-NEXT: 0 | A *O::f()
+void use(O *obj) { obj->f(); }
+void use(P *obj) { obj->f(); }
+// CHECK-LABEL: VFTable for 'O' (1 entry)
+// CHECK-NEXT: 0 | A *O::f()
 
-// CHECK-O: VFTable for 'O' in 'P' (1 entry)
-// CHECK-O-NEXT: 0 | B *P::f()
+// CHECK-LABEL: VFTable for 'O' in 'P' (1 entry)
+// CHECK-NEXT: 0 | B *P::f()
 
 struct Q {
-  // CHECK-Q: VFTable for 'Q' (2 entries)
-  // CHECK-Q-NEXT: 0 | void Q::foo(int)
-  // CHECK-Q-NEXT: 1 | void Q::bar(int)
+  // CHECK-LABEL: VFTable for 'Q' (2 entries)
+  // CHECK-NEXT: 0 | void Q::foo(int)
+  // CHECK-NEXT: 1 | void Q::bar(int)
   void foo(short);
   void bar(short);
   virtual void bar(int);
@@ -274,16 +274,18 @@ struct Q {
 };
 
 Q q;
+void use(Q *obj) { obj->foo(42); }
 
 // Inherited non-virtual overloads don't participate in the ordering.
 struct R : Q {
-  // CHECK-R: VFTable for 'Q' in 'R' (4 entries)
-  // CHECK-R-NEXT: 0 | void Q::foo(int)
-  // CHECK-R-NEXT: 1 | void Q::bar(int)
-  // CHECK-R-NEXT: 2 | void R::bar(long)
-  // CHECK-R-NEXT: 3 | void R::foo(long)
+  // CHECK-LABEL: VFTable for 'Q' in 'R' (4 entries)
+  // CHECK-NEXT: 0 | void Q::foo(int)
+  // CHECK-NEXT: 1 | void Q::bar(int)
+  // CHECK-NEXT: 2 | void R::bar(long)
+  // CHECK-NEXT: 3 | void R::foo(long)
   virtual void bar(long);
   virtual void foo(long);
 };
 
 R r;
+void use(R *obj) { obj->foo(42l); }





More information about the cfe-commits mailing list