/***/
+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()) {
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
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();
}
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 {
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);
}
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));
}
/* *** */
#include "llvm/ADT/SmallSet.h"
#include <vector>
+#include "CGCall.h"
+
namespace llvm {
class FunctionType;
class Module;
class Type;
namespace CodeGen {
- class CGFunctionInfo;
class CodeGenTypes;
/// CGRecordLayout - This class handles struct and union layout info while
/// 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);