diff options
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 43 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.h | 2 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/virt.cpp | 48 |
3 files changed, 55 insertions, 38 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 30682efbb8a..071e3e89550 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/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<const CXXRecordDecl*, 32> &mark, llvm::SmallSet<const CXXRecordDecl*, 32> &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<const CXXRecordDecl*, 32> 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/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h index cdd077403c1..5813e27a840 100644 --- a/clang/lib/AST/RecordLayoutBuilder.h +++ b/clang/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<const CXXRecordDecl*, 32> &mark, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp index d3bffe3a848..25d47ccf8e7 100644 --- a/clang/test/CodeGenCXX/virt.cpp +++ b/clang/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 |