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> &paramInfos,
> +                                 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> &paramInfos,
> +                                        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 &params) {
> +  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