From 1300754fdd0f5bc24c11e1284f9420680bd2a5aa Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 13 Aug 2009 02:02:14 +0000 Subject: [PATCH] Prep for vbase layout refinements. WIP. llvm-svn: 78882 --- clang/lib/AST/RecordLayoutBuilder.cpp | 18 +++++++++++++----- clang/lib/AST/RecordLayoutBuilder.h | 3 ++- clang/lib/CodeGen/CGCXX.cpp | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 0b56d774281b..bd994143087c 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -167,13 +167,14 @@ void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { LayoutBaseNonVirtually(RD); } -void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD) { - // FIXME: audit indirect virtual bases +void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, + llvm::SmallSet &IndirectPrimary) { + // FIXME: Though complete, this is the wrong order for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(), e = RD->vbases_end(); i != e; ++i) { const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); - if (!PrimaryBaseWasVirtual || Base != PrimaryBase) + if (!IndirectPrimary.count(Base)) LayoutVirtualBase(Base); } } @@ -215,13 +216,20 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { if (const AlignedAttr *AA = D->getAttr()) UpdateAlignment(AA->getAlignment()); + // FIXME: Calculate this completely. + llvm::SmallSet IndirectPrimary; + // If this is a C++ class, lay out the nonvirtual bases. const CXXRecordDecl *RD = dyn_cast(D); if (RD) { LayoutVtable(RD); // PrimaryBase goes first. - if (PrimaryBase) + if (PrimaryBase) { + // FIXME: We need all the primaries. + if (PrimaryBaseWasVirtual) + IndirectPrimary.insert(PrimaryBase); LayoutBaseNonVirtually(PrimaryBase); + } LayoutNonVirtualBases(RD); } @@ -231,7 +239,7 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { NonVirtualAlignment = Alignment; if (RD) - LayoutVirtualBases(RD); + LayoutVirtualBases(RD, IndirectPrimary); // Finally, round the size of the total struct up to the alignment of the // struct itself. diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h index 31bbdd753030..05944ece7da4 100644 --- a/clang/lib/AST/RecordLayoutBuilder.h +++ b/clang/lib/AST/RecordLayoutBuilder.h @@ -68,7 +68,8 @@ class ASTRecordLayoutBuilder { void LayoutNonVirtualBases(const CXXRecordDecl *RD); void LayoutBaseNonVirtually(const CXXRecordDecl *RD); void LayoutVirtualBase(const CXXRecordDecl *RD); - void LayoutVirtualBases(const CXXRecordDecl *RD); + void LayoutVirtualBases(const CXXRecordDecl *RD, + llvm::SmallSet &IndirectPrimary); /// FinishLayout - Finalize record layout. Adjust record size based on the /// alignment. diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 4148d7b717a5..9146206589ae 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -765,7 +765,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { } // FIXME: finish layout for virtual bases - // FIXME: audit indirect virtual bases + // FIXME: Though complete, this is the wrong order for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(), e = RD->vbases_end(); i != e; ++i) { const CXXRecordDecl *Base =