]> granicus.if.org Git - clang/commitdiff
Add CodeGenTypes::GetFunctionType overload for getting the effective
authorDaniel Dunbar <daniel@zuster.org>
Wed, 10 Sep 2008 07:00:50 +0000 (07:00 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 10 Sep 2008 07:00:50 +0000 (07:00 +0000)
type of a call.

Change NeXT runtime to use this instead of trying to bitcasting
internally (which doesn't respect the ABI).

Fix subtle bug, use of ConvertTypeRecursive instead of ConvertType is
bad inside GetFunctionType.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56050 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CodeGenTypes.h

index b684b4463ee3f754f548ac3964dae1b1a7cabb3f..473abd5d8be816202371b40501619d89e7716d24 100644 (file)
@@ -143,13 +143,23 @@ static ABIArgInfo classifyReturnType(QualType RetTy) {
 
 /***/
 
+const llvm::FunctionType *
+CodeGenTypes::GetFunctionType(const CGCallInfo &CI, bool IsVariadic) {
+  return GetFunctionType(CI.argtypes_begin(), CI.argtypes_end(), IsVariadic);
+}
+
 const llvm::FunctionType *
 CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
+  return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), FI.isVariadic());
+}
+
+const llvm::FunctionType *
+CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
+                              bool IsVariadic) {
   std::vector<const llvm::Type*> ArgTys;
 
   const llvm::Type *ResultType = 0;
 
-  ArgTypeIterator begin = FI.argtypes_begin(), end = FI.argtypes_end();
   QualType RetTy = *begin;
   ABIArgInfo RetAI = classifyReturnType(RetTy);
   switch (RetAI.getKind()) {    
@@ -157,25 +167,25 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
     if (RetTy->isVoidType()) {
       ResultType = llvm::Type::VoidTy;
     } else {
-      ResultType = ConvertTypeRecursive(RetTy);
+      ResultType = ConvertType(RetTy);
     }
     break;
 
   case ABIArgInfo::StructRet: {
     ResultType = llvm::Type::VoidTy;
-    const llvm::Type *STy = ConvertTypeRecursive(RetTy);
+    const llvm::Type *STy = ConvertType(RetTy);
     ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
     break;
   }
 
   case ABIArgInfo::Coerce:
     ResultType = llvm::Type::VoidTy;
-    ArgTys.push_back(ConvertTypeRecursive(RetAI.getCoerceToType()));
+    ArgTys.push_back(ConvertType(RetAI.getCoerceToType()));
     break;
   }
   
   for (++begin; begin != end; ++begin) {
-    const llvm::Type *Ty = ConvertTypeRecursive(*begin);
+    const llvm::Type *Ty = ConvertType(*begin);
     if (Ty->isSingleValueType())
       ArgTys.push_back(Ty);
     else
@@ -183,9 +193,10 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
       ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
   }
 
-  return llvm::FunctionType::get(ResultType, ArgTys, FI.isVariadic());
+  return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
 }
 
+// FIXME: This can die now?
 bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
   return classifyReturnType(RetTy).isStructRet();
 }
index d63004f2121843dc8cfb9b6ac223b8e41b8d470e..42f8ef71dee3a06da676dd3daab916e881fd910d 100644 (file)
@@ -158,8 +158,7 @@ public:
   ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
   ~ObjCTypesHelper();
   
-  llvm::Value *getMessageSendFn(bool IsSuper, bool isStret, 
-                                const llvm::Type *ReturnTy);
+  llvm::Constant *getMessageSendFn(bool IsSuper, bool isStret);
 };
 
 class CGObjCMac : public CodeGen::CGObjCRuntime {
@@ -529,10 +528,12 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
                                       CGF.getContext().getObjCSelType()));
   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
 
-  llvm::Value *Fn = 
-    ObjCTypes.getMessageSendFn(IsSuper, 
-                               CGM.ReturnTypeUsesSret(ResultType),
-                               CGM.getTypes().ConvertType(ResultType));
+  const llvm::FunctionType *FTy = 
+    CGM.getTypes().GetFunctionType(CGCallInfo(ResultType, ActualArgs),
+                                   false);
+  llvm::Constant *Fn = 
+    ObjCTypes.getMessageSendFn(IsSuper, CGM.ReturnTypeUsesSret(ResultType));
+  Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
   return CGF.EmitCall(Fn, ResultType, ActualArgs);
 }
 
@@ -2199,30 +2200,12 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
 ObjCTypesHelper::~ObjCTypesHelper() {
 }
 
-llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper, 
-                                               bool IsStret,
-                                               const llvm::Type *ReturnTy) {
-  llvm::Function *F;
-  llvm::FunctionType *CallFTy;
-  
-  // FIXME: Should we be caching any of this?
+llvm::Constant *ObjCTypesHelper::getMessageSendFn(bool IsSuper, bool IsStret) {
   if (IsStret) {
-    F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
-    std::vector<const llvm::Type*> Params(3);
-    Params[0] = llvm::PointerType::getUnqual(ReturnTy);
-    Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
-    Params[2] = SelectorPtrTy;
-    CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
+    return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
   } else { // FIXME: floating point?
-    F = IsSuper ? MessageSendSuperFn : MessageSendFn;
-    std::vector<const llvm::Type*> Params(2);
-    Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
-    Params[1] = SelectorPtrTy;
-    CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
+    return IsSuper ? MessageSendSuperFn : MessageSendFn;
   }
-
-  return llvm::ConstantExpr::getBitCast(F, 
-                                        llvm::PointerType::getUnqual(CallFTy));
 }
 
 /* *** */
index d89dfa6d0fc816a789b97269868313b6101cb03f..f9cc4ef08f2720cc143192576b0473cf3e2af9bd 100644 (file)
@@ -18,6 +18,8 @@
 #include "llvm/ADT/SmallSet.h"
 #include <vector>
 
+#include "CGCall.h"
+
 namespace llvm {
   class FunctionType;
   class Module;
@@ -42,7 +44,6 @@ namespace clang {
   class Type;
 
 namespace CodeGen {
-  class CGFunctionInfo;
   class CodeGenTypes;
 
   /// CGRecordLayout - This class handles struct and union layout info while 
@@ -143,6 +144,17 @@ public:
 
   /// GetFunctionType - Get the LLVM function type from Info.
   const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);
+  /// GetFunctionType - Get the LLVM function type from Info. 
+  /// \param IsVariadic Should the resulting type be variadic?
+  const llvm::FunctionType *GetFunctionType(const CGCallInfo &Info,
+                                            bool IsVariadic);
+
+  /// GetFunctionType - Get the LLVM function type for the given types
+  /// and variadicness.
+  // FIXME: Do we even need IsVariadic here?
+  const llvm::FunctionType *GetFunctionType(ArgTypeIterator begin,
+                                            ArgTypeIterator end,
+                                            bool IsVariadic);
   
   void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
                             std::vector<const llvm::Type*> &IvarTypes);