summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp43
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.h2
-rw-r--r--clang/test/CodeGenCXX/virt.cpp48
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
OpenPOWER on IntegriCloud