1 //===-- AttributeSetNode.h - AttributeSet Internal Node ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief This file defines the node class used internally by AttributeSet.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_IR_ATTRIBUTESETNODE_H
16 #define LLVM_IR_ATTRIBUTESETNODE_H
18 #include "llvm/ADT/FoldingSet.h"
19 #include "llvm/IR/Attributes.h"
20 #include "llvm/Support/TrailingObjects.h"
25 //===----------------------------------------------------------------------===//
27 /// \brief This class represents a group of attributes that apply to one
28 /// element: function, return type, or parameter.
29 class AttributeSetNode final
30 : public FoldingSetNode,
31 private TrailingObjects<AttributeSetNode, Attribute> {
32 friend TrailingObjects;
34 unsigned NumAttrs; ///< Number of attributes in this node.
35 /// Bitset with a bit for each available attribute Attribute::AttrKind.
36 uint64_t AvailableAttrs;
38 AttributeSetNode(ArrayRef<Attribute> Attrs)
39 : NumAttrs(Attrs.size()), AvailableAttrs(0) {
40 static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
41 "Too many attributes for AvailableAttrs");
42 // There's memory after the node where we can store the entries in.
43 std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
45 for (Attribute I : *this) {
46 if (!I.isStringAttribute()) {
47 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
52 // AttributesSetNode is uniqued, these should not be publicly available.
53 void operator=(const AttributeSetNode &) = delete;
54 AttributeSetNode(const AttributeSetNode &) = delete;
56 void operator delete(void *p) { ::operator delete(p); }
58 static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
60 static AttributeSetNode *get(AttributeSet AS, unsigned Index) {
61 return AS.getAttributes(Index);
64 /// \brief Return the number of attributes this AttributeSet contains.
65 unsigned getNumAttributes() const { return NumAttrs; }
67 bool hasAttribute(Attribute::AttrKind Kind) const {
68 return AvailableAttrs & ((uint64_t)1) << Kind;
70 bool hasAttribute(StringRef Kind) const;
71 bool hasAttributes() const { return NumAttrs != 0; }
73 Attribute getAttribute(Attribute::AttrKind Kind) const;
74 Attribute getAttribute(StringRef Kind) const;
76 unsigned getAlignment() const;
77 unsigned getStackAlignment() const;
78 uint64_t getDereferenceableBytes() const;
79 uint64_t getDereferenceableOrNullBytes() const;
80 std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
81 std::string getAsString(bool InAttrGrp) const;
83 typedef const Attribute *iterator;
84 iterator begin() const { return getTrailingObjects<Attribute>(); }
85 iterator end() const { return begin() + NumAttrs; }
87 void Profile(FoldingSetNodeID &ID) const {
88 Profile(ID, makeArrayRef(begin(), end()));
90 static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
91 for (unsigned I = 0, E = AttrList.size(); I != E; ++I)
92 AttrList[I].Profile(ID);
96 } // end llvm namespace