From: Reid Kleckner Date: Thu, 29 Mar 2018 22:42:24 +0000 (+0000) Subject: Hoist MethodVFTableLocation out of MicrosoftVTableContext, NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af48a142437e9abc1e2949e362f704cd427e089e;p=clang Hoist MethodVFTableLocation out of MicrosoftVTableContext, NFC This allows forward declaring it so that we can add it to MicrosoftMangleContext::mangleVirtualMemPtrThunk without including VTableBuilder.h. That saves a hashtable lookup when emitting virtual member pointer functions. It also shortens a really long type name. This struct has "VFtable" in the name, so it seems pretty unlikely that someone will assume it is generally useful for non-MS C++ ABI stuff. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328845 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index 7a45d88c23..71c78dcfab 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -30,6 +30,7 @@ namespace clang { class CXXDestructorDecl; class CXXMethodDecl; class FunctionDecl; + struct MethodVFTableLocation; class NamedDecl; class ObjCMethodDecl; class StringLiteral; @@ -201,7 +202,8 @@ public: raw_ostream &Out) = 0; virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, - raw_ostream &) = 0; + const MethodVFTableLocation &ML, + raw_ostream &Out) = 0; virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h index b0b71e4735..96565fa73a 100644 --- a/include/clang/AST/VTableBuilder.h +++ b/include/clang/AST/VTableBuilder.h @@ -479,41 +479,42 @@ struct VirtualBaseInfo { VPtrInfoVector VBPtrPaths; }; +struct MethodVFTableLocation { + /// If nonzero, holds the vbtable index of the virtual base with the vfptr. + uint64_t VBTableIndex; + + /// If nonnull, holds the last vbase which contains the vfptr that the + /// method definition is adjusted to. + const CXXRecordDecl *VBase; + + /// This is the offset of the vfptr from the start of the last vbase, or the + /// complete type if there are no virtual bases. + CharUnits VFPtrOffset; + + /// Method's index in the vftable. + uint64_t Index; + + MethodVFTableLocation() + : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()), + Index(0) {} + + MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase, + CharUnits VFPtrOffset, uint64_t Index) + : VBTableIndex(VBTableIndex), VBase(VBase), VFPtrOffset(VFPtrOffset), + Index(Index) {} + + bool operator<(const MethodVFTableLocation &other) const { + if (VBTableIndex != other.VBTableIndex) { + assert(VBase != other.VBase); + return VBTableIndex < other.VBTableIndex; + } + return std::tie(VFPtrOffset, Index) < + std::tie(other.VFPtrOffset, other.Index); + } +}; + class MicrosoftVTableContext : public VTableContextBase { public: - struct MethodVFTableLocation { - /// If nonzero, holds the vbtable index of the virtual base with the vfptr. - uint64_t VBTableIndex; - - /// If nonnull, holds the last vbase which contains the vfptr that the - /// method definition is adjusted to. - const CXXRecordDecl *VBase; - - /// This is the offset of the vfptr from the start of the last vbase, or the - /// complete type if there are no virtual bases. - CharUnits VFPtrOffset; - - /// Method's index in the vftable. - uint64_t Index; - - MethodVFTableLocation() - : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()), - Index(0) {} - - MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase, - CharUnits VFPtrOffset, uint64_t Index) - : VBTableIndex(VBTableIndex), VBase(VBase), - VFPtrOffset(VFPtrOffset), Index(Index) {} - - bool operator<(const MethodVFTableLocation &other) const { - if (VBTableIndex != other.VBTableIndex) { - assert(VBase != other.VBase); - return VBTableIndex < other.VBTableIndex; - } - return std::tie(VFPtrOffset, Index) < - std::tie(other.VFPtrOffset, other.Index); - } - }; private: ASTContext &Context; diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 785ee3a26e..06936f0b8f 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -135,7 +135,8 @@ public: bool shouldMangleStringLiteral(const StringLiteral *SL) override; void mangleCXXName(const NamedDecl *D, raw_ostream &Out) override; void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, - raw_ostream &) override; + const MethodVFTableLocation &ML, + raw_ostream &Out) override; void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) override; void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, @@ -297,9 +298,8 @@ public: void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD); void mangleMemberFunctionPointer(const CXXRecordDecl *RD, const CXXMethodDecl *MD); - void mangleVirtualMemPtrThunk( - const CXXMethodDecl *MD, - const MicrosoftVTableContext::MethodVFTableLocation &ML); + void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, + const MethodVFTableLocation &ML); void mangleNumber(int64_t Number); void mangleTagTypeKind(TagTypeKind TK); void mangleArtificalTagType(TagTypeKind TK, StringRef UnqualifiedName, @@ -607,7 +607,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, if (MD->isVirtual()) { MicrosoftVTableContext *VTContext = cast(getASTContext().getVTableContext()); - const MicrosoftVTableContext::MethodVFTableLocation &ML = + const MethodVFTableLocation &ML = VTContext->getMethodVFTableLocation(GlobalDecl(MD)); mangleVirtualMemPtrThunk(MD, ML); NVOffset = ML.VFPtrOffset.getQuantity(); @@ -644,8 +644,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, } void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk( - const CXXMethodDecl *MD, - const MicrosoftVTableContext::MethodVFTableLocation &ML) { + const CXXMethodDecl *MD, const MethodVFTableLocation &ML) { // Get the vftable offset. CharUnits PointerWidth = getASTContext().toCharUnitsFromBits( getASTContext().getTargetInfo().getPointerWidth(0)); @@ -2775,14 +2774,9 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, } } -void -MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, - raw_ostream &Out) { - MicrosoftVTableContext *VTContext = - cast(getASTContext().getVTableContext()); - const MicrosoftVTableContext::MethodVFTableLocation &ML = - VTContext->getMethodVFTableLocation(GlobalDecl(MD)); - +void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk( + const CXXMethodDecl *MD, const MethodVFTableLocation &ML, + raw_ostream &Out) { msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << '?'; diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index a95791ce88..5f1ccdf2cc 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -2367,8 +2367,6 @@ namespace { class VFTableBuilder { public: - typedef MicrosoftVTableContext::MethodVFTableLocation MethodVFTableLocation; - typedef llvm::DenseMap MethodVFTableLocationsTy; @@ -3544,10 +3542,9 @@ static void computeFullPathsForVFTables(ASTContext &Context, } } -static bool -vfptrIsEarlierInMDC(const ASTRecordLayout &Layout, - const MicrosoftVTableContext::MethodVFTableLocation &LHS, - const MicrosoftVTableContext::MethodVFTableLocation &RHS) { +static bool vfptrIsEarlierInMDC(const ASTRecordLayout &Layout, + const MethodVFTableLocation &LHS, + const MethodVFTableLocation &RHS) { CharUnits L = LHS.VFPtrOffset; CharUnits R = RHS.VFPtrOffset; if (LHS.VBase) @@ -3733,7 +3730,7 @@ MicrosoftVTableContext::getVFTableLayout(const CXXRecordDecl *RD, return *VFTableLayouts[id]; } -const MicrosoftVTableContext::MethodVFTableLocation & +const MethodVFTableLocation & MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) { assert(cast(GD.getDecl())->isVirtual() && "Only use this method for virtual methods or dtors"); diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 42c0210e1d..0f7ac725d5 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1416,7 +1416,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( // deleting dtor. const auto *DD = dyn_cast(Method); GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method); - MicrosoftVTableContext::MethodVFTableLocation ML = + const MethodVFTableLocation &ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); VIndex = ML.Index; diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 542e1bf5fa..e80c3b33d2 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -230,7 +230,7 @@ public: getThisArgumentTypeForMethod(const CXXMethodDecl *MD) override { MD = MD->getCanonicalDecl(); if (MD->isVirtual() && !isa(MD)) { - MicrosoftVTableContext::MethodVFTableLocation ML = + const MethodVFTableLocation &ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD); // The vbases might be ordered differently in the final overrider object // and the complete object, so the "this" argument may sometimes point to @@ -616,9 +616,8 @@ private: const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD); /// \brief Generate a thunk for calling a virtual member function MD. - llvm::Function *EmitVirtualMemPtrThunk( - const CXXMethodDecl *MD, - const MicrosoftVTableContext::MethodVFTableLocation &ML); + llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, + const MethodVFTableLocation &ML); public: llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override; @@ -1336,7 +1335,7 @@ MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) { LookupGD = GlobalDecl(DD, Dtor_Deleting); } - MicrosoftVTableContext::MethodVFTableLocation ML = + const MethodVFTableLocation &ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); CharUnits Adjustment = ML.VFPtrOffset; @@ -1385,7 +1384,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( // with the base one, so look up the deleting one instead. LookupGD = GlobalDecl(DD, Dtor_Deleting); } - MicrosoftVTableContext::MethodVFTableLocation ML = + const MethodVFTableLocation &ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); CharUnits StaticOffset = ML.VFPtrOffset; @@ -1851,8 +1850,7 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty, MethodDecl->getParent()); MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext(); - MicrosoftVTableContext::MethodVFTableLocation ML = - VFTContext.getMethodVFTableLocation(GD); + const MethodVFTableLocation &ML = VFTContext.getMethodVFTableLocation(GD); // Compute the identity of the most derived class whose virtual table is // located at the MethodVFTableLocation ML. @@ -1937,16 +1935,16 @@ MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) { return VBGlobals; } -llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk( - const CXXMethodDecl *MD, - const MicrosoftVTableContext::MethodVFTableLocation &ML) { +llvm::Function * +MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, + const MethodVFTableLocation &ML) { assert(!isa(MD) && !isa(MD) && "can't form pointers to ctors or virtual dtors"); // Calculate the mangled name. SmallString<256> ThunkName; llvm::raw_svector_ostream Out(ThunkName); - getMangleContext().mangleVirtualMemPtrThunk(MD, Out); + getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out); // If the thunk has been generated previously, just return it. if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName)) @@ -2760,7 +2758,7 @@ MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { FirstField = CGM.GetAddrOfFunction(MD, Ty); } else { auto &VTableContext = CGM.getMicrosoftVTableContext(); - MicrosoftVTableContext::MethodVFTableLocation ML = + const MethodVFTableLocation &ML = VTableContext.getMethodVFTableLocation(MD); FirstField = EmitVirtualMemPtrThunk(MD, ML); // Include the vfptr adjustment if the method is in a non-primary vftable.