1 //===- AttributeImpl.h - Attribute Internals --------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file defines various helper methods and classes used by
11 /// LLVMContextImpl for creating and managing attributes.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H
16 #define LLVM_LIB_IR_ATTRIBUTEIMPL_H
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/IR/Attributes.h"
22 #include "llvm/Support/TrailingObjects.h"
34 //===----------------------------------------------------------------------===//
36 /// This class represents a single, uniqued attribute. That attribute
37 /// could be a single enum, a tuple, or a string.
38 class AttributeImpl
: public FoldingSetNode
{
39 unsigned char KindID
; ///< Holds the AttrEntryKind of the attribute
49 AttributeImpl(AttrEntryKind KindID
) : KindID(KindID
) {}
52 // AttributesImpl is uniqued, these should not be available.
53 AttributeImpl(const AttributeImpl
&) = delete;
54 AttributeImpl
&operator=(const AttributeImpl
&) = delete;
56 virtual ~AttributeImpl();
58 bool isEnumAttribute() const { return KindID
== EnumAttrEntry
; }
59 bool isIntAttribute() const { return KindID
== IntAttrEntry
; }
60 bool isStringAttribute() const { return KindID
== StringAttrEntry
; }
61 bool isTypeAttribute() const { return KindID
== TypeAttrEntry
; }
63 bool hasAttribute(Attribute::AttrKind A
) const;
64 bool hasAttribute(StringRef Kind
) const;
66 Attribute::AttrKind
getKindAsEnum() const;
67 uint64_t getValueAsInt() const;
69 StringRef
getKindAsString() const;
70 StringRef
getValueAsString() const;
72 Type
*getValueAsType() const;
74 /// Used when sorting the attributes.
75 bool operator<(const AttributeImpl
&AI
) const;
77 void Profile(FoldingSetNodeID
&ID
) const {
78 if (isEnumAttribute())
79 Profile(ID
, getKindAsEnum(), static_cast<uint64_t>(0));
80 else if (isIntAttribute())
81 Profile(ID
, getKindAsEnum(), getValueAsInt());
82 else if (isStringAttribute())
83 Profile(ID
, getKindAsString(), getValueAsString());
85 Profile(ID
, getKindAsEnum(), getValueAsType());
88 static void Profile(FoldingSetNodeID
&ID
, Attribute::AttrKind Kind
,
91 if (Val
) ID
.AddInteger(Val
);
94 static void Profile(FoldingSetNodeID
&ID
, StringRef Kind
, StringRef Values
) {
96 if (!Values
.empty()) ID
.AddString(Values
);
99 static void Profile(FoldingSetNodeID
&ID
, Attribute::AttrKind Kind
,
106 //===----------------------------------------------------------------------===//
108 /// A set of classes that contain the value of the
109 /// attribute object. There are three main categories: enum attribute entries,
110 /// represented by Attribute::AttrKind; alignment attribute entries; and string
111 /// attribute enties, which are for target-dependent attributes.
113 class EnumAttributeImpl
: public AttributeImpl
{
114 virtual void anchor();
116 Attribute::AttrKind Kind
;
119 EnumAttributeImpl(AttrEntryKind ID
, Attribute::AttrKind Kind
)
120 : AttributeImpl(ID
), Kind(Kind
) {}
123 EnumAttributeImpl(Attribute::AttrKind Kind
)
124 : AttributeImpl(EnumAttrEntry
), Kind(Kind
) {}
126 Attribute::AttrKind
getEnumKind() const { return Kind
; }
129 class IntAttributeImpl
: public EnumAttributeImpl
{
132 void anchor() override
;
135 IntAttributeImpl(Attribute::AttrKind Kind
, uint64_t Val
)
136 : EnumAttributeImpl(IntAttrEntry
, Kind
), Val(Val
) {
137 assert((Kind
== Attribute::Alignment
|| Kind
== Attribute::StackAlignment
||
138 Kind
== Attribute::Dereferenceable
||
139 Kind
== Attribute::DereferenceableOrNull
||
140 Kind
== Attribute::AllocSize
) &&
141 "Wrong kind for int attribute!");
144 uint64_t getValue() const { return Val
; }
147 class StringAttributeImpl
: public AttributeImpl
{
148 virtual void anchor();
154 StringAttributeImpl(StringRef Kind
, StringRef Val
= StringRef())
155 : AttributeImpl(StringAttrEntry
), Kind(Kind
), Val(Val
) {}
157 StringRef
getStringKind() const { return Kind
; }
158 StringRef
getStringValue() const { return Val
; }
161 class TypeAttributeImpl
: public EnumAttributeImpl
{
162 void anchor() override
;
167 TypeAttributeImpl(Attribute::AttrKind Kind
, Type
*Ty
)
168 : EnumAttributeImpl(TypeAttrEntry
, Kind
), Ty(Ty
) {}
170 Type
*getTypeValue() const { return Ty
; }
173 //===----------------------------------------------------------------------===//
175 /// This class represents a group of attributes that apply to one
176 /// element: function, return type, or parameter.
177 class AttributeSetNode final
178 : public FoldingSetNode
,
179 private TrailingObjects
<AttributeSetNode
, Attribute
> {
180 friend TrailingObjects
;
182 unsigned NumAttrs
; ///< Number of attributes in this node.
183 /// Bitset with a bit for each available attribute Attribute::AttrKind.
184 uint8_t AvailableAttrs
[12] = {};
186 AttributeSetNode(ArrayRef
<Attribute
> Attrs
);
189 // AttributesSetNode is uniqued, these should not be available.
190 AttributeSetNode(const AttributeSetNode
&) = delete;
191 AttributeSetNode
&operator=(const AttributeSetNode
&) = delete;
193 void operator delete(void *p
) { ::operator delete(p
); }
195 static AttributeSetNode
*get(LLVMContext
&C
, const AttrBuilder
&B
);
197 static AttributeSetNode
*get(LLVMContext
&C
, ArrayRef
<Attribute
> Attrs
);
199 /// Return the number of attributes this AttributeList contains.
200 unsigned getNumAttributes() const { return NumAttrs
; }
202 bool hasAttribute(Attribute::AttrKind Kind
) const {
203 return AvailableAttrs
[Kind
/ 8] & ((uint64_t)1) << (Kind
% 8);
205 bool hasAttribute(StringRef Kind
) const;
206 bool hasAttributes() const { return NumAttrs
!= 0; }
208 Attribute
getAttribute(Attribute::AttrKind Kind
) const;
209 Attribute
getAttribute(StringRef Kind
) const;
211 MaybeAlign
getAlignment() const;
212 MaybeAlign
getStackAlignment() const;
213 uint64_t getDereferenceableBytes() const;
214 uint64_t getDereferenceableOrNullBytes() const;
215 std::pair
<unsigned, Optional
<unsigned>> getAllocSizeArgs() const;
216 std::string
getAsString(bool InAttrGrp
) const;
217 Type
*getByValType() const;
219 using iterator
= const Attribute
*;
221 iterator
begin() const { return getTrailingObjects
<Attribute
>(); }
222 iterator
end() const { return begin() + NumAttrs
; }
224 void Profile(FoldingSetNodeID
&ID
) const {
225 Profile(ID
, makeArrayRef(begin(), end()));
228 static void Profile(FoldingSetNodeID
&ID
, ArrayRef
<Attribute
> AttrList
) {
229 for (const auto &Attr
: AttrList
)
234 using IndexAttrPair
= std::pair
<unsigned, AttributeSet
>;
236 //===----------------------------------------------------------------------===//
238 /// This class represents a set of attributes that apply to the function,
239 /// return type, and parameters.
240 class AttributeListImpl final
241 : public FoldingSetNode
,
242 private TrailingObjects
<AttributeListImpl
, AttributeSet
> {
243 friend class AttributeList
;
244 friend TrailingObjects
;
247 LLVMContext
&Context
;
248 unsigned NumAttrSets
; ///< Number of entries in this set.
249 /// Bitset with a bit for each available attribute Attribute::AttrKind.
250 uint8_t AvailableFunctionAttrs
[12] = {};
252 // Helper fn for TrailingObjects class.
253 size_t numTrailingObjects(OverloadToken
<AttributeSet
>) { return NumAttrSets
; }
256 AttributeListImpl(LLVMContext
&C
, ArrayRef
<AttributeSet
> Sets
);
258 // AttributesSetImpt is uniqued, these should not be available.
259 AttributeListImpl(const AttributeListImpl
&) = delete;
260 AttributeListImpl
&operator=(const AttributeListImpl
&) = delete;
262 void operator delete(void *p
) { ::operator delete(p
); }
264 /// Get the context that created this AttributeListImpl.
265 LLVMContext
&getContext() { return Context
; }
267 /// Return true if the AttributeSet or the FunctionIndex has an
268 /// enum attribute of the given kind.
269 bool hasFnAttribute(Attribute::AttrKind Kind
) const {
270 return AvailableFunctionAttrs
[Kind
/ 8] & ((uint64_t)1) << (Kind
% 8);
273 using iterator
= const AttributeSet
*;
275 iterator
begin() const { return getTrailingObjects
<AttributeSet
>(); }
276 iterator
end() const { return begin() + NumAttrSets
; }
278 void Profile(FoldingSetNodeID
&ID
) const;
279 static void Profile(FoldingSetNodeID
&ID
, ArrayRef
<AttributeSet
> Nodes
);
284 } // end namespace llvm
286 #endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H