From 331a03ae3ee069a6daa69381524dc012b60cfab0 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 26 Feb 2010 20:22:44 +0000 Subject: [PATCH] Sundry fixes to the new vtable builder. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97258 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 81f2ac67da..3dc29ad9ca 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -808,6 +808,28 @@ public: bool empty() const { return Offsets.empty(); } }; +static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, + const CXXMethodDecl *RHS) { + ASTContext &C = LHS->getASTContext(); // TODO: thread this down + CanQual + LT = C.getCanonicalType(LHS->getType()).getAs(), + RT = C.getCanonicalType(RHS->getType()).getAs(); + + // Fast-path matches in the canonical types. + if (LT == RT) return true; + + // Force the signatures to match. We can't rely on the overrides + // list here because there isn't necessarily an inheritance + // relationship between the two methods. + if (LT.getQualifiers() != RT.getQualifiers() || + LT->getNumArgs() != RT->getNumArgs()) + return false; + for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) + if (LT->getArgType(I) != RT->getArgType(I)) + return false; + return true; +} + bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, const CXXMethodDecl *RHS) { assert(LHS->isVirtual() && "LHS must be virtual!"); @@ -815,20 +837,14 @@ bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, // FIXME: We need to check more things here. + // Must have the same name. + // FIXME: are destructors an exception to this? DeclarationName LHSName = LHS->getDeclName(); DeclarationName RHSName = RHS->getDeclName(); - if (LHSName.getNameKind() != LHSName.getNameKind()) + if (LHSName != RHSName) return false; - - switch (LHSName.getNameKind()) { - default: - assert(false && "Unhandled name kind!"); - case DeclarationName::Identifier: - if (LHSName.getAsIdentifierInfo() != RHSName.getAsIdentifierInfo()) - return false; - } - - return true; + + return (HasSameVirtualSignature(LHS, RHS)); } bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, @@ -963,8 +979,10 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, const CXXRecordDecl *RD = Base.getBase(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); + // Handle the primary base first. - if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { + if (PrimaryBase) { uint64_t PrimaryBaseOffset; // Get the base offset of the primary base. @@ -1036,6 +1054,8 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, const CXXRecordDecl *BaseDecl = cast(I->getType()->getAs()->getDecl()); + if (BaseDecl == PrimaryBase) + continue; // Get the base offset of this base. uint64_t BaseOffset = Base.getBaseOffset() + @@ -1126,7 +1146,7 @@ private: /// nearest virtual base. int64_t NonVirtual; - /// VCallOffsetOffset - The offset (in bytes), relative to the address point + /// VCallOffsetOffset - The offset (in bytes), relative to the address point, /// of the virtual call offset. int64_t VCallOffsetOffset; -- 2.50.1