Make AttributeSet::getFnAttributes() return an AttributeSet instead of an Attribute.
[oota-llvm.git] / include / llvm / IR / Attributes.h
index 1e5b1bb056d5338643b31c107335d1892356a097..121eae29704a60bb45c9ef9e87142b9d7a0b884a 100644 (file)
@@ -13,8 +13,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_ATTRIBUTES_H
-#define LLVM_ATTRIBUTES_H
+#ifndef LLVM_IR_ATTRIBUTES_H
+#define LLVM_IR_ATTRIBUTES_H
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseSet.h"
@@ -26,6 +26,7 @@ namespace llvm {
 
 class AttrBuilder;
 class AttributeImpl;
+class Constant;
 class LLVMContext;
 class Type;
 
@@ -141,7 +142,7 @@ public:
     return pImpl != A.pImpl;
   }
 
-  uint64_t getBitMask() const;
+  uint64_t Raw() const;
 
   /// \brief Which attributes cannot be applied to a type.
   static Attribute typeIncompatible(Type *Ty);
@@ -182,139 +183,13 @@ template<> struct DenseMapInfo<Attribute::AttrKind> {
   }
 };
 
-//===----------------------------------------------------------------------===//
-/// \class
-/// \brief This class is used in conjunction with the Attribute::get method to
-/// create an Attribute 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 AttrBuilder {
-  DenseSet<Attribute::AttrKind> Attrs;
-  uint64_t Alignment;
-  uint64_t StackAlignment;
-public:
-  AttrBuilder() : Alignment(0), StackAlignment(0) {}
-  explicit AttrBuilder(uint64_t B) : Alignment(0), StackAlignment(0) {
-    addRawValue(B);
-  }
-  AttrBuilder(const Attribute &A) : Alignment(0), StackAlignment(0) {
-    addAttributes(A);
-  }
-
-  void clear();
-
-  /// \brief Add an attribute to the builder.
-  AttrBuilder &addAttribute(Attribute::AttrKind Val);
-
-  /// \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 Remove the attributes from A from the builder.
-  AttrBuilder &removeAttributes(const Attribute &A);
-
-  /// \brief Return true if the builder has the specified attribute.
-  bool contains(Attribute::AttrKind A) const;
-
-  /// \brief Return true if the builder has IR-level attributes.
-  bool hasAttributes() const;
-
-  /// \brief Return true if the builder has any attribute that's in the
-  /// specified attribute.
-  bool hasAttributes(const Attribute &A) const;
-
-  /// \brief Return true if the builder has an alignment attribute.
-  bool hasAlignmentAttr() const;
-
-  /// \brief Retrieve the alignment attribute, if it exists.
-  uint64_t getAlignment() const { return Alignment; }
-
-  /// \brief Retrieve the stack alignment attribute, if it exists.
-  uint64_t getStackAlignment() const { return StackAlignment; }
-
-  /// \brief This turns an int alignment (which must be a power of 2) into the
-  /// form used internally in Attribute.
-  AttrBuilder &addAlignmentAttr(unsigned Align);
-
-  /// \brief This turns an int stack alignment (which must be a power of 2) into
-  /// the form used internally in Attribute.
-  AttrBuilder &addStackAlignmentAttr(unsigned Align);
-
-  typedef DenseSet<Attribute::AttrKind>::iterator       iterator;
-  typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator;
-
-  iterator begin() { return Attrs.begin(); }
-  iterator end()   { return Attrs.end(); }
-
-  const_iterator begin() const { return Attrs.begin(); }
-  const_iterator end() const   { return Attrs.end(); }
-
-  /// \brief Add the raw value to the internal representation.
-  /// 
-  /// N.B. This should be used ONLY for decoding LLVM bitcode!
-  AttrBuilder &addRawValue(uint64_t Val);
-
-  /// \brief Remove attributes that are used on functions only.
-  void removeFunctionOnlyAttrs() {
-    removeAttribute(Attribute::NoReturn)
-      .removeAttribute(Attribute::NoUnwind)
-      .removeAttribute(Attribute::ReadNone)
-      .removeAttribute(Attribute::ReadOnly)
-      .removeAttribute(Attribute::NoInline)
-      .removeAttribute(Attribute::AlwaysInline)
-      .removeAttribute(Attribute::OptimizeForSize)
-      .removeAttribute(Attribute::StackProtect)
-      .removeAttribute(Attribute::StackProtectReq)
-      .removeAttribute(Attribute::NoRedZone)
-      .removeAttribute(Attribute::NoImplicitFloat)
-      .removeAttribute(Attribute::Naked)
-      .removeAttribute(Attribute::InlineHint)
-      .removeAttribute(Attribute::StackAlignment)
-      .removeAttribute(Attribute::UWTable)
-      .removeAttribute(Attribute::NonLazyBind)
-      .removeAttribute(Attribute::ReturnsTwice)
-      .removeAttribute(Attribute::AddressSafety)
-      .removeAttribute(Attribute::MinSize)
-      .removeAttribute(Attribute::NoDuplicate);
-  }
-
-  uint64_t getBitMask() const;
-
-  bool operator==(const AttrBuilder &B);
-  bool operator!=(const AttrBuilder &B) {
-    return !(*this == B);
-  }
-};
-
-//===----------------------------------------------------------------------===//
-/// \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.
-  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;
-    return P;
-  }
-};
-
 //===----------------------------------------------------------------------===//
 // AttributeSet Smart Pointer
 //===----------------------------------------------------------------------===//
 
+class AttrBuilder;
 class AttributeSetImpl;
+struct AttributeWithIndex;
 
 //===----------------------------------------------------------------------===//
 /// \class
@@ -327,6 +202,8 @@ public:
     FunctionIndex = ~0U
   };
 private:
