Skip to content

Commit 7df676d

Browse files
author
git apple-llvm automerger
committed
Merge commit 'd7098ff29c58' from llvm.org/master into apple/main
2 parents d37a12d + d7098ff commit 7df676d

File tree

3 files changed

+77
-71
lines changed

3 files changed

+77
-71
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3826,13 +3826,79 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
38263826
EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, None);
38273827
}
38283828

3829+
#ifndef NDEBUG
3830+
// Determine whether the given argument is an Objective-C method
3831+
// that may have type parameters in its signature.
3832+
static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method) {
3833+
const DeclContext *dc = method->getDeclContext();
3834+
if (const ObjCInterfaceDecl *classDecl = dyn_cast<ObjCInterfaceDecl>(dc)) {
3835+
return classDecl->getTypeParamListAsWritten();
3836+
}
3837+
3838+
if (const ObjCCategoryDecl *catDecl = dyn_cast<ObjCCategoryDecl>(dc)) {
3839+
return catDecl->getTypeParamList();
3840+
}
3841+
3842+
return false;
3843+
}
3844+
#endif
3845+
3846+
/// EmitCallArgs - Emit call arguments for a function.
38293847
void CodeGenFunction::EmitCallArgs(
3830-
CallArgList &Args, ArrayRef<QualType> ArgTypes,
3848+
CallArgList &Args, PrototypeWrapper Prototype,
38313849
llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
38323850
AbstractCallee AC, unsigned ParamsToSkip, EvaluationOrder Order) {
3851+
SmallVector<QualType, 16> ArgTypes;
3852+
3853+
assert((ParamsToSkip == 0 || Prototype.P) &&
3854+
"Can't skip parameters if type info is not provided");
3855+
3856+
// First, use the argument types that the type info knows about
3857+
bool IsVariadic = false;
3858+
if (Prototype.P) {
3859+
const auto *MD = Prototype.P.dyn_cast<const ObjCMethodDecl *>();
3860+
if (MD) {
3861+
IsVariadic = MD->isVariadic();
3862+
ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
3863+
MD->param_type_end());
3864+
} else {
3865+
const auto *FPT = Prototype.P.get<const FunctionProtoType *>();
3866+
IsVariadic = FPT->isVariadic();
3867+
ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
3868+
FPT->param_type_end());
3869+
}
3870+
3871+
#ifndef NDEBUG
3872+
// Check that the prototyped types match the argument expression types.
3873+
bool isGenericMethod = MD && isObjCMethodWithTypeParams(MD);
3874+
CallExpr::const_arg_iterator Arg = ArgRange.begin();
3875+
for (QualType Ty : ArgTypes) {
3876+
assert(Arg != ArgRange.end() && "Running over edge of argument list!");
3877+
assert(
3878+
(isGenericMethod || Ty->isVariablyModifiedType() ||
3879+
Ty.getNonReferenceType()->isObjCRetainableType() ||
3880+
getContext()
3881+
.getCanonicalType(Ty.getNonReferenceType())
3882+
.getTypePtr() ==
3883+
getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
3884+
"type mismatch in call argument!");
3885+
++Arg;
3886+
}
3887+
3888+
// Either we've emitted all the call args, or we have a call to variadic
3889+
// function.
3890+
assert((Arg == ArgRange.end() || IsVariadic) &&
3891+
"Extra arguments in non-variadic function!");
3892+
#endif
3893+
}
3894+
3895+
// If we still have any arguments, emit them using the type of the argument.
3896+
for (auto *A : llvm::make_range(std::next(ArgRange.begin(), ArgTypes.size()),
3897+
ArgRange.end()))
3898+
ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
38333899
assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
38343900

3835-
// We *have* to evaluate arguments from right to left in the MS C++ ABI,
3901+
// We must evaluate arguments from right to left in the MS C++ ABI,
38363902
// because arguments are destroyed left to right in the callee. As a special
38373903
// case, there are certain language constructs that require left-to-right
38383904
// evaluation, and in those cases we consider the evaluation order requirement

