From 62d5c1b5038cdaa4a887a03c37fe1e8d00166ea0 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 10 Sep 2008 07:00:50 +0000 Subject: [PATCH] Add CodeGenTypes::GetFunctionType overload for getting the effective 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 | 23 +++++++++++++++++------ lib/CodeGen/CGObjCMac.cpp | 37 ++++++++++--------------------------- lib/CodeGen/CodeGenTypes.h | 14 +++++++++++++- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index b684b4463e..473abd5d8b 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -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 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(); } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index d63004f212..42f8ef71de 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -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 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 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)); } /* *** */ diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index d89dfa6d0f..f9cc4ef08f 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -18,6 +18,8 @@ #include "llvm/ADT/SmallSet.h" #include +#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 &IvarTypes); -- 2.50.1