summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-08-06 13:41:24 +0000
committerMike Stump <mrs@apple.com>2009-08-06 13:41:24 +0000
commit6b2556f829c95c390468a278a5c718c92c6e28cd (patch)
treefe6c4ed53e33da7ae559baf55db4ea61650bf7bb /clang/lib
parent3ebc08b5bd07988a874116a7654c7354d26e8f89 (diff)
downloadbcm5719-llvm-6b2556f829c95c390468a278a5c718c92c6e28cd.tar.gz
bcm5719-llvm-6b2556f829c95c390468a278a5c718c92c6e28cd.zip
Layout virtual bases. Work in progress.
llvm-svn: 78308
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp27
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.h4
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp4
3 files changed, 27 insertions, 8 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 833e053e145..5f23a8ca46c 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -52,7 +52,7 @@ ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
// Skip the PrimaryBase here, as it is laid down first.
if (Base != PrimaryBase)
- LayoutNonVirtualBase(Base);
+ LayoutBaseNonVirtually(Base);
}
}
}
@@ -155,7 +155,22 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
return;
}
-void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {
+void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
+ LayoutBaseNonVirtually(RD);
+}
+
+void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD) {
+ // FIXME: audit indirect virtual bases
+ 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 (Base != PrimaryBase)
+ LayoutVirtualBase(Base);
+ }
+}
+
+void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD) {
const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
assert(BaseInfo.getDataSize() > 0 &&
"FIXME: Handle empty classes.");
@@ -190,11 +205,12 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
UpdateAlignment(AA->getAlignment());
// If this is a C++ class, lay out the nonvirtual bases.
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
+ if (RD) {
LayoutVtable(RD);
// PrimaryBase goes first.
if (PrimaryBase)
- LayoutNonVirtualBase(PrimaryBase);
+ LayoutBaseNonVirtually(PrimaryBase);
LayoutNonVirtualBases(RD);
}
@@ -203,6 +219,9 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
NonVirtualSize = Size;
NonVirtualAlignment = Alignment;
+ if (RD)
+ LayoutVirtualBases(RD);
+
// Finally, round the size of the total struct up to the alignment of the
// struct itself.
FinishLayout();
diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h
index a6c9c5e873d..a745c85db4e 100644
--- a/clang/lib/AST/RecordLayoutBuilder.h
+++ b/clang/lib/AST/RecordLayoutBuilder.h
@@ -58,7 +58,9 @@ class ASTRecordLayoutBuilder {
bool IsNearlyEmpty(const CXXRecordDecl *RD);
void LayoutVtable(const CXXRecordDecl *RD);
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
- void LayoutNonVirtualBase(const CXXRecordDecl *RD);
+ void LayoutBaseNonVirtually(const CXXRecordDecl *RD);
+ void LayoutVirtualBase(const CXXRecordDecl *RD);
+ void LayoutVirtualBases(const CXXRecordDecl *RD);
/// 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 0f76266acc2..eb8e87d372e 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -623,10 +623,8 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
/// base classes and non-static data members belonging to this constructor.
void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
- assert(ClassDecl->getNumVBases() == 0
- && "FIXME: virtual base initialization unsupported");
+ // FIXME: Add vbase initialization
llvm::Value *LoadOfThis = 0;
-
for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
E = CD->init_end();
OpenPOWER on IntegriCloud