Index: bindings/go/llvm/ir.go =================================================================== --- bindings/go/llvm/ir.go +++ bindings/go/llvm/ir.go @@ -1076,19 +1076,12 @@ func (v Value) LastParam() (rv Value) { rv.C = C.LLVMGetLastParam(v.C); return } func NextParam(v Value) (rv Value) { rv.C = C.LLVMGetNextParam(v.C); return } func PrevParam(v Value) (rv Value) { rv.C = C.LLVMGetPreviousParam(v.C); return } -func (v Value) AddAttribute(a Attribute) { - if a >= 1<<32 { - panic("attribute value currently unsupported") - } - C.LLVMAddAttribute(v.C, C.LLVMAttribute(a)) +func (v Value) AddAttribute(KindID uint) { + C.LLVMAddAttribute(v.C, C.uint(KindID)) } -func (v Value) RemoveAttribute(a Attribute) { - if a >= 1<<32 { - panic("attribute value currently unsupported") - } - C.LLVMRemoveAttribute(v.C, C.LLVMAttribute(a)) +func (v Value) RemoveAttribute(KindID uint) { + C.LLVMRemoveAttribute(v.C, C.uint(KindID)) } -func (v Value) Attribute() Attribute { return Attribute(C.LLVMGetAttribute(v.C)) } func (v Value) SetParamAlignment(align int) { C.LLVMSetParamAlignment(v.C, C.unsigned(align)) } // Operations on basic blocks Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -433,6 +433,19 @@ unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name, unsigned SLen); unsigned LLVMGetMDKindID(const char* Name, unsigned SLen); +const char *LLVMGetStringFromMDKindIDInContext(LLVMContextRef C, + unsigned KindID, + size_t *Length); +const char *LLVMGetStringFromMDKindID(unsigned KindID, size_t *Length); + +unsigned LLVMGetEndAttrKind(); +unsigned LLVMGetAttrKindIDInContext(LLVMContextRef C, const char* Name, + unsigned SLen); +unsigned LLVMGetAttrKindID(const char* Name, unsigned SLen); +const char *LLVMGetStringFromAttrKindIDInContext(LLVMContextRef C, + unsigned KindID, + size_t *Length); +const char *LLVMGetStringFromAttrKindID(unsigned KindID, size_t *Length); /** * @} @@ -1527,7 +1540,7 @@ * * @see ConstantDataSequential::getAsString() */ -const char *LLVMGetAsString(LLVMValueRef c, size_t* out); +const char *LLVMGetAsString(LLVMValueRef c, size_t *Length); /** * Create an anonymous ConstantStruct with the specified values. @@ -1870,28 +1883,43 @@ /** * Add an attribute to a function. * - * @see llvm::Function::addAttribute() + * @see llvm::Function::addFnAttr() */ -void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); +void LLVMAddFunctionAttr(LLVMValueRef Fn, unsigned KindID); /** - * Add a target-dependent attribute to a function + * Add a target-dependent attribute to a function. + * * @see llvm::AttrBuilder::addAttribute() + * @see llvm::Function::addAttributes() */ void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, const char *V); /** - * Obtain an attribute from a function. - * - * @see llvm::Function::getAttributes() + * Remove an attribute from a function. */ -LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn); +void LLVMRemoveFunctionAttr(LLVMValueRef Fn, unsigned KindID); /** - * Remove an attribute from a function. + * Check if a function has an attribute. + */ +LLVMBool LLVMHasFunctionAttr(LLVMValueRef Fn, unsigned KindID); + +/** + * Add a return attribute to a function. */ -void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); +void LLVMAddReturnAttr(LLVMValueRef Fn, unsigned KindID); + +/** + * Remove a return attribute from a function. + */ +void LLVMRemoveReturnAttr(LLVMValueRef Fn, unsigned KindID); + +/** + * Check if a function's return has an attribute. + */ +LLVMBool LLVMHasReturnAttr(LLVMValueRef Fn, unsigned KindID); /** * @defgroup LLVMCCoreValueFunctionParameters Function Parameters @@ -1979,19 +2007,21 @@ * * @see llvm::Argument::addAttr() */ -void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA); +void LLVMAddAttribute(LLVMValueRef Arg, unsigned KindID); /** * Remove an attribute from a function argument. * * @see llvm::Argument::removeAttr() */ -void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA); +void LLVMRemoveAttribute(LLVMValueRef Arg, unsigned KindID); /** - * Get an attribute from a function argument. + * Remove an attribute from a function argument. + * + * @see llvm::Argument::hasAttribute() */ -LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg); +LLVMBool LLVMHasAttribute(LLVMValueRef Arg, unsigned KindID); /** * Set the alignment for a function parameter. @@ -2060,7 +2090,7 @@ * @param Len Memory address which will hold length of returned string. * @return String data in MDString. */ -const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len); +const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len); /** * Obtain the number of operands from an MDNode value. Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -109,6 +109,48 @@ return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen); } +const char *LLVMGetStringFromMDKindIDInContext(LLVMContextRef C, + unsigned KindID, + size_t *Length) { + SmallVector Names; + unwrap(C)->getMDKindNames(Names); + StringRef Str = Names[KindID]; + *Length = Str.size(); + return Str.data(); +} + +const char *LLVMGetStringFromMDKindID(unsigned KindID, size_t *Length) { + return LLVMGetStringFromMDKindIDInContext(LLVMGetGlobalContext(), + KindID, Length); +} + +unsigned LLVMGetEndAttrKind() { + return Attribute::AttrKind::EndAttrKinds; +} + +unsigned LLVMGetAttrKindIDInContext(LLVMContextRef C, const char* Name, + unsigned SLen) { + return Attribute::get(*unwrap(C), StringRef(Name, SLen)).getKindAsEnum(); +} + +unsigned LLVMGetAttrKindID(const char* Name, unsigned SLen) { + return LLVMGetAttrKindIDInContext(LLVMGetGlobalContext(), Name, SLen); +} + +const char *LLVMGetStringFromAttrKindIDInContext(LLVMContextRef C, + unsigned KindID, + size_t *Length) { + auto A = Attribute::get(*unwrap(C), (Attribute::AttrKind)KindID); + StringRef Str = A.getKindAsString(); + *Length = Str.size(); + return Str.data(); +} + +const char *LLVMGetStringFromAttrKindID(unsigned KindID, size_t *Length) { + return LLVMGetStringFromAttrKindIDInContext(LLVMGetGlobalContext(), + KindID, Length); +} + char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) { std::string MsgStorage; raw_string_ostream Stream(MsgStorage); @@ -925,10 +967,10 @@ return unwrap(C)->isString(); } -const char *LLVMGetAsString(LLVMValueRef C, size_t* Length) { - StringRef str = unwrap(C)->getAsString(); - *Length = str.size(); - return str.data(); +const char *LLVMGetAsString(LLVMValueRef C, size_t *Length) { + StringRef Str = unwrap(C)->getAsString(); + *Length = Str.size(); + return Str.data(); } LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, @@ -1740,15 +1782,8 @@ F->clearGC(); } -void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { - Function *Func = unwrap(Fn); - const AttributeSet PAL = Func->getAttributes(); - AttrBuilder B(PA); - const AttributeSet PALnew = - PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex, - AttributeSet::get(Func->getContext(), - AttributeSet::FunctionIndex, B)); - Func->setAttributes(PALnew); +void LLVMAddFunctionAttr(LLVMValueRef Fn, unsigned KindID) { + unwrap(Fn)->addFnAttr((Attribute::AttrKind)KindID); } void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, @@ -1763,21 +1798,27 @@ Func->addAttributes(Idx, Set); } -void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { - Function *Func = unwrap(Fn); - const AttributeSet PAL = Func->getAttributes(); - AttrBuilder B(PA); - const AttributeSet PALnew = - PAL.removeAttributes(Func->getContext(), AttributeSet::FunctionIndex, - AttributeSet::get(Func->getContext(), - AttributeSet::FunctionIndex, B)); - Func->setAttributes(PALnew); +void LLVMRemoveFunctionAttr(LLVMValueRef Fn, unsigned KindID) { + unwrap(Fn)->removeFnAttr((Attribute::AttrKind)KindID); } -LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn) { - Function *Func = unwrap(Fn); - const AttributeSet PAL = Func->getAttributes(); - return (LLVMAttribute)PAL.Raw(AttributeSet::FunctionIndex); +LLVMBool LLVMHasFunctionAttr(LLVMValueRef Fn, unsigned KindID) { + return unwrap(Fn)->hasFnAttribute((Attribute::AttrKind)KindID); +} + +void LLVMAddReturnAttr(LLVMValueRef Fn, unsigned KindID) { + unwrap(Fn)->addAttribute(AttributeSet::ReturnIndex, + (Attribute::AttrKind)KindID); +} + +void LLVMRemoveReturnAttr(LLVMValueRef Fn, unsigned KindID) { + unwrap(Fn)->removeAttribute(AttributeSet::ReturnIndex, + (Attribute::AttrKind)KindID); +} + +LLVMBool LLVMHasReturnAttr(LLVMValueRef Fn, unsigned KindID) { + return unwrap(Fn)->hasAttribute(AttributeSet::ReturnIndex, + (Attribute::AttrKind)KindID); } /*--.. Operations on parameters ............................................--*/ @@ -1838,25 +1879,18 @@ return wrap(&*--I); } -void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA) { - Argument *A = unwrap(Arg); - AttrBuilder B(PA); - A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B)); +void LLVMAddAttribute(LLVMValueRef Arg, unsigned KindID) { + unwrap(Arg)->addAttr((Attribute::AttrKind)KindID); } -void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA) { - Argument *A = unwrap(Arg); - AttrBuilder B(PA); - A->removeAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B)); +void LLVMRemoveAttribute(LLVMValueRef Arg, unsigned KindID) { + unwrap(Arg)->removeAttr((Attribute::AttrKind)KindID); } -LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) { - Argument *A = unwrap(Arg); - return (LLVMAttribute)A->getParent()->getAttributes(). - Raw(A->getArgNo()+1); +LLVMBool LLVMHasAttribute(LLVMValueRef Arg, unsigned KindID) { + return unwrap(Arg)->hasAttribute((Attribute::AttrKind)KindID); } - void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { Argument *A = unwrap(Arg); AttrBuilder B; Index: test/Bindings/llvm-c/invoke.ll =================================================================== --- test/Bindings/llvm-c/invoke.ll +++ test/Bindings/llvm-c/invoke.ll @@ -74,9 +74,10 @@ declare i32 @__sd_eh_personality(i32, i32, i64, i8*, i8*) -declare void @__sd_eh_throw(%C6object9Throwable*) +declare void @__sd_eh_throw(%C6object9Throwable*) #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: tools/llvm-c-test/echo.cpp =================================================================== --- tools/llvm-c-test/echo.cpp +++ tools/llvm-c-test/echo.cpp @@ -757,7 +757,16 @@ 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 (unsigned k = 0, e = LLVMGetEndAttrKind(); k < e; ++k) { + if (LLVMHasFunctionAttr(Cur, k)) + LLVMAddFunctionAttr(F, k); + if (LLVMHasReturnAttr(Cur, k)) + LLVMAddReturnAttr(F, k); + } Next = LLVMGetNextFunction(Cur); if (Next == nullptr) {