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 /// \brief This file defines various helper methods and classes used by 12 /// LLVMContextImpl for creating and managing attributes. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_ATTRIBUTESIMPL_H 17 #define LLVM_ATTRIBUTESIMPL_H 18 19 #include "llvm/ADT/FoldingSet.h" 20 #include "llvm/IR/Attributes.h" 21 #include <string> 22 23 namespace llvm { 24 25 class Constant; 26 class LLVMContext; 27 28 //===----------------------------------------------------------------------===// 29 /// \class 30 /// \brief A set of classes that contain the kind and (optional) value of the 31 /// attribute object. There are three main categories: enum attribute entries, 32 /// represented by Attribute::AttrKind; alignment attribute entries; and string 33 /// attribute enties, which are for target-dependent attributes. 34 class AttributeEntry { 35 unsigned char KindID; 36 protected: 37 enum AttrEntryKind { 38 EnumAttrEntry, 39 AlignAttrEntry, 40 StringAttrEntry 41 }; 42 public: 43 AttributeEntry(AttrEntryKind Kind) 44 : KindID(Kind) {} 45 virtual ~AttributeEntry() {} 46 47 unsigned getKindID() const { return KindID; } 48 49 static inline bool classof(const AttributeEntry *) { return true; } 50 }; 51 52 class EnumAttributeEntry : public AttributeEntry { 53 Attribute::AttrKind Kind; 54 public: 55 EnumAttributeEntry(Attribute::AttrKind Kind) 56 : AttributeEntry(EnumAttrEntry), Kind(Kind) {} 57 58 Attribute::AttrKind getEnumKind() const { return Kind; } 59 60 static inline bool classof(const AttributeEntry *AE) { 61 return AE->getKindID() == EnumAttrEntry; 62 } 63 static inline bool classof(const EnumAttributeEntry *) { return true; } 64 }; 65 66 class AlignAttributeEntry : public AttributeEntry { 67 Attribute::AttrKind Kind; 68 unsigned Align; 69 public: 70 AlignAttributeEntry(Attribute::AttrKind Kind, unsigned Align) 71 : AttributeEntry(AlignAttrEntry), Kind(Kind), Align(Align) {} 72 73 Attribute::AttrKind getEnumKind() const { return Kind; } 74 unsigned getAlignment() const { return Align; } 75 76 static inline bool classof(const AttributeEntry *AE) { 77 return AE->getKindID() == AlignAttrEntry; 78 } 79 static inline bool classof(const AlignAttributeEntry *) { return true; } 80 }; 81 82 class StringAttributeEntry : public AttributeEntry { 83 std::string Kind; 84 std::string Val; 85 public: 86 StringAttributeEntry(StringRef Kind, StringRef Val = StringRef()) 87 : AttributeEntry(StringAttrEntry), Kind(Kind), Val(Val) {} 88 89 StringRef getStringKind() const { return Kind; } 90 StringRef getStringValue() const { return Val; } 91 92 static inline bool classof(const AttributeEntry *AE) { 93 return AE->getKindID() == StringAttrEntry; 94 } 95 static inline bool classof(const StringAttributeEntry *) { return true; } 96 }; 97 98 //===----------------------------------------------------------------------===// 99 /// \class 100 /// \brief This class represents a single, uniqued attribute. That attribute 101 /// could be a single enum, a tuple, or a string. 102 class AttributeImpl : public FoldingSetNode { 103 LLVMContext &Context; ///< Global context for uniquing objects 104 105 AttributeEntry *Entry; ///< Holds the kind and value of the attribute 106 107 // AttributesImpl is uniqued, these should not be publicly available. 108 void operator=(const AttributeImpl &) LLVM_DELETED_FUNCTION; 109 AttributeImpl(const AttributeImpl &) LLVM_DELETED_FUNCTION; 110 public: 111 AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind); 112 AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind, unsigned Align); 113 AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val = StringRef()); 114 ~AttributeImpl(); 115 116 LLVMContext &getContext() { return Context; } 117 118 bool isEnumAttribute() const; 119 bool isAlignAttribute() const; 120 bool isStringAttribute() const; 121 122 bool hasAttribute(Attribute::AttrKind A) const; 123 bool hasAttribute(StringRef Kind) const; 124 125 Attribute::AttrKind getKindAsEnum() const; 126 uint64_t getValueAsInt() const; 127 128 StringRef getKindAsString() const; 129 StringRef getValueAsString() const; 130 131 /// \brief Used when sorting the attributes. 132 bool operator<(const AttributeImpl &AI) const; 133 134 void Profile(FoldingSetNodeID &ID) const { 135 if (isEnumAttribute()) 136 Profile(ID, getKindAsEnum(), 0); 137 else if (isAlignAttribute()) 138 Profile(ID, getKindAsEnum(), getValueAsInt()); 139 else 140 Profile(ID, getKindAsString(), getValueAsString()); 141 } 142 static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind, 143 uint64_t Val) { 144 ID.AddInteger(Kind); 145 if (Val) ID.AddInteger(Val); 146 } 147 static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) { 148 ID.AddString(Kind); 149 if (!Values.empty()) ID.AddString(Values); 150 } 151 152 // FIXME: Remove this! 153 static uint64_t getAttrMask(Attribute::AttrKind Val); 154 }; 155 156 //===----------------------------------------------------------------------===// 157 /// \class 158 /// \brief This class represents a group of attributes that apply to one 159 /// element: function, return type, or parameter. 160 class AttributeSetNode : public FoldingSetNode { 161 SmallVector<Attribute, 4> AttrList; 162 163 AttributeSetNode(ArrayRef<Attribute> Attrs) 164 : AttrList(Attrs.begin(), Attrs.end()) {} 165 166 // AttributesSetNode is uniqued, these should not be publicly available. 167 void operator=(const AttributeSetNode &) LLVM_DELETED_FUNCTION; 168 AttributeSetNode(const AttributeSetNode &) LLVM_DELETED_FUNCTION; 169 public: 170 static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs); 171 172 bool hasAttribute(Attribute::AttrKind Kind) const; 173 bool hasAttribute(StringRef Kind) const; 174 bool hasAttributes() const { return !AttrList.empty(); } 175 176 Attribute getAttribute(Attribute::AttrKind Kind) const; 177 Attribute getAttribute(StringRef Kind) const; 178 179 unsigned getAlignment() const; 180 unsigned getStackAlignment() const; 181 std::string getAsString(bool InAttrGrp) const; 182 183 typedef SmallVectorImpl<Attribute>::iterator iterator; 184 typedef SmallVectorImpl<Attribute>::const_iterator const_iterator; 185 186 iterator begin() { return AttrList.begin(); } 187 iterator end() { return AttrList.end(); } 188 189 const_iterator begin() const { return AttrList.begin(); } 190 const_iterator end() const { return AttrList.end(); } 191 192 void Profile(FoldingSetNodeID &ID) const { 193 Profile(ID, AttrList); 194 } 195 static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) { 196 for (unsigned I = 0, E = AttrList.size(); I != E; ++I) 197 AttrList[I].Profile(ID); 198 } 199 }; 200 201 //===----------------------------------------------------------------------===// 202 /// \class 203 /// \brief This class represents a set of attributes that apply to the function, 204 /// return type, and parameters. 205 class AttributeSetImpl : public FoldingSetNode { 206 friend class AttributeSet; 207 208 LLVMContext &Context; 209 210 typedef std::pair<unsigned, AttributeSetNode*> IndexAttrPair; 211 SmallVector<IndexAttrPair, 4> AttrNodes; 212 213 // AttributesSet is uniqued, these should not be publicly available. 214 void operator=(const AttributeSetImpl &) LLVM_DELETED_FUNCTION; 215 AttributeSetImpl(const AttributeSetImpl &) LLVM_DELETED_FUNCTION; 216 public: 217 AttributeSetImpl(LLVMContext &C, 218 ArrayRef<std::pair<unsigned, AttributeSetNode*> > attrs) 219 : Context(C), AttrNodes(attrs.begin(), attrs.end()) {} 220 221 /// \brief Get the context that created this AttributeSetImpl. 222 LLVMContext &getContext() { return Context; } 223 224 /// \brief Return the number of attributes this AttributeSet contains. 225 unsigned getNumAttributes() const { return AttrNodes.size(); } 226 227 /// \brief Get the index of the given "slot" in the AttrNodes list. This index 228 /// is the index of the return, parameter, or function object that the 229 /// attributes are applied to, not the index into the AttrNodes list where the 230 /// attributes reside. 231 uint64_t getSlotIndex(unsigned Slot) const { 232 return AttrNodes[Slot].first; 233 } 234 235 /// \brief Retrieve the attributes for the given "slot" in the AttrNode list. 236 /// \p Slot is an index into the AttrNodes list, not the index of the return / 237 /// parameter/ function which the attributes apply to. 238 AttributeSet getSlotAttributes(unsigned Slot) const { 239 return AttributeSet::get(Context, AttrNodes[Slot]); 240 } 241 242 /// \brief Retrieve the attribute set node for the given "slot" in the 243 /// AttrNode list. 244 AttributeSetNode *getSlotNode(unsigned Slot) const { 245 return AttrNodes[Slot].second; 246 } 247 248 typedef AttributeSetNode::iterator iterator; 249 typedef AttributeSetNode::const_iterator const_iterator; 250 251 iterator begin(unsigned Idx) 252 { return AttrNodes[Idx].second->begin(); } 253 iterator end(unsigned Idx) 254 { return AttrNodes[Idx].second->end(); } 255 256 const_iterator begin(unsigned Idx) const 257 { return AttrNodes[Idx].second->begin(); } 258 const_iterator end(unsigned Idx) const 259 { return AttrNodes[Idx].second->end(); } 260 261 void Profile(FoldingSetNodeID &ID) const { 262 Profile(ID, AttrNodes); 263 } 264 static void Profile(FoldingSetNodeID &ID, 265 ArrayRef<std::pair<unsigned, AttributeSetNode*> > Nodes) { 266 for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { 267 ID.AddInteger(Nodes[i].first); 268 ID.AddPointer(Nodes[i].second); 269 } 270 } 271 272 // FIXME: This atrocity is temporary. 273 uint64_t Raw(uint64_t Index) const; 274 }; 275 276 } // end llvm namespace 277 278 #endif 279