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:
parent
30105f67b4
commit
8dda7b27ee
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue