Remove the now dead VarArgsIncompatible variable.
[oota-llvm.git] / include / llvm / Attributes.h
index fe0cc353c1f85ac502447061151323aa13c3d5a0..2a0fbc0ee13fe74d3365d7c070794b02b9cf0e16 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef LLVM_ATTRIBUTES_H
 #define LLVM_ATTRIBUTES_H
 
+#include "llvm/AttributesImpl.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/ArrayRef.h"
 #include <cassert>
 
 namespace llvm {
 
+class LLVMContext;
 class Type;
 
 namespace Attribute {
 
-/// We use this proxy POD type to allow constructing Attributes constants using
-/// initializer lists. Do not use this class directly.
+/// AttrConst - We use this proxy POD type to allow constructing Attributes
+/// constants using initializer lists. Do not use this class directly.
 struct AttrConst {
   uint64_t v;
   AttrConst operator | (const AttrConst Attrs) const {
@@ -96,135 +98,6 @@ DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is o
 
 #undef DECLARE_LLVM_ATTRIBUTE
 
-}  // namespace Attribute
-
-/// Attributes - A bitset of attributes.
-class Attributes {
-  // Currently, we need less than 64 bits.
-  uint64_t Bits;
-public:
-  Attributes() : Bits(0) { }
-  explicit Attributes(uint64_t Val) : Bits(Val) { }
-  /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
-
-  // Attribute query methods.
-  // FIXME: StackAlignment & Alignment attributes have no predicate methods.
-  bool hasAttributes() const { return Bits != 0; }
-
-  bool hasZExtAttr() const {
-    return Bits & Attribute::ZExt_i;
-  }
-  bool hasSExtAttr() const {
-    return Bits & Attribute::SExt_i;
-  }
-  bool hasNoReturnAttr() const {
-    return Bits & Attribute::NoReturn_i;
-  }
-  bool hasInRegAttr() const {
-    return Bits & Attribute::InReg_i;
-  }
-  bool hasStructRetAttr() const {
-    return Bits & Attribute::StructRet_i;
-  }
-  bool hasNoUnwindAttr() const {
-    return Bits & Attribute::NoUnwind_i;
-  }
-  bool hasNoAliasAttr() const {
-    return Bits & Attribute::NoAlias_i;
-  }
-  bool hasByValAttr() const {
-    return Bits & Attribute::ByVal_i;
-  }
-  bool hasNestAttr() const {
-    return Bits & Attribute::Nest_i;
-  }
-  bool hasReadNoneAttr() const {
-    return Bits & Attribute::ReadNone_i;
-  }
-  bool hasReadOnlyAttr() const {
-    return Bits & Attribute::ReadOnly_i;
-  }
-  bool hasNoInlineAttr() const {
-    return Bits & Attribute::NoInline_i;
-  }
-  bool hasAlwaysInlineAttr() const {
-    return Bits & Attribute::AlwaysInline_i;
-  }
-  bool hasOptimizeForSizeAttr() const {
-    return Bits & Attribute::OptimizeForSize_i;
-  }
-  bool hasStackProtectAttr() const {
-    return Bits & Attribute::StackProtect_i;
-  }
-  bool hasStackProtectReqAttr() const {
-    return Bits & Attribute::StackProtectReq_i;
-  }
-  bool hasNoCaptureAttr() const {
-    return Bits & Attribute::NoCapture_i;
-  }
-  bool hasNoRedZoneAttr() const {
-    return Bits & Attribute::NoRedZone_i;
-  }
-  bool hasNoImplicitFloatAttr() const {
-    return Bits & Attribute::NoImplicitFloat_i;
-  }
-  bool hasNakedAttr() const {
-    return Bits & Attribute::Naked_i;
-  }
-  bool hasInlineHintAttr() const {
-    return Bits & Attribute::InlineHint_i;
-  }
-  bool hasReturnsTwiceAttr() const {
-    return Bits & Attribute::ReturnsTwice_i;
-  }
-  bool hasUWTableAttr() const {
-    return Bits & Attribute::UWTable_i;
-  }
-  bool hasNonLazyBindAttr() const {
-    return Bits & Attribute::NonLazyBind_i;
-  }
-  bool hasAddressSafetyAttr() const {
-    return Bits & Attribute::AddressSafety_i;
-  }
-
-  // This is a "safe bool() operator".
-  operator const void *() const { return Bits ? this : 0; }
-  bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
-  bool operator == (const Attributes &Attrs) const {
-    return Bits == Attrs.Bits;
-  }
-  bool operator != (const Attributes &Attrs) const {
-    return Bits != Attrs.Bits;
-  }
-  Attributes operator | (const Attributes &Attrs) const {
-    return Attributes(Bits | Attrs.Bits);
-  }
-  Attributes operator & (const Attributes &Attrs) const {
-    return Attributes(Bits & Attrs.Bits);
-  }
-  Attributes operator ^ (const Attributes &Attrs) const {
-    return Attributes(Bits ^ Attrs.Bits);
-  }
-  Attributes &operator |= (const Attributes &Attrs) {
-    Bits |= Attrs.Bits;
-    return *this;
-  }
-  Attributes &operator &= (const Attributes &Attrs) {
-    Bits &= Attrs.Bits;
-    return *this;
-  }
-  Attributes operator ~ () const { return Attributes(~Bits); }
-  uint64_t Raw() const { return Bits; }
-
-  /// The set of Attributes set in Attributes is converted to a string of
-  /// equivalent mnemonics. This is, presumably, for writing out the mnemonics
-  /// for the assembly writer.
-  /// @brief Convert attribute bits to text
-  std::string getAsString() const;
-};
-
-namespace Attribute {
-
 /// Note that uwtable is about the ABI or the user mandating an entry in the
 /// unwind table. The nounwind attribute is about an exception passing by the
 /// function.
@@ -249,9 +122,6 @@ const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_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},
@@ -261,105 +131,219 @@ const AttrConst MutuallyIncompatible[5] = {
   {NoInline_i | AlwaysInline_i}
 };
 
-/// @brief Which attributes cannot be applied to a type.
-Attributes typeIncompatible(Type *Ty);
-
-/// This turns an int alignment (a power of 2, normally) into the
-/// form used internally in Attributes.
-inline Attributes constructAlignmentFromInt(unsigned i) {
-  // Default alignment, allow the target to define how to align it.
-  if (i == 0)
-    return None;
-
-  assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
-  assert(i <= 0x40000000 && "Alignment too large.");
-  return Attributes((Log2_32(i)+1) << 16);
-}
-
-/// This returns the alignment field of an attribute as a byte alignment value.
-inline unsigned getAlignmentFromAttrs(Attributes A) {
-  Attributes Align = A & Attribute::Alignment;
-  if (!Align)
-    return 0;
-
-  return 1U << ((Align.Raw() >> 16) - 1);
-}
-
-/// This turns an int stack alignment (which must be a power of 2) into
-/// the form used internally in Attributes.
-inline Attributes constructStackAlignmentFromInt(unsigned i) {
-  // Default alignment, allow the target to define how to align it.
-  if (i == 0)
-    return None;
-
-  assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
-  assert(i <= 0x100 && "Alignment too large.");
-  return Attributes((Log2_32(i)+1) << 26);
-}
-
-/// This returns the stack alignment field of an attribute as a byte alignment
-/// value.
-inline unsigned getStackAlignmentFromAttrs(Attributes A) {
-  Attributes StackAlign = A & Attribute::StackAlignment;
-  if (!StackAlign)
-    return 0;
-
-  return 1U << ((StackAlign.Raw() >> 26) - 1);
-}
-
-/// This returns an integer containing an encoding of all the
-/// LLVM attributes found in the given attribute bitset.  Any
-/// change to this encoding is a breaking change to bitcode
-/// compatibility.
-inline uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
-  // FIXME: It doesn't make sense to store the alignment information as an
-  // expanded out value, we should store it as a log2 value.  However, we can't
-  // just change that here without breaking bitcode compatibility.  If this ever
-  // becomes a problem in practice, we should introduce new tag numbers in the
-  // bitcode file and have those tags use a more efficiently encoded alignment
-  // field.
-
-  // Store the alignment in the bitcode as a 16-bit raw value instead of a
-  // 5-bit log2 encoded value. Shift the bits above the alignment up by
-  // 11 bits.
-
-  uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
-  if (Attrs & Attribute::Alignment)
-    EncodedAttrs |= (1ull << 16) <<
-      (((Attrs & Attribute::Alignment).Raw()-1) >> 16);
-  EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
-
-  return EncodedAttrs;
-}
-
-/// This returns an attribute bitset containing the LLVM attributes
-/// that have been decoded from the given integer.  This function
-/// must stay in sync with 'encodeLLVMAttributesForBitcode'.
-inline Attributes decodeLLVMAttributesForBitcode(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)
-    Attrs |= Attribute::constructAlignmentFromInt(Alignment);
-  Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
-
-  return Attrs;
-}
-
-} // end namespace Attribute
-
-/// This is just a pair of values to associate a set of attributes
-/// with an index.
+}  // namespace Attribute
+
+/// AttributeImpl - The internal representation of the Attributes class. This is
+/// uniquified.
+class AttributesImpl;
+
+/// Attributes - A bitset of attributes.
+class Attributes {
+public:
+  enum AttrVal {
+    None            = 0,   ///< No attributes have been set
+    ZExt            = 1,   ///< Zero extended before/after call
+    SExt            = 2,   ///< Sign extended before/after call
+    NoReturn        = 3,   ///< Mark the function as not returning
+    InReg           = 4,   ///< Force argument to be passed in register
+    StructRet       = 5,   ///< Hidden pointer to structure to return
+    NoUnwind        = 6,   ///< Function doesn't unwind stack
+    NoAlias         = 7,   ///< Considered to not alias after call
+    ByVal           = 8,   ///< Pass structure by value
+    Nest            = 9,   ///< Nested function static chain
+    ReadNone        = 10,  ///< Function does not access memory
+    ReadOnly        = 11,  ///< Function only reads from memory
+    NoInline        = 12,  ///< inline=never
+    AlwaysInline    = 13,  ///< inline=always
+    OptimizeForSize = 14,  ///< opt_size
+    StackProtect    = 15,  ///< Stack protection.
+    StackProtectReq = 16,  ///< Stack protection required.
+    Alignment       = 17,  ///< Alignment of parameter (5 bits)
+                           ///< stored as log2 of alignment with +1 bias
+                           ///< 0 means unaligned different from align 1
+    NoCapture       = 18,  ///< Function creates no aliases of pointer
+    NoRedZone       = 19,  ///< Disable redzone
+    NoImplicitFloat = 20,  ///< Disable implicit floating point insts
+    Naked           = 21,  ///< Naked function
+    InlineHint      = 22,  ///< Source said inlining was desirable
+    StackAlignment  = 23,  ///< Alignment of stack for function (3 bits)
+                           ///< stored as log2 of alignment with +1 bias 0
+                           ///< means unaligned (different from
+                           ///< alignstack={1))
+    ReturnsTwice    = 24,  ///< Function can return twice
+    UWTable         = 25,  ///< Function must be in a unwind table
+    NonLazyBind     = 26,  ///< Function is called early and/or
+                           ///< often, so lazy binding isn't worthwhile
+    AddressSafety   = 27   ///< Address safety checking is on.
+  };
+private:
+  AttributesImpl Attrs;
+
+  explicit Attributes(AttributesImpl *A);
+public:
+  Attributes() : Attrs(0) {}
+  explicit Attributes(uint64_t Val);
+  /*implicit*/ Attributes(Attribute::AttrConst Val);
+  Attributes(const Attributes &A);
+
+  class Builder {
+    friend class Attributes;
+    uint64_t Bits;
+  public:
+    Builder() : Bits(0) {}
+    Builder(const Attributes &A) : Bits(A.Raw()) {}
+
+    void clear() { Bits = 0; }
+
+    bool hasAttributes() const;
+    bool hasAttributes(const Attributes &A) const;
+    bool hasAlignmentAttr() const;
+
+    uint64_t getAlignment() const;
+
+    void addAttribute(Attributes::AttrVal Val);
+    void removeAttribute(Attributes::AttrVal Val);
+
+    void addAlignmentAttr(unsigned Align);
+    void addStackAlignmentAttr(unsigned Align);
+
+    void removeAttributes(const Attributes &A);
+  };
+
+  /// 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);
+
+  /// @brief Parameter attributes that do not apply to vararg call arguments.
+  bool hasIncompatibleWithVarArgsAttrs() const {
+    return hasAttribute(Attributes::StructRet);
+  }
+
+  /// @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;
+
+  /// This 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.
+  unsigned getStackAlignment() const;
+
+  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.Bits != A.Attrs.Bits;
+  }
+
+  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;
+
+  /// constructAlignmentFromInt - This turns an int alignment (a power of 2,
+  /// normally) into the form used internally in Attributes.
+  static Attributes constructAlignmentFromInt(unsigned i) {
+    // Default alignment, allow the target to define how to align it.
+    if (i == 0)
+      return Attribute::None;
+
+    assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+    assert(i <= 0x40000000 && "Alignment too large.");
+    return Attributes((Log2_32(i)+1) << 16);
+  }
+
+  /// constructStackAlignmentFromInt - This turns an int stack alignment (which
+  /// must be a power of 2) into the form used internally in Attributes.
+  static Attributes constructStackAlignmentFromInt(unsigned i) {
+    // Default alignment, allow the target to define how to align it.
+    if (i == 0)
+      return Attribute::None;
+
+    assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+    assert(i <= 0x100 && "Alignment too large.");
+    return Attributes((Log2_32(i)+1) << 26);
+  }
+
+  /// @brief Which attributes cannot be applied to a type.
+  static Attributes typeIncompatible(Type *Ty);
+
+  /// encodeLLVMAttributesForBitcode - This returns an integer containing an
+  /// encoding of all the LLVM attributes found in the given attribute bitset.
+  /// Any change to this encoding is a breaking change to bitcode compatibility.
+  static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
+    // FIXME: It doesn't make sense to store the alignment information as an
+    // expanded out value, we should store it as a log2 value.  However, we
+    // can't just change that here without breaking bitcode compatibility.  If
+    // this ever becomes a problem in practice, we should introduce new tag
+    // numbers in the bitcode file and have those tags use a more efficiently
+    // encoded alignment field.
+
+    // Store the alignment in the bitcode as a 16-bit raw value instead of a
+    // 5-bit log2 encoded value. Shift the bits above the alignment up by 11
+    // bits.
+    uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
+    if (Attrs.hasAttribute(Attributes::Alignment))
+      EncodedAttrs |= (1ULL << 16) <<
+        (((Attrs.Raw() & Attribute::Alignment_i) - 1) >> 16);
+    EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
+    return EncodedAttrs;
+  }
+
+  /// decodeLLVMAttributesForBitcode - This returns an attribute bitset
+  /// 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) {
+    // 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)
+      Attrs |= Attributes::constructAlignmentFromInt(Alignment);
+    Attrs |= Attributes((EncodedAttrs & (0xfffULL << 32)) >> 11);
+    return Attrs;
+  }
+
+  /// getAsString - The set of Attributes set in Attributes is converted to a
+  /// string of equivalent mnemonics. This is, presumably, for writing out the
+  /// mnemonics for the assembly writer.
+  /// @brief Convert attribute bits to text
+  std::string getAsString() const;
+};
+
+//===----------------------------------------------------------------------===//
+// AttributeWithIndex
+//===----------------------------------------------------------------------===//
+
+/// AttributeWithIndex - This is just a pair of values to associate a set of
+/// attributes with an index.
 struct AttributeWithIndex {
-  Attributes Attrs; ///< The attributes that are set, or'd together.
-  unsigned Index; ///< Index of the parameter for which the attributes apply.
-                  ///< Index 0 is used for return value attributes.
-                  ///< Index ~0U is used for function attributes.
+  Attributes Attrs;  ///< The attributes that are set, or'd together.
+  unsigned Index;    ///< Index of the parameter for which the attributes apply.
+                     ///< Index 0 is used for return value attributes.
+                     ///< Index ~0U is used for function attributes.
 
   static AttributeWithIndex get(unsigned Idx, Attributes Attrs) {
     AttributeWithIndex P;
@@ -410,7 +394,6 @@ public:
   /// getParamAttributes - The attributes for the specified index are
   /// returned.
   Attributes getParamAttributes(unsigned Idx) const {
-    assert (Idx && Idx != ~0U && "Invalid parameter index!");
     return getAttributes(Idx);
   }
 
@@ -428,19 +411,22 @@ public:
   /// paramHasAttr - Return true if the specified parameter index has the
   /// specified attribute set.
   bool paramHasAttr(unsigned Idx, Attributes Attr) const {
-    return getAttributes(Idx) & Attr;
+    return getAttributes(Idx).hasAttributes(Attr);
   }
 
   /// getParamAlignment - Return the alignment for the specified function
   /// parameter.
   unsigned getParamAlignment(unsigned Idx) const {
-    return Attribute::getAlignmentFromAttrs(getAttributes(Idx));
+    return getAttributes(Idx).getAlignment();
   }
 
   /// hasAttrSomewhere - Return true if the specified attribute is set for at
   /// 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; }
@@ -484,7 +470,6 @@ private:
   /// 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