C++程序  |  336行  |  8.75 KB

// RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>&1 \
// RUN:            | FileCheck %s

#pragma pack(push, 8)

class B {
public:
  virtual void b(){}
  int b_field;
protected:
private:
};

class A : public B {
public:
  int a_field;
  virtual void a(){}
  char one;
protected:
private:
};

class D {
public:
  virtual void b(){}
  double a;
};

class C : public virtual A, 
          public D, public B {
public:
  double c1_field;
  int c2_field;
  double c3_field;
  int c4_field;
  virtual void foo(){}
  virtual void bar(){}
protected:
private:
};

struct BaseStruct
{
    BaseStruct(){}
    double v0;
    float v1;
    C fg;
};

struct DerivedStruct : public BaseStruct {
  int x;
};

struct G
{
    int g_field;
};

struct H : public G, 
           public virtual D
{
};

struct I : public virtual D
{
  virtual ~I(){}
  double q;
};

struct K
{
  int k;
};

struct L
{
  int l;
};

struct M : public virtual K
{
  int m;
};

struct N : public L, public M
{
  virtual void f(){}
};

struct O : public H, public G {
  virtual void fo(){}
};

struct P : public M, public virtual L {
  int p;
};

struct R {};

#pragma pack(pop)

// This needs only for building layouts. 
// Without this clang doesn`t dump record layouts.
int main() {
  // This avoid "Can't yet mangle constructors!" for MS ABI.
  C* c;
  c->foo();
  DerivedStruct* v;
  H* g;
  BaseStruct* u;
  I* i;
  N* n;
  O* o;
  P* p;
  R* r;
  return 0;
}

// CHECK:       0 | class D
// CHECK-NEXT:  0 |   (D vftable pointer)
// CHECK-NEXT:  8 |   double a

// CHECK-NEXT: sizeof=16, dsize=16, align=8
// CHECK-NEXT: nvsize=16, nvalign=8

// CHECK: %class.D = type { i32 (...)**, double }

// CHECK:       0 | class B
// CHECK-NEXT:  0 |   (B vftable pointer)
// CHECK-NEXT:  4 |   int b_field

// CHECK-NEXT: sizeof=8, dsize=8, align=4
// CHECK-NEXT: nvsize=8, nvalign=4

// CHECK: %class.B = type { i32 (...)**, i32 }

// CHECK:       0 | class A
// CHECK-NEXT:  0 |   class B (primary base)
// CHECK-NEXT:  0 |     (B vftable pointer)
// CHECK-NEXT:  4 |     int b_field
// CHECK-NEXT:  8 |   int a_field
// CHECK-NEXT: 12 |   char one

// CHECK-NEXT: sizeof=16, dsize=16, align=4
// CHECK-NEXT: nvsize=16, nvalign=4

// CHECK:       0 | class C
// CHECK-NEXT:  0 |   class D (primary base)
// CHECK-NEXT:  0 |     (D vftable pointer)
// CHECK-NEXT:  8 |     double a
// CHECK-NEXT: 16 |   class B (base)
// CHECK-NEXT: 16 |     (B vftable pointer)
// CHECK-NEXT: 20 |     int b_field
// CHECK-NEXT: 24 |   (C vbtable pointer)
// CHECK-NEXT: 32 |   double c1_field
// CHECK-NEXT: 40 |   int c2_field
// CHECK-NEXT: 48 |   double c3_field
// CHECK-NEXT: 56 |   int c4_field
// CHECK-NEXT: 64 |   class A (virtual base)
// CHECK-NEXT: 64 |     class B (primary base)
// CHECK-NEXT: 64 |       (B vftable pointer)
// CHECK-NEXT: 68 |       int b_field
// CHECK-NEXT: 72 |     int a_field
// CHECK-NEXT: 76 |     char one

// CHECK-NEXT: sizeof=80, dsize=80, align=8
// CHECK-NEXT: nvsize=64, nvalign=8

// CHECK: %class.A = type { %class.B, i32, i8 }

// CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A }
// CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 }

// CHECK:       0 | struct BaseStruct
// CHECK-NEXT:  0 |   double v0
// CHECK-NEXT:  8 |   float v1
// CHECK-NEXT: 16 |   class C fg
// CHECK-NEXT: 16 |     class D (primary base)
// CHECK-NEXT: 16 |       (D vftable pointer)
// CHECK-NEXT: 24 |       double a
// CHECK-NEXT: 32 |     class B (base)
// CHECK-NEXT: 32 |       (B vftable pointer)
// CHECK-NEXT: 36 |       int b_field
// CHECK-NEXT: 40 |     (C vbtable pointer)
// CHECK-NEXT: 48 |     double c1_field
// CHECK-NEXT: 56 |     int c2_field
// CHECK-NEXT: 64 |     double c3_field
// CHECK-NEXT: 72 |     int c4_field
// CHECK-NEXT: 80 |     class A (virtual base)
// CHECK-NEXT: 80 |       class B (primary base)
// CHECK-NEXT: 80 |         (B vftable pointer)
// CHECK-NEXT: 84 |         int b_field
// CHECK-NEXT: 88 |       int a_field
// CHECK-NEXT: 92 |       char one

// CHECK-NEXT: sizeof=80, dsize=80, align=8
// CHECK-NEXT: nvsize=64, nvalign=8

// CHECK: sizeof=96, dsize=96, align=8
// CHECK-NEXT: nvsize=96, nvalign=8

// CHECK: %struct.BaseStruct = type { double, float, %class.C }

// CHECK:       0 | struct DerivedStruct
// CHECK-NEXT:  0 |   struct BaseStruct (base)
// CHECK-NEXT:  0 |     double v0
// CHECK-NEXT:  8 |     float v1
// CHECK-NEXT: 16 |     class C fg
// CHECK-NEXT: 16 |       class D (primary base)
// CHECK-NEXT: 16 |         (D vftable pointer)
// CHECK-NEXT: 24 |         double a
// CHECK-NEXT: 32 |       class B (base)
// CHECK-NEXT: 32 |         (B vftable pointer)
// CHECK-NEXT: 36 |         int b_field
// CHECK-NEXT: 40 |       (C vbtable pointer)
// CHECK-NEXT: 48 |       double c1_field
// CHECK-NEXT: 56 |       int c2_field
// CHECK-NEXT: 64 |       double c3_field
// CHECK-NEXT: 72 |       int c4_field
// CHECK-NEXT: 80 |       class A (virtual base)
// CHECK-NEXT: 80 |         class B (primary base)
// CHECK-NEXT: 80 |           (B vftable pointer)
// CHECK-NEXT: 84 |           int b_field
// CHECK-NEXT: 88 |         int a_field
// CHECK-NEXT: 92 |         char one
// CHECK-NEXT: sizeof=80, dsize=80, align=8
// CHECK-NEXT: nvsize=64, nvalign=8

// CHECK: 96 |   int x
// CHECK-NEXT: sizeof=104, dsize=104, align=8
// CHECK-NEXT: nvsize=104, nvalign=8

// CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }

// CHECK:      0 | struct G
// CHECK-NEXT: 0 |   int g_field
// CHECK-NEXT: sizeof=4, dsize=4, align=4
// CHECK-NEXT: nvsize=4, nvalign=4

// CHECK:       0 | struct H
// CHECK-NEXT:  0 |   struct G (base)
// CHECK-NEXT:  0 |     int g_field
// CHECK-NEXT:  4 |   (H vbtable pointer)
// CHECK-NEXT:  8 |   class D (virtual base)
// CHECK-NEXT:  8 |     (D vftable pointer)
// CHECK-NEXT: 16 |     double a
// CHECK-NEXT: sizeof=24, dsize=24, align=8
// CHECK-NEXT: nvsize=8, nvalign=4

// CHECK: %struct.H = type { %struct.G, i32*, %class.D }

