Add facility to add/remove/check attribute on function and arguments.

Summary: This comes from work to make attribute manipulable via the C API.

Reviewers: gottesmm, hfinkel, baldrick, echristo, tejohnson

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D18128

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263404 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Amaury Sechet 2016-03-14 01:37:29 +00:00
parent 001e189f49
commit 41d70ebe79
3 changed files with 44 additions and 28 deletions

View File

@ -120,9 +120,20 @@ public:
/// \brief Add a Attribute to an argument.
void addAttr(AttributeSet AS);
void addAttr(Attribute::AttrKind Kind) {
addAttr(AttributeSet::get(getContext(), getArgNo() + 1, Kind));
}
/// \brief Remove a Attribute from an argument.
void removeAttr(AttributeSet AS);
void removeAttr(Attribute::AttrKind Kind) {
removeAttr(AttributeSet::get(getContext(), getArgNo() + 1, Kind));
}
/// \brief Checks if an argument has a given attribute.
bool hasAttribute(Attribute::AttrKind Kind) const;
/// \brief Method for support type inquiry through isa, cast, and
/// dyn_cast.
static inline bool classof(const Value *V) {

View File

@ -238,9 +238,17 @@ public:
/// @brief adds the attributes to the list of attributes.
void addAttributes(unsigned i, AttributeSet attrs);
/// @brief removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind attr);
/// @brief removes the attributes from the list of attributes.
void removeAttributes(unsigned i, AttributeSet attr);
/// @brief check if an attributes is in the list of attributes.
bool hasAttribute(unsigned i, Attribute::AttrKind attr) const {
return getAttributes().hasAttribute(i, attr);
}
/// @brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
@ -316,8 +324,7 @@ public:
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoUnwind);
return hasFnAttribute(Attribute::NoUnwind);
}
void setDoesNotThrow() {
addFnAttr(Attribute::NoUnwind);
@ -325,8 +332,7 @@ public:
/// @brief Determine if the call cannot be duplicated.
bool cannotDuplicate() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoDuplicate);
return hasFnAttribute(Attribute::NoDuplicate);
}
void setCannotDuplicate() {
addFnAttr(Attribute::NoDuplicate);
@ -334,8 +340,7 @@ public:
/// @brief Determine if the call is convergent.
bool isConvergent() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::Convergent);
return hasFnAttribute(Attribute::Convergent);
}
void setConvergent() {
addFnAttr(Attribute::Convergent);
@ -347,8 +352,7 @@ public:
/// Determine if the function is known not to recurse, directly or
/// indirectly.
bool doesNotRecurse() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoRecurse);
return hasFnAttribute(Attribute::NoRecurse);
}
void setDoesNotRecurse() {
addFnAttr(Attribute::NoRecurse);
@ -357,8 +361,7 @@ public:
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::UWTable);
return hasFnAttribute(Attribute::UWTable);
}
void setHasUWTable() {
addFnAttr(Attribute::UWTable);

View File

@ -89,16 +89,14 @@ bool Argument::hasNonNullAttr() const {
/// in its containing function.
bool Argument::hasByValAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::ByVal);
return hasAttribute(Attribute::ByVal);
}
/// \brief Return true if this argument has the inalloca attribute on it in
/// its containing function.
bool Argument::hasInAllocaAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::InAlloca);
return hasAttribute(Attribute::InAlloca);
}
bool Argument::hasByValOrInAllocaAttr() const {
@ -130,53 +128,46 @@ uint64_t Argument::getDereferenceableOrNullBytes() const {
/// it in its containing function.
bool Argument::hasNestAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::Nest);
return hasAttribute(Attribute::Nest);
}
/// hasNoAliasAttr - Return true if this argument has the noalias attribute on
/// it in its containing function.
bool Argument::hasNoAliasAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::NoAlias);
return hasAttribute(Attribute::NoAlias);
}
/// hasNoCaptureAttr - Return true if this argument has the nocapture attribute
/// on it in its containing function.
bool Argument::hasNoCaptureAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::NoCapture);
return hasAttribute(Attribute::NoCapture);
}
/// hasSRetAttr - Return true if this argument has the sret attribute on
/// it in its containing function.
bool Argument::hasStructRetAttr() const {
if (!getType()->isPointerTy()) return false;
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::StructRet);
return hasAttribute(Attribute::StructRet);
}
/// hasReturnedAttr - Return true if this argument has the returned attribute on
/// it in its containing function.
bool Argument::hasReturnedAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::Returned);
return hasAttribute(Attribute::Returned);
}
/// hasZExtAttr - Return true if this argument has the zext attribute on it in
/// its containing function.
bool Argument::hasZExtAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::ZExt);
return hasAttribute(Attribute::ZExt);
}
/// hasSExtAttr Return true if this argument has the sext attribute on it in its
/// containing function.
bool Argument::hasSExtAttr() const {
return getParent()->getAttributes().
hasAttribute(getArgNo()+1, Attribute::SExt);
return hasAttribute(Attribute::SExt);
}
/// Return true if this argument has the readonly or readnone attribute on it
@ -208,6 +199,11 @@ void Argument::removeAttr(AttributeSet AS) {
getArgNo() + 1, B));
}
/// hasAttribute - Checks if an argument has a given attribute.
bool Argument::hasAttribute(Attribute::AttrKind Kind) const {
return getParent()->hasAttribute(getArgNo() + 1, Kind);
}
//===----------------------------------------------------------------------===//
// Helper Methods in Function
//===----------------------------------------------------------------------===//
@ -349,6 +345,12 @@ void Function::addAttributes(unsigned i, AttributeSet attrs) {
setAttributes(PAL);
}
void Function::removeAttribute(unsigned i, Attribute::AttrKind attr) {
AttributeSet PAL = getAttributes();
PAL = PAL.removeAttribute(getContext(), i, attr);
setAttributes(PAL);
}
void Function::removeAttributes(unsigned i, AttributeSet attrs) {
AttributeSet PAL = getAttributes();
PAL = PAL.removeAttributes(getContext(), i, attrs);