Index: llvm/trunk/docs/ReleaseNotes.rst =================================================================== --- llvm/trunk/docs/ReleaseNotes.rst +++ llvm/trunk/docs/ReleaseNotes.rst @@ -54,8 +54,12 @@ * The C API function LLVMGetDataLayout is deprecated in favor of LLVMGetDataLayoutStr. -* The C API enum LLVMAttribute is deprecated in favor of - LLVMGetAttributeKindForName. +* The C API enum LLVMAttribute and associated API is deprecated in favor of + the new LLVMAttributeRef API. The deprecated functions are + LLVMAddFunctionAttr, LLVMAddTargetDependentFunctionAttr, + LLVMRemoveFunctionAttr, LLVMGetFunctionAttr, LLVMAddAttribute, + LLVMRemoveAttribute, LLVMGetAttribute, LLVMAddInstrAttribute and + LLVMRemoveInstrAttribute. * ``TargetFrameLowering::eliminateCallFramePseudoInstr`` now returns an iterator to the next instruction instead of ``void``. Targets that previously Index: llvm/trunk/include/llvm-c/Core.h =================================================================== --- llvm/trunk/include/llvm-c/Core.h +++ llvm/trunk/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; + +/** * @} */ @@ -477,7 +491,7 @@ unsigned LLVMGetMDKindID(const char *Name, unsigned SLen); /** - * Return an unique id given the name of a target independent attribute, + * Return an unique id given the name of a enum attribute, * or 0 if no attribute by that name exists. * * See http://llvm.org/docs/LangRef.html#parameter-attributes @@ -487,7 +501,48 @@ * NB: Attribute names and/or id are subject to change without * going through the C API deprecation cycle. */ -unsigned LLVMGetAttributeKindForName(const char *Name, size_t SLen); +unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen); +unsigned LLVMGetLastEnumAttributeKind(); + +/** + * Create an enum attribute. + */ +LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID, + uint64_t Val); + +/** + * Get the unique id corresponding to the enum attribute + * passed as argument. + */ +unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A); + +/** + * Get the enum attribute's value. 0 is returned if none exists. + */ +uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A); + +/** + * Create a string attribute. + */ +LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C, + const char *K, unsigned KLength, + const char *V, unsigned VLength); + +/** + * Get the string attribute's kind. + */ +const char *LLVMGetStringAttributeKind(LLVMAttributeRef A, unsigned *Length); + +/** + * Get the string attribute's value. + */ +const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length); + +/** + * Check for the different types of attributes. + */ +LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A); +LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A); /** * @} @@ -1957,6 +2012,14 @@ */ void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); +void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + LLVMAttributeRef A); +LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, + LLVMAttributeIndex Idx, + unsigned KindID); +void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + unsigned KindID); + /** * Add a target-dependent attribute to a function * @see llvm::AttrBuilder::addAttribute() Index: llvm/trunk/include/llvm-c/Types.h =================================================================== --- llvm/trunk/include/llvm-c/Types.h +++ llvm/trunk/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: llvm/trunk/include/llvm/IR/Attributes.h =================================================================== --- llvm/trunk/include/llvm/IR/Attributes.h +++ llvm/trunk/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: llvm/trunk/include/llvm/IR/Function.h =================================================================== --- llvm/trunk/include/llvm/IR/Function.h +++ llvm/trunk/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,14 @@ return getAttributes().hasAttribute(i, attr); } + Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const { + 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: llvm/trunk/lib/IR/AttributeImpl.h =================================================================== --- llvm/trunk/lib/IR/AttributeImpl.h +++ llvm/trunk/lib/IR/AttributeImpl.h @@ -177,6 +177,9 @@ 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; } Index: llvm/trunk/lib/IR/Core.cpp =================================================================== --- llvm/trunk/lib/IR/Core.cpp +++ llvm/trunk/lib/IR/Core.cpp @@ -124,10 +124,60 @@ #define GET_ATTR_KIND_FROM_NAME #include "AttributesCompatFunc.inc" -unsigned LLVMGetAttributeKindForName(const char *Name, size_t SLen) { +unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen) { return getAttrKindFromName(StringRef(Name, SLen)); } +unsigned LLVMGetLastEnumAttributeKind() { + return Attribute::AttrKind::EndAttrKinds; +} + +LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID, + uint64_t Val) { + return wrap(Attribute::get(*unwrap(C), (Attribute::AttrKind)KindID, Val)); +} + +unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A) { + return unwrap(A).getKindAsEnum(); +} + +uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A) { + auto Attr = unwrap(A); + if (Attr.isEnumAttribute()) + return 0; + return Attr.getValueAsInt(); +} + +LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C, + const char *K, unsigned KLength, + const char *V, unsigned VLength) { + return wrap(Attribute::get(*unwrap(C), StringRef(K, KLength), + StringRef(V, VLength))); +} + +const char *LLVMGetStringAttributeKind(LLVMAttributeRef A, + unsigned *Length) { + auto S = unwrap(A).getKindAsString(); + *Length = S.size(); + return S.data(); +} + +const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, + unsigned *Length) { + auto S = unwrap(A).getValueAsString(); + *Length = S.size(); + return S.data(); +} + +LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A) { + auto Attr = unwrap(A); + return Attr.isEnumAttribute() || Attr.isIntAttribute(); +} + +LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A) { + return unwrap(A).isStringAttribute(); +} + char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) { std::string MsgStorage; raw_string_ostream Stream(MsgStorage); @@ -1789,6 +1839,23 @@ Func->setAttributes(PALnew); } +void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, + LLVMAttributeRef A) { + unwrap(F)->addAttribute(Idx, unwrap(A)); +} + +LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, + LLVMAttributeIndex Idx, + unsigned KindID) { + return wrap(unwrap(F)->getAttribute(Idx, + (Attribute::AttrKind)KindID)); +} + +void LLVMRemoveEnumAttributeAtIndex(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); @@ -1894,7 +1961,6 @@ Raw(A->getArgNo()+1); } - void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { Argument *A = unwrap(Arg); AttrBuilder B; Index: llvm/trunk/lib/IR/Function.cpp =================================================================== --- llvm/trunk/lib/IR/Function.cpp +++ llvm/trunk/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); Index: llvm/trunk/test/Bindings/llvm-c/invoke.ll =================================================================== --- llvm/trunk/test/Bindings/llvm-c/invoke.ll +++ llvm/trunk/test/Bindings/llvm-c/invoke.ll @@ -70,13 +70,14 @@ declare void @_D6object6Object6__ctorFMC6object6ObjectZv(%C6object6Object*) -declare i8* @_d_allocmemory(i64) +declare noalias i8* @_d_allocmemory(i64) declare i32 @__sd_eh_personality(i32, i32, i64, i8*, i8*) -declare void @__sd_eh_throw(%C6object9Throwable*) +declare void @__sd_eh_throw(%C6object9Throwable* nonnull) #0 ; Function Attrs: nounwind readnone -declare i32 @llvm.eh.typeid.for(i8*) #0 +declare i32 @llvm.eh.typeid.for(i8*) #1 -attributes #0 = { nounwind readnone } \ No newline at end of file +attributes #0 = { noreturn } +attributes #1 = { nounwind readnone } \ No newline at end of file Index: llvm/trunk/tools/llvm-c-test/echo.cpp =================================================================== --- llvm/trunk/tools/llvm-c-test/echo.cpp +++ llvm/trunk/tools/llvm-c-test/echo.cpp @@ -782,13 +782,28 @@ return; } + auto Ctx = LLVMGetModuleContext(M); + Cur = Begin; Next = nullptr; while (true) { const char *Name = LLVMGetValueName(Cur); if (LLVMGetNamedFunction(M, Name)) report_fatal_error("Function already cloned"); - LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur))); + auto Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur)); + auto F = LLVMAddFunction(M, Name, Ty); + + // Copy attributes + for (int i = LLVMAttributeFunctionIndex, c = LLVMCountParams(F); + i <= c; ++i) { + for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) { + if (auto SrcA = LLVMGetEnumAttributeAtIndex(Cur, i, k)) { + auto Val = LLVMGetEnumAttributeValue(SrcA); + auto DstA = LLVMCreateEnumAttribute(Ctx, k, Val); + LLVMAddAttributeAtIndex(F, i, DstA); + } + } + } Next = LLVMGetNextFunction(Cur); if (Next == nullptr) {