+class EnumAttributeImpl : public AttributeImpl {
+ virtual void anchor();
+ Attribute::AttrKind Kind;
+
+protected:
+ EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind)
+ : AttributeImpl(ID), Kind(Kind) {}
+
+public:
+ EnumAttributeImpl(Attribute::AttrKind Kind)
+ : AttributeImpl(EnumAttrEntry), Kind(Kind) {}
+
+ Attribute::AttrKind getEnumKind() const { return Kind; }
+};
+
+class AlignAttributeImpl : public EnumAttributeImpl {
+ virtual void anchor();
+ unsigned Align;
+
+public:
+ AlignAttributeImpl(Attribute::AttrKind Kind, unsigned Align)
+ : EnumAttributeImpl(AlignAttrEntry, Kind), Align(Align) {
+ assert(
+ (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) &&
+ "Wrong kind for alignment attribute!");
+ }
+
+ unsigned getAlignment() const { return Align; }
+};
+
+class StringAttributeImpl : public AttributeImpl {
+ virtual void anchor();
+ std::string Kind;
+ std::string Val;
+
+public:
+ StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())
+ : AttributeImpl(StringAttrEntry), Kind(Kind), Val(Val) {}
+
+ StringRef getStringKind() const { return Kind; }
+ StringRef getStringValue() const { return Val; }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class represents a group of attributes that apply to one
+/// element: function, return type, or parameter.
+class AttributeSetNode : public FoldingSetNode {
+ unsigned NumAttrs; ///< Number of attributes in this node.
+
+ AttributeSetNode(ArrayRef<Attribute> Attrs) : NumAttrs(Attrs.size()) {
+ // There's memory after the node where we can store the entries in.
+ std::copy(Attrs.begin(), Attrs.end(),
+ reinterpret_cast<Attribute *>(this + 1));
+ }
+
+ // AttributesSetNode is uniqued, these should not be publicly available.
+ void operator=(const AttributeSetNode &) LLVM_DELETED_FUNCTION;
+ AttributeSetNode(const AttributeSetNode &) LLVM_DELETED_FUNCTION;
+public:
+ static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
+
+ bool hasAttribute(Attribute::AttrKind Kind) const;
+ bool hasAttribute(StringRef Kind) const;
+ bool hasAttributes() const { return NumAttrs != 0; }
+
+ Attribute getAttribute(Attribute::AttrKind Kind) const;
+ Attribute getAttribute(StringRef Kind) const;
+
+ unsigned getAlignment() const;
+ unsigned getStackAlignment() const;
+ std::string getAsString(bool InAttrGrp) const;
+
+ typedef const Attribute *iterator;
+ iterator begin() const { return reinterpret_cast<iterator>(this + 1); }
+ iterator end() const { return begin() + NumAttrs; }