bool IsSwiftError : 1;
bool IsCFGuardTarget : 1;
MaybeAlign Alignment = None;
- Type *ByValType = nullptr;
- Type *PreallocatedType = nullptr;
+ // Type for byval, inalloca, or preallocated.
+ Type *IndirectType = nullptr;
ArgListEntry()
: IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
/// Extract the byval type for a call or parameter.
Type *getParamByValType(unsigned ArgNo) const {
- Type *Ty = Attrs.getParamByValType(ArgNo);
- return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType();
+ return Attrs.getParamByValType(ArgNo);
+ }
+
+ /// Extract the inalloca type for a call or parameter.
+ Type *getParamInAllocaType(unsigned ArgNo) const {
+ return Attrs.getParamInAllocaType(ArgNo);
}
/// Extract the preallocated type for a call or parameter.
Type *getParamPreallocatedType(unsigned ArgNo) const {
- Type *Ty = Attrs.getParamPreallocatedType(ArgNo);
- return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType();
+ return Attrs.getParamPreallocatedType(ArgNo);
}
/// Extract the number of dereferenceable bytes for a call or
for (auto &Arg : CLI.getArgs()) {
Type *FinalType = Arg.Ty;
if (Arg.IsByVal)
- FinalType = cast<PointerType>(Arg.Ty)->getElementType();
+ FinalType = Arg.IndirectType;
bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
FinalType, CLI.CallConv, CLI.IsVarArg);
}
MaybeAlign MemAlign = Arg.Alignment;
if (Arg.IsByVal || Arg.IsInAlloca || Arg.IsPreallocated) {
- PointerType *Ty = cast<PointerType>(Arg.Ty);
- Type *ElementTy = Ty->getElementType();
- unsigned FrameSize =
- DL.getTypeAllocSize(Arg.ByValType ? Arg.ByValType : ElementTy);
+ Type *ElementTy = Arg.IndirectType;
+ assert(ElementTy && "Indirect type not set in ArgListEntry");
+
+ unsigned FrameSize = DL.getTypeAllocSize(ElementTy);
// For ByVal, alignment should come from FE. BE will guess if this info
// is not there, but there are cases it cannot get right.
// FIXME: Split arguments if CLI.IsPostTypeLegalization
Type *FinalType = Args[i].Ty;
if (Args[i].IsByVal)
- FinalType = cast<PointerType>(Args[i].Ty)->getElementType();
+ FinalType = Args[i].IndirectType;
bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters(
FinalType, CLI.CallConv, CLI.IsVarArg);
for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues;
}
Align MemAlign;
if (Args[i].IsByVal || Args[i].IsInAlloca || Args[i].IsPreallocated) {
- PointerType *Ty = cast<PointerType>(Args[i].Ty);
- Type *ElementTy = Ty->getElementType();
+ Type *ElementTy = Args[i].IndirectType;
+ assert(ElementTy && "Indirect type not set in ArgListEntry");
- unsigned FrameSize = DL.getTypeAllocSize(
- Args[i].ByValType ? Args[i].ByValType : ElementTy);
+ unsigned FrameSize = DL.getTypeAllocSize(ElementTy);
Flags.setByValSize(FrameSize);
// info is not there but there are cases it cannot get right.
Alignment = Attrs.getParamStackAlignment(ArgIdx);
IsByVal = Attrs.hasParamAttribute(ArgIdx, Attribute::ByVal);
- ByValType = nullptr;
+ IsInAlloca = Attrs.hasParamAttribute(ArgIdx, Attribute::InAlloca);
+ IsPreallocated = Attrs.hasParamAttribute(ArgIdx, Attribute::Preallocated);
+
+ assert(IsByVal + IsInAlloca + IsPreallocated <= 1 &&
+ "can't have multiple indirect attributes");
+ IndirectType = nullptr;
if (IsByVal) {
- ByValType = Call->getParamByValType(ArgIdx);
+ IndirectType = Call->getParamByValType(ArgIdx);
+ assert(IndirectType && "no byval type?");
if (!Alignment)
Alignment = Call->getParamAlign(ArgIdx);
}
- IsInAlloca = Attrs.hasParamAttribute(ArgIdx, Attribute::InAlloca);
- IsPreallocated = Attrs.hasParamAttribute(ArgIdx, Attribute::Preallocated);
- PreallocatedType = nullptr;
- if (IsPreallocated)
- PreallocatedType = Call->getParamPreallocatedType(ArgIdx);
+ if (IsInAlloca) {
+ IndirectType = Call->getParamInAllocaType(ArgIdx);
+ assert(IndirectType && "no inalloca type?");
+ }
+ if (IsPreallocated) {
+ IndirectType = Call->getParamPreallocatedType(ArgIdx);
+ assert(IndirectType && "no preallocated type?");
+ }
}
/// Generate a libcall taking the given operands as arguments and returning a