Home | History | Annotate | Download | only in IR
      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