]> granicus.if.org Git - clang/commitdiff
More work on thunks.
authorAnders Carlsson <andersca@mac.com>
Wed, 17 Mar 2010 20:06:32 +0000 (20:06 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 17 Mar 2010 20:06:32 +0000 (20:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98765 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp

index 9bcf986af8427eff96191f51b08bf32f06209d82..b0c580faaabd5f263495daa36bb1cdf7112db9d4 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/ADT/SetVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Format.h"
+#include <algorithm>
 #include <cstdio>
 
 using namespace clang;
@@ -1147,6 +1148,12 @@ private:
     ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
     
     bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
+
+    friend bool operator==(const ReturnAdjustment &LHS, 
+                           const ReturnAdjustment &RHS) {
+      return LHS.NonVirtual == RHS.NonVirtual && 
+        LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
+    }
   };
   
   /// MethodInfo - Contains information about a method in a vtable.
@@ -1191,6 +1198,12 @@ private:
     ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
 
     bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
+
+    friend bool operator==(const ThisAdjustment &LHS, 
+                           const ThisAdjustment &RHS) {
+      return LHS.NonVirtual == RHS.NonVirtual && 
+        LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
+    }
   };
   
   /// ThunkInfo - The 'this' pointer adjustment as well as an optional return
@@ -1206,8 +1219,12 @@ private:
     
     ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
       : This(This), Return(Return) { }
-    
-    bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }    
+  
+    friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
+      return LHS.This == RHS.This && LHS.Return == RHS.Return;
+    }
+
+    bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
   };
   
   typedef llvm::DenseMap<uint64_t, ThunkInfo> ThunksInfoMapTy;
@@ -1215,6 +1232,15 @@ private:
   /// Thunks - The thunks by vtable index in the vtable currently being built.
   ThunksInfoMapTy Thunks;
 
+  typedef llvm::DenseMap<const CXXMethodDecl *,
+                         llvm::SmallVector<ThunkInfo, 1> > ThunksForMethodMapTy;
+  
+  /// ThunksPerMethod - The thunks for a given method.
+  ThunksForMethodMapTy ThunksForMethod;
+  
+  /// AddThunk - Add a thunk for the given method.
+  void AddThunk(const CXXMethodDecl *MD, ThunkInfo &Thunk);
+  
   /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the
   /// part of the vtable we're currently building.
   void ComputeThisAdjustments();
@@ -1330,6 +1356,17 @@ public:
   void dumpLayout(llvm::raw_ostream&);
 };
 
+void VtableBuilder::AddThunk(const CXXMethodDecl *MD, ThunkInfo &Thunk) {
+  llvm::SmallVector<ThunkInfo, 1> &ThunksVector = ThunksForMethod[MD];
+  
+  // Check if we have this thunk already.
+  if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 
+      ThunksVector.end())
+    return;
+  
+  ThunksVector.push_back(Thunk);
+}
+
 /// OverridesMethodInBases - Checks whether whether this virtual member 
 /// function overrides a member function in any of the given bases.
 /// Returns the overridden member function, or null if none was found.