Index: bindings/ocaml/linker/linker_ocaml.c =================================================================== --- bindings/ocaml/linker/linker_ocaml.c +++ bindings/ocaml/linker/linker_ocaml.c @@ -31,3 +31,23 @@ return Val_unit; } + +/* llmodule -> lllinker */ +CAMLprim LLVMLinkerCtx llvm_get_linker(LLVMModuleRef Dest) { + return LLVMGetLinkerCtx(Dest); +} + +/* lllinker -> llmodule -> unit */ +CAMLprim value llvm_link_in(LLVMLinkerCtx Dest, LLVMModuleRef Src) { + if (LLVMLinkInModule(Dest, Src)) + llvm_raise(*caml_named_value("Llvm_linker.Error"), + LLVMCreateMessage("Linking failed")); + + return Val_unit; +} + +/* lllinker -> unit */ +CAMLprim value llvm_linker_dispose(LLVMLinkerCtx L) { + LLVMDisposeLinkerCtx(L); + return Val_unit; +} Index: bindings/ocaml/linker/llvm_linker.ml =================================================================== --- bindings/ocaml/linker/llvm_linker.ml +++ bindings/ocaml/linker/llvm_linker.ml @@ -12,3 +12,9 @@ external link_modules' : Llvm.llmodule -> Llvm.llmodule -> unit = "llvm_link_modules" + +external get_linker : Llvm.llmodule -> Llvm.lllinker = "llvm_get_linker" + +external linker_dispose : Llvm.lllinker -> unit = "llvm_linker_dispose" + +external link_in : Llvm.lllinker -> Llvm.llmodule -> unit = "llvm_link_in" Index: bindings/ocaml/linker/llvm_linker.mli =================================================================== --- bindings/ocaml/linker/llvm_linker.mli +++ bindings/ocaml/linker/llvm_linker.mli @@ -15,4 +15,15 @@ (** [link_modules' dst src] links [src] into [dst], raising [Error] if the linking fails. The src module is destroyed. *) -val link_modules' : Llvm.llmodule -> Llvm.llmodule -> unit \ No newline at end of file +val link_modules' : Llvm.llmodule -> Llvm.llmodule -> unit + +(** [get_linker dst] creates a linker context used to link into module [dst]. + See the [llvm::Linker] class. *) +val get_linker : Llvm.llmodule -> Llvm.lllinker + +(** [link_in dst src] links [src] into [dst], raising [Error] if the linking + fails. See the [llvm::Linker::linkInModule] method. *) +val link_in : Llvm.lllinker -> Llvm.llmodule -> unit + +(** [linker_dispose linker] frees up linker from [get_linker]. *) +val linker_dispose : Llvm.lllinker -> unit Index: bindings/ocaml/llvm/llvm.ml =================================================================== --- bindings/ocaml/llvm/llvm.ml +++ bindings/ocaml/llvm/llvm.ml @@ -9,6 +9,7 @@ type llcontext type llmodule +type lllinker type lltype type llvalue type lluse Index: bindings/ocaml/llvm/llvm.mli =================================================================== --- bindings/ocaml/llvm/llvm.mli +++ bindings/ocaml/llvm/llvm.mli @@ -24,6 +24,10 @@ objects. See the [llvm::Module] class. *) type llmodule +(** A linker used to link in other LLVM IR modules. See the [llvm::Linker] + class. *) +type lllinker + (** Each value in the LLVM IR has a type, an instance of [lltype]. See the [llvm::Type] class. *) type lltype Index: include/llvm-c/Linker.h =================================================================== --- include/llvm-c/Linker.h +++ include/llvm-c/Linker.h @@ -34,6 +34,23 @@ */ LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src); +/** + * Construct a linker for a module. + * @see llvm::Linker(Module&) + */ +LLVMLinkerCtx LLVMGetLinkerCtx(LLVMModuleRef Dest); + +/** + * Link Src into the composite Dest. + * @see llvm::Linker::linkInModule + */ +LLVMBool LLVMLinkInModule(LLVMLinkerCtx Dest, LLVMModuleRef Src); + +/** + * Destroy a linker. + */ +void LLVMDisposeLinkerCtx(LLVMLinkerCtx L); + #ifdef __cplusplus } #endif Index: include/llvm-c/Types.h =================================================================== --- include/llvm-c/Types.h +++ include/llvm-c/Types.h @@ -48,6 +48,13 @@ */ typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef; +/** + * Used to pass linkers through LLVM interfaces. + * + * @see llvm::Linker + */ +typedef struct LLVMOpaqueLinkerCtx *LLVMLinkerCtx; + /** * The top-level container for all LLVM global data. See the LLVMContext class. */ Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -603,3 +603,18 @@ std::unique_ptr M(unwrap(Src)); return Linker::linkModules(*D, std::move(M)); } + +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Linker, LLVMLinkerCtx) + +LLVMLinkerCtx LLVMGetLinkerCtx(LLVMModuleRef Dest) { + Module *D = unwrap(Dest); + return wrap(new Linker(*D)); +} + +LLVMBool LLVMLinkInModule(LLVMLinkerCtx Dest, LLVMModuleRef Src) { + Linker *L = unwrap(Dest); + std::unique_ptr M(unwrap(Src)); + return L->linkInModule(std::move(M), Linker::Flags::None, {}); +} + +void LLVMDisposeLinkerCtx(LLVMLinkerCtx L) { delete unwrap(L); }