Hoist MethodVFTableLocation out of MicrosoftVTableContext, NFC
authorReid Kleckner <rnk@google.com>
Thu, 29 Mar 2018 22:42:24 +0000 (22:42 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 29 Mar 2018 22:42:24 +0000 (22:42 +0000)
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.

llvm-svn: 328845

clang/include/clang/AST/Mangle.h
clang/include/clang/AST/VTableBuilder.h
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/AST/VTableBuilder.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/MicrosoftCXXABI.cpp

index 7a45d88..71c78dc 100644 (file)
@@ -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,
index b0b71e4..96565fa 100644 (file)
@@ -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;
index 785ee3a..06936f0 100644 (file)
@@ -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<MicrosoftVTableContext>(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<MicrosoftVTableContext>(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() << '?';
index a95791c..5f1ccdf 100644 (file)
@@ -2367,8 +2367,6 @@ namespace {
 
 class VFTableBuilder {
 public:
-  typedef MicrosoftVTableContext::MethodVFTableLocation MethodVFTableLocation;
-
   typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
     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<CXXMethodDecl>(GD.getDecl())->isVirtual() &&
          "Only use this method for virtual methods or dtors");
index 42c0210..0f7ac72 100644 (file)
@@ -1416,7 +1416,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
       // deleting dtor.
       const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
       GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method);
-      MicrosoftVTableContext::MethodVFTableLocation ML =
+      const MethodVFTableLocation &ML =
           CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
       VIndex = ML.Index;
 
index 542e1bf..e80c3b3 100644 (file)
@@ -230,7 +230,7 @@ public:
   getThisArgumentTypeForMethod(const CXXMethodDecl *MD) override {
     MD = MD->getCanonicalDecl();
     if (MD->isVirtual() && !isa<CXXDestructorDecl>(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<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(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.