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