diff options
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 97 |
1 files changed, 62 insertions, 35 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c052cf245c4..6403fa99aa7 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -83,14 +83,15 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) { // When translating an unprototyped function type, always use a // variadic type. return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(), - false, None, FTNP->getExtInfo(), - RequiredArgs(0)); + /*instanceMethod=*/false, + /*chainCall=*/false, None, + FTNP->getExtInfo(), RequiredArgs(0)); } /// Arrange the LLVM function layout for a value of the given function /// type, on top of any implicit parameters already stored. static const CGFunctionInfo & -arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool IsInstanceMethod, +arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod, SmallVectorImpl<CanQualType> &prefix, CanQual<FunctionProtoType> FTP) { RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, prefix.size()); @@ -98,7 +99,8 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool IsInstanceMethod, for (unsigned i = 0, e = FTP->getNumParams(); i != e; ++i) prefix.push_back(FTP->getParamType(i)); CanQualType resultType = FTP->getReturnType().getUnqualifiedType(); - return CGT.arrangeLLVMFunctionInfo(resultType, IsInstanceMethod, prefix, + return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod, + /*chainCall=*/false, prefix, FTP->getExtInfo(), required); } @@ -107,7 +109,8 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool IsInstanceMethod, const CGFunctionInfo & CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) { SmallVector<CanQualType, 16> argTypes; - return ::arrangeLLVMFunctionInfo(*this, false, argTypes, FTP); + return ::arrangeLLVMFunctionInfo(*this, /*instanceMethod=*/false, argTypes, + FTP); } static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) { @@ -219,7 +222,9 @@ CodeGenTypes::arrangeCXXStructorDeclaration(const CXXMethodDecl *MD, : TheCXXABI.hasMostDerivedReturn(GD) ? CGM.getContext().VoidPtrTy : Context.VoidTy; - return arrangeLLVMFunctionInfo(resultType, true, argTypes, extInfo, required); + return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true, + /*chainCall=*/false, argTypes, extInfo, + required); } /// Arrange a call to a C++ method, passing the given arguments. @@ -243,7 +248,9 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args, : Context.VoidTy; FunctionType::ExtInfo Info = FPT->getExtInfo(); - return arrangeLLVMFunctionInfo(ResultType, true, ArgTypes, Info, Required); + return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true, + /*chainCall=*/false, ArgTypes, Info, + Required); } /// Arrange the argument and result information for the declaration or @@ -262,8 +269,9 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) { // non-variadic type. if (isa<FunctionNoProtoType>(FTy)) { CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>(); - return arrangeLLVMFunctionInfo(noProto->getReturnType(), false, None, - noProto->getExtInfo(), RequiredArgs::All); + return arrangeLLVMFunctionInfo( + noProto->getReturnType(), /*instanceMethod=*/false, + /*chainCall=*/false, None, noProto->getExtInfo(), RequiredArgs::All); } assert(isa<FunctionProtoType>(FTy)); @@ -307,8 +315,9 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, RequiredArgs required = (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All); - return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()), false, - argTys, einfo, required); + return arrangeLLVMFunctionInfo( + GetReturnType(MD->getReturnType()), /*instanceMethod=*/false, + /*chainCall=*/false, argTys, einfo, required); } const CGFunctionInfo & @@ -335,7 +344,8 @@ CodeGenTypes::arrangeMSMemberPointerThunk(const CXXMethodDecl *MD) { assert(MD->isVirtual() && "only virtual memptrs have thunks"); CanQual<FunctionProtoType> FTP = GetFormalType(MD); CanQualType ArgTys[] = { GetThisType(Context, MD->getParent()) }; - return arrangeLLVMFunctionInfo(Context.VoidTy, false, ArgTys, + return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false, + /*chainCall=*/false, ArgTys, FTP->getExtInfo(), RequiredArgs(1)); } @@ -346,7 +356,8 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT, CodeGenModule &CGM, const CallArgList &args, const FunctionType *fnType, - unsigned numExtraRequiredArgs) { + unsigned numExtraRequiredArgs, + bool chainCall) { assert(args.size() >= numExtraRequiredArgs); // In most cases, there are no optional arguments. @@ -368,8 +379,13 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT, required = RequiredArgs(args.size()); } - return CGT.arrangeFreeFunctionCall(fnType->getReturnType(), args, - fnType->getExtInfo(), required); + // FIXME: Kill copy. + SmallVector<CanQualType, 16> argTypes; + for (const auto &arg : args) + argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty)); + return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()), + /*instanceMethod=*/false, chainCall, + argTypes, fnType->getExtInfo(), required); } /// Figure out the rules for calling a function with the given formal @@ -378,8 +394,10 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT, /// target-dependent in crazy ways. const CGFunctionInfo & CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args, - const FunctionType *fnType) { - return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 0); + const FunctionType *fnType, + bool chainCall) { + return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, + chainCall ? 1 : 0, chainCall); } /// A block function call is essentially a free-function call with an @@ -387,7 +405,8 @@ CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args, const CGFunctionInfo & CodeGenTypes::arrangeBlockFunctionCall(const CallArgList &args, const FunctionType *fnType) { - return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 1); + return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 1, + /*chainCall=*/false); } const CGFunctionInfo & @@ -399,8 +418,9 @@ CodeGenTypes::arrangeFreeFunctionCall(QualType resultType, SmallVector<CanQualType, 16> argTypes; for (const auto &Arg : args) argTypes.push_back(Context.getCanonicalParamType(Arg.Ty)); - return arrangeLLVMFunctionInfo(GetReturnType(resultType), false, argTypes, - info, required); + return arrangeLLVMFunctionInfo( + GetReturnType(resultType), /*instanceMethod=*/false, + /*chainCall=*/false, argTypes, info, required); } /// Arrange a call to a C++ method, passing the given arguments. @@ -414,8 +434,9 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args, argTypes.push_back(Context.getCanonicalParamType(Arg.Ty)); FunctionType::ExtInfo info = FPT->getExtInfo(); - return arrangeLLVMFunctionInfo(GetReturnType(FPT->getReturnType()), true, - argTypes, info, required); + return arrangeLLVMFunctionInfo( + GetReturnType(FPT->getReturnType()), /*instanceMethod=*/true, + /*chainCall=*/false, argTypes, info, required); } const CGFunctionInfo &CodeGenTypes::arrangeFreeFunctionDeclaration( @@ -428,13 +449,15 @@ const CGFunctionInfo &CodeGenTypes::arrangeFreeFunctionDeclaration( RequiredArgs required = (isVariadic ? RequiredArgs(args.size()) : RequiredArgs::All); - return arrangeLLVMFunctionInfo(GetReturnType(resultType), false, argTypes, info, - required); + return arrangeLLVMFunctionInfo( + GetReturnType(resultType), /*instanceMethod=*/false, + /*chainCall=*/false, argTypes, info, required); } const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() { - return arrangeLLVMFunctionInfo(getContext().VoidTy, false, None, - FunctionType::ExtInfo(), RequiredArgs::All); + return arrangeLLVMFunctionInfo( + getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false, + None, FunctionType::ExtInfo(), RequiredArgs::All); } /// Arrange the argument and result information for an abstract value @@ -442,7 +465,8 @@ const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() { /// above functions ultimately defer to. const CGFunctionInfo & CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, - bool IsInstanceMethod, + bool instanceMethod, + bool chainCall, ArrayRef<CanQualType> argTypes, FunctionType::ExtInfo info, RequiredArgs required) { @@ -453,8 +477,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, // Lookup or create unique function info. llvm::FoldingSetNodeID ID; - CGFunctionInfo::Profile(ID, IsInstanceMethod, info, required, resultType, - argTypes); + CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, required, + resultType, argTypes); void *insertPos = nullptr; CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos); @@ -462,8 +486,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, return *FI; // Construct the function info. We co-allocate the ArgInfos. - FI = CGFunctionInfo::create(CC, IsInstanceMethod, info, resultType, argTypes, - required); + FI = CGFunctionInfo::create(CC, instanceMethod, chainCall, info, + resultType, argTypes, required); FunctionInfos.InsertNode(FI, insertPos); bool inserted = FunctionsBeingProcessed.insert(FI).second; @@ -491,7 +515,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, } CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, - bool IsInstanceMethod, + bool instanceMethod, + bool chainCall, const FunctionType::ExtInfo &info, CanQualType resultType, ArrayRef<CanQualType> argTypes, @@ -502,7 +527,8 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, FI->CallingConvention = llvmCC; FI->EffectiveCallingConvention = llvmCC; FI->ASTCallingConvention = info.getCC(); - FI->InstanceMethod = IsInstanceMethod; + FI->InstanceMethod = instanceMethod; + FI->ChainCall = chainCall; FI->NoReturn = info.getNoReturn(); FI->ReturnsRetained = info.getProducesResult(); FI->Required = required; @@ -1497,7 +1523,6 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, getLLVMContext(), IRFunctionArgs.getInallocaArgNo() + 1, Attrs)); } - unsigned ArgNo = 0; for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(), E = FI.arg_end(); @@ -1525,7 +1550,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, Attrs.addAttribute(llvm::Attribute::ZExt); // FALL THROUGH case ABIArgInfo::Direct: - if (AI.getInReg()) + if (ArgNo == 0 && FI.isChainCall()) + Attrs.addAttribute(llvm::Attribute::Nest); + else if (AI.getInReg()) Attrs.addAttribute(llvm::Attribute::InReg); break; |