diff options
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 38 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp | 1 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/vtable-layout.cpp | 19 | 
3 files changed, 29 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 768e6a7566e..23cef42a3c0 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1900,20 +1900,32 @@ VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base,    // Compute 'this' pointer adjustments.    ComputeThisAdjustments(); -  // Record the address point. -  AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(), -                                                    OffsetInLayoutClass), -                                      AddressPoint)); -   -  // Record the address points for all primary bases. -  for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(), -       E = PrimaryBases.end(); I != E; ++I) { -    const CXXRecordDecl *BaseDecl = *I; +  // Add all address points. +  const CXXRecordDecl *RD = Base.getBase(); +  while (true) { +    AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass), +                                        AddressPoint)); + +    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); +    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); -    // We know that all the primary bases have the same offset as the base -    // subobject. -    BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass); -    AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint)); +    if (!PrimaryBase) +      break; +     +    if (Layout.getPrimaryBaseWasVirtual()) { +      // Check if this virtual primary base is a primary base in the layout +      // class. If it's not, we don't want to add it. +      const ASTRecordLayout &LayoutClassLayout = +        Context.getASTRecordLayout(LayoutClass); + +      if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != +          OffsetInLayoutClass) { +        // We don't want to add this class (or any of its primary bases). +        break; +      } +    } + +    RD = PrimaryBase;    }    bool BaseIsMorallyVirtual = BaseIsVirtual; diff --git a/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp index a82fca736c7..c01c5ef72cc 100644 --- a/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp +++ b/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp @@ -178,7 +178,6 @@ struct C : virtual public A { int j; };  // CHECK-NEXT:    7 | vcall_offset (-16)  // CHECK-NEXT:    8 | offset_to_top (-16)  // CHECK-NEXT:    9 | Test2::D RTTI -// CHECK-NEXT:        -- (Test2::A, 16) vtable address --  // CHECK-NEXT:        -- (Test2::C, 16) vtable address --  // CHECK-NEXT:   10 | [unused] void Test2::A::f()  struct D : public B, public C { diff --git a/clang/test/CodeGenCXX/vtable-layout.cpp b/clang/test/CodeGenCXX/vtable-layout.cpp index bc3d54b8e4a..335816e5443 100644 --- a/clang/test/CodeGenCXX/vtable-layout.cpp +++ b/clang/test/CodeGenCXX/vtable-layout.cpp @@ -635,7 +635,6 @@ struct D : virtual B, virtual C { virtual void f(); };  // CHECK-NEXT:    9 | vcall_offset (-8)  // CHECK-NEXT:   10 | offset_to_top (-8)  // CHECK-NEXT:   11 | Test17::E RTTI -// CHECK-NEXT:        -- (Test17::A, 8) vtable address --  // CHECK-NEXT:        -- (Test17::C, 8) vtable address --  // CHECK-NEXT:   12 | void Test17::E::f()  // CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset] @@ -693,7 +692,6 @@ struct C : A, B {  // CHECK-NEXT:   19 | vcall_offset (-16)  // CHECK-NEXT:   20 | offset_to_top (-16)  // CHECK-NEXT:   21 | Test18::D RTTI -// CHECK-NEXT:        -- (Test18::A, 16) vtable address --  // CHECK-NEXT:        -- (Test18::B, 16) vtable address --  // CHECK-NEXT:   22 | void Test18::D::f()  // CHECK-NEXT:        [this adjustment: -8 non-virtual, -32 vcall offset offset] @@ -725,7 +723,6 @@ struct C : A, B {  // CHECK-NEXT:    9 | vcall_offset (0)  // CHECK-NEXT:   10 | offset_to_top (-8)  // CHECK-NEXT:   11 | Test18::C RTTI -// CHECK-NEXT:        -- (Test18::A, 16) vtable address --  // CHECK-NEXT:        -- (Test18::B, 16) vtable address --  // CHECK-NEXT:   12 | void Test18::B::f()  // CHECK-NEXT:   13 | [unused] void Test18::C::g() @@ -745,7 +742,6 @@ struct C : A, B {  // CHECK-NEXT:    2 | vcall_offset (0)  // CHECK-NEXT:    3 | offset_to_top (0)  // CHECK-NEXT:    4 | Test18::B RTTI -// CHECK-NEXT:        -- (Test18::A, 16) vtable address --  // CHECK-NEXT:        -- (Test18::B, 16) vtable address --  // CHECK-NEXT:    5 | void Test18::B::f()  // CHECK-NEXT:    6 | [unused] void Test18::A::g() @@ -881,9 +877,6 @@ class E : virtual C { };  // CHECK-NEXT:   12 | vcall_offset (-8)  // CHECK-NEXT:   13 | offset_to_top (-8)  // CHECK-NEXT:   14 | Test21::F RTTI -// CHECK-NEXT:        -- (Test21::A, 8) vtable address -- -// CHECK-NEXT:        -- (Test21::B, 8) vtable address -- -// CHECK-NEXT:        -- (Test21::C, 8) vtable address --  // CHECK-NEXT:        -- (Test21::E, 8) vtable address --  // CHECK-NEXT:   15 | [unused] void Test21::F::f()  // @@ -1012,7 +1005,6 @@ struct C : virtual A { };  // CHECK-NEXT:    6 | vcall_offset (-8)  // CHECK-NEXT:    7 | offset_to_top (-8)  // CHECK-NEXT:    8 | Test24::D RTTI -// CHECK-NEXT:        -- (Test24::A, 8) vtable address --  // CHECK-NEXT:        -- (Test24::C, 8) vtable address --  // CHECK-NEXT:    9 | [unused] void Test24::D::f() @@ -1030,14 +1022,13 @@ struct C : virtual A { };  // CHECK-NEXT:    1 | vcall_offset (-8)  // CHECK-NEXT:    2 | offset_to_top (0)  // CHECK-NEXT:    3 | Test24::C RTTI -// CHECK-NEXT:        -- (Test24::A, 8) vtable address --  // CHECK-NEXT:        -- (Test24::C, 8) vtable address --  // CHECK-NEXT:    4 | [unused] void Test24::A::f()  // CHECK-NEXT:    5 | vcall_offset (0) -// CHECK-NEXT: 6 | offset_to_top (8) -// CHECK-NEXT: 7 | Test24::C RTTI -// CHECK-NEXT:     -- (Test24::A, 0) vtable address -- -// CHECK-NEXT: 8 | void Test24::A::f() +// CHECK-NEXT:    6 | offset_to_top (8) +// CHECK-NEXT:    7 | Test24::C RTTI +// CHECK-NEXT:        -- (Test24::A, 0) vtable address -- +// CHECK-NEXT:    8 | void Test24::A::f()  struct D : B, C {    virtual void f();  }; @@ -1071,7 +1062,6 @@ struct B : virtual V { };  // CHECK-NEXT:    8 | offset_to_top (-8)  // CHECK-NEXT:    9 | Test25::C RTTI  // CHECK-NEXT:        -- (Test25::B, 8) vtable address -- -// CHECK-NEXT:        -- (Test25::V, 8) vtable address --  // CHECK-NEXT:   10 | [unused] void Test25::V::f()  // CHECK:      Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries). @@ -1089,7 +1079,6 @@ struct B : virtual V { };  // CHECK-NEXT:    2 | offset_to_top (0)  // CHECK-NEXT:    3 | Test25::B RTTI  // CHECK-NEXT:        -- (Test25::B, 8) vtable address -- -// CHECK-NEXT:        -- (Test25::V, 8) vtable address --  // CHECK-NEXT:    4 | [unused] void Test25::V::f()  // CHECK-NEXT:    5 | vcall_offset (0)  // CHECK-NEXT:    6 | offset_to_top (8)  | 

