forked from OSchip/llvm-project
[CodeGen] Note where we add ABI-specific args in ctors. NFC.
Meta: The ultimate goal is to teach ExtParameterInfo about pass_object_size attributes. This is necessary for that, since our ExtParameterInfo is a bit buggy in C++. I plan to actually make use of this Prefix/Suffix info in the near future, but I like small single-purpose changes. Especially when those changes are hard to actually test... At the moment, some of our C++-specific CodeGen pretends that ABIs can only add arguments to the beginning of a function call. This isn't quite correct: args can be appended to the end, as well. It hasn't mattered much until now, since we seem to only use this "number of arguments added" data when calculating the ExtParameterInfo to use when making a CGFunctionInfo. Said ExtParameterInfo is currently only used for ParameterABIs (Swift) and ns_consumed (ObjC). So, this patch allows ABIs to indicate whether args they added were at the beginning or end of an argument list. We can use this information to emit ExtParameterInfos more correctly, though like said, that bit is coming soon. No tests since this is theoretically a nop. llvm-svn: 295870
This commit is contained in:
parent
8e6ee2070a
commit
f203dbfba9
|
@ -291,11 +291,26 @@ public:
|
|||
/// Emit constructor variants required by this ABI.
|
||||
virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;
|
||||
|
||||
/// Notes how many arguments were added to the beginning (Prefix) and ending
|
||||
/// (Suffix) of an arg list.
|
||||
///
|
||||
/// Note that Prefix actually refers to the number of args *after* the first
|
||||
/// one: `this` arguments always come first.
|
||||
struct AddedStructorArgs {
|
||||
unsigned Prefix = 0;
|
||||
unsigned Suffix = 0;
|
||||
AddedStructorArgs() = default;
|
||||
AddedStructorArgs(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
|
||||
static AddedStructorArgs prefix(unsigned N) { return {N, 0}; }
|
||||
static AddedStructorArgs suffix(unsigned N) { return {0, N}; }
|
||||
};
|
||||
|
||||
/// Build the signature of the given constructor or destructor variant by
|
||||
/// adding any required parameters. For convenience, ArgTys has been
|
||||
/// initialized with the type of 'this'.
|
||||
virtual void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) = 0;
|
||||
virtual AddedStructorArgs
|
||||
buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) = 0;
|
||||
|
||||
/// Returns true if the given destructor type should be emitted as a linkonce
|
||||
/// delegating thunk, regardless of whether the dtor is defined in this TU or
|
||||
|
@ -355,9 +370,9 @@ public:
|
|||
|
||||
/// Add any ABI-specific implicit arguments needed to call a constructor.
|
||||
///
|
||||
/// \return The number of args added to the call, which is typically zero or
|
||||
/// one.
|
||||
virtual unsigned
|
||||
/// \return The number of arguments added at the beginning and end of the
|
||||
/// call, which is typically zero or one.
|
||||
virtual AddedStructorArgs
|
||||
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
|
||||
CXXCtorType Type, bool ForVirtualBase,
|
||||
bool Delegating, CallArgList &Args) = 0;
|
||||
|
|
|
@ -2032,14 +2032,15 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
|
|||
}
|
||||
|
||||
// Insert any ABI-specific implicit constructor arguments.
|
||||
unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs(
|
||||
*this, D, Type, ForVirtualBase, Delegating, Args);
|
||||
CGCXXABI::AddedStructorArgs ExtraArgs =
|
||||
CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase,
|
||||
Delegating, Args);
|
||||
|
||||
// Emit the call.
|
||||
llvm::Constant *CalleePtr =
|
||||
CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
|
||||
const CGFunctionInfo &Info =
|
||||
CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);
|
||||
const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
|
||||
Args, D, Type, ExtraArgs.Prefix + ExtraArgs.Suffix);
|
||||
CGCallee Callee = CGCallee::forDirect(CalleePtr, D);
|
||||
EmitCall(Info, Callee, ReturnValueSlot(), Args);
|
||||
|
||||
|
|
|
@ -207,8 +207,9 @@ public:
|
|||
|
||||
void EmitCXXConstructors(const CXXConstructorDecl *D) override;
|
||||
|
||||
void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) override;
|
||||
AddedStructorArgs
|
||||
buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) override;
|
||||
|
||||
bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
|
||||
CXXDtorType DT) const override {
|
||||
|
@ -225,11 +226,10 @@ public:
|
|||
|
||||
void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
|
||||
|
||||
unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
|
||||
const CXXConstructorDecl *D,
|
||||
CXXCtorType Type, bool ForVirtualBase,
|
||||
bool Delegating,
|
||||
CallArgList &Args) override;
|
||||
AddedStructorArgs
|
||||
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
|
||||
CXXCtorType Type, bool ForVirtualBase,
|
||||
bool Delegating, CallArgList &Args) override;
|
||||
|
||||
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
|
||||
CXXDtorType Type, bool ForVirtualBase,
|
||||
|
@ -1353,7 +1353,7 @@ void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGCXXABI::AddedStructorArgs
|
||||
ItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) {
|
||||
ASTContext &Context = getContext();
|
||||
|
@ -1362,9 +1362,12 @@ ItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
|||
// These are Clang types, so we don't need to worry about sret yet.
|
||||
|
||||
// Check if we need to add a VTT parameter (which has type void **).
|
||||
if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0)
|
||||
if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0) {
|
||||
ArgTys.insert(ArgTys.begin() + 1,
|
||||
Context.getPointerType(Context.VoidPtrTy));
|
||||
return AddedStructorArgs::prefix(1);
|
||||
}
|
||||
return AddedStructorArgs{};
|
||||
}
|
||||
|
||||
void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
|
||||
|
@ -1429,11 +1432,11 @@ void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
|
|||
CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
|
||||
}
|
||||
|
||||
unsigned ItaniumCXXABI::addImplicitConstructorArgs(
|
||||
CGCXXABI::AddedStructorArgs ItaniumCXXABI::addImplicitConstructorArgs(
|
||||
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
|
||||
bool ForVirtualBase, bool Delegating, CallArgList &Args) {
|
||||
if (!NeedsVTTParameter(GlobalDecl(D, Type)))
|
||||
return 0;
|
||||
return AddedStructorArgs{};
|
||||
|
||||
// Insert the implicit 'vtt' argument as the second argument.
|
||||
llvm::Value *VTT =
|
||||
|
@ -1441,7 +1444,7 @@ unsigned ItaniumCXXABI::addImplicitConstructorArgs(
|
|||
QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
|
||||
Args.insert(Args.begin() + 1,
|
||||
CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false));
|
||||
return 1; // Added one arg.
|
||||
return AddedStructorArgs::prefix(1); // Added one arg.
|
||||
}
|
||||
|
||||
void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
|
||||
|
|
|
@ -206,8 +206,9 @@ public:
|
|||
// lacks a definition for the destructor, non-base destructors must always
|
||||
// delegate to or alias the base destructor.
|
||||
|
||||
void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) override;
|
||||
AddedStructorArgs
|
||||
buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) override;
|
||||
|
||||
/// Non-base dtors should be emitted as delegating thunks in this ABI.
|
||||
bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
|
||||
|
@ -248,11 +249,10 @@ public:
|
|||
|
||||
void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
|
||||
|
||||
unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
|
||||
const CXXConstructorDecl *D,
|
||||
CXXCtorType Type, bool ForVirtualBase,
|
||||
bool Delegating,
|
||||
CallArgList &Args) override;
|
||||
AddedStructorArgs
|
||||
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
|
||||
CXXCtorType Type, bool ForVirtualBase,
|
||||
bool Delegating, CallArgList &Args) override;
|
||||
|
||||
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
|
||||
CXXDtorType Type, bool ForVirtualBase,
|
||||
|
@ -1261,17 +1261,19 @@ void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGCXXABI::AddedStructorArgs
|
||||
MicrosoftCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
||||
SmallVectorImpl<CanQualType> &ArgTys) {
|
||||
AddedStructorArgs Added;
|
||||
// TODO: 'for base' flag
|
||||
if (T == StructorType::Deleting) {
|
||||
// The scalar deleting destructor takes an implicit int parameter.
|
||||
ArgTys.push_back(getContext().IntTy);
|
||||
++Added.Suffix;
|
||||
}
|
||||
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
|
||||
if (!CD)
|
||||
return;
|
||||
return Added;
|
||||
|
||||
// All parameters are already in place except is_most_derived, which goes
|
||||
// after 'this' if it's variadic and last if it's not.
|
||||
|
@ -1279,11 +1281,16 @@ MicrosoftCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
|
|||
const CXXRecordDecl *Class = CD->getParent();
|
||||
const FunctionProtoType *FPT = CD->getType()->castAs<FunctionProtoType>();
|
||||
if (Class->getNumVBases()) {
|
||||
if (FPT->isVariadic())
|
||||
if (FPT->isVariadic()) {
|
||||
ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
|
||||
else
|
||||
++Added.Prefix;
|
||||
} else {
|
||||
ArgTys.push_back(getContext().IntTy);
|
||||
++Added.Suffix;
|
||||
}
|
||||
}
|
||||
|
||||
return Added;
|
||||
}
|
||||
|
||||
void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
|
||||
|
@ -1493,14 +1500,14 @@ void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
|
||||
CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
|
||||
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
|
||||
bool ForVirtualBase, bool Delegating, CallArgList &Args) {
|
||||
assert(Type == Ctor_Complete || Type == Ctor_Base);
|
||||
|
||||
// Check if we need a 'most_derived' parameter.
|
||||
if (!D->getParent()->getNumVBases())
|
||||
return 0;
|
||||
return AddedStructorArgs{};
|
||||
|
||||
// Add the 'most_derived' argument second if we are variadic or last if not.
|
||||
const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
|
||||
|
@ -1511,13 +1518,13 @@ unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
|
|||
MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
|
||||
}
|
||||
RValue RV = RValue::get(MostDerivedArg);
|
||||
if (FPT->isVariadic())
|
||||
if (FPT->isVariadic()) {
|
||||
Args.insert(Args.begin() + 1,
|
||||
CallArg(RV, getContext().IntTy, /*needscopy=*/false));
|
||||
else
|
||||
Args.add(RV, getContext().IntTy);
|
||||
|
||||
return 1; // Added one arg.
|
||||
return AddedStructorArgs::prefix(1);
|
||||
}
|
||||
Args.add(RV, getContext().IntTy);
|
||||
return AddedStructorArgs::suffix(1);
|
||||
}
|
||||
|
||||
void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
|
||||
|
@ -3918,16 +3925,16 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
|
|||
CGF.EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
|
||||
|
||||
// Insert any ABI-specific implicit constructor arguments.
|
||||
unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
|
||||
/*ForVirtualBase=*/false,
|
||||
/*Delegating=*/false, Args);
|
||||
|
||||
AddedStructorArgs ExtraArgs =
|
||||
addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
|
||||
/*ForVirtualBase=*/false,
|
||||
/*Delegating=*/false, Args);
|
||||
// Call the destructor with our arguments.
|
||||
llvm::Constant *CalleePtr =
|
||||
CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
|
||||
CGCallee Callee = CGCallee::forDirect(CalleePtr, CD);
|
||||
const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
|
||||
Args, CD, Ctor_Complete, ExtraArgs);
|
||||
Args, CD, Ctor_Complete, ExtraArgs.Prefix + ExtraArgs.Suffix);
|
||||
CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
|
||||
|
||||
Cleanups.ForceCleanup();
|
||||
|
|
Loading…
Reference in New Issue