]> granicus.if.org Git - clang/commitdiff
Add a ThunkAdjustment struct which holds a non-virtual and a virtual adjustment offse...
authorAnders Carlsson <andersca@mac.com>
Thu, 26 Nov 2009 02:32:05 +0000 (02:32 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 26 Nov 2009 02:32:05 +0000 (02:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89925 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGVtable.cpp
lib/CodeGen/CGVtable.h
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.h
lib/CodeGen/Mangle.cpp
lib/CodeGen/Mangle.h

index 71cdf95f48beff3590ca183125e672fa785be0cb..96741468259746630376c727c55bd6eabd39d911 100644 (file)
@@ -819,11 +819,13 @@ const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
   return UniqueMangledName(Name.begin(), Name.end());
 }
 
-llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
-                                               const CXXMethodDecl *MD,
-                                               bool Extern, int64_t nv,
-                                               int64_t v) {
-  return GenerateCovariantThunk(Fn, MD, Extern, nv, v, 0, 0);
+llvm::Constant *
+CodeGenFunction::GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
+                               bool Extern, 
+                               const ThunkAdjustment &ThisAdjustment) {
+  return GenerateCovariantThunk(Fn, MD, Extern, 
+                                ThisAdjustment.NonVirtual,
+                                ThisAdjustment.Virtual, 0, 0);
 }
 
 llvm::Value *CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, int64_t nv,
@@ -961,10 +963,14 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
   return Fn;
 }
 
-llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
-                                          int64_t nv, int64_t v) {
+llvm::Constant *
+CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
+                          const ThunkAdjustment &ThisAdjustment) {
+  
   llvm::SmallString<256> OutName;
-  getMangleContext().mangleThunk(MD, nv, v, OutName);
+  getMangleContext().mangleThunk(MD, ThisAdjustment.NonVirtual,
+                                 ThisAdjustment.Virtual, OutName);
+  
   llvm::GlobalVariable::LinkageTypes linktype;
   linktype = llvm::GlobalValue::WeakAnyLinkage;
   if (!Extern)
@@ -977,7 +983,7 @@ llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
 
   llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(),
                                               &getModule());
-  CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, nv, v);
+  CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, ThisAdjustment);
   llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
   return m;
 }
index 0c36ef492b39c1ad08da1e2f40cb4e665b7ca415..08690f23a8a8130eb2d1f2e951bb7f60f356eda8 100644 (file)
@@ -333,7 +333,8 @@ public:
       Index_t idx = Index[GD];
       Index_t nv_O = i->second.first;
       Index_t v_O = i->second.second;
