Distinguish more carefully between free functions and C++ instance methods

in the ABI arrangement, and leave a hook behind so that we can easily
tweak CCs on platforms that use different CCs by default for C++
instance methods.

llvm-svn: 159894
This commit is contained in:
John McCall 2012-07-07 06:41:13 +00:00
parent 30105f67b4
commit 8dda7b27ee
12 changed files with 216 additions and 156 deletions

View File

@ -876,7 +876,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E,
const FunctionType *FuncTy = FnType->castAs<FunctionType>();
const CGFunctionInfo &FnInfo =
CGM.getTypes().arrangeFunctionCall(Args, FuncTy);
CGM.getTypes().arrangeFreeFunctionCall(Args, FuncTy);
// Cast the function pointer to the right type.
llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo);

View File

@ -984,9 +984,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)),
getContext().VoidPtrTy);
const CGFunctionInfo &FuncInfo =
CGM.getTypes().arrangeFunctionCall(E->getType(), Args,
FunctionType::ExtInfo(),
RequiredArgs::All);
CGM.getTypes().arrangeFreeFunctionCall(E->getType(), Args,
FunctionType::ExtInfo(),
RequiredArgs::All);
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
return EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);

View File

@ -67,39 +67,64 @@ static CanQualType GetReturnType(QualType RetTy) {
return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType();
}
/// Arrange the argument and result information for a value of the
/// given unprototyped function type.
/// Arrange the argument and result information for a value of the given
/// unprototyped freestanding function type.
const CGFunctionInfo &
CodeGenTypes::arrangeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
// When translating an unprototyped function type, always use a
// variadic type.
return arrangeFunctionType(FTNP->getResultType().getUnqualifiedType(),
ArrayRef<CanQualType>(),
FTNP->getExtInfo(),
RequiredArgs(0));
return arrangeLLVMFunctionInfo(FTNP->getResultType().getUnqualifiedType(),
ArrayRef<CanQualType>(),
FTNP->getExtInfo(),
RequiredArgs(0));
}
/// Arrange the argument and result information for a value of the
/// given function type, on top of any implicit parameters already
/// stored.
static const CGFunctionInfo &arrangeFunctionType(CodeGenTypes &CGT,
SmallVectorImpl<CanQualType> &argTypes,
CanQual<FunctionProtoType> FTP) {
RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size());
/// Arrange the LLVM function layout for a value of the given function
/// type, on top of any implicit parameters already stored. Use the
/// given ExtInfo instead of the ExtInfo from the function type.
static const CGFunctionInfo &arrangeLLVMFunctionInfo(CodeGenTypes &CGT,
SmallVectorImpl<CanQualType> &prefix,
CanQual<FunctionProtoType> FTP,
FunctionType::ExtInfo extInfo) {
RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
// FIXME: Kill copy.
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
argTypes.push_back(FTP->getArgType(i));
prefix.push_back(FTP->getArgType(i));
CanQualType resultType = FTP->getResultType().getUnqualifiedType();
return CGT.arrangeFunctionType(resultType, argTypes,
FTP->getExtInfo(), required);
return CGT.arrangeLLVMFunctionInfo(resultType, prefix, extInfo, required);
}
/// Arrange the argument and result information for a free function (i.e.
/// not a C++ or ObjC instance method) of the given type.
static const CGFunctionInfo &arrangeFreeFunctionType(CodeGenTypes &CGT,
SmallVectorImpl<CanQualType> &prefix,
CanQual<FunctionProtoType> FTP) {
return arrangeLLVMFunctionInfo(CGT, prefix, FTP, FTP->getExtInfo());
}
/// Given the formal ext-info of a C++ instance method, adjust it
/// according to the C++ ABI in effect.
static void adjustCXXMethodInfo(CodeGenTypes &CGT,
FunctionType::ExtInfo &extInfo) {
// FIXME: thiscall on Microsoft
}
/// Arrange the argument and result information for a free function (i.e.
/// not a C++ or ObjC instance method) of the given type.
static const CGFunctionInfo &arrangeCXXMethodType(CodeGenTypes &CGT,
SmallVectorImpl<CanQualType> &prefix,
CanQual<FunctionProtoType> FTP) {
FunctionType::ExtInfo extInfo = FTP->getExtInfo();
adjustCXXMethodInfo(CGT, extInfo);
return arrangeLLVMFunctionInfo(CGT, prefix, FTP, extInfo);
}
/// Arrange the argument and result information for a value of the
/// given function type.
/// given freestanding function type.
const CGFunctionInfo &
CodeGenTypes::arrangeFunctionType(CanQual<FunctionProtoType> FTP) {
CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) {
SmallVector<CanQualType, 16> argTypes;
return ::arrangeFunctionType(*this, argTypes, FTP);
return ::arrangeFreeFunctionType(*this, argTypes, FTP);
}
static CallingConv getCallingConventionForDecl(const Decl *D) {
@ -134,7 +159,7 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
// Add the 'this' pointer.
argTypes.push_back(GetThisType(Context, RD));
return ::arrangeFunctionType(*this, argTypes,
return ::arrangeCXXMethodType(*this, argTypes,
FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
}
@ -154,7 +179,7 @@ CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) {
return arrangeCXXMethodType(MD->getParent(), prototype.getTypePtr());
}
return arrangeFunctionType(prototype);
return arrangeFreeFunctionType(prototype);
}
/// Arrange the argument and result information for a declaration
@ -176,7 +201,9 @@ CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D,
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
argTypes.push_back(FTP->getArgType(i));
return arrangeFunctionType(resultType, argTypes, FTP->getExtInfo(), required);
FunctionType::ExtInfo extInfo = FTP->getExtInfo();
adjustCXXMethodInfo(*this, extInfo);
return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, required);
}
/// Arrange the argument and result information for a declaration,
@ -194,8 +221,10 @@ CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D,
CanQual<FunctionProtoType> FTP = GetFormalType(D);
assert(FTP->getNumArgs() == 0 && "dtor with formal parameters");
return arrangeFunctionType(resultType, argTypes, FTP->getExtInfo(),
RequiredArgs::All);
FunctionType::ExtInfo extInfo = FTP->getExtInfo();
adjustCXXMethodInfo(*this, extInfo);
return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo,
RequiredArgs::All);
}
/// Arrange the argument and result information for the declaration or
@ -214,14 +243,14 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
// non-variadic type.
if (isa<FunctionNoProtoType>(FTy)) {
CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>();
return arrangeFunctionType(noProto->getResultType(),
ArrayRef<CanQualType>(),
noProto->getExtInfo(),
RequiredArgs::All);
return arrangeLLVMFunctionInfo(noProto->getResultType(),
ArrayRef<CanQualType>(),
noProto->getExtInfo(),
RequiredArgs::All);
}
assert(isa<FunctionProtoType>(FTy));
return arrangeFunctionType(FTy.getAs<FunctionProtoType>());
return arrangeFreeFunctionType(FTy.getAs<FunctionProtoType>());
}
/// Arrange the argument and result information for the declaration or
@ -261,8 +290,8 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
RequiredArgs required =
(MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
return arrangeFunctionType(GetReturnType(MD->getResultType()), argTys,
einfo, required);
return arrangeLLVMFunctionInfo(GetReturnType(MD->getResultType()), argTys,
einfo, required);
}
const CGFunctionInfo &
@ -284,8 +313,8 @@ CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) {
/// because the function might be unprototyped, in which case it's
/// target-dependent in crazy ways.
const CGFunctionInfo &
CodeGenTypes::arrangeFunctionCall(const CallArgList &args,
const FunctionType *fnType) {
CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args,
const FunctionType *fnType) {
RequiredArgs required = RequiredArgs::All;
if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
if (proto->isVariadic())
@ -295,22 +324,39 @@ CodeGenTypes::arrangeFunctionCall(const CallArgList &args,
required = RequiredArgs(0);
}
return arrangeFunctionCall(fnType->getResultType(), args,
fnType->getExtInfo(), required);
return arrangeFreeFunctionCall(fnType->getResultType(), args,
fnType->getExtInfo(), required);
}
const CGFunctionInfo &
CodeGenTypes::arrangeFunctionCall(QualType resultType,
const CallArgList &args,
const FunctionType::ExtInfo &info,
RequiredArgs required) {
CodeGenTypes::arrangeFreeFunctionCall(QualType resultType,
const CallArgList &args,
FunctionType::ExtInfo info,
RequiredArgs required) {
// FIXME: Kill copy.
SmallVector<CanQualType, 16> argTypes;
for (CallArgList::const_iterator i = args.begin(), e = args.end();
i != e; ++i)
argTypes.push_back(Context.getCanonicalParamType(i->Ty));
return arrangeFunctionType(GetReturnType(resultType), argTypes, info,
required);
return arrangeLLVMFunctionInfo(GetReturnType(resultType), argTypes, info,
required);
}
/// Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo &
CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
const FunctionProtoType *FPT,
RequiredArgs required) {
// FIXME: Kill copy.
SmallVector<CanQualType, 16> argTypes;
for (CallArgList::const_iterator i = args.begin(), e = args.end();
i != e; ++i)
argTypes.push_back(Context.getCanonicalParamType(i->Ty));
FunctionType::ExtInfo info = FPT->getExtInfo();
adjustCXXMethodInfo(*this, info);
return arrangeLLVMFunctionInfo(GetReturnType(FPT->getResultType()),
argTypes, info, required);
}
const CGFunctionInfo &
@ -326,23 +372,23 @@ CodeGenTypes::arrangeFunctionDeclaration(QualType resultType,
RequiredArgs required =
(isVariadic ? RequiredArgs(args.size()) : RequiredArgs::All);
return arrangeFunctionType(GetReturnType(resultType), argTypes, info,
required);
return arrangeLLVMFunctionInfo(GetReturnType(resultType), argTypes, info,
required);
}
const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
return arrangeFunctionType(getContext().VoidTy, ArrayRef<CanQualType>(),
FunctionType::ExtInfo(), RequiredArgs::All);
return arrangeLLVMFunctionInfo(getContext().VoidTy, ArrayRef<CanQualType>(),
FunctionType::ExtInfo(), RequiredArgs::All);
}
/// Arrange the argument and result information for an abstract value
/// of a given function type. This is the method which all of the
/// above functions ultimately defer to.
const CGFunctionInfo &
CodeGenTypes::arrangeFunctionType(CanQualType resultType,
ArrayRef<CanQualType> argTypes,
const FunctionType::ExtInfo &info,
RequiredArgs required) {
CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs required) {
#ifndef NDEBUG
for (ArrayRef<CanQualType>::const_iterator
I = argTypes.begin(), E = argTypes.end(); I != E; ++I)

View File

@ -1310,8 +1310,8 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
EmitCallArg(Args, *Arg, ArgType);
}
EmitCall(CGM.getTypes().arrangeFunctionCall(Args, FPT), Callee,
ReturnValueSlot(), Args, D);
EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, RequiredArgs::All),
Callee, ReturnValueSlot(), Args, D);
}
void
@ -1744,38 +1744,42 @@ CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,
return CGM.GetAddrOfFunction(MD, fnType);
}
void CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *Lambda,
CallArgList &CallArgs) {
void CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *lambda,
CallArgList &callArgs) {
// Lookup the call operator
DeclarationName Name
DeclarationName operatorName
= getContext().DeclarationNames.getCXXOperatorName(OO_Call);
DeclContext::lookup_const_result Calls = Lambda->lookup(Name);
CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(*Calls.first++);
const FunctionProtoType *FPT =
CallOperator->getType()->getAs<FunctionProtoType>();
QualType ResultType = FPT->getResultType();
CXXMethodDecl *callOperator =
cast<CXXMethodDecl>(*lambda->lookup(operatorName).first);
// Get the address of the call operator.
GlobalDecl GD(CallOperator);
const CGFunctionInfo &CalleeFnInfo =
CGM.getTypes().arrangeFunctionCall(ResultType, CallArgs, FPT->getExtInfo(),
RequiredArgs::forPrototypePlus(FPT, 1));
llvm::Type *Ty = CGM.getTypes().GetFunctionType(CalleeFnInfo);
llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty);
const CGFunctionInfo &calleeFnInfo =
CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
llvm::Value *callee =
CGM.GetAddrOfFunction(GlobalDecl(callOperator),
CGM.getTypes().GetFunctionType(calleeFnInfo));
// Determine whether we have a return value slot to use.
ReturnValueSlot Slot;
if (!ResultType->isVoidType() &&
CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
hasAggregateLLVMType(CurFnInfo->getReturnType()))
Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
// Prepare the return slot.
const FunctionProtoType *FPT =
callOperator->getType()->castAs<FunctionProtoType>();
QualType resultType = FPT->getResultType();
ReturnValueSlot returnSlot;
if (!resultType->isVoidType() &&
calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
hasAggregateLLVMType(calleeFnInfo.getReturnType()))
returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified());
// We don't need to separately arrange the call arguments because
// the call can't be variadic anyway --- it's impossible to forward
// variadic arguments.
// Now emit our call.
RValue RV = EmitCall(CalleeFnInfo, Callee, Slot, CallArgs, CallOperator);
RValue RV = EmitCall(calleeFnInfo, callee, returnSlot,
callArgs, callOperator);
// Forward the returned value
if (!ResultType->isVoidType() && Slot.isNull())
EmitReturnOfRValue(RV, ResultType);
// If necessary, copy the returned value into the slot.
if (!resultType->isVoidType() && returnSlot.isNull())
EmitReturnOfRValue(RV, resultType);
}
void CodeGenFunction::EmitLambdaBlockInvokeBody() {

View File

@ -2717,7 +2717,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
const CGFunctionInfo &FnInfo =
CGM.getTypes().arrangeFunctionCall(Args, FnType);
CGM.getTypes().arrangeFreeFunctionCall(Args, FnType);
// C99 6.5.2.2p6:
// If the expression that denotes the called function has a type
@ -3107,7 +3107,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
getContext().IntTy);
const CGFunctionInfo &FuncInfo =
CGM.getTypes().arrangeFunctionCall(RetTy, Args,
CGM.getTypes().arrangeFreeFunctionCall(RetTy, Args,
FunctionType::ExtInfo(), RequiredArgs::All);
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);