+  friend class AttrBuilder;
+
   /// \brief The attributes that we are managing.  This can be null to represent
   /// the empty attributes list.
   AttributeSetImpl *AttrList;
@@ -354,6 +231,14 @@ public:
   /// list.
   AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attribute 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;
+
+  /// \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;
+
   /// \brief Remove the specified attribute at the specified index from this
   /// attribute list.  Since attribute lists are immutable, this returns the new
   /// list.
@@ -374,14 +259,10 @@ public:
   }
 
   /// \brief The function attributes are returned.
-  Attribute getFnAttributes() const {
-    return getAttributes(FunctionIndex);
-  }
+  AttributeSet getFnAttributes() const;
 
   /// \brief Return the alignment for the specified function parameter.
-  unsigned getParamAlignment(unsigned Idx) const {
-    return getAttributes(Idx).getAlignment();
-  }
+  unsigned getParamAlignment(unsigned Idx) const;
 
   /// \brief Return true if the attribute exists at the given index.
   bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
@@ -395,7 +276,7 @@ public:
   /// \brief Return the attributes at the index as a string.
   std::string getAsString(unsigned Index) const;
 
-  uint64_t getBitMask(unsigned Index) const;
+  uint64_t Raw(unsigned Index) const;
 
   /// \brief Return true if the specified attribute is set for at least one
   /// parameter or for the return value.
@@ -439,6 +320,146 @@ public:
   void dump() const;
 };
 
+//===----------------------------------------------------------------------===//
+/// \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.
+
+  // FIXME: These methods all need to be revised. The first one is temporary.
+  static AttributeWithIndex get(LLVMContext &C, unsigned Idx, AttributeSet AS);
+  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;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class is used in conjunction with the Attribute::get method to
+/// create an Attribute 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 AttrBuilder {
+  DenseSet<Attribute::AttrKind> Attrs;
+  uint64_t Alignment;
+  uint64_t StackAlignment;
+public:
+  AttrBuilder() : Alignment(0), StackAlignment(0) {}
+  explicit AttrBuilder(uint64_t B) : Alignment(0), StackAlignment(0) {
+    addRawValue(B);
+  }
+  AttrBuilder(const Attribute &A) : Alignment(0), StackAlignment(0) {
+    addAttributes(A);
+  }
+  AttrBuilder(AttributeSet AS, unsigned Idx);
+
+  void clear();
+
+  /// \brief Add an attribute to the builder.
+  AttrBuilder &addAttribute(Attribute::AttrKind Val);
+
+  /// \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 Remove the attributes from A from the builder.
+  AttrBuilder &removeAttributes(const Attribute &A);
+
+  /// \brief Return true if the builder has the specified attribute.
+  bool contains(Attribute::AttrKind A) const;
+
+  /// \brief Return true if the builder has IR-level attributes.
+  bool hasAttributes() const;
+
+  /// \brief Return true if the builder has any attribute that's in the
+  /// specified attribute.
+  bool hasAttributes(const Attribute &A) const;
+
+  /// \brief Return true if the builder has an alignment attribute.
+  bool hasAlignmentAttr() const;
+
+  /// \brief Retrieve the alignment attribute, if it exists.
+  uint64_t getAlignment() const { return Alignment; }
+
+  /// \brief Retrieve the stack alignment attribute, if it exists.
+  uint64_t getStackAlignment() const { return StackAlignment; }
+
+  /// \brief This turns an int alignment (which must be a power of 2) into the
+  /// form used internally in Attribute.
+  AttrBuilder &addAlignmentAttr(unsigned Align);
+
+  /// \brief This turns an int stack alignment (which must be a power of 2) into
+  /// the form used internally in Attribute.
+  AttrBuilder &addStackAlignmentAttr(unsigned Align);
+
+  typedef DenseSet<Attribute::AttrKind>::iterator       iterator;
+  typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator;
+
+  iterator begin() { return Attrs.begin(); }
+  iterator end()   { return Attrs.end(); }
+
+  const_iterator begin() const { return Attrs.begin(); }
+  const_iterator end() const   { return Attrs.end(); }
+
+  /// \brief Add the raw value to the internal representation.
+  /// 
+  /// N.B. This should be used ONLY for decoding LLVM bitcode!
+  AttrBuilder &addRawValue(uint64_t Val);
+
+  /// \brief Remove attributes that are used on functions only.
+  void removeFunctionOnlyAttrs() {
+    removeAttribute(Attribute::NoReturn)
+      .removeAttribute(Attribute::NoUnwind)
+      .removeAttribute(Attribute::ReadNone)
+      .removeAttribute(Attribute::ReadOnly)
+      .removeAttribute(Attribute::NoInline)
+      .removeAttribute(Attribute::AlwaysInline)
+      .removeAttribute(Attribute::OptimizeForSize)
+      .removeAttribute(Attribute::StackProtect)
+      .removeAttribute(Attribute::StackProtectReq)
+      .removeAttribute(Attribute::NoRedZone)
+      .removeAttribute(Attribute::NoImplicitFloat)
+      .removeAttribute(Attribute::Naked)
+      .removeAttribute(Attribute::InlineHint)
+      .removeAttribute(Attribute::StackAlignment)
+      .removeAttribute(Attribute::UWTable)
+      .removeAttribute(Attribute::NonLazyBind)
+      .removeAttribute(Attribute::ReturnsTwice)
+      .removeAttribute(Attribute::AddressSafety)
+      .removeAttribute(Attribute::MinSize)
+      .removeAttribute(Attribute::NoDuplicate);
+  }
+
+  uint64_t Raw() const;
+
+  bool operator==(const AttrBuilder &B);
+  bool operator!=(const AttrBuilder &B) {
+    return !(*this == B);
+  }
+};
+
 } // end llvm namespace
 
 #endif