[cfe-commits] r81014 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CodeGenFunction.h CodeGenModule.h

Mike Stump mrs at apple.com
Fri Sep 4 11:27:16 PDT 2009


Author: mrs
Date: Fri Sep  4 13:27:16 2009
New Revision: 81014

URL: http://llvm.org/viewvc/llvm-project?rev=81014&view=rev
Log:
Add overidding for methods for vtable building for the secondary
vtables.  Add thunk generation.  WIP.

Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=81014&r1=81013&r2=81014&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Sep  4 13:27:16 2009
@@ -246,8 +246,8 @@
   
   const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
   const llvm::Type *Ty = 
-  CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 
-                                 FPT->isVariadic());
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 
+                                   FPT->isVariadic());
   llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
   
   llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
@@ -849,13 +849,15 @@
   llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
   std::vector<Index_t> VCalls;
   typedef CXXRecordDecl::method_iterator method_iter;
+  // FIXME: Linkage should follow vtable
+  const bool Extern;
 public:
   VtableBuilder(std::vector<llvm::Constant *> &meth,
                 const CXXRecordDecl *c,
                 CodeGenModule &cgm)
     : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
       rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
-      CGM(cgm) {
+      CGM(cgm), Extern(true) {
     Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
   }
 
@@ -893,7 +895,9 @@
   }
 
   bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
