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