// CHECK:       0 | struct I
// CHECK-NEXT:  0 |   (I vftable pointer)
// CHECK-NEXT:  8 |   (I vbtable pointer)
// CHECK-NEXT: 16 |   double q
// CHECK-NEXT: 24 |   class D (virtual base)
// CHECK-NEXT: 24 |     (D vftable pointer)
// CHECK-NEXT: 32 |     double a
// CHECK-NEXT: sizeof=40, dsize=40, align=8
// CHECK-NEXT: nvsize=24, nvalign=8

// CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D }
// CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double }

// CHECK:       0 | struct L
// CHECK-NEXT:  0 |   int l
// CHECK-NEXT: sizeof=4, dsize=4, align=4
// CHECK-NEXT: nvsize=4, nvalign=4

// CHECK:       0 | struct K
// CHECK-NEXT:  0 |   int k
// CHECK-NEXT: sizeof=4, dsize=4, align=4
// CHECK-NEXT: nvsize=4, nvalign=4

// CHECK:       0 | struct M
// CHECK-NEXT:  0 |   (M vbtable pointer)
// CHECK-NEXT:  4 |   int m
// CHECK-NEXT:  8 |   struct K (virtual base)
// CHECK-NEXT:  8 |     int k
// CHECK-NEXT: sizeof=12, dsize=12, align=4

//CHECK: %struct.M = type { i32*, i32, %struct.K }
//CHECK: %struct.M.base = type { i32*, i32 }

// CHECK:       0 | struct N
// CHECK-NEXT:  4 |   struct L (base)
// CHECK-NEXT:  4 |     int l
// CHECK-NEXT:  8 |   struct M (base)
// CHECK-NEXT:  8 |     (M vbtable pointer)
// CHECK-NEXT: 12 |     int m
// CHECK-NEXT:  0 |   (N vftable pointer)
// CHECK-NEXT: 16 |   struct K (virtual base)
// CHECK-NEXT: 16 |     int k
// CHECK-NEXT: sizeof=20, dsize=20, align=4
// CHECK-NEXT: nvsize=16, nvalign=4

//CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K }

// FIXME: MSVC place struct H at offset 8.
// CHECK:       0 | struct O
// CHECK-NEXT:  4 |   struct H (base)
// CHECK-NEXT:  4 |     struct G (base)
// CHECK-NEXT:  4 |       int g_field
// CHECK-NEXT:  8 |     (H vbtable pointer)
// CHECK-NEXT: 12 |   struct G (base)
// CHECK-NEXT: 12 |     int g_field
// CHECK-NEXT:  0 |   (O vftable pointer)
// CHECK-NEXT: 16 |   class D (virtual base)
// CHECK-NEXT: 16 |     (D vftable pointer)
// CHECK-NEXT: 24 |     double a
// CHECK-NEXT: sizeof=32, dsize=32, align=8
// CHECK-NEXT: nvsize=16, nvalign=4

//CHECK: %struct.O = type { i32 (...)**, %struct.H.base, %struct.G, %class.D }
//CHECK: %struct.O.base = type { i32 (...)**, %struct.H.base, %struct.G }

// CHECK:       0 | struct P
// CHECK-NEXT:  0 |   struct M (base)
// CHECK-NEXT:  0 |     (M vbtable pointer)
// CHECK-NEXT:  4 |     int m
// CHECK-NEXT:  8 |   int p
// CHECK-NEXT: 12 |   struct K (virtual base)
// CHECK-NEXT: 12 |     int k
// CHECK-NEXT: 16 |   struct L (virtual base)
// CHECK-NEXT: 16 |     int l
// CHECK-NEXT: sizeof=20, dsize=20, align=4
// CHECK-NEXT: nvsize=12, nvalign=4

//CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }

// CHECK:       0 | struct R (empty)
// CHECK-NEXT:  sizeof=1, dsize=0, align=1
// CHECK-NEXT:  nvsize=0, nvalign=1

//CHECK: %struct.R = type { i8 }