Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -2014,6 +2014,9 @@ void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A); +unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx); +void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + LLVMAttributeRef *Attrs); LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID); @@ -2600,6 +2603,9 @@ void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef A); +unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx); +void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, + LLVMAttributeRef *Attrs); LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID); Index: include/llvm/IR/AttributeSetNode.h =================================================================== --- /dev/null +++ include/llvm/IR/AttributeSetNode.h @@ -0,0 +1,97 @@ +//===-- AttributeSetNode.h - AttributeSet Internal Node ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file defines the node class used internally by AttributeSet. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_ATTRIBUTESETNODE_H +#define LLVM_IR_ATTRIBUTESETNODE_H + +#include "llvm/ADT/FoldingSet.h" +#include "llvm/IR/Attributes.h" +#include "llvm/Support/TrailingObjects.h" + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// \class +/// \brief This class represents a group of attributes that apply to one +/// element: function, return type, or parameter. +class AttributeSetNode final + : public FoldingSetNode, + private TrailingObjects { + friend TrailingObjects; + + unsigned NumAttrs; ///< Number of attributes in this node. + /// Bitset with a bit for each available attribute Attribute::AttrKind. + uint64_t AvailableAttrs; + + AttributeSetNode(ArrayRef Attrs) + : NumAttrs(Attrs.size()), AvailableAttrs(0) { + static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT, + "Too many attributes for AvailableAttrs"); + // There's memory after the node where we can store the entries in. + std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects()); + + for (iterator I = begin(), E = end(); I != E; ++I) { + if (!I->isStringAttribute()) { + AvailableAttrs |= ((uint64_t)1) << I->getKindAsEnum(); + } + } + } + + // AttributesSetNode is uniqued, these should not be publicly available. + void operator=(const AttributeSetNode &) = delete; + AttributeSetNode(const AttributeSetNode &) = delete; +public: + void operator delete(void *p) { ::operator delete(p); } + + static AttributeSetNode *get(LLVMContext &C, ArrayRef Attrs); + + static AttributeSetNode *get(const AttributeSet AS, unsigned i) { + return AS.getAttributes(i); + } + + /// \brief Return the number of attributes this AttributeSet contains. + unsigned getNumAttributes() const { return NumAttrs; } + + bool hasAttribute(Attribute::AttrKind Kind) const { + return AvailableAttrs & ((uint64_t)1) << Kind; + } + bool hasAttribute(StringRef Kind) const; + bool hasAttributes() const { return NumAttrs != 0; } + + Attribute getAttribute(Attribute::AttrKind Kind) const; + Attribute getAttribute(StringRef Kind) const; + + unsigned getAlignment() const; + unsigned getStackAlignment() const; + uint64_t getDereferenceableBytes() const; + uint64_t getDereferenceableOrNullBytes() const; + std::pair> getAllocSizeArgs() const; + std::string getAsString(bool InAttrGrp) const; + + typedef const Attribute *iterator; + iterator begin() const { return getTrailingObjects(); } + iterator end() const { return begin() + NumAttrs; } + + void Profile(FoldingSetNodeID &ID) const { + Profile(ID, makeArrayRef(begin(), end())); + } + static void Profile(FoldingSetNodeID &ID, ArrayRef AttrList) { + for (unsigned I = 0, E = AttrList.size(); I != E; ++I) + AttrList[I].Profile(ID); + } +}; + +} // end llvm namespace + +#endif Index: include/llvm/IR/Attributes.h =================================================================== --- include/llvm/IR/Attributes.h +++ include/llvm/IR/Attributes.h @@ -210,6 +210,7 @@ private: friend class AttrBuilder; friend class AttributeSetImpl; + friend class AttributeSetNode; template friend struct DenseMapInfo; /// \brief The attributes that we are managing. This can be null to represent Index: lib/IR/AttributeImpl.h =================================================================== --- lib/IR/AttributeImpl.h +++ lib/IR/AttributeImpl.h @@ -19,8 +19,8 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Optional.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/AttributeSetNode.h" #include "llvm/Support/DataTypes.h" -#include "llvm/Support/TrailingObjects.h" #include #include @@ -142,73 +142,6 @@ StringRef getStringValue() const { return Val; } }; -//===----------------------------------------------------------------------===// -/// \class -/// \brief This class represents a group of attributes that apply to one -/// element: function, return type, or parameter. -class AttributeSetNode final - : public FoldingSetNode, - private TrailingObjects { - friend TrailingObjects; - - unsigned NumAttrs; ///< Number of attributes in this node. - /// Bitset with a bit for each available attribute Attribute::AttrKind. - uint64_t AvailableAttrs; - - AttributeSetNode(ArrayRef Attrs) - : NumAttrs(Attrs.size()), AvailableAttrs(0) { - static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT, - "Too many attributes for AvailableAttrs"); - // There's memory after the node where we can store the entries in. - std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects()); - - for (iterator I = begin(), E = end(); I != E; ++I) { - if (!I->isStringAttribute()) { - AvailableAttrs |= ((uint64_t)1) << I->getKindAsEnum(); - } - } - } - - // AttributesSetNode is uniqued, these should not be publicly available. - void operator=(const AttributeSetNode &) = delete; - AttributeSetNode(const AttributeSetNode &) = delete; -public: - void operator delete(void *p) { ::operator delete(p); } - - static AttributeSetNode *get(LLVMContext &C, ArrayRef Attrs); - - /// \brief Return the number of attributes this AttributeSet contains. - unsigned getNumAttributes() const { return NumAttrs; } - - bool hasAttribute(Attribute::AttrKind Kind) const { - return AvailableAttrs & ((uint64_t)1) << Kind; - } - bool hasAttribute(StringRef Kind) const; - bool hasAttributes() const { return NumAttrs != 0; } - - Attribute getAttribute(Attribute::AttrKind Kind) const; - Attribute getAttribute(StringRef Kind) const; - - unsigned getAlignment() const; - unsigned getStackAlignment() const; - uint64_t getDereferenceableBytes() const; - uint64_t getDereferenceableOrNullBytes() const; - std::pair> getAllocSizeArgs() const; - std::string getAsString(bool InAttrGrp) const; - - typedef const Attribute *iterator; - iterator begin() const { return getTrailingObjects(); } - iterator end() const { return begin() + NumAttrs; } - - void Profile(FoldingSetNodeID &ID) const { - Profile(ID, makeArrayRef(begin(), end())); - } - static void Profile(FoldingSetNodeID &ID, ArrayRef AttrList) { - for (unsigned I = 0, E = AttrList.size(); I != E; ++I) - AttrList[I].Profile(ID); - } -}; - typedef std::pair IndexAttrPair; //===----------------------------------------------------------------------===// Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/AttributeSetNode.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" @@ -1844,6 +1845,18 @@ unwrap(F)->addAttribute(Idx, unwrap(A)); } +unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) { + auto *ASN = AttributeSetNode::get(unwrap(F)->getAttributes(), Idx); + return ASN->getNumAttributes(); +} + +void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + LLVMAttributeRef *Attrs) { + auto *ASN = AttributeSetNode::get(unwrap(F)->getAttributes(), Idx); + for (auto A: make_range(ASN->begin(), ASN->end())) + *Attrs++ = wrap(A); +} + LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID) { @@ -2216,6 +2229,21 @@ CallSite(unwrap(C)).addAttribute(Idx, unwrap(A)); } +unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, + LLVMAttributeIndex Idx) { + auto CS = CallSite(unwrap(C)); + auto *ASN = AttributeSetNode::get(CS.getAttributes(), Idx); + return ASN->getNumAttributes(); +} + +void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, + LLVMAttributeRef *Attrs) { + auto CS = CallSite(unwrap(C)); + auto *ASN = AttributeSetNode::get(CS.getAttributes(), Idx); + for (auto A: make_range(ASN->begin(), ASN->end())) + *Attrs++ = wrap(A); +} + LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID) {