summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp15
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.h6
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp4
3 files changed, 16 insertions, 9 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 5f23a8ca46c..1d96c1a20b7 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -30,7 +30,7 @@ void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
// FIXME: audit indirect virtual bases
if (!RD->isPolymorphic() && !RD->getNumVBases()) {
// There is no primary base in this case.
- setPrimaryBase(0);
+ setPrimaryBase(0, false);
return;
}
@@ -103,7 +103,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (Base->isDynamicClass()) {
- setPrimaryBase(Base);
+ setPrimaryBase(Base, false);
return;
}
}
@@ -116,7 +116,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
// is expensive.
// FIXME: audit indirect virtual bases
if (RD->getNumVBases() == 0) {
- setPrimaryBase(0);
+ setPrimaryBase(0, false);
return;
}
@@ -143,15 +143,15 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
if (FirstPrimary==0)
FirstPrimary = Base;
if (!IndirectPrimary.count(Base)) {
- setPrimaryBase(Base);
+ setPrimaryBase(Base, true);
return;
}
}
}
- // Otherwise if is the first nearly empty base, if one exists, otherwise
- // there is no primary base class.
- setPrimaryBase(FirstPrimary);
+ // Otherwise if is the first nearly empty virtual base, if one exists,
+ // otherwise there is no primary base class.
+ setPrimaryBase(FirstPrimary, true);
return;
}
@@ -404,6 +404,7 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
NonVirtualSize,
Builder.NonVirtualAlignment,
Builder.PrimaryBase,
+ Builder.PrimaryBaseWasVirtual,
Builder.Bases.data(),
Builder.BaseOffsets.data(),
Builder.Bases.size());
diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h
index a745c85db4e..75c6b519211 100644
--- a/clang/lib/AST/RecordLayoutBuilder.h
+++ b/clang/lib/AST/RecordLayoutBuilder.h
@@ -37,6 +37,7 @@ class ASTRecordLayoutBuilder {
uint64_t NonVirtualSize;
unsigned NonVirtualAlignment;
const CXXRecordDecl *PrimaryBase;
+ bool PrimaryBaseWasVirtual;
llvm::SmallVector<const CXXRecordDecl *, 4> Bases;
llvm::SmallVector<uint64_t, 4> BaseOffsets;
@@ -54,7 +55,10 @@ class ASTRecordLayoutBuilder {
void SelectPrimaryBase(const CXXRecordDecl *RD);
void SelectPrimaryForBase(const CXXRecordDecl *RD,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
- void setPrimaryBase(const CXXRecordDecl *PB) { PrimaryBase = PB; }
+ void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
+ PrimaryBase = PB;
+ PrimaryBaseWasVirtual = Virtual;
+ }
bool IsNearlyEmpty(const CXXRecordDecl *RD);
void LayoutVtable(const CXXRecordDecl *RD);
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 00993be161b..d5b21345ea1 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -614,9 +614,11 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+ const bool PrimaryBaseWasVirtual = Layout.getPrimaryBase();
// The primary base comes first.
- GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true);
+ GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true,
+ PrimaryBaseWasVirtual);
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
if (i->isVirtual())
OpenPOWER on IntegriCloud