/// Check if an argument has a given attribute.
bool hasAttribute(Attribute::AttrKind Kind) const;
+ Attribute getAttribute(Attribute::AttrKind Kind) const;
+
/// Method for support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
return getAttributes().hasParamAttribute(ArgNo, Kind);
}
+ /// gets the specified attribute from the list of attributes.
+ Attribute getParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const {
+ return getAttributes().getParamAttr(ArgNo, Kind);
+ }
+
/// gets the attribute from the list of attributes.
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
return AttributeSets.getAttribute(i, Kind);
return AttributeSets.getParamAlignment(ArgNo);
}
- /// Extract the byval type for a parameter (nullptr=unknown).
+ /// Extract the byval type for a parameter.
Type *getParamByValType(unsigned ArgNo) const {
- return AttributeSets.getParamByValType(ArgNo);
+ Type *Ty = AttributeSets.getParamByValType(ArgNo);
+ return Ty ? Ty : (arg_begin() + ArgNo)->getType()->getPointerElementType();
}
/// Extract the number of dereferenceable bytes for a call or
return Attrs.getParamAlignment(ArgNo);
}
- /// Extract the byval type for a call or parameter (nullptr=unknown).
+ /// Extract the byval type for a call or parameter.
Type *getParamByValType(unsigned ArgNo) const {
- return Attrs.getParamByValType(ArgNo);
+ Type *Ty = Attrs.getParamByValType(ArgNo);
+ return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType();
}
/// Extract the number of dereferenceable bytes for a call or
// pointee type. There should be no opaque pointers where the byval type is
// implicit.
for (auto &Arg : Func->args()) {
- if (Arg.hasByValAttr() && !Arg.getParamByValType()) {
+ if (Arg.hasByValAttr() &&
+ !Arg.getAttribute(Attribute::ByVal).getValueAsType()) {
Arg.removeAttr(Attribute::ByVal);
Arg.addAttr(Attribute::getWithByValType(
Context, Arg.getType()->getPointerElementType()));
// Adding function arguments to the value table.
for (const auto &I : F.args()) {
EnumerateValue(&I);
- if (I.hasAttribute(Attribute::ByVal) && I.getParamByValType())
+ if (I.hasAttribute(Attribute::ByVal))
EnumerateType(I.getParamByValType());
}
FirstFuncConstantID = Values.size();
// For ByVal, size and alignment should be passed from FE. BE will
// guess if this info is not there but there are cases it cannot get
// right.
- unsigned FrameSize = DL.getTypeAllocSize(
- Arg.getParamByValType() ? Arg.getParamByValType() : ElementTy);
+ unsigned FrameSize = DL.getTypeAllocSize(Arg.getParamByValType());
Flags.setByValSize(FrameSize);
unsigned FrameAlign;
IsSwiftSelf = Call->paramHasAttr(ArgIdx, Attribute::SwiftSelf);
IsSwiftError = Call->paramHasAttr(ArgIdx, Attribute::SwiftError);
Alignment = Call->getParamAlignment(ArgIdx);
- ByValType = Call->getParamByValType(ArgIdx);
+ ByValType = nullptr;
+ if (Call->paramHasAttr(ArgIdx, Attribute::ByVal))
+ ByValType = Call->getParamByValType(ArgIdx);
}
/// Generate a libcall taking the given operands as arguments and returning a
return getParent()->hasParamAttribute(getArgNo(), Kind);
}
+Attribute Argument::getAttribute(Attribute::AttrKind Kind) const {
+ return getParent()->getParamAttribute(getArgNo(), Kind);
+}
+
//===----------------------------------------------------------------------===//
// Helper Methods in Function
//===----------------------------------------------------------------------===//