1*9880d681SAndroid Build Coastguard Worker //===-- AttributeImpl.h - Attribute Internals -------------------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker /// 10*9880d681SAndroid Build Coastguard Worker /// \file 11*9880d681SAndroid Build Coastguard Worker /// \brief This file defines various helper methods and classes used by 12*9880d681SAndroid Build Coastguard Worker /// LLVMContextImpl for creating and managing attributes. 13*9880d681SAndroid Build Coastguard Worker /// 14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H 17*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_IR_ATTRIBUTEIMPL_H 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/FoldingSet.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Optional.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Attributes.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataTypes.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TrailingObjects.h" 24*9880d681SAndroid Build Coastguard Worker #include <climits> 25*9880d681SAndroid Build Coastguard Worker #include <string> 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker namespace llvm { 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker class Constant; 30*9880d681SAndroid Build Coastguard Worker class LLVMContext; 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 33*9880d681SAndroid Build Coastguard Worker /// \class 34*9880d681SAndroid Build Coastguard Worker /// \brief This class represents a single, uniqued attribute. That attribute 35*9880d681SAndroid Build Coastguard Worker /// could be a single enum, a tuple, or a string. 36*9880d681SAndroid Build Coastguard Worker class AttributeImpl : public FoldingSetNode { 37*9880d681SAndroid Build Coastguard Worker unsigned char KindID; ///< Holds the AttrEntryKind of the attribute 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker // AttributesImpl is uniqued, these should not be publicly available. 40*9880d681SAndroid Build Coastguard Worker void operator=(const AttributeImpl &) = delete; 41*9880d681SAndroid Build Coastguard Worker AttributeImpl(const AttributeImpl &) = delete; 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker protected: 44*9880d681SAndroid Build Coastguard Worker enum AttrEntryKind { 45*9880d681SAndroid Build Coastguard Worker EnumAttrEntry, 46*9880d681SAndroid Build Coastguard Worker IntAttrEntry, 47*9880d681SAndroid Build Coastguard Worker StringAttrEntry 48*9880d681SAndroid Build Coastguard Worker }; 49*9880d681SAndroid Build Coastguard Worker AttributeImpl(AttrEntryKind KindID)50*9880d681SAndroid Build Coastguard Worker AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker public: 53*9880d681SAndroid Build Coastguard Worker virtual ~AttributeImpl(); 54*9880d681SAndroid Build Coastguard Worker isEnumAttribute()55*9880d681SAndroid Build Coastguard Worker bool isEnumAttribute() const { return KindID == EnumAttrEntry; } isIntAttribute()56*9880d681SAndroid Build Coastguard Worker bool isIntAttribute() const { return KindID == IntAttrEntry; } isStringAttribute()57*9880d681SAndroid Build Coastguard Worker bool isStringAttribute() const { return KindID == StringAttrEntry; } 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker bool hasAttribute(Attribute::AttrKind A) const; 60*9880d681SAndroid Build Coastguard Worker bool hasAttribute(StringRef Kind) const; 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker Attribute::AttrKind getKindAsEnum() const; 63*9880d681SAndroid Build Coastguard Worker uint64_t getValueAsInt() const; 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker StringRef getKindAsString() const; 66*9880d681SAndroid Build Coastguard Worker StringRef getValueAsString() const; 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker /// \brief Used when sorting the attributes. 69*9880d681SAndroid Build Coastguard Worker bool operator<(const AttributeImpl &AI) const; 70*9880d681SAndroid Build Coastguard Worker Profile(FoldingSetNodeID & ID)71*9880d681SAndroid Build Coastguard Worker void Profile(FoldingSetNodeID &ID) const { 72*9880d681SAndroid Build Coastguard Worker if (isEnumAttribute()) 73*9880d681SAndroid Build Coastguard Worker Profile(ID, getKindAsEnum(), 0); 74*9880d681SAndroid Build Coastguard Worker else if (isIntAttribute()) 75*9880d681SAndroid Build Coastguard Worker Profile(ID, getKindAsEnum(), getValueAsInt()); 76*9880d681SAndroid Build Coastguard Worker else 77*9880d681SAndroid Build Coastguard Worker Profile(ID, getKindAsString(), getValueAsString()); 78*9880d681SAndroid Build Coastguard Worker } Profile(FoldingSetNodeID & ID,Attribute::AttrKind Kind,uint64_t Val)79*9880d681SAndroid Build Coastguard Worker static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind, 80*9880d681SAndroid Build Coastguard Worker uint64_t Val) { 81*9880d681SAndroid Build Coastguard Worker ID.AddInteger(Kind); 82*9880d681SAndroid Build Coastguard Worker if (Val) ID.AddInteger(Val); 83*9880d681SAndroid Build Coastguard Worker } Profile(FoldingSetNodeID & ID,StringRef Kind,StringRef Values)84*9880d681SAndroid Build Coastguard Worker static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) { 85*9880d681SAndroid Build Coastguard Worker ID.AddString(Kind); 86*9880d681SAndroid Build Coastguard Worker if (!Values.empty()) ID.AddString(Values); 87*9880d681SAndroid Build Coastguard Worker } 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker // FIXME: Remove this! 90*9880d681SAndroid Build Coastguard Worker static uint64_t getAttrMask(Attribute::AttrKind Val); 91*9880d681SAndroid Build Coastguard Worker }; 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 94*9880d681SAndroid Build Coastguard Worker /// \class 95*9880d681SAndroid Build Coastguard Worker /// \brief A set of classes that contain the value of the 96*9880d681SAndroid Build Coastguard Worker /// attribute object. There are three main categories: enum attribute entries, 97*9880d681SAndroid Build Coastguard Worker /// represented by Attribute::AttrKind; alignment attribute entries; and string 98*9880d681SAndroid Build Coastguard Worker /// attribute enties, which are for target-dependent attributes. 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker class EnumAttributeImpl : public AttributeImpl { 101*9880d681SAndroid Build Coastguard Worker virtual void anchor(); 102*9880d681SAndroid Build Coastguard Worker Attribute::AttrKind Kind; 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker protected: EnumAttributeImpl(AttrEntryKind ID,Attribute::AttrKind Kind)105*9880d681SAndroid Build Coastguard Worker EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind) 106*9880d681SAndroid Build Coastguard Worker : AttributeImpl(ID), Kind(Kind) {} 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker public: EnumAttributeImpl(Attribute::AttrKind Kind)109*9880d681SAndroid Build Coastguard Worker EnumAttributeImpl(Attribute::AttrKind Kind) 110*9880d681SAndroid Build Coastguard Worker : AttributeImpl(EnumAttrEntry), Kind(Kind) {} 111*9880d681SAndroid Build Coastguard Worker getEnumKind()112*9880d681SAndroid Build Coastguard Worker Attribute::AttrKind getEnumKind() const { return Kind; } 113*9880d681SAndroid Build Coastguard Worker }; 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker class IntAttributeImpl : public EnumAttributeImpl { 116*9880d681SAndroid Build Coastguard Worker void anchor() override; 117*9880d681SAndroid Build Coastguard Worker uint64_t Val; 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker public: IntAttributeImpl(Attribute::AttrKind Kind,uint64_t Val)120*9880d681SAndroid Build Coastguard Worker IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val) 121*9880d681SAndroid Build Coastguard Worker : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) { 122*9880d681SAndroid Build Coastguard Worker assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment || 123*9880d681SAndroid Build Coastguard Worker Kind == Attribute::Dereferenceable || 124*9880d681SAndroid Build Coastguard Worker Kind == Attribute::DereferenceableOrNull || 125*9880d681SAndroid Build Coastguard Worker Kind == Attribute::AllocSize) && 126*9880d681SAndroid Build Coastguard Worker "Wrong kind for int attribute!"); 127*9880d681SAndroid Build Coastguard Worker } 128*9880d681SAndroid Build Coastguard Worker getValue()129*9880d681SAndroid Build Coastguard Worker uint64_t getValue() const { return Val; } 130*9880d681SAndroid Build Coastguard Worker }; 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker class StringAttributeImpl : public AttributeImpl { 133*9880d681SAndroid Build Coastguard Worker virtual void anchor(); 134*9880d681SAndroid Build Coastguard Worker std::string Kind; 135*9880d681SAndroid Build Coastguard Worker std::string Val; 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker public: 138*9880d681SAndroid Build Coastguard Worker StringAttributeImpl(StringRef Kind, StringRef Val = StringRef()) AttributeImpl(StringAttrEntry)139*9880d681SAndroid Build Coastguard Worker : AttributeImpl(StringAttrEntry), Kind(Kind), Val(Val) {} 140*9880d681SAndroid Build Coastguard Worker getStringKind()141*9880d681SAndroid Build Coastguard Worker StringRef getStringKind() const { return Kind; } getStringValue()142*9880d681SAndroid Build Coastguard Worker StringRef getStringValue() const { return Val; } 143*9880d681SAndroid Build Coastguard Worker }; 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 146*9880d681SAndroid Build Coastguard Worker /// \class 147*9880d681SAndroid Build Coastguard Worker /// \brief This class represents a group of attributes that apply to one 148*9880d681SAndroid Build Coastguard Worker /// element: function, return type, or parameter. 149*9880d681SAndroid Build Coastguard Worker class AttributeSetNode final 150*9880d681SAndroid Build Coastguard Worker : public FoldingSetNode, 151*9880d681SAndroid Build Coastguard Worker private TrailingObjects<AttributeSetNode, Attribute> { 152*9880d681SAndroid Build Coastguard Worker friend TrailingObjects; 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker unsigned NumAttrs; ///< Number of attributes in this node. 155*9880d681SAndroid Build Coastguard Worker /// Bitset with a bit for each available attribute Attribute::AttrKind. 156*9880d681SAndroid Build Coastguard Worker uint64_t AvailableAttrs; 157*9880d681SAndroid Build Coastguard Worker AttributeSetNode(ArrayRef<Attribute> Attrs)158*9880d681SAndroid Build Coastguard Worker AttributeSetNode(ArrayRef<Attribute> Attrs) 159*9880d681SAndroid Build Coastguard Worker : NumAttrs(Attrs.size()), AvailableAttrs(0) { 160*9880d681SAndroid Build Coastguard Worker static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT, 161*9880d681SAndroid Build Coastguard Worker "Too many attributes for AvailableAttrs"); 162*9880d681SAndroid Build Coastguard Worker // There's memory after the node where we can store the entries in. 163*9880d681SAndroid Build Coastguard Worker std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>()); 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker for (Attribute I : *this) { 166*9880d681SAndroid Build Coastguard Worker if (!I.isStringAttribute()) { 167*9880d681SAndroid Build Coastguard Worker AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum(); 168*9880d681SAndroid Build Coastguard Worker } 169*9880d681SAndroid Build Coastguard Worker } 170*9880d681SAndroid Build Coastguard Worker } 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Worker // AttributesSetNode is uniqued, these should not be publicly available. 173*9880d681SAndroid Build Coastguard Worker void operator=(const AttributeSetNode &) = delete; 174*9880d681SAndroid Build Coastguard Worker AttributeSetNode(const AttributeSetNode &) = delete; 175*9880d681SAndroid Build Coastguard Worker public: delete(void * p)176*9880d681SAndroid Build Coastguard Worker void operator delete(void *p) { ::operator delete(p); } 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs); 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker /// \brief Return the number of attributes this AttributeSet contains. getNumAttributes()181*9880d681SAndroid Build Coastguard Worker unsigned getNumAttributes() const { return NumAttrs; } 182*9880d681SAndroid Build Coastguard Worker hasAttribute(Attribute::AttrKind Kind)183*9880d681SAndroid Build Coastguard Worker bool hasAttribute(Attribute::AttrKind Kind) const { 184*9880d681SAndroid Build Coastguard Worker return AvailableAttrs & ((uint64_t)1) << Kind; 185*9880d681SAndroid Build Coastguard Worker } 186*9880d681SAndroid Build Coastguard Worker bool hasAttribute(StringRef Kind) const; hasAttributes()187*9880d681SAndroid Build Coastguard Worker bool hasAttributes() const { return NumAttrs != 0; } 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker Attribute getAttribute(Attribute::AttrKind Kind) const; 190*9880d681SAndroid Build Coastguard Worker Attribute getAttribute(StringRef Kind) const; 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker unsigned getAlignment() const; 193*9880d681SAndroid Build Coastguard Worker unsigned getStackAlignment() const; 194*9880d681SAndroid Build Coastguard Worker uint64_t getDereferenceableBytes() const; 195*9880d681SAndroid Build Coastguard Worker uint64_t getDereferenceableOrNullBytes() const; 196*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; 197*9880d681SAndroid Build Coastguard Worker std::string getAsString(bool InAttrGrp) const; 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker typedef const Attribute *iterator; begin()200*9880d681SAndroid Build Coastguard Worker iterator begin() const { return getTrailingObjects<Attribute>(); } end()201*9880d681SAndroid Build Coastguard Worker iterator end() const { return begin() + NumAttrs; } 202*9880d681SAndroid Build Coastguard Worker Profile(FoldingSetNodeID & ID)203*9880d681SAndroid Build Coastguard Worker void Profile(FoldingSetNodeID &ID) const { 204*9880d681SAndroid Build Coastguard Worker Profile(ID, makeArrayRef(begin(), end())); 205*9880d681SAndroid Build Coastguard Worker } Profile(FoldingSetNodeID & ID,ArrayRef<Attribute> AttrList)206*9880d681SAndroid Build Coastguard Worker static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) { 207*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = AttrList.size(); I != E; ++I) 208*9880d681SAndroid Build Coastguard Worker AttrList[I].Profile(ID); 209*9880d681SAndroid Build Coastguard Worker } 210*9880d681SAndroid Build Coastguard Worker }; 211*9880d681SAndroid Build Coastguard Worker 212*9880d681SAndroid Build Coastguard Worker typedef std::pair<unsigned, AttributeSetNode *> IndexAttrPair; 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 215*9880d681SAndroid Build Coastguard Worker /// \class 216*9880d681SAndroid Build Coastguard Worker /// \brief This class represents a set of attributes that apply to the function, 217*9880d681SAndroid Build Coastguard Worker /// return type, and parameters. 218*9880d681SAndroid Build Coastguard Worker class AttributeSetImpl final 219*9880d681SAndroid Build Coastguard Worker : public FoldingSetNode, 220*9880d681SAndroid Build Coastguard Worker private TrailingObjects<AttributeSetImpl, IndexAttrPair> { 221*9880d681SAndroid Build Coastguard Worker friend class AttributeSet; 222*9880d681SAndroid Build Coastguard Worker friend TrailingObjects; 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Worker private: 225*9880d681SAndroid Build Coastguard Worker LLVMContext &Context; 226*9880d681SAndroid Build Coastguard Worker unsigned NumSlots; ///< Number of entries in this set. 227*9880d681SAndroid Build Coastguard Worker /// Bitset with a bit for each available attribute Attribute::AttrKind. 228*9880d681SAndroid Build Coastguard Worker uint64_t AvailableFunctionAttrs; 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Worker // Helper fn for TrailingObjects class. numTrailingObjects(OverloadToken<IndexAttrPair>)231*9880d681SAndroid Build Coastguard Worker size_t numTrailingObjects(OverloadToken<IndexAttrPair>) { return NumSlots; } 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Worker /// \brief Return a pointer to the IndexAttrPair for the specified slot. getNode(unsigned Slot)234*9880d681SAndroid Build Coastguard Worker const IndexAttrPair *getNode(unsigned Slot) const { 235*9880d681SAndroid Build Coastguard Worker return getTrailingObjects<IndexAttrPair>() + Slot; 236*9880d681SAndroid Build Coastguard Worker } 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Worker // AttributesSet is uniqued, these should not be publicly available. 239*9880d681SAndroid Build Coastguard Worker void operator=(const AttributeSetImpl &) = delete; 240*9880d681SAndroid Build Coastguard Worker AttributeSetImpl(const AttributeSetImpl &) = delete; 241*9880d681SAndroid Build Coastguard Worker public: AttributeSetImpl(LLVMContext & C,ArrayRef<std::pair<unsigned,AttributeSetNode * >> Slots)242*9880d681SAndroid Build Coastguard Worker AttributeSetImpl(LLVMContext &C, 243*9880d681SAndroid Build Coastguard Worker ArrayRef<std::pair<unsigned, AttributeSetNode *> > Slots) 244*9880d681SAndroid Build Coastguard Worker : Context(C), NumSlots(Slots.size()), AvailableFunctionAttrs(0) { 245*9880d681SAndroid Build Coastguard Worker static_assert(Attribute::EndAttrKinds <= 246*9880d681SAndroid Build Coastguard Worker sizeof(AvailableFunctionAttrs) * CHAR_BIT, 247*9880d681SAndroid Build Coastguard Worker "Too many attributes"); 248*9880d681SAndroid Build Coastguard Worker 249*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG 250*9880d681SAndroid Build Coastguard Worker if (Slots.size() >= 2) { 251*9880d681SAndroid Build Coastguard Worker for (const std::pair<unsigned, AttributeSetNode *> *i = Slots.begin() + 1, 252*9880d681SAndroid Build Coastguard Worker *e = Slots.end(); 253*9880d681SAndroid Build Coastguard Worker i != e; ++i) { 254*9880d681SAndroid Build Coastguard Worker assert((i-1)->first <= i->first && "Attribute set not ordered!"); 255*9880d681SAndroid Build Coastguard Worker } 256*9880d681SAndroid Build Coastguard Worker } 257*9880d681SAndroid Build Coastguard Worker #endif 258*9880d681SAndroid Build Coastguard Worker // There's memory after the node where we can store the entries in. 259*9880d681SAndroid Build Coastguard Worker std::copy(Slots.begin(), Slots.end(), getTrailingObjects<IndexAttrPair>()); 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Worker // Initialize AvailableFunctionAttrs summary bitset. 262*9880d681SAndroid Build Coastguard Worker if (NumSlots > 0) { 263*9880d681SAndroid Build Coastguard Worker static_assert(AttributeSet::FunctionIndex == ~0u, 264*9880d681SAndroid Build Coastguard Worker "FunctionIndex should be biggest possible index"); 265*9880d681SAndroid Build Coastguard Worker const std::pair<unsigned, AttributeSetNode *> &Last = Slots.back(); 266*9880d681SAndroid Build Coastguard Worker if (Last.first == AttributeSet::FunctionIndex) { 267*9880d681SAndroid Build Coastguard Worker const AttributeSetNode *Node = Last.second; 268*9880d681SAndroid Build Coastguard Worker for (Attribute I : *Node) { 269*9880d681SAndroid Build Coastguard Worker if (!I.isStringAttribute()) 270*9880d681SAndroid Build Coastguard Worker AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum(); 271*9880d681SAndroid Build Coastguard Worker } 272*9880d681SAndroid Build Coastguard Worker } 273*9880d681SAndroid Build Coastguard Worker } 274*9880d681SAndroid Build Coastguard Worker } 275*9880d681SAndroid Build Coastguard Worker delete(void * p)276*9880d681SAndroid Build Coastguard Worker void operator delete(void *p) { ::operator delete(p); } 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker /// \brief Get the context that created this AttributeSetImpl. getContext()279*9880d681SAndroid Build Coastguard Worker LLVMContext &getContext() { return Context; } 280*9880d681SAndroid Build Coastguard Worker 281*9880d681SAndroid Build Coastguard Worker /// \brief Return the number of slots used in this attribute list. This is 282*9880d681SAndroid Build Coastguard Worker /// the number of arguments that have an attribute set on them (including the 283*9880d681SAndroid Build Coastguard Worker /// function itself). getNumSlots()284*9880d681SAndroid Build Coastguard Worker unsigned getNumSlots() const { return NumSlots; } 285*9880d681SAndroid Build Coastguard Worker 286*9880d681SAndroid Build Coastguard Worker /// \brief Get the index of the given "slot" in the AttrNodes list. This index 287*9880d681SAndroid Build Coastguard Worker /// is the index of the return, parameter, or function object that the 288*9880d681SAndroid Build Coastguard Worker /// attributes are applied to, not the index into the AttrNodes list where the 289*9880d681SAndroid Build Coastguard Worker /// attributes reside. getSlotIndex(unsigned Slot)290*9880d681SAndroid Build Coastguard Worker unsigned getSlotIndex(unsigned Slot) const { 291*9880d681SAndroid Build Coastguard Worker return getNode(Slot)->first; 292*9880d681SAndroid Build Coastguard Worker } 293*9880d681SAndroid Build Coastguard Worker 294*9880d681SAndroid Build Coastguard Worker /// \brief Retrieve the attributes for the given "slot" in the AttrNode list. 295*9880d681SAndroid Build Coastguard Worker /// \p Slot is an index into the AttrNodes list, not the index of the return / 296*9880d681SAndroid Build Coastguard Worker /// parameter/ function which the attributes apply to. getSlotAttributes(unsigned Slot)297*9880d681SAndroid Build Coastguard Worker AttributeSet getSlotAttributes(unsigned Slot) const { 298*9880d681SAndroid Build Coastguard Worker return AttributeSet::get(Context, *getNode(Slot)); 299*9880d681SAndroid Build Coastguard Worker } 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard Worker /// \brief Retrieve the attribute set node for the given "slot" in the 302*9880d681SAndroid Build Coastguard Worker /// AttrNode list. getSlotNode(unsigned Slot)303*9880d681SAndroid Build Coastguard Worker AttributeSetNode *getSlotNode(unsigned Slot) const { 304*9880d681SAndroid Build Coastguard Worker return getNode(Slot)->second; 305*9880d681SAndroid Build Coastguard Worker } 306*9880d681SAndroid Build Coastguard Worker 307*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the AttributeSetNode for the FunctionIndex has an 308*9880d681SAndroid Build Coastguard Worker /// enum attribute of the given kind. hasFnAttribute(Attribute::AttrKind Kind)309*9880d681SAndroid Build Coastguard Worker bool hasFnAttribute(Attribute::AttrKind Kind) const { 310*9880d681SAndroid Build Coastguard Worker return AvailableFunctionAttrs & ((uint64_t)1) << Kind; 311*9880d681SAndroid Build Coastguard Worker } 312*9880d681SAndroid Build Coastguard Worker 313*9880d681SAndroid Build Coastguard Worker typedef AttributeSetNode::iterator iterator; begin(unsigned Slot)314*9880d681SAndroid Build Coastguard Worker iterator begin(unsigned Slot) const { return getSlotNode(Slot)->begin(); } end(unsigned Slot)315*9880d681SAndroid Build Coastguard Worker iterator end(unsigned Slot) const { return getSlotNode(Slot)->end(); } 316*9880d681SAndroid Build Coastguard Worker Profile(FoldingSetNodeID & ID)317*9880d681SAndroid Build Coastguard Worker void Profile(FoldingSetNodeID &ID) const { 318*9880d681SAndroid Build Coastguard Worker Profile(ID, makeArrayRef(getNode(0), getNumSlots())); 319*9880d681SAndroid Build Coastguard Worker } Profile(FoldingSetNodeID & ID,ArrayRef<std::pair<unsigned,AttributeSetNode * >> Nodes)320*9880d681SAndroid Build Coastguard Worker static void Profile(FoldingSetNodeID &ID, 321*9880d681SAndroid Build Coastguard Worker ArrayRef<std::pair<unsigned, AttributeSetNode*> > Nodes) { 322*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { 323*9880d681SAndroid Build Coastguard Worker ID.AddInteger(Nodes[i].first); 324*9880d681SAndroid Build Coastguard Worker ID.AddPointer(Nodes[i].second); 325*9880d681SAndroid Build Coastguard Worker } 326*9880d681SAndroid Build Coastguard Worker } 327*9880d681SAndroid Build Coastguard Worker 328*9880d681SAndroid Build Coastguard Worker // FIXME: This atrocity is temporary. 329*9880d681SAndroid Build Coastguard Worker uint64_t Raw(unsigned Index) const; 330*9880d681SAndroid Build Coastguard Worker 331*9880d681SAndroid Build Coastguard Worker void dump() const; 332*9880d681SAndroid Build Coastguard Worker }; 333*9880d681SAndroid Build Coastguard Worker 334*9880d681SAndroid Build Coastguard Worker } // end llvm namespace 335*9880d681SAndroid Build Coastguard Worker 336*9880d681SAndroid Build Coastguard Worker #endif 337