Index: llvm/trunk/include/llvm-c/Core.h =================================================================== --- llvm/trunk/include/llvm-c/Core.h +++ llvm/trunk/include/llvm-c/Core.h @@ -2587,13 +2587,20 @@ */ unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr); - void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute); void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute); void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, unsigned Align); +void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, + LLVMAttributeRef A); +LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, + LLVMAttributeIndex Idx, + unsigned KindID); +void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, + unsigned KindID); + /** * Obtain the pointer to the function invoked by this instruction. * Index: llvm/trunk/include/llvm/IR/CallSite.h =================================================================== --- llvm/trunk/include/llvm/IR/CallSite.h +++ llvm/trunk/include/llvm/IR/CallSite.h @@ -313,6 +313,10 @@ CALLSITE_DELEGATE_SETTER(addAttribute(i, Kind, Value)); } + void addAttribute(unsigned i, Attribute Attr) { + CALLSITE_DELEGATE_SETTER(addAttribute(i, Attr)); + } + void removeAttribute(unsigned i, Attribute::AttrKind Kind) { CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind)); } @@ -336,6 +340,10 @@ CALLSITE_DELEGATE_GETTER(paramHasAttr(i, Kind)); } + Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const { + CALLSITE_DELEGATE_GETTER(getAttribute(i, Kind)); + } + /// \brief Return true if the data operand at index \p i directly or /// indirectly has the attribute \p A. /// Index: llvm/trunk/include/llvm/IR/Instructions.h =================================================================== --- llvm/trunk/include/llvm/IR/Instructions.h +++ llvm/trunk/include/llvm/IR/Instructions.h @@ -1623,6 +1623,9 @@ /// addAttribute - adds the attribute to the list of attributes. void addAttribute(unsigned i, StringRef Kind, StringRef Value); + /// addAttribute - adds the attribute to the list of attributes. + void addAttribute(unsigned i, Attribute Attr); + /// removeAttribute - removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute::AttrKind Kind); @@ -1651,6 +1654,9 @@ /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const; + /// \brief Get the attribute of a given kind at a position. + Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const; + /// \brief Return true if the data operand at index \p i has the attribute \p /// A. /// @@ -3564,6 +3570,9 @@ /// addAttribute - adds the attribute to the list of attributes. void addAttribute(unsigned i, Attribute::AttrKind Kind); + /// addAttribute - adds the attribute to the list of attributes. + void addAttribute(unsigned i, Attribute Attr); + /// removeAttribute - removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute::AttrKind Kind); @@ -3592,6 +3601,9 @@ /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const; + /// \brief Get the attribute of a given kind at a position. + Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const; + /// \brief Return true if the data operand at index \p i has the attribute \p /// A. /// Index: llvm/trunk/lib/IR/Core.cpp =================================================================== --- llvm/trunk/lib/IR/Core.cpp +++ llvm/trunk/lib/IR/Core.cpp @@ -2201,6 +2201,24 @@ index, B))); } +void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, + LLVMAttributeRef A) { + CallSite(unwrap(C)).addAttribute(Idx, unwrap(A)); +} + +LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, + LLVMAttributeIndex Idx, + unsigned KindID) { + return wrap(CallSite(unwrap(C)) + .getAttribute(Idx, (Attribute::AttrKind)KindID)); +} + +void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, + unsigned KindID) { + CallSite(unwrap(C)) + .removeAttribute(Idx, (Attribute::AttrKind)KindID); +} + LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) { return wrap(CallSite(unwrap(Instr)).getCalledValue()); } Index: llvm/trunk/lib/IR/Instructions.cpp =================================================================== --- llvm/trunk/lib/IR/Instructions.cpp +++ llvm/trunk/lib/IR/Instructions.cpp @@ -343,6 +343,12 @@ setAttributes(PAL); } +void CallInst::addAttribute(unsigned i, Attribute Attr) { + AttributeSet PAL = getAttributes(); + PAL = PAL.addAttribute(getContext(), i, Attr); + setAttributes(PAL); +} + void CallInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) { AttributeSet PAL = getAttributes(); PAL = PAL.removeAttribute(getContext(), i, Kind); @@ -380,6 +386,10 @@ return false; } +Attribute CallInst::getAttribute(unsigned i, Attribute::AttrKind Kind) const { + return getAttributes().getAttribute(i, Kind); +} + bool CallInst::dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const { // There are getNumOperands() - 1 data operands. The last operand is the @@ -702,6 +712,12 @@ setAttributes(PAL); } +void InvokeInst::addAttribute(unsigned i, Attribute Attr) { + AttributeSet PAL = getAttributes(); + PAL = PAL.addAttribute(getContext(), i, Attr); + setAttributes(PAL); +} + void InvokeInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) { AttributeSet PAL = getAttributes(); PAL = PAL.removeAttribute(getContext(), i, Kind); @@ -716,6 +732,11 @@ setAttributes(PAL); } +Attribute InvokeInst::getAttribute(unsigned i, + Attribute::AttrKind Kind) const { + return getAttributes().getAttribute(i, Kind); +} + void InvokeInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) { AttributeSet PAL = getAttributes(); PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes); 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 @@ -21,7 +21,7 @@ define i32 @_D8test01494mainFMZi() personality i32 (i32, i32, i64, i8*, i8*)* @__sd_eh_personality { body: - %0 = invoke i8* @_d_allocmemory(i64 8) + %0 = invoke noalias i8* @_d_allocmemory(i64 8) to label %then unwind label %landingPad then: ; preds = %body @@ -33,7 +33,7 @@ then1: ; preds = %then %3 = bitcast i8* %0 to %C6object9Throwable* - invoke void @__sd_eh_throw(%C6object9Throwable* %3) + invoke void @__sd_eh_throw(%C6object9Throwable* nonnull %3) to label %then2 unwind label %landingPad then2: ; preds = %then1 @@ -46,7 +46,7 @@ catch %C6object9ClassInfo* @C6object9Exception__ClassInfo catch %C6object9ClassInfo* @C6object9Throwable__ClassInfo %5 = extractvalue { i8*, i32 } %4, 1 - %6 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%C6object9ClassInfo* @C6object5Error__ClassInfo to i8*)) + %6 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object5Error__ClassInfo to i8*)) %7 = icmp eq i32 %6, %5 br i1 %7, label %catch, label %unwind3 @@ -55,12 +55,12 @@ ret i32 %merge unwind3: ; preds = %landingPad - %8 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*)) + %8 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*)) %9 = icmp eq i32 %8, %5 br i1 %9, label %catch, label %unwind5 unwind5: ; preds = %unwind3 - %10 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*)) + %10 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*)) %11 = icmp eq i32 %10, %5 br i1 %11, label %catch, label %unwind7 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 @@ -375,6 +375,20 @@ return Dst; } + void CloneAttrs(LLVMValueRef Src, LLVMValueRef Dst) { + auto Ctx = LLVMGetModuleContext(M); + int ArgCount = LLVMGetNumArgOperands(Src); + for (int i = LLVMAttributeReturnIndex; i <= ArgCount; i++) { + for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) { + if (auto SrcA = LLVMGetCallSiteEnumAttribute(Src, i, k)) { + auto Val = LLVMGetEnumAttributeValue(SrcA); + auto A = LLVMCreateEnumAttribute(Ctx, k, Val); + LLVMAddCallSiteAttribute(Dst, i, A); + } + } + } + } + LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) { check_value_kind(Src, LLVMInstructionValueKind); if (!LLVMIsAInstruction(Src)) @@ -439,6 +453,7 @@ LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src)); Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount, Then, Unwind, Name); + CloneAttrs(Src, Dst); break; } case LLVMUnreachable: @@ -599,6 +614,7 @@ LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src)); Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name); LLVMSetTailCall(Dst, LLVMIsTailCall(Src)); + CloneAttrs(Src, Dst); break; } case LLVMResume: {