From 928f1506eb38bb26a1284b876213a8f5244f6933 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Fri, 7 Aug 2009 19:00:50 +0000 Subject: [PATCH] Add ability to generate vcall offsets for primary virtual base. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78396 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/RecordLayout.h | 14 ++++++++++++-- lib/AST/RecordLayoutBuilder.cpp | 15 ++++++++------- lib/AST/RecordLayoutBuilder.h | 6 +++++- lib/CodeGen/CGCXX.cpp | 4 +++- test/CodeGenCXX/virt.cpp | 10 +++++----- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index bb40da7647..68287a3b70 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -56,6 +56,8 @@ class ASTRecordLayout { /// PrimaryBase - The primary base for our vtable. const CXXRecordDecl *PrimaryBase; + /// PrimaryBase - Wether or not the primary base was a virtual base. + bool PrimaryBaseWasVirtual; /// BaseOffsets - Contains a map from base classes to their offset. /// FIXME: Does it make sense to store offsets for virtual base classes @@ -86,8 +88,9 @@ class ASTRecordLayout { ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize, const uint64_t *fieldoffsets, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, - const CXXRecordDecl *PB, const CXXRecordDecl **bases, - const uint64_t *baseoffsets, unsigned basecount) + const CXXRecordDecl *PB, bool PBVirtual, + const CXXRecordDecl **bases, const uint64_t *baseoffsets, + unsigned basecount) : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) { if (FieldCount > 0) { @@ -97,6 +100,7 @@ class ASTRecordLayout { } CXXInfo->PrimaryBase = PB; + CXXInfo->PrimaryBaseWasVirtual = PBVirtual; CXXInfo->NonVirtualSize = nonvirtualsize; CXXInfo->NonVirtualAlign = nonvirtualalign; for (unsigned i = 0; i != basecount; ++i) @@ -156,6 +160,12 @@ public: return CXXInfo->PrimaryBase; } + /// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual. + bool getPrimaryBaseWasVirtual() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + + return CXXInfo->PrimaryBaseWasVirtual; + } /// getBaseClassOffset - Get the offset, in bits, for the given base class. uint64_t getBaseClassOffset(const CXXRecordDecl *Base) const { diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 5f23a8ca46..1d96c1a20b 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/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(i->getType()->getAs()->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/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h index a745c85db4..75c6b51921 100644 --- a/lib/AST/RecordLayoutBuilder.h +++ b/lib/AST/RecordLayoutBuilder.h @@ -37,6 +37,7 @@ class ASTRecordLayoutBuilder { uint64_t NonVirtualSize; unsigned NonVirtualAlignment; const CXXRecordDecl *PrimaryBase; + bool PrimaryBaseWasVirtual; llvm::SmallVector Bases; llvm::SmallVector BaseOffsets; @@ -54,7 +55,10 @@ class ASTRecordLayoutBuilder { void SelectPrimaryBase(const CXXRecordDecl *RD); void SelectPrimaryForBase(const CXXRecordDecl *RD, llvm::SmallSet &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/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 00993be161..d5b21345ea 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/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()) diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index aa1bca156c..04d7333310 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -121,10 +121,10 @@ int main() { // CHECK-LP32: .long __ZN1C4bee1Ev // CHECK-LP32: .long __ZN1C4bee2Ev -// CHECK-LP32: __ZTV1F: -// CHECK-LP32 .space 4 +// CHECK-LP32:__ZTV1F: +// CHECK-LP32: .space 4 // CHECK-LP32 .long 8 -// CHECK-LP32 .space 4 +// CHECK-LP32: .space 4 // CHECK-LP32: .space 4 // CHECK-LP32: .long __ZTI1F // CHECK-LP32: .long __ZN1D3booEv @@ -143,9 +143,9 @@ int main() { // CHECK-LP32: .long __ZN2D14bar5Ev // CHECK-LP64: __ZTV1F: -// CHECK-LP64 .space 8 +// CHECK-LP64: .space 8 // CHECK-LP64 .quad 16 -// CHECK-LP64 .space 8 +// CHECK-LP64: .space 8 // CHECK-LP64: .space 8 // CHECK-LP64: .quad __ZTI1F // CHECK-LP64: .quad __ZN1D3booEv -- 2.40.0