clang/lib/CodeGen/CGExprCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
13291329
const CallExpr *TheCall,
13301330
bool IsDelete) {
13311331
CallArgList Args;
1332-
EmitCallArgs(Args, Type->getParamTypes(), TheCall->arguments());
1332+
EmitCallArgs(Args, Type, TheCall->arguments());
13331333
// Find the allocation or deallocation function that we're calling.
13341334
ASTContext &Ctx = getContext();
13351335
DeclarationName Name = Ctx.DeclarationNames

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 8 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4606,26 +4606,6 @@ class CodeGenFunction : public CodeGenTypeCache {
46064606
Address Loc);
46074607

46084608
public:
4609-
#ifndef NDEBUG
4610-
// Determine whether the given argument is an Objective-C method
4611-
// that may have type parameters in its signature.
4612-
static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method) {
4613-
const DeclContext *dc = method->getDeclContext();
4614-
if (const ObjCInterfaceDecl *classDecl= dyn_cast<ObjCInterfaceDecl>(dc)) {
4615-
return classDecl->getTypeParamListAsWritten();
4616-
}
4617-
4618-
if (const ObjCCategoryDecl *catDecl = dyn_cast<ObjCCategoryDecl>(dc)) {
4619-
return catDecl->getTypeParamList();
4620-
}
4621-
4622-
return false;
4623-
}
4624-
4625-
template<typename T>
4626-
static bool isObjCMethodWithTypeParams(const T *) { return false; }
4627-
#endif
4628-
46294609
enum class EvaluationOrder {
46304610
///! No language constraints on evaluation order.
46314611
Default,
@@ -4635,56 +4615,16 @@ class CodeGenFunction : public CodeGenTypeCache {
46354615
ForceRightToLeft
46364616
};
46374617

4638-
/// EmitCallArgs - Emit call arguments for a function.
4639-
template <typename T>
4640-
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo,
4641-
llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
4642-
AbstractCallee AC = AbstractCallee(),
4643-
unsigned ParamsToSkip = 0,
4644-
EvaluationOrder Order = EvaluationOrder::Default) {
4645-
SmallVector<QualType, 16> ArgTypes;
4646-
CallExpr::const_arg_iterator Arg = ArgRange.begin();
4647-
4648-
assert((ParamsToSkip == 0 || CallArgTypeInfo) &&
4649-
"Can't skip parameters if type info is not provided");
4650-
if (CallArgTypeInfo) {
4651-
#ifndef NDEBUG
4652-
bool isGenericMethod = isObjCMethodWithTypeParams(CallArgTypeInfo);
4653-
#endif
4654-
4655-
// First, use the argument types that the type info knows about
4656-
for (auto I = CallArgTypeInfo->param_type_begin() + ParamsToSkip,
4657-
E = CallArgTypeInfo->param_type_end();
4658-
I != E; ++I, ++Arg) {
4659-
assert(Arg != ArgRange.end() && "Running over edge of argument list!");
4660-
assert((isGenericMethod ||
4661-
((*I)->isVariablyModifiedType() ||
4662-
(*I).getNonReferenceType()->isObjCRetainableType() ||
4663-
getContext()
4664-
.getCanonicalType((*I).getNonReferenceType())
4665-
.getTypePtr() ==
4666-
getContext()
4667-
.getCanonicalType((*Arg)->getType())
4668-
.getTypePtr())) &&
4669-
"type mismatch in call argument!");
4670-
ArgTypes.push_back(*I);
4671-
}
4672-
}
4673-
4674-
// Either we've emitted all the call args, or we have a call to variadic
4675-
// function.
4676-
assert((Arg == ArgRange.end() || !CallArgTypeInfo ||
4677-
CallArgTypeInfo->isVariadic()) &&
4678-
"Extra arguments in non-variadic function!");
4679-
4680-
// If we still have any arguments, emit them using the type of the argument.
4681-
for (auto *A : llvm::make_range(Arg, ArgRange.end()))
4682-
ArgTypes.push_back(CallArgTypeInfo ? getVarArgType(A) : A->getType());
4618+
// Wrapper for function prototype sources. Wraps either a FunctionProtoType or
4619+
// an ObjCMethodDecl.
4620+
struct PrototypeWrapper {
4621+
llvm::PointerUnion<const FunctionProtoType *, const ObjCMethodDecl *> P;
46834622

4684-
EmitCallArgs(Args, ArgTypes, ArgRange, AC, ParamsToSkip, Order);
4685-
}
4623+
PrototypeWrapper(const FunctionProtoType *FT) : P(FT) {}
4624+
PrototypeWrapper(const ObjCMethodDecl *MD) : P(MD) {}
4625+
};
46864626

4687-
void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes,
4627+
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype,
46884628
llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
46894629
AbstractCallee AC = AbstractCallee(),
46904630
unsigned ParamsToSkip = 0,

0 commit comments

Comments
 (0)