/// declarations. This is done to avoid static CTORs and at the same time to
/// keep type-safety of Attributes.
#define DECLARE_LLVM_ATTRIBUTE(name, value) \
- const uint64_t name##_i = value; \
const AttrConst name = {value};
DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set
/// an exception might pass by.
/// uwtable + nounwind = Needs an entry because the ABI says so.
-/// @brief Attributes that only apply to function parameters.
-const AttrConst ParameterOnly = {ByVal_i | Nest_i |
- StructRet_i | NoCapture_i};
-
-/// @brief Attributes that may be applied to the function itself. These cannot
-/// be used on return values or function parameters.
-const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
- ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
- StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
- Naked_i | InlineHint_i | StackAlignment_i |
- UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
-
-/// @brief Parameter attributes that do not apply to vararg call arguments.
-const AttrConst VarArgsIncompatible = {StructRet_i};
-
-/// @brief Attributes that are mutually incompatible.
-const AttrConst MutuallyIncompatible[5] = {
- {ByVal_i | Nest_i | StructRet_i},
- {ByVal_i | Nest_i | InReg_i },
- {ZExt_i | SExt_i},
- {ReadNone_i | ReadOnly_i},
- {NoInline_i | AlwaysInline_i}
-};
-
} // namespace Attribute
/// AttributeImpl - The internal representation of the Attributes class. This is
/// Attributes - A bitset of attributes.
class Attributes {
- // Currently, we need less than 64 bits.
- AttributesImpl Attrs;
-#if 0
- enum Attribute {
- None = 0, ///< No attributes have been set
- ZExt = 1 << 0, ///< Zero extended before/after call
- SExt = 1 << 1, ///< Sign extended before/after call
- NoReturn = 1 << 2, ///< Mark the function as not returning
- InReg = 1 << 3, ///< Force argument to be passed in register
- StructRet = 1 << 4, ///< Hidden pointer to structure to return
- NoUnwind = 1 << 5, ///< Function doesn't unwind stack
- NoAlias = 1 << 6, ///< Considered to not alias after call
- ByVal = 1 << 7, ///< Pass structure by value
- Nest = 1 << 8, ///< Nested function static chain
- ReadNone = 1 << 9, ///< Function does not access memory
- ReadOnly = 1 << 10, ///< Function only reads from memory
- NoInline = 1 << 11, ///< inline=never
- AlwaysInline = 1 << 12, ///< inline=always
- OptimizeForSize = 1 << 13, ///< opt_size
- StackProtect = 1 << 14, ///< Stack protection.
- StackProtectReq = 1 << 15, ///< Stack protection required.
- Alignment = 31 << 16, ///< Alignment of parameter (5 bits)
- ///< stored as log2 of alignment with +1 bias
- ///< 0 means unaligned different from align 1
- NoCapture = 1 << 21, ///< Function creates no aliases of pointer
- NoRedZone = 1 << 22, ///< Disable redzone
- NoImplicitFloat = 1 << 23, ///< Disable implicit floating point insts
- Naked = 1 << 24, ///< Naked function
- InlineHint = 1 << 25, ///< Source said inlining was desirable
- StackAlignment = 7 << 26, ///< Alignment of stack for function (3 bits)
- ///< stored as log2 of alignment with +1 bias 0
- ///< means unaligned (different from
- ///< alignstack={1))
- ReturnsTwice = 1 << 29, ///< Function can return twice
- UWTable = 1 << 30, ///< Function must be in a unwind table
- NonLazyBind = 1U << 31, ///< Function is called early and/or
- ///< often, so lazy binding isn't worthwhile
- AddressSafety = 1ULL << 32 ///< Address safety checking is on.
+public:
+ enum AttrVal {
+ None = 0, ///< No attributes have been set
+ AddressSafety = 1, ///< Address safety checking is on.
+ Alignment = 2, ///< Alignment of parameter (5 bits)
+ ///< stored as log2 of alignment with +1 bias
+ ///< 0 means unaligned different from align 1
+ AlwaysInline = 3, ///< inline=always
+ ByVal = 4, ///< Pass structure by value
+ InlineHint = 5, ///< Source said inlining was desirable
+ InReg = 6, ///< Force argument to be passed in register
+ Naked = 7, ///< Naked function
+ Nest = 8, ///< Nested function static chain
+ NoAlias = 9, ///< Considered to not alias after call
+ NoCapture = 10, ///< Function creates no aliases of pointer
+ NoImplicitFloat = 11, ///< Disable implicit floating point insts
+ NoInline = 12, ///< inline=never
+ NonLazyBind = 13, ///< Function is called early and/or
+ ///< often, so lazy binding isn't worthwhile
+ NoRedZone = 14, ///< Disable redzone
+ NoReturn = 15, ///< Mark the function as not returning
+ NoUnwind = 16, ///< Function doesn't unwind stack
+ OptimizeForSize = 17, ///< opt_size
+ ReadNone = 18, ///< Function does not access memory
+ ReadOnly = 19, ///< Function only reads from memory
+ ReturnsTwice = 20, ///< Function can return twice
+ SExt = 21, ///< Sign extended before/after call
+ StackAlignment = 22, ///< Alignment of stack for function (3 bits)
+ ///< stored as log2 of alignment with +1 bias 0
+ ///< means unaligned (different from
+ ///< alignstack={1))
+ StackProtect = 23, ///< Stack protection.
+ StackProtectReq = 24, ///< Stack protection required.
+ StructRet = 25, ///< Hidden pointer to structure to return
+ UWTable = 26, ///< Function must be in a unwind table
+ ZExt = 27 ///< Zero extended before/after call
};
-#endif
+private:
+ AttributesImpl Attrs;
+
explicit Attributes(AttributesImpl *A);
public:
Attributes() : Attrs(0) {}
void clear() { Bits = 0; }
bool hasAttributes() const;
+ bool hasAttributes(const Attributes &A) const;
bool hasAlignmentAttr() const;
uint64_t getAlignment() const;
- void addAddressSafetyAttr();
- void addAlwaysInlineAttr();
- void addByValAttr();
- void addInlineHintAttr();
- void addInRegAttr();
- void addNakedAttr();
- void addNestAttr();
- void addNoAliasAttr();
- void addNoCaptureAttr();
- void addNoImplicitFloatAttr();
- void addNoInlineAttr();
- void addNonLazyBindAttr();
- void addNoRedZoneAttr();
- void addNoReturnAttr();
- void addNoUnwindAttr();
- void addOptimizeForSizeAttr();
- void addReadNoneAttr();
- void addReadOnlyAttr();
- void addReturnsTwiceAttr();
- void addSExtAttr();
- void addStackProtectAttr();
- void addStackProtectReqAttr();
- void addStructRetAttr();
- void addUWTableAttr();
- void addZExtAttr();
+ Builder &addAttribute(Attributes::AttrVal Val);
+ Builder &removeAttribute(Attributes::AttrVal Val);
void addAlignmentAttr(unsigned Align);
void addStackAlignmentAttr(unsigned Align);
- void removeAddressSafetyAttr();
- void removeAlwaysInlineAttr();
- void removeByValAttr();
- void removeInlineHintAttr();
- void removeInRegAttr();
- void removeNakedAttr();
- void removeNestAttr();
- void removeNoAliasAttr();
- void removeNoCaptureAttr();
- void removeNoImplicitFloatAttr();
- void removeNoInlineAttr();
- void removeNonLazyBindAttr();
- void removeNoRedZoneAttr();
- void removeNoReturnAttr();
- void removeNoUnwindAttr();
- void removeOptimizeForSizeAttr();
- void removeReadNoneAttr();
- void removeReadOnlyAttr();
- void removeReturnsTwiceAttr();
- void removeSExtAttr();
- void removeStackProtectAttr();
- void removeStackProtectReqAttr();
- void removeStructRetAttr();
- void removeUWTableAttr();
- void removeZExtAttr();
-
- void removeAlignmentAttr();
- void removeStackAlignmentAttr();
+ void removeAttributes(const Attributes &A);
+
+ /// @brief Remove attributes that are used on functions only.
+ void removeFunctionOnlyAttrs() {
+ removeAttribute(Attributes::NoReturn)
+ .removeAttribute(Attributes::NoUnwind)
+ .removeAttribute(Attributes::ReadNone)
+ .removeAttribute(Attributes::ReadOnly)
+ .removeAttribute(Attributes::NoInline)
+ .removeAttribute(Attributes::AlwaysInline)
+ .removeAttribute(Attributes::OptimizeForSize)
+ .removeAttribute(Attributes::StackProtect)
+ .removeAttribute(Attributes::StackProtectReq)
+ .removeAttribute(Attributes::NoRedZone)
+ .removeAttribute(Attributes::NoImplicitFloat)
+ .removeAttribute(Attributes::Naked)
+ .removeAttribute(Attributes::InlineHint)
+ .removeAttribute(Attributes::StackAlignment)
+ .removeAttribute(Attributes::UWTable)
+ .removeAttribute(Attributes::NonLazyBind)
+ .removeAttribute(Attributes::ReturnsTwice)
+ .removeAttribute(Attributes::AddressSafety);
+ }
};
/// get - Return a uniquified Attributes object. This takes the uniquified
static Attributes get(Builder &B);
static Attributes get(LLVMContext &Context, Builder &B);
- // Attribute query methods.
- // FIXME: StackAlignment & Alignment attributes have no predicate methods.
+ /// @brief Return true if the attribute is present.
+ bool hasAttribute(AttrVal Val) const;
+
+ /// @brief Return true if attributes exist
bool hasAttributes() const {
return Attrs.hasAttributes();
}
+
+ /// @brief Return true if the attributes are a non-null intersection.
bool hasAttributes(const Attributes &A) const;
- bool hasAddressSafetyAttr() const;
- bool hasAlignmentAttr() const;
- bool hasAlwaysInlineAttr() const;
- bool hasByValAttr() const;
- bool hasInRegAttr() const;
- bool hasInlineHintAttr() const;
- bool hasNakedAttr() const;
- bool hasNestAttr() const;
- bool hasNoAliasAttr() const;
- bool hasNoCaptureAttr() const;
- bool hasNoImplicitFloatAttr() const;
- bool hasNoInlineAttr() const;
- bool hasNonLazyBindAttr() const;
- bool hasNoRedZoneAttr() const;
- bool hasNoReturnAttr() const;
- bool hasNoUnwindAttr() const;
- bool hasOptimizeForSizeAttr() const;
- bool hasReadNoneAttr() const;
- bool hasReadOnlyAttr() const;
- bool hasReturnsTwiceAttr() const;
- bool hasSExtAttr() const;
- bool hasStackAlignmentAttr() const;
- bool hasStackProtectAttr() const;
- bool hasStackProtectReqAttr() const;
- bool hasStructRetAttr() const;
- bool hasUWTableAttr() const;
- bool hasZExtAttr() const;
-
- /// This returns the alignment field of an attribute as a byte alignment
+
+ /// @brief Returns the alignment field of an attribute as a byte alignment
/// value.
unsigned getAlignment() const;
- /// This returns the stack alignment field of an attribute as a byte alignment
- /// value.
+ /// @brief Returns the stack alignment field of an attribute as a byte
+ /// alignment value.
unsigned getStackAlignment() const;
+ /// @brief Parameter attributes that do not apply to vararg call arguments.
+ bool hasIncompatibleWithVarArgsAttrs() const {
+ return hasAttribute(Attributes::StructRet);
+ }
+
+ /// @brief Attributes that only apply to function parameters.
+ bool hasParameterOnlyAttrs() const {
+ return hasAttribute(Attributes::ByVal) ||
+ hasAttribute(Attributes::Nest) ||
+ hasAttribute(Attributes::StructRet) ||
+ hasAttribute(Attributes::NoCapture);
+ }
+
+ /// @brief Attributes that may be applied to the function itself. These cannot
+ /// be used on return values or function parameters.
+ bool hasFunctionOnlyAttrs() const {
+ return hasAttribute(Attributes::NoReturn) ||
+ hasAttribute(Attributes::NoUnwind) ||
+ hasAttribute(Attributes::ReadNone) ||
+ hasAttribute(Attributes::ReadOnly) ||
+ hasAttribute(Attributes::NoInline) ||
+ hasAttribute(Attributes::AlwaysInline) ||
+ hasAttribute(Attributes::OptimizeForSize) ||
+ hasAttribute(Attributes::StackProtect) ||
+ hasAttribute(Attributes::StackProtectReq) ||
+ hasAttribute(Attributes::NoRedZone) ||
+ hasAttribute(Attributes::NoImplicitFloat) ||
+ hasAttribute(Attributes::Naked) ||
+ hasAttribute(Attributes::InlineHint) ||
+ hasAttribute(Attributes::StackAlignment) ||
+ hasAttribute(Attributes::UWTable) ||
+ hasAttribute(Attributes::NonLazyBind) ||
+ hasAttribute(Attributes::ReturnsTwice) ||
+ hasAttribute(Attributes::AddressSafety);
+ }
+
bool isEmptyOrSingleton() const;
// This is a "safe bool() operator".
static Attributes constructAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
- return Attribute::None;
+ return Attributes();
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x40000000 && "Alignment too large.");
static Attributes constructStackAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
- return Attribute::None;
+ return Attributes();
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x100 && "Alignment too large.");
// 5-bit log2 encoded value. Shift the bits above the alignment up by 11
// bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
- if (Attrs.hasAlignmentAttr())
- EncodedAttrs |= (1ULL << 16) <<
- (((Attrs.Raw() & Attribute::Alignment_i) - 1) >> 16);
+ if (Attrs.hasAttribute(Attributes::Alignment))
+ EncodedAttrs |= Attrs.getAlignment() << 16;
EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
return EncodedAttrs;
}
/// least one parameter or for the return value.
bool hasAttrSomewhere(Attributes Attr) const;
+ unsigned getNumAttrs() const;
+ Attributes &getAttributesAtIndex(unsigned i) const;
+
/// operator==/!= - Provide equality predicates.
bool operator==(const AttrListPtr &RHS) const
{ return AttrList == RHS.AttrList; }
/// getAttributes - The attributes for the specified index are
/// returned. Attributes for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
-
};
} // End llvm namespace