From: Mike Stump Date: Sun, 16 Aug 2009 19:04:13 +0000 (+0000) Subject: Refine vbase offset calculations. WIP. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe3010d09cec5cd06e31a3d57fe188a04d9bfa17;p=clang Refine vbase offset calculations. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79198 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 30682efbb8..071e3e8955 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -168,6 +168,7 @@ void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { } void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, + const CXXRecordDecl *PB, int64_t Offset, llvm::SmallSet &mark, llvm::SmallSet &IndirectPrimary) { @@ -187,22 +188,36 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, VBaseOffsets.push_back(BaseOffset); } #endif + int64_t BaseOffset = Offset;; + // FIXME: Calculate BaseOffset. if (i->isVirtual()) { - // Mark it so we don't lay it out twice. - if (mark.count(Base)) - continue; - if (IndirectPrimary.count(Base)) { - int64_t BaseOffset; - // FIXME: audit - BaseOffset = Offset; - // BaseOffset = (1<<63) | (1<<31); + if (Base == PB) { + // Only lay things out once. + if (mark.count(Base)) + continue; + // Mark it so we don't lay it out twice. + mark.insert(Base); + assert (IndirectPrimary.count(Base) && "IndirectPrimary was wrong"); VBases.push_back(Base); - VBaseOffsets.push_back(BaseOffset); - } else + VBaseOffsets.push_back(Offset); + } else if (IndirectPrimary.count(Base)) { + // Someone else will eventually lay this out. + ; + } else { + // Only lay things out once. + if (mark.count(Base)) + continue; + // Mark it so we don't lay it out twice. + mark.insert(Base); LayoutVirtualBase(Base); + BaseOffset = *(VBaseOffsets.end()-1); + } + } + if (Base->getNumVBases()) { + const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base); + const CXXRecordDecl *PB = L.getPrimaryBase(); + LayoutVirtualBases(Base, PB, BaseOffset, mark, IndirectPrimary); } - if (Base->getNumVBases()) - LayoutVirtualBases(Base, Offset, mark, IndirectPrimary); } } @@ -227,6 +242,7 @@ void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD, BaseOffsets.push_back(Size); } +#if 0 // And now add offsets for all our primary virtual bases as well, so // they all have offsets. const ASTRecordLayout *L = &BaseInfo; @@ -240,6 +256,7 @@ void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD, if (PB) L = &Ctx.getASTRecordLayout(PB); } +#endif // Reserve space for this base. Size += BaseSize; @@ -285,7 +302,7 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { if (RD) { llvm::SmallSet mark; - LayoutVirtualBases(RD, 0, mark, IndirectPrimary); + LayoutVirtualBases(RD, PrimaryBase, 0, mark, IndirectPrimary); } // Finally, round the size of the total struct up to the alignment of the diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h index cdd077403c..5813e27a84 100644 --- a/lib/AST/RecordLayoutBuilder.h +++ b/lib/AST/RecordLayoutBuilder.h @@ -73,7 +73,7 @@ class ASTRecordLayoutBuilder { void LayoutNonVirtualBases(const CXXRecordDecl *RD); void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase); void LayoutVirtualBase(const CXXRecordDecl *RD); - void LayoutVirtualBases(const CXXRecordDecl *RD, + void LayoutVirtualBases(const CXXRecordDecl *RD, const CXXRecordDecl *PB, int64_t Offset, llvm::SmallSet &mark, llvm::SmallSet &IndirectPrimary); diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index d3bffe3a84..25d47ccf8e 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -206,13 +206,13 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { // CHECK-LP32:__ZTV7test5_D: // CHECK-LP32-NEXT: .long 16 // CHECK-LP32-NEXT: .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-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 8 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .long 4 +// CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 @@ -224,13 +224,13 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { // CHECK-LP32-NEXT: .long __ZN8test5_B26funcB2Ev // CHECK-LP32-NEXT: .long __ZN8test5_B16funcB1Ev // CHECK-LP32-NEXT: .long __ZN7test5_D5funcDEv -// CHECK-LP32: .space 4 // CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 -// CHECK-LP32 .long 4294967292 -// CHECK-LP32: .long __ZTI7test5_D +// CHECK-LP32-NEXT: .space 4 +// CHECK-LP32: .long 4294967292 +// CHECK-LP32-NEXT: .long __ZTI7test5_D // CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev // CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev // CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev @@ -241,8 +241,8 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { // CHECK-LP32: .long 4 // CHECK-LP32-NEXT: .space 4 // CHECK-LP32-NEXT: .space 4 -// CHECK-LP32 .long 4294967288 -// CHECK-LP32: .long __ZTI7test5_D +// CHECK-LP32: .long 4294967288 +// CHECK-LP32-NEXT: .long __ZTI7test5_D // CHECK-LP32-NEXT: .long __ZN9test5_B337funcB33Ev // CHECK-LP32-NEXT: .long __ZN9test5_B327funcB32Ev // CHECK-LP32-NEXT: .long __ZN9test5_B317funcB31Ev @@ -258,13 +258,13 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { // CHECK-LP64:__ZTV7test5_D: // CHECK-LP64-NEXT: .quad 32 // CHECK-LP64-NEXT: .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-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 16 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 @@ -276,13 +276,13 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { // CHECK-LP64-NEXT: .quad __ZN8test5_B26funcB2Ev // CHECK-LP64-NEXT: .quad __ZN8test5_B16funcB1Ev // CHECK-LP64-NEXT: .quad __ZN7test5_D5funcDEv -// CHECK-LP64: .space 8 // CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 -// CHECK-LP64 .quad 18446744073709551608 -// CHECK-LP64: .quad __ZTI7test5_D +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D // CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev // CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev // CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev @@ -293,8 +293,8 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { // CHECK-LP64: .quad 8 // CHECK-LP64-NEXT: .space 8 // CHECK-LP64-NEXT: .space 8 -// CHECK-LP64 .quad 18446744073709551600 -// CHECK-LP64: .quad __ZTI7test5_D +// CHECK-LP64: .quad 18446744073709551600 +// CHECK-LP64-NEXT: .quad __ZTI7test5_D // CHECK-LP64-NEXT: .quad __ZN9test5_B337funcB33Ev // CHECK-LP64-NEXT: .quad __ZN9test5_B327funcB32Ev // CHECK-LP64-NEXT: .quad __ZN9test5_B317funcB31Ev