blob: fab1ed51e4d6bca223f398742f2b812a055178a0 [file] [log] [blame]
Amaury Sechet17b67cd2016-07-21 04:25:06 +00001//===-- AttributeSetNode.h - AttributeSet Internal Node ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file defines the node class used internally by AttributeSet.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_ATTRIBUTESETNODE_H
16#define LLVM_IR_ATTRIBUTESETNODE_H
17
18#include "llvm/ADT/FoldingSet.h"
19#include "llvm/IR/Attributes.h"
20#include "llvm/Support/TrailingObjects.h"
Amaury Secheted7b7d72016-07-21 04:31:38 +000021#include <climits>
Amaury Sechet17b67cd2016-07-21 04:25:06 +000022
23namespace llvm {
24
25//===----------------------------------------------------------------------===//
26/// \class
27/// \brief This class represents a group of attributes that apply to one
28/// element: function, return type, or parameter.
29class AttributeSetNode final
30 : public FoldingSetNode,
31 private TrailingObjects<AttributeSetNode, Attribute> {
32 friend TrailingObjects;
33
34 unsigned NumAttrs; ///< Number of attributes in this node.
35 /// Bitset with a bit for each available attribute Attribute::AttrKind.
36 uint64_t AvailableAttrs;
37
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>());
44
45 for (Attribute I : *this) {
46 if (!I.isStringAttribute()) {
47 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
48 }
49 }
50 }
51
52 // AttributesSetNode is uniqued, these should not be publicly available.
53 void operator=(const AttributeSetNode &) = delete;
54 AttributeSetNode(const AttributeSetNode &) = delete;
55public:
56 void operator delete(void *p) { ::operator delete(p); }
57
58 static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
59
60 static AttributeSetNode *get(AttributeSet AS, unsigned Index) {
61 return AS.getAttributes(Index);
62 }
63
64 /// \brief Return the number of attributes this AttributeSet contains.
65 unsigned getNumAttributes() const { return NumAttrs; }
66
67 bool hasAttribute(Attribute::AttrKind Kind) const {
68 return AvailableAttrs & ((uint64_t)1) << Kind;
69 }
70 bool hasAttribute(StringRef Kind) const;
71 bool hasAttributes() const { return NumAttrs != 0; }
72
73 Attribute getAttribute(Attribute::AttrKind Kind) const;
74 Attribute getAttribute(StringRef Kind) const;
75
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;
82
83 typedef const Attribute *iterator;
84 iterator begin() const { return getTrailingObjects<Attribute>(); }
85 iterator end() const { return begin() + NumAttrs; }
86
87 void Profile(FoldingSetNodeID &ID) const {
88 Profile(ID, makeArrayRef(begin(), end()));
89 }
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);
93 }
94};
95
96} // end llvm namespace
97
98#endif