-                      bool MorallyVirtual, Index_t Offset) {
+                      bool MorallyVirtual, Index_t Offset,
+                      std::vector<llvm::Constant *> &submethods,
+                      Index_t AddressPoint) {
     typedef CXXMethodDecl::method_iterator meth_iter;
 
     // FIXME: Don't like the nested loops.  For very large inheritance
@@ -910,13 +914,18 @@
       om = CGM.GetAddrOfFunction(GlobalDecl(OMD), Ptr8Ty);
       om = llvm::ConstantExpr::getBitCast(om, Ptr8Ty);
 
-      for (Index_t i = 0, e = submethods.size();
+      for (Index_t i = AddressPoint, e = submethods.size();
            i != e; ++i) {
         // FIXME: begin_overridden_methods might be too lax, covariance */
         if (submethods[i] == om) {
+          int64_t O = VCallOffset[OMD] - Offset/8;
           // FIXME: thunks
-          submethods[i] = m;
-          Index[MD] = i;
+          if (O) {
+            submethods[i] = CGM.BuildThunk(MD, Extern, true, 0, O);
+          } else
+            submethods[i] = m;
+          // FIXME: audit
+          Index[MD] = i - AddressPoint;
           if (MorallyVirtual) {
             VCallOffset[MD] = Offset/8;
             VCalls[VCall[OMD]] = Offset/8 - VCallOffset[OMD];
@@ -937,14 +946,14 @@
       if (mi->isVirtual()) {
         const CXXMethodDecl *MD = *mi;
         llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
-        OverrideMethod(MD, m, MorallyVirtual, Offset);
+        OverrideMethod(MD, m, MorallyVirtual, Offset, methods, AddressPoint);
       }
   }
 
   void AddMethod(const CXXMethodDecl *MD, Index_t AddressPoint,
                  bool MorallyVirtual, Index_t Offset) {
     llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
-    if (OverrideMethod(MD, m, MorallyVirtual, Offset))
+    if (OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0))
       return;
     
     // else allocate a new slot.
@@ -1048,7 +1057,9 @@
       if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
         uint64_t o = Offset + Layout.getBaseClassOffset(Base);
         StartNewTable();
-        GenerateVtableForBase(Base, true, true, false, o, false);
+        Index_t AP;
+        AP = GenerateVtableForBase(Base, true, true, MorallyVirtual, o, false);
+        OverrideMethods(RD, AP, MorallyVirtual, o);
       }
     }
     return AddressPoint;
@@ -1065,7 +1076,9 @@
         IndirectPrimary.insert(Base);
         StartNewTable();
         int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
-        GenerateVtableForBase(Base, false, true, true, BaseOffset, true);
+        Index_t AP;
+        AP = GenerateVtableForBase(Base, false, true, true, BaseOffset, true);
+        OverrideMethods(RD, AP, true, BaseOffset);
       }
       if (Base->getNumVBases())
         GenerateVtableForVBases(Base, Class);
@@ -1145,6 +1158,62 @@
 // FIXME: move to Context
 static VtableInfo *vtableinfo;
 
+llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
+                                               const CXXMethodDecl *MD,
+                                               bool Extern, bool Virtual,
+                                               int64_t nv, int64_t v) {
+  QualType R = MD->getType()->getAsFunctionType()->getResultType();
+
+  FunctionArgList Args;
+  ImplicitParamDecl *ThisDecl =
+    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+                              MD->getThisType(getContext()));
+  Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType()));
+  for (FunctionDecl::param_const_iterator i = MD->param_begin(),
+         e = MD->param_end();
+       i != e; ++i) {
+    ParmVarDecl *D = *i;
+    Args.push_back(std::make_pair(D, D->getType()));
+  }
+  IdentifierInfo *II
+    = &CGM.getContext().Idents.get("__thunk_named_foo_");
+  FunctionDecl *FD = FunctionDecl::Create(getContext(),
+                                          getContext().getTranslationUnitDecl(),
+                                          SourceLocation(), II, R, 0,
+                                          Extern
+                                            ? FunctionDecl::Extern
+                                            : FunctionDecl::Static,
+                                          false, true);
+  StartFunction(FD, R, Fn, Args, SourceLocation());
+  // FIXME: generate body
+  FinishFunction();
+  return Fn;
+}
+
+llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD,
+                                          bool Extern, bool Virtual, int64_t nv,
+                                          int64_t v) {
+  llvm::SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  mangleThunk(MD, Virtual, nv, v, getContext(), Out);
+  llvm::GlobalVariable::LinkageTypes linktype;
+  linktype = llvm::GlobalValue::WeakAnyLinkage;
+  if (!Extern)
+    linktype = llvm::GlobalValue::InternalLinkage;
+  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
+  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
+  const llvm::FunctionType *FTy =
+    getTypes().GetFunctionType(getTypes().getFunctionInfo(MD),
+                               FPT->isVariadic());
+
+  llvm::Function *Fn = llvm::Function::Create(FTy, linktype, Out.str(),
+                                              &getModule());
+  CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, Virtual, nv, v);
+  // Fn = Builder.CreateBitCast(Fn, Ptr8Ty);
+  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
+  return m;
+}
+
 llvm::Value *
 CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
                                   const llvm::Type *Ty) {
@@ -1309,8 +1378,7 @@
     // Push the Src ptr.
     CallArgs.push_back(std::make_pair(RValue::get(Src),
                                       MD->getParamDecl(0)->getType()));
-    QualType ResultType =
-    MD->getType()->getAsFunctionType()->getResultType();
+    QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
     EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
              Callee, CallArgs, MD);
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=81014&r1=81013&r2=81014&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Sep  4 13:27:16 2009
@@ -364,6 +364,11 @@
   /// GenerateVtable - Generate the vtable for the given type.
   llvm::Value *GenerateVtable(const CXXRecordDecl *RD);
 
+  /// GenerateThunk - Generate a thunk for the given method
+  llvm::Constant *GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
+                                bool Extern, bool Virtual, int64_t nv,
+                                int64_t v);
+
   void EmitCtorPrologue(const CXXConstructorDecl *CD);
   
   void SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=81014&r1=81013&r2=81014&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Sep  4 13:27:16 2009
@@ -235,6 +235,10 @@
   /// GenerateRtti - Generate the rtti information for the given type.
   llvm::Constant *GenerateRtti(const CXXRecordDecl *RD);
 
+  /// BuildThunk - Build a thunk for the given method
+  llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, bool Virtual,
+                             int64_t nv, int64_t v);
+
   /// GetStringForStringLiteral - Return the appropriate bytes for a string
   /// literal, properly padded to match the literal type. If only the address of
   /// a constant is needed consider using GetAddrOfConstantStringLiteral.





More information about the cfe-commits mailing list