From a4a541708a65184466b97fe562a293891fa7e811 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 13 Feb 2010 20:41:15 +0000 Subject: [PATCH] Handle virtual bases in ComputeBaseOffset. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96117 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 7d3f35f077..f7b8c53d02 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -288,7 +288,7 @@ ComputeBaseOffset(ASTContext &Context, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD) { CXXBasePaths Paths(/*FindAmbiguities=*/false, - /*RecordPaths=*/true, /*DetectVirtual=*/true); + /*RecordPaths=*/true, /*DetectVirtual=*/false); if (!const_cast(DerivedRD)-> isDerivedFrom(const_cast(BaseRD), Paths)) { @@ -296,15 +296,30 @@ ComputeBaseOffset(ASTContext &Context, return FinalOverriders::BaseOffset(); } - assert(!Paths.getDetectedVirtual() && - "FIXME: Handle virtual bases!"); - uint64_t NonVirtualOffset = 0; const CXXBasePath &Path = Paths.front(); - for (size_t Start = 0, End = Path.size(); Start != End; ++Start) { - const CXXBasePathElement &Element = Path[Start]; + unsigned NonVirtualStart = 0; + const CXXRecordDecl *VirtualBase = 0; + + // First, look for the virtual base class. + for (unsigned I = 0, E = Path.size(); I != E; ++I) { + const CXXBasePathElement &Element = Path[I]; + + if (Element.Base->isVirtual()) { + // FIXME: Can we break when we find the first virtual base? + // (If we can't, can't we just iterate over the path in reverse order?) + NonVirtualStart = I + 1; + QualType VBaseType = Element.Base->getType(); + VirtualBase = + cast(VBaseType->getAs()->getDecl()); + } + } + + // Now compute the non-virtual offset. + for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) { + const CXXBasePathElement &Element = Path[I]; // Check the base class offset. const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); @@ -318,7 +333,7 @@ ComputeBaseOffset(ASTContext &Context, // FIXME: This should probably use CharUnits or something. Maybe we should // even change the base offsets in ASTRecordLayout to be specified in // CharUnits. - return FinalOverriders::BaseOffset(0, NonVirtualOffset / 8); + return FinalOverriders::BaseOffset(VirtualBase, NonVirtualOffset / 8); } static FinalOverriders::BaseOffset @@ -510,10 +525,12 @@ void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) const { ReturnAdjustments.find(std::make_pair(Base, MD)); if (AI != ReturnAdjustments.end()) { const BaseOffset &Offset = AI->second; - - assert(!Offset.VirtualBase && "FIXME: Handle vbases!"); + + Out << " [ret-adj: "; + if (Offset.VirtualBase) + Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, "; - Out << " [ret-adj: " << Offset.NonVirtualOffset << " nv]"; + Out << Offset.NonVirtualOffset << " nv]"; } Out << "\n"; } -- 2.40.0