AttributeImpl.h revision b1ac6e617291e2a628bc460933bde97c73466cb0
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 23namespace llvm { 24 25class Constant; 26class 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. 34class AttributeEntry { 35 unsigned char KindID; 36protected: 37 enum AttrEntryKind { 38 EnumAttrEntry, 39 AlignAttrEntry, 40 StringAttrEntry 41 }; 42public: 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 52class EnumAttributeEntry : public AttributeEntry { 53 Attribute::AttrKind Kind; 54public: 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 66class AlignAttributeEntry : public AttributeEntry { 67 Attribute::AttrKind Kind; 68 unsigned Align; 69public: 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 82class StringAttributeEntry : public AttributeEntry { 83 std::string Kind; 84 std::string Val; 85public: 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. 102class 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; 110public: 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. 160class 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; 169public: 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 TargetIndependent, 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. 205class 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; 216public: 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