-      submethods[idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
+      submethods[idx] = CGM.BuildThunk(MD, Extern, 
+                                       ThunkAdjustment(nv_O, v_O));
     }
     Thunks.clear();
     for (CovariantThunks_t::iterator i = CovariantThunks.begin(),
index 78ae670cf35af9c421078ee5fd79c9acb897de17..af718b36328e510a33c8c38b75526758b2795d3c 100644 (file)
@@ -23,7 +23,28 @@ namespace clang {
   
 namespace CodeGen {
   class CodeGenModule;
+
+/// ThunkAdjustment - Virtual and non-virtual adjustment for thunks. 
+struct ThunkAdjustment {
+  ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
+  : NonVirtual(NonVirtual), 
+    Virtual(Virtual) { }
+  
+  ThunkAdjustment()
+    : NonVirtual(0), Virtual(0) { }
+  
+  // isEmpty - Return whether this thunk adjustment is empty.
+  bool isEmpty() const { 
+    return NonVirtual == 0 && Virtual == 0;
+  }
   
+  /// NonVirtual - The non-virtual adjustment.
+  int64_t NonVirtual;
+  
+  /// Virtual - The virtual adjustment.
+  int64_t Virtual;
+};
+
 class CGVtableInfo {
   CodeGenModule &CGM;
   
index 28e000a49208588c00bbd39387da6674aa1c41fc..b811c25b8a8d09d6901bec073f10aa5ebb5240f7 100644 (file)
@@ -441,7 +441,8 @@ public:
 
   /// GenerateThunk - Generate a thunk for the given method
   llvm::Constant *GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
-                                bool Extern, int64_t nv, int64_t v);
+                                bool Extern, 
+                                const ThunkAdjustment &ThisAdjustment);
   llvm::Constant *GenerateCovariantThunk(llvm::Function *Fn,
                                          const CXXMethodDecl *MD, bool Extern,
                                          int64_t nv_t, int64_t v_t,
index 64314d3fbec86a3eb3ff1d411f167cc643af8dfc..bc2d73edc1d9a209da37fb7b44c7745f311f419c 100644 (file)
@@ -233,9 +233,10 @@ public:
   /// non-class type.
   llvm::Constant *GenerateRtti(QualType Ty);
 
-  /// BuildThunk - Build a thunk for the given method
-  llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, int64_t nv,
-                             int64_t v);
+  /// BuildThunk - Build a thunk for the given method.
+  llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, 
+                             const ThunkAdjustment &ThisAdjustment);
+
   /// BuildCoVariantThunk - Build a thunk for the given method
   llvm::Constant *BuildCovariantThunk(const CXXMethodDecl *MD, bool Extern,
                                       int64_t nv_t, int64_t v_t,
index b09b27f489ac0b0dac93bd40307c0e6055d5aeb9..e2ae86bd45148bcc5aa07e8f75d7b2bb3c0cc303 100644 (file)
@@ -67,7 +67,9 @@ public:
   llvm::raw_svector_ostream &getStream() { return Out; }
 
   void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z");
-  void mangleCalloffset(int64_t nv, int64_t v);
+  void mangleCallOffset(int64_t NonVirtualOffset, 
+                        int64_t VirtualOffset);
+  void mangleNumber(int64_t Number);
   void mangleFunctionEncoding(const FunctionDecl *FD);
   void mangleName(const NamedDecl *ND);
   void mangleType(QualType T);
@@ -336,34 +338,35 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {
   addSubstitution(ND);
 }
 
-void CXXNameMangler::mangleCalloffset(int64_t nv, int64_t v) {
+void CXXNameMangler::mangleNumber(int64_t Number) {
+  //  <number> ::= [n] <non-negative decimal integer>
+  if (Number < 0) {
+    Out << 'n';
+    Number = -Number;
+  }
+  
+  Out << Number;
+}
+
+void CXXNameMangler::mangleCallOffset(int64_t NonVirtualOffset, 
+                                      int64_t VirtualOffset) {
   //  <call-offset>  ::= h <nv-offset> _
   //                 ::= v <v-offset> _
   //  <nv-offset>    ::= <offset number>        # non-virtual base override
-  //  <v-offset>     ::= <offset nubmer> _ <virtual offset number>
+  //  <v-offset>     ::= <offset number> _ <virtual offset number>
   //                      # virtual base override, with vcall offset
-  if (v == 0) {
-    Out << "h";
-    if (nv < 0) {
-      Out << "n";
-      nv = -nv;
-    }
-    Out << nv;
-  } else {
-    Out << "v";
-    if (nv < 0) {
-      Out << "n";
-      nv = -nv;
-    }
-    Out << nv;
-    Out << "_";
-    if (v < 0) {
-      Out << "n";
-      v = -v;
-    }
-    Out << v;
+  if (!VirtualOffset) {
+    Out << 'h';
+    mangleNumber(NonVirtualOffset);
+    Out << '_';
+    return;
   }
-  Out << "_";
+  
+  Out << 'v';
+  mangleNumber(NonVirtualOffset);
+  Out << '_';
+  mangleNumber(VirtualOffset);
+  Out << '_';
 }
 
 void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
@@ -1351,7 +1354,9 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
 
 /// \brief Mangles the a thunk with the offset n for the declaration D and
 /// emits that name to the given output stream.
-void MangleContext::mangleThunk(const FunctionDecl *FD, int64_t nv, int64_t v,
+void MangleContext::mangleThunk(const FunctionDecl *FD, 
+                                int64_t NonVirtualOffset, 
+                                int64_t VirtualOffset,
                                 llvm::SmallVectorImpl<char> &Res) {
   // FIXME: Hum, we might have to thunk these, fix.
   assert(!isa<CXXDestructorDecl>(FD) &&
@@ -1361,7 +1366,7 @@ void MangleContext::mangleThunk(const FunctionDecl *FD, int64_t nv, int64_t v,
   //                      # base is the nominal target function of thunk
   CXXNameMangler Mangler(*this, Res);
   Mangler.getStream() << "_ZT";
-  Mangler.mangleCalloffset(nv, v);
+  Mangler.mangleCallOffset(NonVirtualOffset, VirtualOffset);
   Mangler.mangleFunctionEncoding(FD);
 }
 
@@ -1380,8 +1385,8 @@ void MangleContext::mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t,
   //                      # second call-offset is result adjustment
   CXXNameMangler Mangler(*this, Res);
   Mangler.getStream() << "_ZTc";
-  Mangler.mangleCalloffset(nv_t, v_t);
-  Mangler.mangleCalloffset(nv_r, v_r);
+  Mangler.mangleCallOffset(nv_t, v_t);
+  Mangler.mangleCallOffset(nv_r, v_r);
   Mangler.mangleFunctionEncoding(FD);
 }
 
index edbbff5161927ca787bfac284ee92f23b032acd5..15951fe87607731f837db2532e769f1f84fd9d6c 100644 (file)
@@ -61,7 +61,8 @@ public:
   bool shouldMangleDeclName(const NamedDecl *D);
 
   void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
-  void mangleThunk(const FunctionDecl *FD, int64_t n, int64_t vn,
+  void mangleThunk(const FunctionDecl *FD, 
+                   int64_t NonVirtualOffset, int64_t VirtualOffset,
                    llvm::SmallVectorImpl<char> &);
   void mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t, int64_t v_t,
                             int64_t nv_r, int64_t v_r,