View File

@ -50,9 +50,7 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
// And the rest of the call args.
EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
return EmitCall(CGM.getTypes().arrangeFunctionCall(FPT->getResultType(), Args,
FPT->getExtInfo(),
required),
return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required),
Callee, ReturnValue, Args, MD);
}
@ -343,10 +341,12 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
// Push the this ptr.
Args.add(RValue::get(This), ThisType);
RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, 1);
// And the rest of the call args
EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end());
return EmitCall(CGM.getTypes().arrangeFunctionCall(Args, FPT), Callee,
return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), Callee,
ReturnValue, Args);
}
@ -1029,7 +1029,7 @@ namespace {
DeleteArgs.add(getPlacementArgs()[I], *AI++);
// Call 'operator delete'.
CGF.EmitCall(CGF.CGM.getTypes().arrangeFunctionCall(DeleteArgs, FPT),
CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT),
CGF.CGM.GetAddrOfFunction(OperatorDelete),
ReturnValueSlot(), DeleteArgs, OperatorDelete);
}
@ -1090,7 +1090,7 @@ namespace {
}
// Call 'operator delete'.
CGF.EmitCall(CGF.CGM.getTypes().arrangeFunctionCall(DeleteArgs, FPT),
CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT),
CGF.CGM.GetAddrOfFunction(OperatorDelete),
ReturnValueSlot(), DeleteArgs, OperatorDelete);
}
@ -1205,8 +1205,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
// TODO: kill any unnecessary computations done for the size
// argument.
} else {
RV = EmitCall(CGM.getTypes().arrangeFunctionCall(allocatorArgs,
allocatorType),
RV = EmitCall(CGM.getTypes().arrangeFreeFunctionCall(allocatorArgs,
allocatorType),
CGM.GetAddrOfFunction(allocator), ReturnValueSlot(),
allocatorArgs, allocator);
}
@ -1329,7 +1329,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
DeleteArgs.add(RValue::get(Size), SizeTy);
// Emit the call to delete.
EmitCall(CGM.getTypes().arrangeFunctionCall(DeleteArgs, DeleteFTy),
EmitCall(CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, DeleteFTy),
CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(),
DeleteArgs, DeleteFD);
}
@ -1485,7 +1485,7 @@ namespace {
}
// Emit the call to delete.
CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(Args, DeleteFTy),
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Args, DeleteFTy),
CGF.CGM.GetAddrOfFunction(OperatorDelete),
ReturnValueSlot(), Args, OperatorDelete);
}

