AttributeImpl.h revision 263508
1168404Spjd//===-- AttributeImpl.h - Attribute Internals -------------------*- C++ -*-===// 2168404Spjd// 3168404Spjd// The LLVM Compiler Infrastructure 4168404Spjd// 5168404Spjd// This file is distributed under the University of Illinois Open Source 6168404Spjd// License. See LICENSE.TXT for details. 7168404Spjd// 8168404Spjd//===----------------------------------------------------------------------===// 9168404Spjd/// 10168404Spjd/// \file 11168404Spjd/// \brief This file defines various helper methods and classes used by 12168404Spjd/// LLVMContextImpl for creating and managing attributes. 13168404Spjd/// 14168404Spjd//===----------------------------------------------------------------------===// 15168404Spjd 16168404Spjd#ifndef LLVM_ATTRIBUTESIMPL_H 17168404Spjd#define LLVM_ATTRIBUTESIMPL_H 18168404Spjd 19168404Spjd#include "llvm/ADT/FoldingSet.h" 20168404Spjd#include "llvm/IR/Attributes.h" 21168404Spjd#include <string> 22168404Spjd 23168404Spjdnamespace llvm { 24168404Spjd 25168404Spjdclass Constant; 26168404Spjdclass LLVMContext; 27168404Spjd 28168404Spjd//===----------------------------------------------------------------------===// 29168404Spjd/// \class 30168404Spjd/// \brief This class represents a single, uniqued attribute. That attribute 31168404Spjd/// could be a single enum, a tuple, or a string. 32168404Spjdclass AttributeImpl : public FoldingSetNode { 33168404Spjd unsigned char KindID; ///< Holds the AttrEntryKind of the attribute 34168404Spjd 35168404Spjd // AttributesImpl is uniqued, these should not be publicly available. 36168404Spjd void operator=(const AttributeImpl &) LLVM_DELETED_FUNCTION; 37168404Spjd AttributeImpl(const AttributeImpl &) LLVM_DELETED_FUNCTION; 38168404Spjd 39168404Spjdprotected: 40168404Spjd enum AttrEntryKind { 41168404Spjd EnumAttrEntry, 42168404Spjd AlignAttrEntry, 43168404Spjd StringAttrEntry 44168404Spjd }; 45168404Spjd 46168404Spjd AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {} 47168404Spjd 48168404Spjdpublic: 49168404Spjd virtual ~AttributeImpl(); 50168404Spjd 51168404Spjd bool isEnumAttribute() const { return KindID == EnumAttrEntry; } 52168404Spjd bool isAlignAttribute() const { return KindID == AlignAttrEntry; } 53168404Spjd bool isStringAttribute() const { return KindID == StringAttrEntry; } 54168404Spjd 55168404Spjd bool hasAttribute(Attribute::AttrKind A) const; 56168404Spjd bool hasAttribute(StringRef Kind) const; 57168404Spjd 58168404Spjd Attribute::AttrKind getKindAsEnum() const; 59168404Spjd uint64_t getValueAsInt() const; 60168404Spjd 61168404Spjd StringRef getKindAsString() const; 62168404Spjd StringRef getValueAsString() const; 63168404Spjd 64168404Spjd /// \brief Used when sorting the attributes. 65168404Spjd bool operator<(const AttributeImpl &AI) const; 66168404Spjd 67168404Spjd void Profile(FoldingSetNodeID &ID) const { 68168404Spjd if (isEnumAttribute()) 69168404Spjd Profile(ID, getKindAsEnum(), 0); 70168404Spjd else if (isAlignAttribute()) 71168404Spjd Profile(ID, getKindAsEnum(), getValueAsInt()); 72168404Spjd else 73168404Spjd Profile(ID, getKindAsString(), getValueAsString()); 74168404Spjd } 75168404Spjd static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind, 76168404Spjd uint64_t Val) { 77168404Spjd ID.AddInteger(Kind); 78168404Spjd if (Val) ID.AddInteger(Val); 79168404Spjd } 80168404Spjd static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) { 81168404Spjd ID.AddString(Kind); 82168404Spjd if (!Values.empty()) ID.AddString(Values); 83168404Spjd } 84168404Spjd 85168404Spjd // FIXME: Remove this! 86168404Spjd static uint64_t getAttrMask(Attribute::AttrKind Val); 87168404Spjd}; 88168404Spjd 89168404Spjd//===----------------------------------------------------------------------===// 90168404Spjd/// \class 91168404Spjd/// \brief A set of classes that contain the value of the 92168404Spjd/// attribute object. There are three main categories: enum attribute entries, 93168404Spjd/// represented by Attribute::AttrKind; alignment attribute entries; and string 94168404Spjd/// attribute enties, which are for target-dependent attributes. 95168404Spjd 96168404Spjdclass EnumAttributeImpl : public AttributeImpl { 97168404Spjd virtual void anchor(); 98168404Spjd Attribute::AttrKind Kind; 99168404Spjd 100168404Spjdprotected: 101168404Spjd EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind) 102168404Spjd : AttributeImpl(ID), Kind(Kind) {} 103168404Spjd 104168404Spjdpublic: 105168404Spjd EnumAttributeImpl(Attribute::AttrKind Kind) 106168404Spjd : AttributeImpl(EnumAttrEntry), Kind(Kind) {} 107168404Spjd 108168404Spjd Attribute::AttrKind getEnumKind() const { return Kind; } 109168404Spjd}; 110168404Spjd 111168404Spjdclass AlignAttributeImpl : public EnumAttributeImpl { 112168404Spjd virtual void anchor(); 113168404Spjd unsigned Align; 114168404Spjd 115168404Spjdpublic: 116168404Spjd AlignAttributeImpl(Attribute::AttrKind Kind, unsigned Align) 117168404Spjd : EnumAttributeImpl(AlignAttrEntry, Kind), Align(Align) { 118168404Spjd assert( 119168404Spjd (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) && 120168404Spjd "Wrong kind for alignment attribute!"); 121168404Spjd } 122168404Spjd 123168404Spjd unsigned getAlignment() const { return Align; } 124168404Spjd}; 125168404Spjd 126168404Spjdclass StringAttributeImpl : public AttributeImpl { 127168404Spjd virtual void anchor(); 128168404Spjd std::string Kind; 129168404Spjd std::string Val; 130168404Spjd 131168404Spjdpublic: 132168404Spjd StringAttributeImpl(StringRef Kind, StringRef Val = StringRef()) 133168404Spjd : AttributeImpl(StringAttrEntry), Kind(Kind), Val(Val) {} 134168404Spjd 135168404Spjd StringRef getStringKind() const { return Kind; } 136168404Spjd StringRef getStringValue() const { return Val; } 137168404Spjd}; 138168404Spjd 139168404Spjd//===----------------------------------------------------------------------===// 140168404Spjd/// \class 141168404Spjd/// \brief This class represents a group of attributes that apply to one 142168404Spjd/// element: function, return type, or parameter. 143168404Spjdclass AttributeSetNode : public FoldingSetNode { 144168404Spjd unsigned NumAttrs; ///< Number of attributes in this node. 145168404Spjd 146168404Spjd AttributeSetNode(ArrayRef<Attribute> Attrs) : NumAttrs(Attrs.size()) { 147168404Spjd // There's memory after the node where we can store the entries in. 148168404Spjd std::copy(Attrs.begin(), Attrs.end(), 149168404Spjd reinterpret_cast<Attribute *>(this + 1)); 150168404Spjd } 151168404Spjd 152168404Spjd // AttributesSetNode is uniqued, these should not be publicly available. 153168404Spjd void operator=(const AttributeSetNode &) LLVM_DELETED_FUNCTION; 154168404Spjd AttributeSetNode(const AttributeSetNode &) LLVM_DELETED_FUNCTION; 155168404Spjdpublic: 156168404Spjd static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs); 157168404Spjd 158168404Spjd bool hasAttribute(Attribute::AttrKind Kind) const; 159168404Spjd bool hasAttribute(StringRef Kind) const; 160168404Spjd bool hasAttributes() const { return NumAttrs != 0; } 161168404Spjd 162168404Spjd Attribute getAttribute(Attribute::AttrKind Kind) const; 163168404Spjd Attribute getAttribute(StringRef Kind) const; 164168404Spjd 165168404Spjd unsigned getAlignment() const; 166168404Spjd unsigned getStackAlignment() const; 167168404Spjd std::string getAsString(bool InAttrGrp) const; 168168404Spjd 169168404Spjd typedef const Attribute *iterator; 170168404Spjd iterator begin() const { return reinterpret_cast<iterator>(this + 1); } 171168404Spjd iterator end() const { return begin() + NumAttrs; } 172168404Spjd 173168404Spjd void Profile(FoldingSetNodeID &ID) const { 174168404Spjd Profile(ID, makeArrayRef(begin(), end())); 175168404Spjd } 176168404Spjd static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) { 177168404Spjd for (unsigned I = 0, E = AttrList.size(); I != E; ++I) 178168404Spjd AttrList[I].Profile(ID); 179168404Spjd } 180168404Spjd}; 181168404Spjd 182168404Spjd//===----------------------------------------------------------------------===// 183168404Spjd/// \class 184168404Spjd/// \brief This class represents a set of attributes that apply to the function, 185168404Spjd/// return type, and parameters. 186168404Spjdclass AttributeSetImpl : public FoldingSetNode { 187168404Spjd friend class AttributeSet; 188168404Spjd 189168404Spjd LLVMContext &Context; 190168404Spjd 191168404Spjd typedef std::pair<unsigned, AttributeSetNode*> IndexAttrPair; 192168404Spjd unsigned NumAttrs; ///< Number of entries in this set. 193168404Spjd 194168404Spjd /// \brief Return a pointer to the IndexAttrPair for the specified slot. 195168404Spjd const IndexAttrPair *getNode(unsigned Slot) const { 196168404Spjd return reinterpret_cast<const IndexAttrPair *>(this + 1) + Slot; 197168404Spjd } 198168404Spjd 199168404Spjd // AttributesSet is uniqued, these should not be publicly available. 200168404Spjd void operator=(const AttributeSetImpl &) LLVM_DELETED_FUNCTION; 201168404Spjd AttributeSetImpl(const AttributeSetImpl &) LLVM_DELETED_FUNCTION; 202168404Spjdpublic: 203168404Spjd AttributeSetImpl(LLVMContext &C, 204168404Spjd ArrayRef<std::pair<unsigned, AttributeSetNode *> > Attrs) 205168404Spjd : Context(C), NumAttrs(Attrs.size()) { 206168404Spjd#ifndef NDEBUG 207168404Spjd if (Attrs.size() >= 2) { 208168404Spjd for (const std::pair<unsigned, AttributeSetNode *> *i = Attrs.begin() + 1, 209168404Spjd *e = Attrs.end(); 210168404Spjd i != e; ++i) { 211168404Spjd assert((i-1)->first <= i->first && "Attribute set not ordered!"); 212168404Spjd } 213168404Spjd } 214168404Spjd#endif 215168404Spjd // There's memory after the node where we can store the entries in. 216168404Spjd std::copy(Attrs.begin(), Attrs.end(), 217168404Spjd reinterpret_cast<IndexAttrPair *>(this + 1)); 218168404Spjd } 219168404Spjd 220168404Spjd /// \brief Get the context that created this AttributeSetImpl. 221168404Spjd LLVMContext &getContext() { return Context; } 222168404Spjd 223168404Spjd /// \brief Return the number of attributes this AttributeSet contains. 224168404Spjd unsigned getNumAttributes() const { return NumAttrs; } 225168404Spjd 226168404Spjd /// \brief Get the index of the given "slot" in the AttrNodes list. This index 227168404Spjd /// is the index of the return, parameter, or function object that the 228168404Spjd /// attributes are applied to, not the index into the AttrNodes list where the 229168404Spjd /// attributes reside. 230168404Spjd unsigned getSlotIndex(unsigned Slot) const { 231168404Spjd return getNode(Slot)->first; 232168404Spjd } 233168404Spjd 234168404Spjd /// \brief Retrieve the attributes for the given "slot" in the AttrNode list. 235168404Spjd /// \p Slot is an index into the AttrNodes list, not the index of the return / 236168404Spjd /// parameter/ function which the attributes apply to. 237168404Spjd AttributeSet getSlotAttributes(unsigned Slot) const { 238168404Spjd return AttributeSet::get(Context, *getNode(Slot)); 239168404Spjd } 240168404Spjd 241168404Spjd /// \brief Retrieve the attribute set node for the given "slot" in the 242168404Spjd /// AttrNode list. 243168404Spjd AttributeSetNode *getSlotNode(unsigned Slot) const { 244168404Spjd return getNode(Slot)->second; 245168404Spjd } 246168404Spjd 247168404Spjd typedef AttributeSetNode::iterator iterator; 248168404Spjd iterator begin(unsigned Slot) const { return getSlotNode(Slot)->begin(); } 249168404Spjd iterator end(unsigned Slot) const { return getSlotNode(Slot)->end(); } 250168404Spjd 251168404Spjd void Profile(FoldingSetNodeID &ID) const { 252168404Spjd Profile(ID, makeArrayRef(getNode(0), getNumAttributes())); 253168404Spjd } 254168404Spjd static void Profile(FoldingSetNodeID &ID, 255168404Spjd ArrayRef<std::pair<unsigned, AttributeSetNode*> > Nodes) { 256168404Spjd for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { 257168404Spjd ID.AddInteger(Nodes[i].first); 258168404Spjd ID.AddPointer(Nodes[i].second); 259168404Spjd } 260168404Spjd } 261168404Spjd 262168404Spjd // FIXME: This atrocity is temporary. 263168404Spjd uint64_t Raw(unsigned Index) const; 264168404Spjd 265168404Spjd void dump() const; 266168404Spjd}; 267168404Spjd 268168404Spjd} // end llvm namespace 269168404Spjd 270168404Spjd#endif 271168404Spjd