diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml index 7ab6f51efb9f..e0c168a2d9d4 100644 --- a/bindings/ocaml/llvm/llvm.ml +++ b/bindings/ocaml/llvm/llvm.ml @@ -280,6 +280,8 @@ let fold_right_uses f v init = (*--... Operations on users ................................................--*) external operand : llvalue -> int -> llvalue = "llvm_operand" +external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand" +external num_operands : llvalue -> int = "llvm_num_operands" (*--... Operations on constants of (mostly) any type .......................--*) external is_constant : llvalue -> bool = "llvm_is_constant" diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index 742265cd3d5c..2f9e83797f0f 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -557,6 +557,14 @@ val fold_right_uses : (lluse -> 'a -> 'a) -> llvalue -> 'a -> 'a method [llvm::User::getOperand]. *) external operand : llvalue -> int -> llvalue = "llvm_operand" +(** [set_operand v i o] sets the operand of the value [v] at the index [i] to + the value [o]. + See the method [llvm::User::setOperand]. *) +external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand" + +(** [num_operands v] returns the number of operands for the value [v]. + See the method [llvm::User::getNumOperands]. *) +external num_operands : llvalue -> int = "llvm_num_operands" (** {7 Operations on constants of (mostly) any type} *) diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 2caa3876dc48..d25d2942d147 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -452,6 +452,17 @@ CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) { return LLVMGetOperand(V, Int_val(I)); } +/* llvalue -> int -> llvalue -> unit */ +CAMLprim value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) { + LLVMSetOperand(U, Int_val(I), V); + return Val_unit; +} + +/* llvalue -> int */ +CAMLprim value llvm_num_operands(LLVMValueRef V) { + return Val_int(LLVMGetNumOperands(V)); +} + /*--... Operations on constants of (mostly) any type .......................--*/ /* llvalue -> bool */ diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 99de9e33987d..665dd0447c98 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -523,6 +523,8 @@ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U); /* Operations on Users */ LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index); +void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val); +int LLVMGetNumOperands(LLVMValueRef Val); /* Operations on constants of any type */ LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */ diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index e42a68baff9c..f458051c31c7 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -489,6 +489,14 @@ LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) { return wrap(unwrap(Val)->getOperand(Index)); } +void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) { + unwrap(Val)->setOperand(Index, unwrap(Op)); +} + +int LLVMGetNumOperands(LLVMValueRef Val) { + return unwrap(Val)->getNumOperands(); +} + /*--.. Operations on constants of any type .................................--*/ LLVMValueRef LLVMConstNull(LLVMTypeRef Ty) { diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml index ba8c6962a55a..2894637e2b84 100644 --- a/test/Bindings/Ocaml/vmcore.ml +++ b/test/Bindings/Ocaml/vmcore.ml @@ -642,11 +642,18 @@ let test_users () = let p1 = param fn 0 in let p2 = param fn 1 in + let a3 = build_alloca i32_type "user_alloca" b in + let p3 = build_load a3 "user_load" b in let i = build_add p1 p2 "sum" b in + insist ((num_operands i) = 2); insist ((operand i 0) = p1); insist ((operand i 1) = p2); + set_operand i 1 p3; + insist ((operand i 1) != p2); + insist ((operand i 1) = p3); + ignore (build_unreachable b)