r263191 - Preserve ExtParameterInfos into CGFunctionInfo.
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 1 17:25:01 PDT 2016
> On Apr 1, 2016, at 3:50 PM, Nico Weber <thakis at chromium.org> wrote:
> On Thu, Mar 10, 2016 at 8:30 PM, John McCall via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> Author: rjmccall
> Date: Thu Mar 10 22:30:31 2016
> New Revision: 263191
>
> URL: http://llvm.org/viewvc/llvm-project?rev=263191&view=rev <http://llvm.org/viewvc/llvm-project?rev=263191&view=rev>
> Log:
> Preserve ExtParameterInfos into CGFunctionInfo.
>
> As part of this, make the function-arrangement interfaces
> a little simpler and more semantic.
>
> NFC.
>
> Modified:
> cfe/trunk/include/clang/AST/CanonicalType.h
> cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
> cfe/trunk/lib/CodeGen/CGAtomic.cpp
> cfe/trunk/lib/CodeGen/CGBlocks.cpp
> cfe/trunk/lib/CodeGen/CGBuiltin.cpp
> cfe/trunk/lib/CodeGen/CGCall.cpp
> cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
> cfe/trunk/lib/CodeGen/CGException.cpp
> cfe/trunk/lib/CodeGen/CGExpr.cpp
> cfe/trunk/lib/CodeGen/CGObjC.cpp
> cfe/trunk/lib/CodeGen/CGObjCMac.cpp
> cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
> cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
> cfe/trunk/lib/CodeGen/CGStmt.cpp
> cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
> cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp
> cfe/trunk/lib/CodeGen/CodeGenTypes.h
> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>
> Modified: cfe/trunk/include/clang/AST/CanonicalType.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=263191&r1=263190&r2=263191&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=263191&r1=263190&r2=263191&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/CanonicalType.h (original)
> +++ cfe/trunk/include/clang/AST/CanonicalType.h Thu Mar 10 22:30:31 2016
> @@ -484,6 +484,9 @@ struct CanProxyAdaptor<FunctionProtoType
> LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
> + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
> + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
> + ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
> CanQualType getParamType(unsigned i) const {
> return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
> }
>
> Modified: cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h?rev=263191&r1=263190&r2=263191&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h?rev=263191&r1=263190&r2=263191&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h (original)
> +++ cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h Thu Mar 10 22:30:31 2016
> @@ -343,8 +343,10 @@ struct CGFunctionInfoArgInfo {
> /// function definition.
> class CGFunctionInfo final
> : public llvm::FoldingSetNode,
> - private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo> {
> + private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
> + FunctionProtoType::ExtParameterInfo> {
> typedef CGFunctionInfoArgInfo ArgInfo;
> + typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo;
>
> /// The LLVM::CallingConv to use for this function (as specified by the
> /// user).
> @@ -378,7 +380,8 @@ class CGFunctionInfo final
> /// The struct representing all arguments passed in memory. Only used when
> /// passing non-trivial types with inalloca. Not part of the profile.
> llvm::StructType *ArgStruct;
> - unsigned ArgStructAlign;
> + unsigned ArgStructAlign : 31;
> + unsigned HasExtParameterInfos : 1;
>
> unsigned NumArgs;
>
> @@ -389,7 +392,19 @@ class CGFunctionInfo final
> return getTrailingObjects<ArgInfo>();
> }
>
> - size_t numTrailingObjects(OverloadToken<ArgInfo>) { return NumArgs + 1; }
> + ExtParameterInfo *getExtParameterInfosBuffer() {
> + return getTrailingObjects<ExtParameterInfo>();
> + }
> + const ExtParameterInfo *getExtParameterInfosBuffer() const{
> + return getTrailingObjects<ExtParameterInfo>();
> + }
> +
> + size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
> + return NumArgs + 1;
> + }
> + size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
> + return (HasExtParameterInfos ? NumArgs : 0);
> + }
> friend class TrailingObjects;
>
> CGFunctionInfo() : Required(RequiredArgs::All) {}
> @@ -399,6 +414,7 @@ public:
> bool instanceMethod,
> bool chainCall,
> const FunctionType::ExtInfo &extInfo,
> + ArrayRef<ExtParameterInfo> paramInfos,
> CanQualType resultType,
> ArrayRef<CanQualType> argTypes,
> RequiredArgs required);
> @@ -472,6 +488,16 @@ public:
> ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
> const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
>
> + ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
> + if (!HasExtParameterInfos) return {};
> + return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
> + }
> + ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
> + assert(argIndex <= NumArgs);
> + if (!HasExtParameterInfos) return ExtParameterInfo();
> + return getExtParameterInfos()[argIndex];
> + }
> +
> /// \brief Return true if this function uses inalloca arguments.
> bool usesInAlloca() const { return ArgStruct; }
>
> @@ -494,6 +520,11 @@ public:
> ID.AddBoolean(HasRegParm);
> ID.AddInteger(RegParm);
> ID.AddInteger(Required.getOpaqueData());
> + ID.AddBoolean(HasExtParameterInfos);
> + if (HasExtParameterInfos) {
> + for (auto paramInfo : getExtParameterInfos())
> + ID.AddInteger(paramInfo.getOpaqueValue());
> + }
> getReturnType().Profile(ID);
> for (const auto &I : arguments())
> I.type.Profile(ID);
> @@ -502,6 +533,7 @@ public:
> bool InstanceMethod,
> bool ChainCall,
> const FunctionType::ExtInfo &info,
> + ArrayRef<ExtParameterInfo> paramInfos,
> RequiredArgs required,
> CanQualType resultType,
> ArrayRef<CanQualType> argTypes) {
> @@ -513,6 +545,11 @@ public:
> ID.AddBoolean(info.getHasRegParm());
> ID.AddInteger(info.getRegParm());
> ID.AddInteger(required.getOpaqueData());
> + ID.AddBoolean(!paramInfos.empty());
> + if (!paramInfos.empty()) {
> + for (auto paramInfo : paramInfos)
> + ID.AddInteger(paramInfo.getOpaqueValue());
> + }
> resultType.Profile(ID);
> for (ArrayRef<CanQualType>::iterator
> i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
>
> Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=263191&r1=263190&r2=263191&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=263191&r1=263190&r2=263191&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGAtomic.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp Thu Mar 10 22:30:31 2016
> @@ -323,8 +323,7 @@ static RValue emitAtomicLibcall(CodeGenF
> QualType resultType,
> CallArgList &args) {
> const CGFunctionInfo &fnInfo =
> - CGF.CGM.getTypes().arrangeFreeFunctionCall(resultType, args,
> - FunctionType::ExtInfo(), RequiredArgs::All);
> + CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args);
> llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo);
> llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName);
> return CGF.EmitCall(fnInfo, fn, ReturnValueSlot(), args);
>
> Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=263191&r1=263190&r2=263191&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=263191&r1=263190&r2=263191&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Mar 10 22:30:31 2016
> @@ -1174,9 +1174,8 @@ CodeGenFunction::GenerateBlockFunction(G
>
> // Create the function declaration.
> const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType();
> - const CGFunctionInfo &fnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
> - fnType->getReturnType(), args, fnType->getExtInfo(),
> - fnType->isVariadic());
> + const CGFunctionInfo &fnInfo =
> + CGM.getTypes().arrangeBlockFunctionDeclaration(fnType, args);
> if (CGM.ReturnSlotInterferesWithArgs(fnInfo))
> blockInfo.UsesStret = true;
>
> @@ -1329,8 +1328,8 @@ CodeGenFunction::GenerateCopyHelperFunct
> C.VoidPtrTy);
> args.push_back(&srcDecl);
>
> - const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
> - C.VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
> + const CGFunctionInfo &FI =
> + CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
>
> // FIXME: it would be nice if these were mergeable with things with
> // identical semantics.
> @@ -1505,8 +1504,8 @@ CodeGenFunction::GenerateDestroyHelperFu
> C.VoidPtrTy);
> args.push_back(&srcDecl);
>
> - const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
> - C.VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
> + const CGFunctionInfo &FI =
> + CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
>
> // FIXME: We'd like to put these into a mergable by content, with
> // internal linkage.
> @@ -1791,8 +1790,8 @@ generateByrefCopyHelper(CodeGenFunction
> Context.VoidPtrTy);
> args.push_back(&src);
>
> - const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration(
> - R, args, FunctionType::ExtInfo(), /*variadic=*/false);
> + const CGFunctionInfo &FI =
> + CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args);
>
> llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);
>
> @@ -1864,8 +1863,8 @@ generateByrefDisposeHelper(CodeGenFuncti
> Context.VoidPtrTy);
> args.push_back(&src);
>
> - const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration(
> - R, args, FunctionType::ExtInfo(), /*variadic=*/false);
> + const CGFunctionInfo &FI =
> + CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args);
>
> llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);
>
>
> Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=263191&r1=263190&r2=263191&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=263191&r1=263190&r2=263191&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Mar 10 22:30:31 2016
> @@ -1330,9 +1330,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(
> Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)),
> getContext().VoidPtrTy);
> const CGFunctionInfo &FuncInfo =
> - CGM.getTypes().arrangeFreeFunctionCall(E->getType(), Args,
> - FunctionType::ExtInfo(),
> - RequiredArgs::All);
> + CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
> llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
> llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
> return EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);
>
> Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=263191&r1=263190&r2=263191&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=263191&r1=263190&r2=263191&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Mar 10 22:30:31 2016
> @@ -91,15 +91,25 @@ CodeGenTypes::arrangeFreeFunctionType(Ca
> return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
> /*instanceMethod=*/false,
> /*chainCall=*/false, None,
> - FTNP->getExtInfo(), RequiredArgs(0));
> + FTNP->getExtInfo(), {}, RequiredArgs(0));
> }
>
> /// Adds the formal paramaters in FPT to the given prefix. If any parameter in
> /// FPT has pass_object_size attrs, then we'll add parameters for those, too.
> static void appendParameterTypes(const CodeGenTypes &CGT,
> SmallVectorImpl<CanQualType> &prefix,
> - const CanQual<FunctionProtoType> &FPT,
> + SmallVectorImpl<FunctionProtoType::ExtParameterInfo> ¶mInfos,
> + CanQual<FunctionProtoType> FPT,
> const FunctionDecl *FD) {
> + // Fill out paramInfos.
> + if (FPT->hasExtParameterInfos() || !paramInfos.empty()) {
> + assert(paramInfos.size() <= prefix.size());
> + auto protoParamInfos = FPT->getExtParameterInfos();
> + paramInfos.reserve(prefix.size() + protoParamInfos.size());
> + paramInfos.resize(prefix.size());
> + paramInfos.append(paramInfos.begin(), paramInfos.end());
> + }
> +
> // Fast path: unknown target.
> if (FD == nullptr) {
> prefix.append(FPT->param_type_begin(), FPT->param_type_end());
> @@ -126,13 +136,16 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CG
> SmallVectorImpl<CanQualType> &prefix,
> CanQual<FunctionProtoType> FTP,
> const FunctionDecl *FD) {
> + SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
> RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
> // FIXME: Kill copy.
> - appendParameterTypes(CGT, prefix, FTP, FD);
> + appendParameterTypes(CGT, prefix, paramInfos, FTP, FD);
> CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
> +
> return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
> /*chainCall=*/false, prefix,
> - FTP->getExtInfo(), required);
> + FTP->getExtInfo(), paramInfos,
> + required);
> }
>
> /// Arrange the argument and result information for a value of the
> @@ -225,6 +238,7 @@ CodeGenTypes::arrangeCXXStructorDeclarat
> StructorType Type) {
>
> SmallVector<CanQualType, 16> argTypes;
> + SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
> argTypes.push_back(GetThisType(Context, MD->getParent()));
>
> GlobalDecl GD;
> @@ -238,7 +252,7 @@ CodeGenTypes::arrangeCXXStructorDeclarat
> CanQual<FunctionProtoType> FTP = GetFormalType(MD);
>
> // Add the formal parameters.
> - appendParameterTypes(*this, argTypes, FTP, MD);
> + appendParameterTypes(*this, argTypes, paramInfos, FTP, MD);
>
> TheCXXABI.buildStructorSignature(MD, Type, argTypes);
>
> @@ -253,7 +267,53 @@ CodeGenTypes::arrangeCXXStructorDeclarat
> : Context.VoidTy;
> return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true,
> /*chainCall=*/false, argTypes, extInfo,
> - required);
> + paramInfos, required);
> +}
> +
> +static SmallVector<CanQualType, 16>
> +getArgTypesForCall(ASTContext &ctx, const CallArgList &args) {
> + SmallVector<CanQualType, 16> argTypes;
> + for (auto &arg : args)
> + argTypes.push_back(ctx.getCanonicalParamType(arg.Ty));
> + return argTypes;
> +}
> +
> +static SmallVector<CanQualType, 16>
> +getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args) {
> + SmallVector<CanQualType, 16> argTypes;
> + for (auto &arg : args)
> + argTypes.push_back(ctx.getCanonicalParamType(arg->getType()));
> + return argTypes;
> +}
> +
> +static void addExtParameterInfosForCall(
> + llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> ¶mInfos,
> + const FunctionProtoType *proto,
> + unsigned prefixArgs,
> + unsigned totalArgs) {
> + assert(proto->hasExtParameterInfos());
> + assert(paramInfos.size() <= prefixArgs);
> + assert(proto->getNumParams() + prefixArgs <= totalArgs);
> +
> + // Add default infos for any prefix args that don't already have infos.
> + paramInfos.resize(prefixArgs);
> +
> + // Add infos for the prototype.
> + auto protoInfos = proto->getExtParameterInfos();
> + paramInfos.append(protoInfos.begin(), protoInfos.end());
> +
> + // Add default infos for the variadic arguments.
> + paramInfos.resize(totalArgs);
> +}
> +
> +static llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16>
> +getExtParameterInfosForCall(const FunctionProtoType *proto,
> + unsigned prefixArgs, unsigned totalArgs) {
> + llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> result;
> + if (proto->hasExtParameterInfos()) {
> + addExtParameterInfosForCall(result, proto, prefixArgs, totalArgs);
> + }
> + return result;
> }
>
> /// Arrange a call to a C++ method, passing the given arguments.
> @@ -277,9 +337,11 @@ CodeGenTypes::arrangeCXXConstructorCall(
> : Context.VoidTy;
>
> FunctionType::ExtInfo Info = FPT->getExtInfo();
> + auto ParamInfos = getExtParameterInfosForCall(FPT.getTypePtr(), 1 + ExtraArgs,
> + ArgTypes.size());
> return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
> /*chainCall=*/false, ArgTypes, Info,
> - Required);
> + ParamInfos, Required);
> }
>
> /// Arrange the argument and result information for the declaration or
> @@ -300,7 +362,7 @@ CodeGenTypes::arrangeFunctionDeclaration
> CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>();
> return arrangeLLVMFunctionInfo(
> noProto->getReturnType(), /*instanceMethod=*/false,
> - /*chainCall=*/false, None, noProto->getExtInfo(), RequiredArgs::All);
> + /*chainCall=*/false, None, noProto->getExtInfo(), {},RequiredArgs::All);
> }
>
> assert(isa<FunctionProtoType>(FTy));
> @@ -346,7 +408,18 @@ CodeGenTypes::arrangeObjCMessageSendSign
>
> return arrangeLLVMFunctionInfo(
> GetReturnType(MD->getReturnType()), /*instanceMethod=*/false,
> - /*chainCall=*/false, argTys, einfo, required);
> + /*chainCall=*/false, argTys, einfo, {}, required);
> +}
> +
> +const CGFunctionInfo &
> +CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
> + const CallArgList &args) {
> + auto argTypes = getArgTypesForCall(Context, args);
> + FunctionType::ExtInfo einfo;
> +
> + return arrangeLLVMFunctionInfo(
> + GetReturnType(returnType), /*instanceMethod=*/false,
> + /*chainCall=*/false, argTypes, einfo, {}, RequiredArgs::All);
> }
>
> const CGFunctionInfo &
> @@ -375,7 +448,7 @@ CodeGenTypes::arrangeMSMemberPointerThun
> CanQualType ArgTys[] = { GetThisType(Context, MD->getParent()) };
> return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false,
> /*chainCall=*/false, ArgTys,
> - FTP->getExtInfo(), RequiredArgs(1));
> + FTP->getExtInfo(), {}, RequiredArgs(1));
> }
>
> const CGFunctionInfo &
> @@ -395,7 +468,8 @@ CodeGenTypes::arrangeMSCtorClosure(const
> /*IsVariadic=*/false, /*IsCXXMethod=*/true);
> return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/true,
> /*chainCall=*/false, ArgTys,
> - FunctionType::ExtInfo(CC), RequiredArgs::All);
> + FunctionType::ExtInfo(CC), {},
> + RequiredArgs::All);
> }
>
> /// Arrange a call as unto a free function, except possibly with an
> @@ -409,6 +483,8 @@ arrangeFreeFunctionLikeCall(CodeGenTypes
> bool chainCall) {
> assert(args.size() >= numExtraRequiredArgs);
>
> + llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
> +
> // In most cases, there are no optional arguments.
> RequiredArgs required = RequiredArgs::All;
>
> @@ -418,6 +494,10 @@ arrangeFreeFunctionLikeCall(CodeGenTypes
> if (proto->isVariadic())
> required = RequiredArgs(proto->getNumParams() + numExtraRequiredArgs);
>
> + if (proto->hasExtParameterInfos())
> + addExtParameterInfosForCall(paramInfos, proto, numExtraRequiredArgs,
> + args.size());
> +
> // If we don't have a prototype at all, but we're supposed to
> // explicitly use the variadic convention for unprototyped calls,
> // treat all of the arguments as required but preserve the nominal
> @@ -434,7 +514,8 @@ arrangeFreeFunctionLikeCall(CodeGenTypes
> argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
> return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
> /*instanceMethod=*/false, chainCall,
> - argTypes, fnType->getExtInfo(), required);
> + argTypes, fnType->getExtInfo(), paramInfos,
> + required);
> }
>
> /// Figure out the rules for calling a function with the given formal
> @@ -449,7 +530,7 @@ CodeGenTypes::arrangeFreeFunctionCall(co
> chainCall ? 1 : 0, chainCall);
> }
>
> -/// A block function call is essentially a free-function call with an
> +/// A block function is essentially a free function with an
> /// extra implicit argument.
> const CGFunctionInfo &
> CodeGenTypes::arrangeBlockFunctionCall(const CallArgList &args,
> @@ -459,54 +540,99 @@ CodeGenTypes::arrangeBlockFunctionCall(c
> }
>
> const CGFunctionInfo &
> -CodeGenTypes::arrangeFreeFunctionCall(QualType resultType,
> - const CallArgList &args,
> - FunctionType::ExtInfo info,
> - RequiredArgs required) {
> +CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
> + const FunctionArgList ¶ms) {
> + auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size());
> + auto argTypes = getArgTypesForDeclaration(Context, params);
> +
> + return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
> + /*instanceMethod*/ false, /*chainCall*/ false,
> + argTypes, proto->getExtInfo(), paramInfos,
> + RequiredArgs::forPrototypePlus(proto, 1));
> +}
> +
> +const CGFunctionInfo &
> +CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
> + const CallArgList &args) {
> // FIXME: Kill copy.
> SmallVector<CanQualType, 16> argTypes;
> for (const auto &Arg : args)
> argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
> return arrangeLLVMFunctionInfo(
> GetReturnType(resultType), /*instanceMethod=*/false,
> - /*chainCall=*/false, argTypes, info, required);
> + /*chainCall=*/false, argTypes, FunctionType::ExtInfo(),
> + /*paramInfos=*/ {}, RequiredArgs::All);
> }
>
> -/// 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 (const auto &Arg : args)
> - argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
> +CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType,
> + const FunctionArgList &args) {
> + auto argTypes = getArgTypesForDeclaration(Context, args);
>
> - FunctionType::ExtInfo info = FPT->getExtInfo();
> return arrangeLLVMFunctionInfo(
> - GetReturnType(FPT->getReturnType()), /*instanceMethod=*/true,
> - /*chainCall=*/false, argTypes, info, required);
> + GetReturnType(resultType), /*instanceMethod=*/false, /*chainCall=*/false,
> + argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
> }
>
> -const CGFunctionInfo &CodeGenTypes::arrangeFreeFunctionDeclaration(
> - QualType resultType, const FunctionArgList &args,
> - const FunctionType::ExtInfo &info, bool isVariadic) {
> +const CGFunctionInfo &
> +CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
> + ArrayRef<CanQualType> argTypes) {
> + return arrangeLLVMFunctionInfo(
> + resultType, /*instanceMethod=*/false, /*chainCall=*/false,
> + argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
> +}
> +
> +
> +/// Arrange a call to a C++ method, passing the given arguments.
> +const CGFunctionInfo &
> +CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
> + const FunctionProtoType *proto,
> + RequiredArgs required) {
> + unsigned numRequiredArgs =
> + (proto->isVariadic() ? required.getNumRequiredArgs() : args.size());
> + unsigned numPrefixArgs = numRequiredArgs - proto->getNumParams();
> + auto paramInfos =
> + getExtParameterInfosForCall(proto, numPrefixArgs, args.size());
> +
> // FIXME: Kill copy.
> - SmallVector<CanQualType, 16> argTypes;
> - for (auto Arg : args)
> - argTypes.push_back(Context.getCanonicalParamType(Arg->getType()));
> + auto argTypes = getArgTypesForCall(Context, args);
>
> - RequiredArgs required =
> - (isVariadic ? RequiredArgs(args.size()) : RequiredArgs::All);
> + FunctionType::ExtInfo info = proto->getExtInfo();
> return arrangeLLVMFunctionInfo(
> - GetReturnType(resultType), /*instanceMethod=*/false,
> - /*chainCall=*/false, argTypes, info, required);
> + GetReturnType(proto->getReturnType()), /*instanceMethod=*/true,
> + /*chainCall=*/false, argTypes, info, paramInfos, required);
> }
>
> const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
> return arrangeLLVMFunctionInfo(
> getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
> - None, FunctionType::ExtInfo(), RequiredArgs::All);
> + None, FunctionType::ExtInfo(), {}, RequiredArgs::All);
> +}
> +
> +const CGFunctionInfo &
> +CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
> + const CallArgList &args) {
> + assert(signature.arg_size() <= args.size());
> + if (signature.arg_size() == args.size())
> + return signature;
> +
> + SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
> + auto sigParamInfos = signature.getExtParameterInfos();
> + if (!sigParamInfos.empty()) {
> + paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
> + paramInfos.resize(args.size());
> + }
> +
> + auto argTypes = getArgTypesForCall(Context, args);
> +
> + assert(signature.getRequiredArgs().allowsOptionalArgs());
> + return arrangeLLVMFunctionInfo(signature.getReturnType(),
> + signature.isInstanceMethod(),
> + signature.isChainCall(),
> + argTypes,
> + signature.getExtInfo(),
> + paramInfos,
> + signature.getRequiredArgs());
> }
>
> /// Arrange the argument and result information for an abstract value
> @@ -518,25 +644,26 @@ CodeGenTypes::arrangeLLVMFunctionInfo(Ca
> bool chainCall,
> ArrayRef<CanQualType> argTypes,
> FunctionType::ExtInfo info,
> + ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
> RequiredArgs required) {
> assert(std::all_of(argTypes.begin(), argTypes.end(),
> std::mem_fun_ref(&CanQualType::isCanonicalAsParam)));
>
> - unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
> -
> // Lookup or create unique function info.
> llvm::FoldingSetNodeID ID;
> - CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, required,
> - resultType, argTypes);
> + CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos,
> + required, resultType, argTypes);
>
> void *insertPos = nullptr;
> CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
> if (FI)
> return *FI;
>
> + unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
> +
> // Construct the function info. We co-allocate the ArgInfos.
> FI = CGFunctionInfo::create(CC, instanceMethod, chainCall, info,
> - resultType, argTypes, required);
> + paramInfos, resultType, argTypes, required);
> FunctionInfos.InsertNode(FI, insertPos);
>
> bool inserted = FunctionsBeingProcessed.insert(FI).second;
> @@ -567,10 +694,16 @@ CGFunctionInfo *CGFunctionInfo::create(u
> bool instanceMethod,
> bool chainCall,
> const FunctionType::ExtInfo &info,
> + ArrayRef<ExtParameterInfo> paramInfos,
> CanQualType resultType,
> ArrayRef<CanQualType> argTypes,
> RequiredArgs required) {
> - void *buffer = operator new(totalSizeToAlloc<ArgInfo>(argTypes.size() + 1));
> + assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
>
> This assert fires on e.g.
>
> $ cat test.mm <http://test.mm/>
> struct S {
> S(__attribute((ns_consumed)) id object, int policy);
> };
> void f() {
> S s(0, 0);
> }
> $ bin/clang -c test.mm <http://test.mm/> -fobjc-arc
> Assertion failed: (paramInfos.empty() || paramInfos.size() == argTypes.size()), function create, file /b/build/slave/build_and_upload_clang/build/src/third_party/llvm/tools/clang/lib/CodeGen/CGCall.cpp, line 709.
>
> Can you take a look, please?
Sure thing. I believe I actually found and fixed this bug as part of implementing the real codegen support for this anyway.
Aside: something about how you quoted this made it really difficult to find your comment in the midst of a thousand lines of patch.
John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160401/db7a0764/attachment-0001.html>
More information about the cfe-commits
mailing list