1 //===- AttributeImpl.h - Attribute Internals --------------------*- 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 /// This file defines various helper methods and classes used by 12 /// LLVMContextImpl for creating and managing attributes. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H 17 #define LLVM_LIB_IR_ATTRIBUTEIMPL_H 18 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/ADT/FoldingSet.h" 21 #include "llvm/ADT/StringRef.h" 22 #include "llvm/IR/Attributes.h" 23 #include "llvm/Support/TrailingObjects.h" 24 #include <cassert> 25 #include <cstddef> 26 #include <cstdint> 27 #include <string> 28 #include <utility> 29 30 namespace llvm { 31 32 class LLVMContext; 33 34 //===----------------------------------------------------------------------===// 35 /// \class 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 40 41 protected: 42 enum AttrEntryKind { 43 EnumAttrEntry, 44 IntAttrEntry, 45 StringAttrEntry 46 }; 47 AttributeImpl(AttrEntryKind KindID)48 AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {} 49 50 public: 51 // AttributesImpl is uniqued, these should not be available. 52 AttributeImpl(const AttributeImpl &) = delete; 53 AttributeImpl &operator=(const AttributeImpl &) = delete; 54 55 virtual ~AttributeImpl(); 56 isEnumAttribute()57 bool isEnumAttribute() const { return KindID == EnumAttrEntry; } isIntAttribute()58 bool isIntAttribute() const { return KindID == IntAttrEntry; } isStringAttribute()59 bool isStringAttribute() const { return KindID == StringAttrEntry; } 60 61 bool hasAttribute(Attribute::AttrKind A) const; 62 bool hasAttribute(StringRef Kind) const; 63 64 Attribute::AttrKind getKindAsEnum() const; 65 uint64_t getValueAsInt() const; 66 67 StringRef getKindAsString() const; 68 StringRef getValueAsString() const; 69 70 /// Used when sorting the attributes. 71 bool operator<(const AttributeImpl &AI) const; 72 Profile(FoldingSetNodeID & ID)73 void Profile(FoldingSetNodeID &ID) const { 74 if (isEnumAttribute()) 75 Profile(ID, getKindAsEnum(), 0); 76 else if (isIntAttribute()) 77 Profile(ID, getKindAsEnum(), getValueAsInt()); 78 else 79 Profile(ID, getKindAsString(), getValueAsString()); 80 } 81 Profile(FoldingSetNodeID & ID,Attribute::AttrKind Kind,uint64_t Val)82 static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind, 83 uint64_t Val) { 84 ID.AddInteger(Kind); 85 if (Val) ID.AddInteger(Val); 86 } 87 Profile(FoldingSetNodeID & ID,StringRef Kind,StringRef Values)88 static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) { 89 ID.AddString(Kind); 90 if (!Values.empty()) ID.AddString(Values); 91 } 92 }; 93 94 //===----------------------------------------------------------------------===// 95 /// \class 96 /// A set of classes that contain the value of the 97 /// attribute object. There are three main categories: enum attribute entries, 98 /// represented by Attribute::AttrKind; alignment attribute entries; and string 99 /// attribute enties, which are for target-dependent attributes. 100 101 class EnumAttributeImpl : public AttributeImpl { 102 virtual void anchor(); 103 104 Attribute::AttrKind Kind; 105 106 protected: EnumAttributeImpl(AttrEntryKind ID,Attribute::AttrKind Kind)107 EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind) 108 : AttributeImpl(ID), Kind(Kind) {} 109 110 public: EnumAttributeImpl(Attribute::AttrKind Kind)111 EnumAttributeImpl(Attribute::AttrKind Kind) 112 : AttributeImpl(EnumAttrEntry), Kind(Kind) {} 113 getEnumKind()114 Attribute::AttrKind getEnumKind() const { return Kind; } 115 }; 116 117 class IntAttributeImpl : public EnumAttributeImpl { 118 uint64_t Val; 119 120 void anchor() override; 121 122 public: IntAttributeImpl(Attribute::AttrKind Kind,uint64_t Val)123 IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val) 124 : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) { 125 assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment || 126 Kind == Attribute::Dereferenceable || 127 Kind == Attribute::DereferenceableOrNull || 128 Kind == Attribute::AllocSize) && 129 "Wrong kind for int attribute!"); 130 } 131 getValue()132 uint64_t getValue() const { return Val; } 133 }; 134 135 class StringAttributeImpl : public AttributeImpl { 136 virtual void anchor(); 137 138 std::string Kind; 139 std::string Val; 140 141 public: 142 StringAttributeImpl(StringRef Kind, StringRef Val = StringRef()) AttributeImpl(StringAttrEntry)143 : AttributeImpl(StringAttrEntry), Kind(Kind), Val(Val) {} 144 getStringKind()145 StringRef getStringKind() const { return Kind; } getStringValue()146 StringRef getStringValue() const { return Val; } 147 }; 148 149 //===----------------------------------------------------------------------===// 150 /// \class 151 /// This class represents a group of attributes that apply to one 152 /// element: function, return type, or parameter. 153 class AttributeSetNode final 154 : public FoldingSetNode, 155 private TrailingObjects<AttributeSetNode, Attribute> { 156 friend TrailingObjects; 157 158 /// Bitset with a bit for each available attribute Attribute::AttrKind. 159 uint64_t AvailableAttrs; 160 unsigned NumAttrs; ///< Number of attributes in this node. 161 162 AttributeSetNode(ArrayRef<Attribute> Attrs); 163 164 public: 165 // AttributesSetNode is uniqued, these should not be available. 166 AttributeSetNode(const AttributeSetNode &) = delete; 167 AttributeSetNode &operator=(const AttributeSetNode &) = delete; 168 delete(void * p)169 void operator delete(void *p) { ::operator delete(p); } 170 171 static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B); 172 173 static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs); 174 175 /// Return the number of attributes this AttributeList contains. getNumAttributes()176 unsigned getNumAttributes() const { return NumAttrs; } 177 hasAttribute(Attribute::AttrKind Kind)178 bool hasAttribute(Attribute::AttrKind Kind) const { 179 return AvailableAttrs & ((uint64_t)1) << Kind; 180 } 181 bool hasAttribute(StringRef Kind) const; hasAttributes()182 bool hasAttributes() const { return NumAttrs != 0; } 183 184 Attribute getAttribute(Attribute::AttrKind Kind) const; 185 Attribute getAttribute(StringRef Kind) const; 186 187 unsigned getAlignment() const; 188 unsigned getStackAlignment() const; 189 uint64_t getDereferenceableBytes() const; 190 uint64_t getDereferenceableOrNullBytes() const; 191 std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; 192 std::string getAsString(bool InAttrGrp) const; 193 194 using iterator = const Attribute *; 195 begin()196 iterator begin() const { return getTrailingObjects<Attribute>(); } end()197 iterator end() const { return begin() + NumAttrs; } 198 Profile(FoldingSetNodeID & ID)199 void Profile(FoldingSetNodeID &ID) const { 200 Profile(ID, makeArrayRef(begin(), end())); 201 } 202 Profile(FoldingSetNodeID & ID,ArrayRef<Attribute> AttrList)203 static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) { 204 for (const auto &Attr : AttrList) 205 Attr.Profile(ID); 206 } 207 }; 208 209 using IndexAttrPair = std::pair<unsigned, AttributeSet>; 210 211 //===----------------------------------------------------------------------===// 212 /// \class 213 /// This class represents a set of attributes that apply to the function, 214 /// return type, and parameters. 215 class AttributeListImpl final 216 : public FoldingSetNode, 217 private TrailingObjects<AttributeListImpl, AttributeSet> { 218 friend class AttributeList; 219 friend TrailingObjects; 220 221 private: 222 /// Bitset with a bit for each available attribute Attribute::AttrKind. 223 uint64_t AvailableFunctionAttrs; 224 LLVMContext &Context; 225 unsigned NumAttrSets; ///< Number of entries in this set. 226 227 // Helper fn for TrailingObjects class. numTrailingObjects(OverloadToken<AttributeSet>)228 size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; } 229 230 public: 231 AttributeListImpl(LLVMContext &C, ArrayRef<AttributeSet> Sets); 232 233 // AttributesSetImpt is uniqued, these should not be available. 234 AttributeListImpl(const AttributeListImpl &) = delete; 235 AttributeListImpl &operator=(const AttributeListImpl &) = delete; 236 delete(void * p)237 void operator delete(void *p) { ::operator delete(p); } 238 239 /// Get the context that created this AttributeListImpl. getContext()240 LLVMContext &getContext() { return Context; } 241 242 /// Return true if the AttributeSet or the FunctionIndex has an 243 /// enum attribute of the given kind. hasFnAttribute(Attribute::AttrKind Kind)244 bool hasFnAttribute(Attribute::AttrKind Kind) const { 245 return AvailableFunctionAttrs & ((uint64_t)1) << Kind; 246 } 247 248 using iterator = const AttributeSet *; 249 begin()250 iterator begin() const { return getTrailingObjects<AttributeSet>(); } end()251 iterator end() const { return begin() + NumAttrSets; } 252 253 void Profile(FoldingSetNodeID &ID) const; 254 static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeSet> Nodes); 255 256 void dump() const; 257 }; 258 259 } // end namespace llvm 260 261 #endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H 262