Rewrite the removeAttr() method.
[oota-llvm.git] / include / llvm / IR / Attributes.h
index 067e001ac851635ee3329e42502e3333fb2ed8c4..63f9d08837577ac926f11daaad810c9bd02dc2ec 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/MathExtras.h"
 #include <cassert>
 #include <string>
@@ -90,6 +91,7 @@ public:
                            ///< alignstack=(1))
     StackProtect,          ///< Stack protection.
     StackProtectReq,       ///< Stack protection required.
+    StackProtectStrong,    ///< Strong Stack protection.
     StructRet,             ///< Hidden pointer to structure to return
     UWTable,               ///< Function must be in a unwind table
     ZExt,                  ///< Zero extended before/after call
@@ -105,11 +107,15 @@ private:
 public:
   Attribute() : pImpl(0) {}
 
-  /// \brief Return a uniquified Attribute object. This takes the uniquified
-  /// value from the Builder and wraps it in the Attribute class.
-  static Attribute get(LLVMContext &Context, ArrayRef<AttrKind> Vals);
+  /// \brief Return a uniquified Attribute object.
+  static Attribute get(LLVMContext &Context, ArrayRef<AttrKind> Kinds);
   static Attribute get(LLVMContext &Context, AttrBuilder &B);
 
+  /// \brief Return a uniquified Attribute object that has the specific
+  /// alignment set.
+  static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align);
+  static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
+
   /// \brief Return true if the attribute is present.
   bool hasAttribute(AttrKind Val) const;
 
@@ -120,47 +126,29 @@ public:
   /// value.
   unsigned getAlignment() const;
 
-  /// \brief Set the alignment field of an attribute.
-  void setAlignment(unsigned Align);
-
   /// \brief Returns the stack alignment field of an attribute as a byte
   /// alignment value.
   unsigned getStackAlignment() const;
 
-  /// \brief Set the stack alignment field of an attribute.
-  void setStackAlignment(unsigned Align);
-
   /// \brief Equality and non-equality query methods.
   bool operator==(AttrKind K) const;
   bool operator!=(AttrKind K) const;
 
-  // FIXME: Remove these 'operator' methods.
-  bool operator==(const Attribute &A) const {
-    return pImpl == A.pImpl;
-  }
-  bool operator!=(const Attribute &A) const {
-    return pImpl != A.pImpl;
-  }
-
-  uint64_t Raw() const;
-
-  /// \brief Which attributes cannot be applied to a type.
-  static Attribute typeIncompatible(Type *Ty);
+  bool operator==(Attribute A) const { return pImpl == A.pImpl; }
+  bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
 
-  /// \brief 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(Attribute Attrs);
-
-  /// \brief 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 Attribute decodeLLVMAttributesForBitcode(LLVMContext &C,
-                                                  uint64_t EncodedAttrs);
+  /// \brief Less-than operator. Useful for sorting the attributes list.
+  bool operator<(Attribute A) const;
 
   /// \brief The Attribute is converted to a string of equivalent mnemonic. This
   /// is, presumably, for writing out the mnemonics for the assembly writer.
   std::string getAsString() const;
+
+  void Profile(FoldingSetNodeID &ID) const {
+    ID.AddPointer(pImpl);
+  }
+
+  uint64_t Raw() const;
 };
 
 //===----------------------------------------------------------------------===//
@@ -183,44 +171,29 @@ template<> struct DenseMapInfo<Attribute::AttrKind> {
   }
 };
 
+//===----------------------------------------------------------------------===//
+// AttributeSet Smart Pointer
+//===----------------------------------------------------------------------===//
+
+class AttrBuilder;
+class AttributeSetImpl;
+
 //===----------------------------------------------------------------------===//
 /// \class
 /// \brief This is just a pair of values to associate a set of attributes with
 /// an index.
 struct AttributeWithIndex {
   Attribute Attrs;  ///< The attributes that are set, or'd together.
-  Constant *Val;    ///< Value attached to attribute, e.g. alignment.
   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(LLVMContext &C, unsigned Idx,
-                                ArrayRef<Attribute::AttrKind> Attrs) {
-    return get(Idx, Attribute::get(C, Attrs));
-  }
   static AttributeWithIndex get(unsigned Idx, Attribute Attrs) {
     AttributeWithIndex P;
     P.Index = Idx;
     P.Attrs = Attrs;
-    P.Val = 0;
-    return P;
-  }
-  static AttributeWithIndex get(unsigned Idx, Attribute Attrs, Constant *Val) {
-    AttributeWithIndex P;
-    P.Index = Idx;
-    P.Attrs = Attrs;
-    P.Val = Val;
     return P;
   }
 };
 
