blob: 2d0144bf8f65cb3de6102197fd8ec8a5c7c96418 [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"
21
22namespace llvm {
23
24//===----------------------------------------------------------------------===//
25/// \class
26/// \brief This class represents a group of attributes that apply to one
27/// element: function, return type, or parameter.
28class AttributeSetNode final
29 : public FoldingSetNode,
30 private TrailingObjects<AttributeSetNode, Attribute> {
31 friend TrailingObjects;
32
33 unsigned NumAttrs; ///< Number of attributes in this node.
34 /// Bitset with a bit for each available attribute Attribute::AttrKind.
35 uint64_t AvailableAttrs;
36
37 AttributeSetNode(ArrayRef<Attribute> Attrs)
38 : NumAttrs(Attrs.size()), AvailableAttrs(0) {
39 static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
40 "Too many attributes for AvailableAttrs");
41 // There's memory after the node where we can store the entries in.
42 std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
43
44 for (Attribute I : *this) {
45 if (!I.isStringAttribute()) {
46 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
47 }
48 }
49 }
50
51 // AttributesSetNode is uniqued, these should not be publicly available.
52 void operator=(const AttributeSetNode &) = delete;
53 AttributeSetNode(const AttributeSetNode &) = delete;
54public:
55 void operator delete(void *p) { ::operator delete(p); }
56
57 static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
58
59 static AttributeSetNode *get(AttributeSet AS, unsigned Index) {
60 return AS.getAttributes(Index);
61 }
62
63 /// \brief Return the number of attributes this AttributeSet contains.
64 unsigned getNumAttributes() const { return NumAttrs; }
65
66 bool hasAttribute(Attribute::AttrKind Kind) const {
67 return AvailableAttrs & ((uint64_t)1) << Kind;
68 }
69 bool hasAttribute(StringRef Kind) const;
70 bool hasAttributes() const { return NumAttrs != 0; }
71
72 Attribute getAttribute(Attribute::AttrKind Kind) const;
73 Attribute getAttribute(StringRef Kind) const;
74
75 unsigned getAlignment() const;
76 unsigned getStackAlignment() const;
77 uint64_t getDereferenceableBytes() const;
78 uint64_t getDereferenceableOrNullBytes() const;
79 std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
80 std::string getAsString(bool InAttrGrp) const;
81
82 typedef const Attribute *iterator;
83 iterator begin() const { return getTrailingObjects<Attribute>(); }
84 iterator end() const { return begin() + NumAttrs; }
85
86 void Profile(FoldingSetNodeID &ID) const {
87 Profile(ID, makeArrayRef(begin(), end()));
88 }
89 static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
90 for (unsigned I = 0, E = AttrList.size(); I != E; ++I)
91 AttrList[I].Profile(ID);
92 }
93};
94
95} // end llvm namespace
96
97#endif