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/ArrayRef.h"
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/IR/Attributes.h"
23 #include "llvm/Support/TrailingObjects.h"
32 //===----------------------------------------------------------------------===//
34 /// \brief This class represents a group of attributes that apply to one
35 /// element: function, return type, or parameter.
36 class AttributeSetNode final
37 : public FoldingSetNode,
38 private TrailingObjects<AttributeSetNode, Attribute> {
39 friend TrailingObjects;
41 unsigned NumAttrs; ///< Number of attributes in this node.
42 /// Bitset with a bit for each available attribute Attribute::AttrKind.
43 uint64_t AvailableAttrs;
45 AttributeSetNode(ArrayRef<Attribute> Attrs)
46 : NumAttrs(Attrs.size()), AvailableAttrs(0) {
47 static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
48 "Too many attributes for AvailableAttrs");
49 // There's memory after the node where we can store the entries in.
50 std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
52 for (Attribute I : *this) {
53 if (!I.isStringAttribute()) {
54 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
60 // AttributesSetNode is uniqued, these should not be available.
61 AttributeSetNode(const AttributeSetNode &) = delete;
62 AttributeSetNode &operator=(const AttributeSetNode &) = delete;
64 void operator delete(void *p) { ::operator delete(p); }
66 static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
68 static AttributeSetNode *get(AttributeSet AS, unsigned Index) {
69 return AS.getAttributes(Index);
72 /// \brief Return the number of attributes this AttributeSet contains.
73 unsigned getNumAttributes() const { return NumAttrs; }
75 bool hasAttribute(Attribute::AttrKind Kind) const {
76 return AvailableAttrs & ((uint64_t)1) << Kind;
78 bool hasAttribute(StringRef Kind) const;
79 bool hasAttributes() const { return NumAttrs != 0; }
81 Attribute getAttribute(Attribute::AttrKind Kind) const;
82 Attribute getAttribute(StringRef Kind) const;
84 unsigned getAlignment() const;
85 unsigned getStackAlignment() const;
86 uint64_t getDereferenceableBytes() const;
87 uint64_t getDereferenceableOrNullBytes() const;
88 std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
89 std::string getAsString(bool InAttrGrp) const;
91 typedef const Attribute *iterator;
92 iterator begin() const { return getTrailingObjects<Attribute>(); }
93 iterator end() const { return begin() + NumAttrs; }
95 void Profile(FoldingSetNodeID &ID) const {
96 Profile(ID, makeArrayRef(begin(), end()));
98 static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
99 for (const auto &Attr : AttrList)
104 } // end namespace llvm
106 #endif // LLVM_IR_ATTRIBUTESETNODE_H