-//===----------------------------------------------------------------------===//
-// AttributeSet Smart Pointer
-//===----------------------------------------------------------------------===//
-
-class AttrBuilder;
-class AttributeSetImpl;
-
 //===----------------------------------------------------------------------===//
 /// \class
 /// \brief This class manages the ref count for the opaque AttributeSetImpl
@@ -233,76 +206,100 @@ public:
   };
 private:
   friend class AttrBuilder;
+  friend class AttributeSetImpl;
 
   /// \brief The attributes that we are managing.  This can be null to represent
   /// the empty attributes list.
-  AttributeSetImpl *AttrList;
+  AttributeSetImpl *pImpl;
 
   /// \brief The attributes for the specified index are returned.  Attributes
   /// for the result are denoted with Idx = 0.
   Attribute getAttributes(unsigned Idx) const;
 
-  explicit AttributeSet(AttributeSetImpl *LI) : AttrList(LI) {}
+  /// \brief Create an AttributeSet from the AttributeWithIndex structures.
+  /// N.B. this is only temporary. It will be disappearing in the future.
+  static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
+
+  explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {}
 public:
-  AttributeSet() : AttrList(0) {}
-  AttributeSet(const AttributeSet &P) : AttrList(P.AttrList) {}
-  const AttributeSet &operator=(const AttributeSet &RHS);
+  AttributeSet() : pImpl(0) {}
+  AttributeSet(const AttributeSet &P) : pImpl(P.pImpl) {}
+  const AttributeSet &operator=(const AttributeSet &RHS) {
+    pImpl = RHS.pImpl;
+    return *this;
+  }
 
   //===--------------------------------------------------------------------===//
   // Attribute List Construction and Mutation
   //===--------------------------------------------------------------------===//
 
   /// \brief Return an AttributeSet with the specified parameters in it.
-  static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
+  static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
+  static AttributeSet get(LLVMContext &C, unsigned Idx,
+                          ArrayRef<Attribute::AttrKind> Kind);
   static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B);
 
-  /// \brief Add the specified attribute at the specified index to this
-  /// attribute list.  Since attribute lists are immutable, this returns the new
-  /// list.
-  AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+  /// \brief Add an attribute to the attribute set at the given index. Since
+  /// attribute sets are immutable, this returns a new set.
+  AttributeSet addAttribute(LLVMContext &C, unsigned Idx,
+                            Attribute::AttrKind Attr) const;
+
+  /// \brief Add attributes to the attribute set at the given index. Since
+  /// attribute sets are immutable, this returns a new set.
+  AttributeSet addAttributes(LLVMContext &C, unsigned Idx,
+                             AttributeSet Attrs) const;
+
+  /// \brief Add return attributes to this attribute set. Since attribute sets
+  /// are immutable, this returns a new set.
+  AttributeSet addRetAttributes(LLVMContext &C, AttributeSet Attrs) const {
+    return addAttributes(C, ReturnIndex, Attrs);
+  }
 
   /// \brief Add function attributes to this attribute set. Since attribute sets
   /// are immutable, this returns a new set.
-  AttributeSet addFnAttributes(LLVMContext &C, AttributeSet Attrs) const;
+  AttributeSet addFnAttributes(LLVMContext &C, AttributeSet Attrs) const {
+    return addAttributes(C, FunctionIndex, Attrs);
+  }
 
   /// \brief Remove the specified attribute at the specified index from this
-  /// attribute list.  Since attribute lists are immutable, this returns the new
+  /// attribute list. Since attribute lists are immutable, this returns the new
+  /// list.
+  AttributeSet removeAttribute(LLVMContext &C, unsigned Idx, 
+                               Attribute::AttrKind Attr) const;
+
+  /// \brief Remove the specified attributes at the specified index from this
+  /// attribute list. Since attribute lists are immutable, this returns the new
   /// list.
-  AttributeSet removeAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+  AttributeSet removeAttributes(LLVMContext &C, unsigned Idx, 
+                                AttributeSet Attrs) const;
 
   //===--------------------------------------------------------------------===//
-  // Attribute List Accessors
+  // Attribute Set Accessors
   //===--------------------------------------------------------------------===//
 
   /// \brief The attributes for the specified index are returned.
-  Attribute getParamAttributes(unsigned Idx) const {
-    return getAttributes(Idx);
-  }
+  AttributeSet getParamAttributes(unsigned Idx) const;
 
   /// \brief The attributes for the ret value are returned.
-  Attribute getRetAttributes() const {
-    return getAttributes(ReturnIndex);
-  }
+  AttributeSet getRetAttributes() const;
 
   /// \brief The function attributes are returned.
