+external gc : llvalue -> string option = "llvm_gc"
+external set_gc : string option -> llvalue -> unit = "llvm_set_gc"
+external function_begin : llmodule -> (llmodule, llvalue) llpos
+ = "llvm_function_begin"
+external function_succ : llvalue -> (llmodule, llvalue) llpos
+ = "llvm_function_succ"
+external function_end : llmodule -> (llmodule, llvalue) llrev_pos
+ = "llvm_function_end"
+external function_pred : llvalue -> (llmodule, llvalue) llrev_pos
+ = "llvm_function_pred"
+
+let rec iter_function_range f i e =
+ if i = e then () else
+ match i with
+ | At_end _ -> raise (Invalid_argument "Invalid function range.")
+ | Before fn ->
+ f fn;
+ iter_function_range f (function_succ fn) e
+
+let iter_functions f m =
+ iter_function_range f (function_begin m) (At_end m)
+
+let rec fold_left_function_range f init i e =
+ if i = e then init else
+ match i with
+ | At_end _ -> raise (Invalid_argument "Invalid function range.")
+ | Before fn -> fold_left_function_range f (f init fn) (function_succ fn) e
+
+let fold_left_functions f init m =
+ fold_left_function_range f init (function_begin m) (At_end m)
+
+let rec rev_iter_function_range f i e =
+ if i = e then () else
+ match i with
+ | At_start _ -> raise (Invalid_argument "Invalid function range.")
+ | After fn ->
+ f fn;
+ rev_iter_function_range f (function_pred fn) e
+
+let rev_iter_functions f m =
+ rev_iter_function_range f (function_end m) (At_start m)
+
+let rec fold_right_function_range f i e init =
+ if i = e then init else
+ match i with
+ | At_start _ -> raise (Invalid_argument "Invalid function range.")
+ | After fn -> fold_right_function_range f (function_pred fn) e (f fn init)
+
+let fold_right_functions f m init =
+ fold_right_function_range f (function_end m) (At_start m) init
+
+external llvm_add_function_attr : llvalue -> int -> unit
+ = "llvm_add_function_attr"
+external llvm_remove_function_attr : llvalue -> int -> unit
+ = "llvm_remove_function_attr"
+
+let pack_attr (attr:Attribute.t) : int =
+ match attr with
+ Attribute.Zext -> 1 lsl 0
+ | Attribute.Sext -> 1 lsl 1
+ | Attribute.Noreturn -> 1 lsl 2
+ | Attribute.Inreg -> 1 lsl 3
+ | Attribute.Structret -> 1 lsl 4
+ | Attribute.Nounwind -> 1 lsl 5
+ | Attribute.Noalias -> 1 lsl 6
+ | Attribute.Byval -> 1 lsl 7
+ | Attribute.Nest -> 1 lsl 8
+ | Attribute.Readnone -> 1 lsl 9
+ | Attribute.Readonly -> 1 lsl 10
+ | Attribute.Noinline -> 1 lsl 11
+ | Attribute.Alwaysinline -> 1 lsl 12
+ | Attribute.Optsize -> 1 lsl 13
+ | Attribute.Ssp -> 1 lsl 14
+ | Attribute.Sspreq -> 1 lsl 15
+ | Attribute.Alignment n -> n lsl 16
+ | Attribute.Nocapture -> 1 lsl 21
+ | Attribute.Noredzone -> 1 lsl 22
+ | Attribute.Noimplicitfloat -> 1 lsl 23
+ | Attribute.Naked -> 1 lsl 24
+ | Attribute.Inlinehint -> 1 lsl 25
+ | Attribute.Stackalignment n -> n lsl 26
+
+let add_function_attr llval attr =
+ llvm_add_function_attr llval (pack_attr attr)
+
+let remove_function_attr llval attr =
+ llvm_remove_function_attr llval (pack_attr attr)
+
+(*--... Operations on params ...............................................--*)
+external params : llvalue -> llvalue array = "llvm_params"
+external param : llvalue -> int -> llvalue = "llvm_param"
+external param_parent : llvalue -> llvalue = "LLVMGetParamParent"
+external param_begin : llvalue -> (llvalue, llvalue) llpos = "llvm_param_begin"
+external param_succ : llvalue -> (llvalue, llvalue) llpos = "llvm_param_succ"
+external param_end : llvalue -> (llvalue, llvalue) llrev_pos = "llvm_param_end"
+external param_pred : llvalue -> (llvalue, llvalue) llrev_pos ="llvm_param_pred"