#ifndef LLVM_ATTRIBUTES_H
#define LLVM_ATTRIBUTES_H
-#include "llvm/AttributesImpl.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/ArrayRef.h"
#include <cassert>
/// uwtable + nounwind = Needs an entry because the ABI says so.
enum AttrVal {
+ // IR-Level Attributes
None = 0, ///< No attributes have been set
AddressSafety = 1, ///< Address safety checking is on.
Alignment = 2, ///< Alignment of parameter (5 bits)
ZExt = 27 ///< Zero extended before/after call
};
private:
- AttributesImpl Attrs;
-
- explicit Attributes(AttributesImpl *A);
+ AttributesImpl *Attrs;
+ Attributes(AttributesImpl *A);
public:
Attributes() : Attrs(0) {}
- explicit Attributes(uint64_t Val);
- explicit Attributes(LLVMContext &C, AttrVal Val);
Attributes(const Attributes &A);
+ Attributes &operator=(const Attributes &A) {
+ Attrs = A.Attrs;
+ return *this;
+ }
+ /// get - Return a uniquified Attributes object. This takes the uniquified
+ /// value from the Builder and wraps it in the Attributes class.
+ class Builder;
+ static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals);
+ static Attributes get(LLVMContext &Context, Builder &B);
+
+ //===--------------------------------------------------------------------===//
+ /// Attributes::Builder - This class is used in conjunction with the
+ /// Attributes::get method to create an Attributes object. The object itself
+ /// is uniquified. The Builder's value, however, is not. So this can be used
+ /// as a quick way to test for equality, presence of attributes, etc.
class Builder {
friend class Attributes;
uint64_t Bits;
public:
Builder() : Bits(0) {}
+ explicit Builder(uint64_t B) : Bits(B) {}
Builder(const Attributes &A) : Bits(A.Raw()) {}
+ Builder(const Builder &B) : Bits(B.Bits) {}
void clear() { Bits = 0; }
+ /// addAttribute - Add an attribute to the builder.
+ Builder &addAttribute(Attributes::AttrVal Val);
+
+ /// removeAttribute - Remove an attribute from the builder.
+ Builder &removeAttribute(Attributes::AttrVal Val);
+
+ /// addAttribute - Add the attributes from A to the builder.
+ Builder &addAttributes(const Attributes &A);
+
+ /// removeAttribute - Remove the attributes from A from the builder.
+ Builder &removeAttributes(const Attributes &A);
+
+ /// hasAttribute - Return true if the builder has the specified attribute.
bool hasAttribute(Attributes::AttrVal A) const;
+
+ /// hasAttributes - Return true if the builder has IR-level attributes.
bool hasAttributes() const;
+
+ /// hasAttributes - Return true if the builder has any attribute that's in
+ /// the specified attribute.
bool hasAttributes(const Attributes &A) const;
+
+ /// hasAlignmentAttr - Return true if the builder has an alignment
+ /// attribute.
bool hasAlignmentAttr() const;
+ /// getAlignment - Retrieve the alignment attribute, if it exists.
uint64_t getAlignment() const;
- uint64_t getStackAlignment() const;
- Builder &addAttribute(Attributes::AttrVal Val);
- Builder &removeAttribute(Attributes::AttrVal Val);
+ /// getStackAlignment - Retrieve the stack alignment attribute, if it
+ /// exists.
+ uint64_t getStackAlignment() const;
/// addAlignmentAttr - This turns an int alignment (which must be a power of
/// 2) into the form used internally in Attributes.
/// a power of 2) into the form used internally in Attributes.
Builder &addStackAlignmentAttr(unsigned Align);
- void removeAttributes(const Attributes &A);
+ /// addRawValue - Add the raw value to the internal representation.
+ /// N.B. This should be used ONLY for decoding LLVM bitcode!
+ Builder &addRawValue(uint64_t Val);
/// @brief Remove attributes that are used on functions only.
void removeFunctionOnlyAttrs() {
.removeAttribute(Attributes::ReturnsTwice)
.removeAttribute(Attributes::AddressSafety);
}
- };
- /// get - Return a uniquified Attributes object. This takes the uniquified
- /// value from the Builder and wraps it in the Attributes class.
- static Attributes get(Builder &B);
- static Attributes get(LLVMContext &Context, Builder &B);
+ bool operator==(const Builder &B) {
+ return Bits == B.Bits;
+ }
+ bool operator!=(const Builder &B) {
+ return Bits != B.Bits;
+ }
+ };
/// @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();
- }
+ bool hasAttributes() const;
/// @brief Return true if the attributes are a non-null intersection.
bool hasAttributes(const Attributes &A) const;
hasAttribute(Attributes::AddressSafety);
}
- bool isEmptyOrSingleton() const;
-
- // This is a "safe bool() operator".
- operator const void *() const { return Attrs.Bits ? this : 0; }
- bool operator == (const Attributes &A) const {
- return Attrs.Bits == A.Attrs.Bits;
+ bool operator==(const Attributes &A) const {
+ return Attrs == A.Attrs;
}
- bool operator != (const Attributes &A) const {
- return Attrs.Bits != A.Attrs.Bits;
+ bool operator!=(const Attributes &A) const {
+ return Attrs != A.Attrs;
}
- Attributes operator | (const Attributes &A) const;
- Attributes operator & (const Attributes &A) const;
- Attributes operator ^ (const Attributes &A) const;
- Attributes &operator |= (const Attributes &A);
- Attributes &operator &= (const Attributes &A);
- Attributes operator ~ () const;
-
uint64_t Raw() const;
/// @brief Which attributes cannot be applied to a type.
/// containing the LLVM attributes that have been decoded from the given
/// integer. This function must stay in sync with
/// 'encodeLLVMAttributesForBitcode'.
- static Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) {
+ static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C,
+ uint64_t EncodedAttrs) {
// The alignment is stored as a 16-bit raw value from bits 31--16. We shift
// the bits above 31 down by 11 bits.
unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
assert((!Alignment || isPowerOf2_32(Alignment)) &&
"Alignment must be a power of two.");
- Attributes Attrs(EncodedAttrs & 0xffff);
- if (Alignment) {
- Attributes::Builder B;
+ Attributes::Builder B(EncodedAttrs & 0xffff);
+ if (Alignment)
B.addAlignmentAttr(Alignment);
- Attrs |= Attributes::get(B);
- }
- Attrs |= Attributes((EncodedAttrs & (0xfffULL << 32)) >> 11);
- return Attrs;
+ B.addRawValue((EncodedAttrs & (0xfffULL << 32)) >> 11);
+ return Attributes::get(C, B);
}
/// getAsString - The set of Attributes set in Attributes is converted to a
///< Index 0 is used for return value attributes.
///< Index ~0U is used for function attributes.
- static AttributeWithIndex get(unsigned Idx,
+ static AttributeWithIndex get(LLVMContext &C, unsigned Idx,
ArrayRef<Attributes::AttrVal> Attrs) {
Attributes::Builder B;
AttributeWithIndex P;
P.Index = Idx;
- P.Attrs = Attributes::get(B);
+ P.Attrs = Attributes::get(C, B);
return P;
}
static AttributeWithIndex get(unsigned Idx, Attributes Attrs) {
/// AttrListPtr - This class manages the ref count for the opaque
/// AttributeListImpl object and provides accessors for it.
class AttrListPtr {
+public:
+ enum AttrIndex {
+ ReturnIndex = 0U,
+ FunctionIndex = ~0U
+ };
+private:
/// AttrList - The attributes that we are managing. This can be null
/// to represent the empty attributes list.
AttributeListImpl *AttrList;
/// addAttr - Add the specified attribute at the specified index to this
/// attribute list. Since attribute lists are immutable, this
/// returns the new list.
- AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const;
+ AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const;
/// removeAttr - Remove the specified attribute at the specified index from
/// this attribute list. Since attribute lists are immutable, this
/// returns the new list.
- AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const;
+ AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const;
//===--------------------------------------------------------------------===//
// Attribute List Accessors
/// getRetAttributes - The attributes for the ret value are
/// returned.
Attributes getRetAttributes() const {
- return getAttributes(0);
+ return getAttributes(ReturnIndex);
}
/// getFnAttributes - The function attributes are returned.
Attributes getFnAttributes() const {
- return getAttributes(~0U);
+ return getAttributes(FunctionIndex);
}
/// paramHasAttr - Return true if the specified parameter index has the