-  Attribute getFnAttributes() const {
-    return getAttributes(FunctionIndex);
-  }
-
-  /// \brief Return the alignment for the specified function parameter.
-  unsigned getParamAlignment(unsigned Idx) const;
+  AttributeSet getFnAttributes() const;
 
   /// \brief Return true if the attribute exists at the given index.
-  bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+  bool hasAttribute(uint64_t Index, Attribute::AttrKind Kind) const;
 
   /// \brief Return true if attribute exists at the given index.
-  bool hasAttributes(unsigned Index) const;
+  bool hasAttributes(uint64_t Index) const;
+
+  /// \brief Return the alignment for the specified function parameter.
+  unsigned getParamAlignment(uint64_t Idx) const;
 
   /// \brief Get the stack alignment.
-  unsigned getStackAlignment(unsigned Index) const;
+  unsigned getStackAlignment(uint64_t Index) const;
 
   /// \brief Return the attributes at the index as a string.
-  std::string getAsString(unsigned Index) const;
+  std::string getAsString(uint64_t Index) const;
 
   uint64_t Raw(unsigned Index) const;
 
@@ -312,10 +309,10 @@ public:
 
   /// operator==/!= - Provide equality predicates.
   bool operator==(const AttributeSet &RHS) const {
-    return AttrList == RHS.AttrList;
+    return pImpl == RHS.pImpl;
   }
   bool operator!=(const AttributeSet &RHS) const {
-    return AttrList != RHS.AttrList;
+    return pImpl != RHS.pImpl;
   }
 
   //===--------------------------------------------------------------------===//
@@ -324,7 +321,7 @@ public:
 
   /// \brief Return a raw pointer that uniquely identifies this attribute list.
   void *getRawPointer() const {
-    return AttrList;
+    return pImpl;
   }
 
   // Attributes are stored as a dense set of slots, where there is one slot for
@@ -333,7 +330,7 @@ public:
 
   /// \brief Return true if there are no attributes.
   bool isEmpty() const {
-    return AttrList == 0;
+    return pImpl == 0;
   }
 
   /// \brief Return the number of slots used in this attribute list.  This is
@@ -341,9 +338,11 @@ public:
   /// function itself).
   unsigned getNumSlots() const;
 
-  /// \brief Return the AttributeWithIndex at the specified slot.  This holds a
-  /// index number plus a set of attributes.
-  const AttributeWithIndex &getSlot(unsigned Slot) const;
+  /// \brief Return the index for the given slot.
+  uint64_t getSlotIndex(unsigned Slot) const;
+
+  /// \brief Return the attributes at the given slot.
+  AttributeSet getSlotAttributes(unsigned Slot) const;
 
   void dump() const;
 };
@@ -376,11 +375,14 @@ public:
   /// \brief Remove an attribute from the builder.
   AttrBuilder &removeAttribute(Attribute::AttrKind Val);
 
-  /// \brief Add the attributes from A to the builder.
-  AttrBuilder &addAttributes(const Attribute &A);
+  /// \brief Add the attributes to the builder.
+  AttrBuilder &addAttributes(Attribute A);
+
+  /// \brief Remove the attributes from the builder.
+  AttrBuilder &removeAttributes(Attribute A);
 
-  /// \brief Remove the attributes from A from the builder.
-  AttrBuilder &removeAttributes(const Attribute &A);
+  /// \brief Add the attributes to the builder.
+  AttrBuilder &addAttributes(AttributeSet A);
 
   /// \brief Return true if the builder has the specified attribute.
   bool contains(Attribute::AttrKind A) const;
@@ -434,6 +436,7 @@ public:
       .removeAttribute(Attribute::OptimizeForSize)
       .removeAttribute(Attribute::StackProtect)
       .removeAttribute(Attribute::StackProtectReq)
+      .removeAttribute(Attribute::StackProtectStrong)
       .removeAttribute(Attribute::NoRedZone)
       .removeAttribute(Attribute::NoImplicitFloat)
       .removeAttribute(Attribute::Naked)
@@ -455,6 +458,24 @@ public:
   }
 };
 
+namespace AttributeFuncs {
+
+/// \brief Which attributes cannot be applied to a type.
+Attribute typeIncompatible(Type *Ty);
+
+/// \brief 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.
+uint64_t encodeLLVMAttributesForBitcode(AttributeSet Attrs, unsigned Index);
+
+/// \brief 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'.
+Attribute decodeLLVMAttributesForBitcode(LLVMContext &C,
+                                         uint64_t EncodedAttrs);
+
+} // end AttributeFuncs namespace
+
 } // end llvm namespace
 
 #endif