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