<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> ¶mInfos,<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> ¶mInfos,<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 ¶ms) {<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>