View File

@ -507,9 +507,9 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
llvm::Value *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(Context.VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Context.VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
fn, ReturnValueSlot(), args);
}
@ -764,9 +764,10 @@ static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
llvm::Value *copyCppAtomicObjectFn =
CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(CGF.getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
args,
FunctionType::ExtInfo(),
RequiredArgs::All),
copyCppAtomicObjectFn, ReturnValueSlot(), args);
}
@ -852,9 +853,9 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
// FIXME: We shouldn't need to get the function info here, the
// runtime already should have computed it to build the function.
RValue RV = EmitCall(getTypes().arrangeFunctionCall(propType, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
RValue RV = EmitCall(getTypes().arrangeFreeFunctionCall(propType, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
getPropertyFn, ReturnValueSlot(), args);
// We need to fix the type here. Ivars with copy & retain are
@ -956,9 +957,10 @@ static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
llvm::Value *copyStructFn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(CGF.getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
args,
FunctionType::ExtInfo(),
RequiredArgs::All),
copyStructFn, ReturnValueSlot(), args);
}
@ -993,9 +995,10 @@ static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
llvm::Value *copyCppAtomicObjectFn =
CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(CGF.getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
args,
FunctionType::ExtInfo(),
RequiredArgs::All),
copyCppAtomicObjectFn, ReturnValueSlot(), args);
@ -1129,9 +1132,9 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
if (setOptimizedPropertyFn) {
args.add(RValue::get(arg), getContext().getObjCIdType());
args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
EmitCall(getTypes().arrangeFunctionCall(getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
EmitCall(getTypes().arrangeFreeFunctionCall(getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
setOptimizedPropertyFn, ReturnValueSlot(), args);
} else {
args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
@ -1142,9 +1145,9 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
getContext().BoolTy);
// FIXME: We shouldn't need to get the function info here, the runtime
// already should have computed it to build the function.
EmitCall(getTypes().arrangeFunctionCall(getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
EmitCall(getTypes().arrangeFreeFunctionCall(getContext().VoidTy, args,
FunctionType::ExtInfo(),
RequiredArgs::All),
setPropertyFn, ReturnValueSlot(), args);
}
@ -1507,9 +1510,9 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
Args2.add(RValue::get(V), getContext().getObjCIdType());
// FIXME: We shouldn't need to get the function info here, the runtime already
// should have computed it to build the function.
EmitCall(CGM.getTypes().arrangeFunctionCall(getContext().VoidTy, Args2,
FunctionType::ExtInfo(),
RequiredArgs::All),
EmitCall(CGM.getTypes().arrangeFreeFunctionCall(getContext().VoidTy, Args2,
FunctionType::ExtInfo(),
RequiredArgs::All),
EnumerationMutationFn, ReturnValueSlot(), Args2);
// Otherwise, or if the mutation function returns, just continue.

View File

@ -241,9 +241,9 @@ public:
Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
Params.push_back(Ctx.BoolTy);
llvm::FunctionType *FTy =
Types.GetFunctionType(Types.arrangeFunctionType(IdType, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
}
@ -261,9 +261,9 @@ public:
Params.push_back(Ctx.BoolTy);
Params.push_back(Ctx.BoolTy);
llvm::FunctionType *FTy =
Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
}
@ -287,9 +287,9 @@ public:
Params.push_back(IdType);
Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
llvm::FunctionType *FTy =
Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
const char *name;
if (atomic && copy)
name = "objc_setProperty_atomic_copy";
@ -314,9 +314,9 @@ public:
Params.push_back(Ctx.BoolTy);
Params.push_back(Ctx.BoolTy);
llvm::FunctionType *FTy =
Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
}
@ -333,9 +333,9 @@ public:
Params.push_back(Ctx.VoidPtrTy);
Params.push_back(Ctx.VoidPtrTy);
llvm::FunctionType *FTy =
Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
}
@ -346,7 +346,7 @@ public:
SmallVector<CanQualType,1> Params;
Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
llvm::FunctionType *FTy =
Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
FunctionType::ExtInfo(),
RequiredArgs::All));
return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");

View File

@ -358,17 +358,17 @@ CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
// Otherwise, there is.
FunctionType::ExtInfo einfo = signature.getExtInfo();
const CGFunctionInfo &argsInfo =
CGM.getTypes().arrangeFunctionCall(resultType, callArgs, einfo,
signature.getRequiredArgs());
CGM.getTypes().arrangeFreeFunctionCall(resultType, callArgs, einfo,
signature.getRequiredArgs());
return MessageSendInfo(argsInfo, signatureType);
}
// There's no method; just use a default CC.
const CGFunctionInfo &argsInfo =
CGM.getTypes().arrangeFunctionCall(resultType, callArgs,
FunctionType::ExtInfo(),
RequiredArgs::All);
CGM.getTypes().arrangeFreeFunctionCall(resultType, callArgs,
FunctionType::ExtInfo(),
RequiredArgs::All);
// Derive the signature to call from that.
llvm::PointerType *signatureType =

