diff options
author | Mike Stump <mrs@apple.com> | 2009-08-07 19:00:50 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-08-07 19:00:50 +0000 |
commit | c266c6d797f74090266fb8812029f92a34fb5151 (patch) | |
tree | 8565a7856f987095a29a415321049ea65f7425c8 /clang/lib | |
parent | 4f4aab2aeb257c6748000009e38354c78690ecb3 (diff) | |
download | bcm5719-llvm-c266c6d797f74090266fb8812029f92a34fb5151.tar.gz bcm5719-llvm-c266c6d797f74090266fb8812029f92a34fb5151.zip |
Add ability to generate vcall offsets for primary virtual base.
llvm-svn: 78396
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 15 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.h | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 4 |
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()) |