Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -381,6 +381,20 @@ } LLVMDiagnosticSeverity; /** + * Attribute index are either LLVMAttributeReturnIndex, + * LLVMAttributeFunctionIndex or a parameter number from 1 to N. + */ +enum { + LLVMAttributeReturnIndex = 0U, + // ISO C restricts enumerator values to range of 'int' + // (4294967295 is too large) + // LLVMAttributeFunctionIndex = ~0U, + LLVMAttributeFunctionIndex = -1, +}; + +typedef unsigned LLVMAttributeIndex; + +/** * @} */ @@ -490,6 +504,17 @@ unsigned LLVMGetAttributeKindForName(const char *Name, size_t SLen); /** + * Create an attribute without argument. + */ +LLVMAttributeRef LLVMCreateAttribute(LLVMContextRef C, unsigned KindID); + +/** + * Get the unique id corresponding to the target independent attribute + * passed as argument. + */ +unsigned LLVMGetAttributeKind(LLVMAttributeRef A); + +/** * @} */ @@ -1957,6 +1982,14 @@ */ void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); +void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + LLVMAttributeRef A); +LLVMAttributeRef LLVMGetAttributeAtIndex(LLVMValueRef F, + LLVMAttributeIndex Idx, + unsigned KindID); +void LLVMRemoveAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + unsigned KindID); + /** * Add a target-dependent attribute to a function * @see llvm::AttrBuilder::addAttribute() Index: include/llvm-c/Types.h =================================================================== --- include/llvm-c/Types.h +++ include/llvm-c/Types.h @@ -109,6 +109,13 @@ typedef struct LLVMOpaqueUse *LLVMUseRef; /** + * Used to represent an attributes. + * + * @see llvm::Attribute + */ +typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef; + +/** * @see llvm::DiagnosticInfo */ typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef; Index: include/llvm/IR/Attributes.h =================================================================== --- include/llvm/IR/Attributes.h +++ include/llvm/IR/Attributes.h @@ -21,6 +21,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm-c/Types.h" #include #include #include @@ -169,8 +170,28 @@ void Profile(FoldingSetNodeID &ID) const { ID.AddPointer(pImpl); } + + /// \brief Return a raw pointer that uniquely identifies this attribute. + void *getRawPointer() const { + return pImpl; + } + + /// \brief Get an attribute from a raw pointer created by getRawPointer. + static Attribute fromRawPointer(void *RawPtr) { + return Attribute(reinterpret_cast(RawPtr)); + } }; +// Specialized opaque value conversions. +inline LLVMAttributeRef wrap(Attribute Attr) { + return reinterpret_cast(Attr.getRawPointer()); +} + +// Specialized opaque value conversions. +inline Attribute unwrap(LLVMAttributeRef Attr) { + return Attribute::fromRawPointer(Attr); +} + //===----------------------------------------------------------------------===// /// \class /// \brief This class holds the attributes for a function, its return value, and Index: include/llvm/IR/Function.h =================================================================== --- include/llvm/IR/Function.h +++ include/llvm/IR/Function.h @@ -205,12 +205,10 @@ /// @brief Return the attribute for the given attribute kind. Attribute getFnAttribute(Attribute::AttrKind Kind) const { - if (!hasFnAttribute(Kind)) - return Attribute(); - return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind); + return getAttribute(AttributeSet::FunctionIndex, Kind); } Attribute getFnAttribute(StringRef Kind) const { - return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind); + return getAttribute(AttributeSet::FunctionIndex, Kind); } /// \brief Return the stack alignment for the function. @@ -232,6 +230,9 @@ /// @brief adds the attribute to the list of attributes. void addAttribute(unsigned i, Attribute::AttrKind attr); + /// @brief adds the attribute to the list of attributes. + void addAttribute(unsigned i, Attribute Attr); + /// @brief adds the attributes to the list of attributes. void addAttributes(unsigned i, AttributeSet attrs); @@ -246,6 +247,16 @@ return getAttributes().hasAttribute(i, attr); } + Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const { + if (!hasFnAttribute(Kind)) + return Attribute(); + return AttributeSets.getAttribute(i, Kind); + } + + Attribute getAttribute(unsigned i, StringRef Kind) const { + return AttributeSets.getAttribute(i, Kind); + } + /// @brief adds the dereferenceable attribute to the list of attributes. void addDereferenceableAttr(unsigned i, uint64_t Bytes); Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -128,6 +128,14 @@ return getAttrKindFromName(StringRef(Name, SLen)); } +LLVMAttributeRef LLVMCreateAttribute(LLVMContextRef C, unsigned KindID) { + return wrap(Attribute::get(*unwrap(C), (Attribute::AttrKind)KindID)); +} + +unsigned LLVMGetAttributeKind(LLVMAttributeRef A) { + return unwrap(A).getKindAsEnum(); +} + char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) { std::string MsgStorage; raw_string_ostream Stream(MsgStorage); @@ -1789,6 +1797,22 @@ Func->setAttributes(PALnew); } +void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + LLVMAttributeRef A) { + unwrap(F)->addAttribute(Idx, unwrap(A)); +} + +LLVMAttributeRef LLVMGetAttributeAtIndex(LLVMValueRef F, + LLVMAttributeIndex Idx, + unsigned KindID) { + return wrap(unwrap(F)->getAttribute(Idx, (Attribute::AttrKind)KindID)); +} + +void LLVMRemoveAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + unsigned KindID) { + unwrap(F)->removeAttribute(Idx, (Attribute::AttrKind)KindID); +} + void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, const char *V) { Function *Func = unwrap(Fn); Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -372,6 +372,12 @@ setAttributes(PAL); } +void Function::addAttribute(unsigned i, Attribute Attr) { + AttributeSet PAL = getAttributes(); + PAL = PAL.addAttribute(getContext(), i, Attr); + setAttributes(PAL); +} + void Function::addAttributes(unsigned i, AttributeSet attrs) { AttributeSet PAL = getAttributes(); PAL = PAL.addAttributes(getContext(), i, attrs);