View File

@ -355,13 +355,14 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
#ifndef NDEBUG
const CGFunctionInfo &CallFnInfo =
CGM.getTypes().arrangeFunctionCall(ResultType, CallArgs, FPT->getExtInfo(),
const CGFunctionInfo &CallFnInfo =
CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT,
RequiredArgs::forPrototypePlus(FPT, 1));
assert(CallFnInfo.getRegParm() == FnInfo.getRegParm() &&
CallFnInfo.isNoReturn() == FnInfo.isNoReturn() &&
CallFnInfo.getCallingConvention() == FnInfo.getCallingConvention());
assert(similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types
similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
FnInfo.getReturnInfo(), FnInfo.getReturnType()));
assert(CallFnInfo.arg_size() == FnInfo.arg_size());
for (unsigned i = 0, e = FnInfo.arg_size(); i != e; ++i)

View File

@ -474,11 +474,11 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// build it.
const CGFunctionInfo *FI;
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
FI = &arrangeFunctionType(
FI = &arrangeFreeFunctionType(
CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)));
} else {
const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT);
FI = &arrangeFunctionType(
FI = &arrangeFreeFunctionType(
CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0)));
}

View File

@ -189,26 +189,32 @@ public:
const CGFunctionInfo &arrangeCXXDestructor(const CXXDestructorDecl *D,
CXXDtorType Type);
const CGFunctionInfo &arrangeFunctionCall(const CallArgList &Args,
const FunctionType *Ty);
const CGFunctionInfo &arrangeFunctionCall(QualType ResTy,
const CallArgList &args,
const FunctionType::ExtInfo &info,
RequiredArgs required);
const CGFunctionInfo &arrangeFreeFunctionCall(const CallArgList &Args,
const FunctionType *Ty);
const CGFunctionInfo &arrangeFreeFunctionCall(QualType ResTy,
const CallArgList &args,
FunctionType::ExtInfo info,
RequiredArgs required);
const CGFunctionInfo &arrangeFunctionType(CanQual<FunctionProtoType> Ty);
const CGFunctionInfo &arrangeFunctionType(CanQual<FunctionNoProtoType> Ty);
const CGFunctionInfo &arrangeCXXMethodCall(const CallArgList &args,
const FunctionProtoType *type,
RequiredArgs required);
const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty);
const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionNoProtoType> Ty);
const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
const FunctionProtoType *FTP);
/// Retrieves the ABI information for the given function signature.
/// This is the "core" routine to which all the others defer.
/// "Arrange" the LLVM information for a call or type with the given
/// signature. This is largely an internal method; other clients
/// should use one of the above routines, which ultimately defer to
/// this.
///
/// \param argTypes - must all actually be canonical as params
const CGFunctionInfo &arrangeFunctionType(CanQualType returnType,
ArrayRef<CanQualType> argTypes,
const FunctionType::ExtInfo &info,
RequiredArgs args);
const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args);
/// \brief Compute a new LLVM record layout object for the given record.
CGRecordLayout *ComputeRecordLayout(const RecordDecl *D,