diff options
author | Mike Stump <mrs@apple.com> | 2009-08-12 21:50:08 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-08-12 21:50:08 +0000 |
commit | 6f3793b4065b09f96797e7786570a43ba2adbc5c (patch) | |
tree | 63062069eb943d43888b557b26b8450110022089 | |
parent | 1f8c7a76f71c94c7993d14415e93ffefd430891b (diff) | |
download | bcm5719-llvm-6f3793b4065b09f96797e7786570a43ba2adbc5c.tar.gz bcm5719-llvm-6f3793b4065b09f96797e7786570a43ba2adbc5c.zip |
Refine primary vbase selection ordering. WIP.
llvm-svn: 78844
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 42 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.h | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/virt.cpp | 126 |
3 files changed, 156 insertions, 15 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 8e09e9e65bb..2a7477c4493 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -93,6 +93,30 @@ void ASTRecordLayoutBuilder::SelectPrimaryForBase(const CXXRecordDecl *RD, } } +void ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD, + const CXXRecordDecl *&FirstPrimary, + llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { + for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), + e = RD->bases_end(); i != e; ++i) { + const CXXRecordDecl *Base = + cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + if (!i->isVirtual()) { + SelectPrimaryVBase(Base, FirstPrimary, IndirectPrimary); + if (PrimaryBase) + return; + continue; + } + if (IsNearlyEmpty(Base)) { + if (FirstPrimary==0) + FirstPrimary = Base; + if (!IndirectPrimary.count(Base)) { + setPrimaryBase(Base, true); + return; + } + } + } +} + /// SelectPrimaryBase - Selects the primary base for the given class and /// record that with setPrimaryBase. void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { @@ -110,6 +134,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { } } + setPrimaryBase(0, false); + // Otherwise, it is the first nearly empty virtual base that is not an // indirect primary virtual base class, if one exists. @@ -117,7 +143,6 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { // is expensive. // FIXME: audit indirect virtual bases if (RD->getNumVBases() == 0) { - setPrimaryBase(0, false); return; } @@ -133,20 +158,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { } // Then we can search for the first nearly empty virtual base itself. - // FIXME: audit indirect virtual bases and order (backwards?) - for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(), - e = RD->vbases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); - if (IsNearlyEmpty(Base)) { - if (FirstPrimary==0) - FirstPrimary = Base; - if (!IndirectPrimary.count(Base)) { - setPrimaryBase(Base, true); - return; - } - } - } + SelectPrimaryVBase(RD, FirstPrimary, IndirectPrimary); // Otherwise if is the first nearly empty virtual base, if one exists, // otherwise there is no primary base class. diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h index 488f6662c00..31bbdd75303 100644 --- a/clang/lib/AST/RecordLayoutBuilder.h +++ b/clang/lib/AST/RecordLayoutBuilder.h @@ -54,6 +54,9 @@ class ASTRecordLayoutBuilder { void LayoutField(const FieldDecl *D); void SelectPrimaryBase(const CXXRecordDecl *RD); + void SelectPrimaryVBase(const CXXRecordDecl *RD, + const CXXRecordDecl *&FirstPrimary, + llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); void SelectPrimaryForBase(const CXXRecordDecl *RD, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) { diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp index d9e8664460c..7a1e2c31edf 100644 --- a/clang/test/CodeGenCXX/virt.cpp +++ b/clang/test/CodeGenCXX/virt.cpp @@ -164,6 +164,131 @@ struct test4_D : virtual B, virtual C { // CHECK-LP64: .quad __ZN1B4bar2Ev +struct test5_B3 { virtual void funcB3(); }; +struct test5_B2 : virtual test5_B3 { virtual void funcB2(); }; +struct test5_B1 : virtual test5_B2 { virtual void funcB1(); }; + +struct test5_B23 { virtual void funcB23(); }; +struct test5_B22 : virtual test5_B23 { virtual void funcB22(); }; +struct test5_B21 : virtual test5_B22 { virtual void funcB21(); }; + + +struct B232 { virtual void funcB232(); }; +struct B231 { virtual void funcB231(); }; + +struct test5_B33 { virtual void funcB33(); }; +struct test5_B32 : virtual test5_B33, virtual B232 { virtual void funcB32(); }; +struct test5_B31 : virtual test5_B32, virtual B231 { virtual void funcB31(); }; + +struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { + virtual void funcD() { } +}; + +// CHECK-LP32:__ZTV7test5_D: +// CHECK-LP32 .long 16 +// CHECK-LP32 .long 12 +// CHECK-LP32 .long 8 +// CHECK-LP32 .long 8 +// CHECK-LP32 .long 8 +// CHECK-LP32 .long 4 +// CHECK-LP32 .long 4 +// CHECK-LP32 .long 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .long __ZTI7test5_D +// CHECK-LP32: .long __ZN8test5_B36funcB3Ev +// CHECK-LP32: .long __ZN8test5_B26funcB2Ev +// CHECK-LP32: .long __ZN8test5_B16funcB1Ev +// CHECK-LP32: .long __ZN7test5_D5funcDEv +// CHECK-LP32 .space 4 +// CHECK-LP32 .space 4 +// CHECK-LP32 .space 4 +// CHECK-LP32 .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32 .long -4 +// CHECK-LP32: .long __ZTI7test5_D +// CHECK-LP32: .long __ZN9test5_B237funcB23Ev +// CHECK-LP32: .long __ZN9test5_B227funcB22Ev +// CHECK-LP32 .long __ZN9test5_B217funcB21Ev +// CHECK-LP32 .space 4 +// CHECK-LP32 .long 8 +// CHECK-LP32 .space 4 +// CHECK-LP32 .space 4 +// CHECK-LP32 .long 4 +// CHECK-LP32 .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32 .long -8 +// CHECK-LP32 .long __ZTI7test5_D +// CHECK-LP32 .long __ZN9test5_B337funcB33Ev +// CHECK-LP32 .long __ZN9test5_B327funcB32Ev +// CHECK-LP32 .long __ZN9test5_B317funcB31Ev +// CHECK-LP32: .space 4 +// CHECK-LP32 .long -12 +// CHECK-LP32: .long __ZTI7test5_D +// CHECK-LP32: .long __ZN4B2328funcB232Ev +// CHECK-LP32: .space 4 +// CHECK-LP32 .long -16 +// CHECK-LP32: .long __ZTI7test5_D +// CHECK-LP32: .long __ZN4B2318funcB231Ev + +// CHECK-LP64:__ZTV7test5_D: +// CHECK-LP64 .quad 32 +// CHECK-LP64 .quad 24 +// CHECK-LP64 .quad 16 +// CHECK-LP64 .quad 16 +// CHECK-LP64 .quad 16 +// CHECK-LP64 .quad 8 +// CHECK-LP64 .quad 8 +// CHECK-LP64 .quad 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .quad __ZTI7test5_D +// CHECK-LP64: .quad __ZN8test5_B36funcB3Ev +// CHECK-LP64: .quad __ZN8test5_B26funcB2Ev +// CHECK-LP64: .quad __ZN8test5_B16funcB1Ev +// CHECK-LP64: .quad __ZN7test5_D5funcDEv +// CHECK-LP64 .space 8 +// CHECK-LP64 .space 8 +// CHECK-LP64 .space 8 +// CHECK-LP64 .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64 .quad 18446744073709551608 +// CHECK-LP64: .quad __ZTI7test5_D +// CHECK-LP64: .quad __ZN9test5_B237funcB23Ev +// CHECK-LP64: .quad __ZN9test5_B227funcB22Ev +// CHECK-LP64 .quad __ZN9test5_B217funcB21Ev +// CHECK-LP64 .space 8 +// CHECK-LP64 .quad 16 +// CHECK-LP64 .space 8 +// CHECK-LP64 .space 8 +// CHECK-LP64 .quad 8 +// CHECK-LP64 .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64 .quad 18446744073709551600 +// CHECK-LP64 .quad __ZTI7test5_D +// CHECK-LP64 .quad __ZN9test5_B337funcB33Ev +// CHECK-LP64 .quad __ZN9test5_B327funcB32Ev +// CHECK-LP64 .quad __ZN9test5_B317funcB31Ev +// CHECK-LP64: .space 8 +// CHECK-LP64 .quad 18446744073709551592 +// CHECK-LP64: .quad __ZTI7test5_D +// CHECK-LP64: .quad __ZN4B2328funcB232Ev +// CHECK-LP64: .space 8 +// CHECK-LP64 .quad 18446744073709551584 +// CHECK-LP64: .quad __ZTI7test5_D +// CHECK-LP64: .quad __ZN4B2318funcB231Ev + + // CHECK-LP64: __ZTV1B: @@ -245,5 +370,6 @@ struct test4_D : virtual B, virtual C { // CHECK-LP64: .quad __ZN2D14bar5Ev +test5_D d5; test4_D d4; test3_D d3; |