|
@@ -362,18 +362,31 @@ getExtParameterInfosForCall(const FunctionProtoType *proto,
|
|
}
|
|
}
|
|
|
|
|
|
/// Arrange a call to a C++ method, passing the given arguments.
|
|
/// Arrange a call to a C++ method, passing the given arguments.
|
|
|
|
+///
|
|
|
|
+/// ExtraPrefixArgs is the number of ABI-specific args passed after the `this`
|
|
|
|
+/// parameter.
|
|
|
|
+/// ExtraSuffixArgs is the number of ABI-specific args passed at the end of
|
|
|
|
+/// args.
|
|
|
|
+/// PassProtoArgs indicates whether `args` has args for the parameters in the
|
|
|
|
+/// given CXXConstructorDecl.
|
|
const CGFunctionInfo &
|
|
const CGFunctionInfo &
|
|
CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
|
|
CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
|
|
const CXXConstructorDecl *D,
|
|
const CXXConstructorDecl *D,
|
|
CXXCtorType CtorKind,
|
|
CXXCtorType CtorKind,
|
|
- unsigned ExtraArgs) {
|
|
|
|
|
|
+ unsigned ExtraPrefixArgs,
|
|
|
|
+ unsigned ExtraSuffixArgs,
|
|
|
|
+ bool PassProtoArgs) {
|
|
// FIXME: Kill copy.
|
|
// FIXME: Kill copy.
|
|
SmallVector<CanQualType, 16> ArgTypes;
|
|
SmallVector<CanQualType, 16> ArgTypes;
|
|
for (const auto &Arg : args)
|
|
for (const auto &Arg : args)
|
|
ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
|
|
ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
|
|
|
|
|
|
|
|
+ // +1 for implicit this, which should always be args[0].
|
|
|
|
+ unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
|
|
|
|
+
|
|
CanQual<FunctionProtoType> FPT = GetFormalType(D);
|
|
CanQual<FunctionProtoType> FPT = GetFormalType(D);
|
|
- RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, 1 + ExtraArgs, D);
|
|
|
|
|
|
+ RequiredArgs Required =
|
|
|
|
+ RequiredArgs::forPrototypePlus(FPT, TotalPrefixArgs + ExtraSuffixArgs, D);
|
|
GlobalDecl GD(D, CtorKind);
|
|
GlobalDecl GD(D, CtorKind);
|
|
CanQualType ResultType = TheCXXABI.HasThisReturn(GD)
|
|
CanQualType ResultType = TheCXXABI.HasThisReturn(GD)
|
|
? ArgTypes.front()
|
|
? ArgTypes.front()
|
|
@@ -382,8 +395,14 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
|
|
: Context.VoidTy;
|
|
: Context.VoidTy;
|
|
|
|
|
|
FunctionType::ExtInfo Info = FPT->getExtInfo();
|
|
FunctionType::ExtInfo Info = FPT->getExtInfo();
|
|
- auto ParamInfos = getExtParameterInfosForCall(FPT.getTypePtr(), 1 + ExtraArgs,
|
|
|
|
- ArgTypes.size());
|
|
|
|
|
|
+ llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> ParamInfos;
|
|
|
|
+ // If the prototype args are elided, we should only have ABI-specific args,
|
|
|
|
+ // which never have param info.
|
|
|
|
+ if (PassProtoArgs && FPT->hasExtParameterInfos()) {
|
|
|
|
+ // ABI-specific suffix arguments are treated the same as variadic arguments.
|
|
|
|
+ addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
|
|
|
|
+ ArgTypes.size());
|
|
|
|
+ }
|
|
return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
|
|
return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
|
|
/*chainCall=*/false, ArgTypes, Info,
|
|
/*chainCall=*/false, ArgTypes, Info,
|
|
ParamInfos, Required);
|
|
ParamInfos, Required);
|
|
@@ -627,15 +646,20 @@ CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
|
|
}
|
|
}
|
|
|
|
|
|
/// Arrange a call to a C++ method, passing the given arguments.
|
|
/// Arrange a call to a C++ method, passing the given arguments.
|
|
|
|
+///
|
|
|
|
+/// numPrefixArgs is the number of ABI-specific prefix arguments we have. It
|
|
|
|
+/// does not count `this`.
|
|
const CGFunctionInfo &
|
|
const CGFunctionInfo &
|
|
CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
|
|
CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
|
|
const FunctionProtoType *proto,
|
|
const FunctionProtoType *proto,
|
|
- RequiredArgs required) {
|
|
|
|
- unsigned numRequiredArgs =
|
|
|
|
- (proto->isVariadic() ? required.getNumRequiredArgs() : args.size());
|
|
|
|
- unsigned numPrefixArgs = numRequiredArgs - proto->getNumParams();
|
|
|
|
|
|
+ RequiredArgs required,
|
|
|
|
+ unsigned numPrefixArgs) {
|
|
|
|
+ assert(numPrefixArgs + 1 <= args.size() &&
|
|
|
|
+ "Emitting a call with less args than the required prefix?");
|
|
|
|
+ // Add one to account for `this`. It's a bit awkward here, but we don't count
|
|
|
|
+ // `this` in similar places elsewhere.
|
|
auto paramInfos =
|
|
auto paramInfos =
|
|
- getExtParameterInfosForCall(proto, numPrefixArgs, args.size());
|
|
|
|
|
|
+ getExtParameterInfosForCall(proto, numPrefixArgs + 1, args.size());
|
|
|
|
|
|
// FIXME: Kill copy.
|
|
// FIXME: Kill copy.
|
|
auto argTypes = getArgTypesForCall(Context, args);
|
|
auto argTypes = getArgTypesForCall(Context, args);
|