[llvm] 506df1b - [OCaml] DebugInfo support for OCaml bindings

Vaivaswatha Nagaraj via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 16 21:46:42 PDT 2021


Author: Vaivaswatha Nagaraj
Date: 2021-03-17T10:15:56+05:30
New Revision: 506df1bbfd16233134a6ddea96ed2d49077840fd

URL: https://github.com/llvm/llvm-project/commit/506df1bbfd16233134a6ddea96ed2d49077840fd
DIFF: https://github.com/llvm/llvm-project/commit/506df1bbfd16233134a6ddea96ed2d49077840fd.diff

LOG: [OCaml] DebugInfo support for OCaml bindings

Many (but not all) DebugInfo functions are now added to the
OCaml bindings, and rest can be safely added incrementally.

Differential Revision: https://reviews.llvm.org/D90831

Added: 
    llvm/bindings/ocaml/.ocamlformat
    llvm/bindings/ocaml/debuginfo/CMakeLists.txt
    llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
    llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml
    llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli
    llvm/bindings/ocaml/llvm/llvm_ocaml.h

Modified: 
    llvm/bindings/ocaml/CMakeLists.txt
    llvm/bindings/ocaml/README.txt
    llvm/bindings/ocaml/llvm/CMakeLists.txt
    llvm/bindings/ocaml/llvm/META.llvm.in
    llvm/bindings/ocaml/llvm/llvm.ml
    llvm/bindings/ocaml/llvm/llvm.mli
    llvm/bindings/ocaml/llvm/llvm_ocaml.c

Removed: 
    


################################################################################
diff  --git a/llvm/bindings/ocaml/.ocamlformat b/llvm/bindings/ocaml/.ocamlformat
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/llvm/bindings/ocaml/CMakeLists.txt b/llvm/bindings/ocaml/CMakeLists.txt
index 20583682c3d7..7fe960b67f27 100644
--- a/llvm/bindings/ocaml/CMakeLists.txt
+++ b/llvm/bindings/ocaml/CMakeLists.txt
@@ -4,6 +4,7 @@ add_subdirectory(analysis)
 add_subdirectory(backends)
 add_subdirectory(bitreader)
 add_subdirectory(bitwriter)
+add_subdirectory(debuginfo)
 add_subdirectory(irreader)
 add_subdirectory(linker)
 add_subdirectory(target)

diff  --git a/llvm/bindings/ocaml/README.txt b/llvm/bindings/ocaml/README.txt
index 68216b6792a7..a6a595e75bb5 100644
--- a/llvm/bindings/ocaml/README.txt
+++ b/llvm/bindings/ocaml/README.txt
@@ -20,7 +20,8 @@ The bindings can also be built out-of-tree, i.e. targeting a preinstalled
 LLVM. To do this, configure the LLVM build tree as follows:
 
     $ cmake -DLLVM_OCAML_OUT_OF_TREE=TRUE \
-            -DCMAKE_INSTALL_PREFIX=[OCaml install prefix] \
+            -DCMAKE_INSTALL_PREFIX=[Preinstalled LLVM path] \
+            -DLLVM_OCAML_INSTALL_PATH=[OCaml install prefix] \
             [... any other options]
 
 then build and install it as:

diff  --git a/llvm/bindings/ocaml/debuginfo/CMakeLists.txt b/llvm/bindings/ocaml/debuginfo/CMakeLists.txt
new file mode 100644
index 000000000000..07f4956cccf2
--- /dev/null
+++ b/llvm/bindings/ocaml/debuginfo/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_ocaml_library(llvm_debuginfo
+  OCAML    llvm_debuginfo
+  OCAMLDEP llvm
+  C        debuginfo_ocaml
+  CFLAGS   "-I${CMAKE_CURRENT_SOURCE_DIR}/../llvm"
+  LLVM     Core)

diff  --git a/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c b/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
new file mode 100644
index 000000000000..22ac2d4ba256
--- /dev/null
+++ b/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
@@ -0,0 +1,876 @@
+/*===-- debuginfo_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file glues LLVM's OCaml interface to its C interface. These functions *|
+|* are by and large transparent wrappers to the corresponding C functions.    *|
+|*                                                                            *|
+|* Note that these functions intentionally take liberties with the CAMLparamX *|
+|* macros, since most of the parameters are not GC heap objects.              *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#include <string.h>
+
+#include "caml/memory.h"
+#include "caml/mlvalues.h"
+#include "llvm-c/Core.h"
+#include "llvm-c/DebugInfo.h"
+#include "llvm-c/Support.h"
+
+#include "llvm_ocaml.h"
+
+// This is identical to the definition in llvm_debuginfo.ml:DIFlag.t
+typedef enum {
+  i_DIFlagZero,
+  i_DIFlagPrivate,
+  i_DIFlagProtected,
+  i_DIFlagPublic,
+  i_DIFlagFwdDecl,
+  i_DIFlagAppleBlock,
+  i_DIFlagReservedBit4,
+  i_DIFlagVirtual,
+  i_DIFlagArtificial,
+  i_DIFlagExplicit,
+  i_DIFlagPrototyped,
+  i_DIFlagObjcClassComplete,
+  i_DIFlagObjectPointer,
+  i_DIFlagVector,
+  i_DIFlagStaticMember,
+  i_DIFlagLValueReference,
+  i_DIFlagRValueReference,
+  i_DIFlagReserved,
+  i_DIFlagSingleInheritance,
+  i_DIFlagMultipleInheritance,
+  i_DIFlagVirtualInheritance,
+  i_DIFlagIntroducedVirtual,
+  i_DIFlagBitField,
+  i_DIFlagNoReturn,
+  i_DIFlagTypePassByValue,
+  i_DIFlagTypePassByReference,
+  i_DIFlagEnumClass,
+  i_DIFlagFixedEnum,
+  i_DIFlagThunk,
+  i_DIFlagNonTrivial,
+  i_DIFlagBigEndian,
+  i_DIFlagLittleEndian,
+  i_DIFlagIndirectVirtualBase,
+  i_DIFlagAccessibility,
+  i_DIFlagPtrToMemberRep
+} LLVMDIFlag_i;
+
+static LLVMDIFlags map_DIFlag(LLVMDIFlag_i DIF) {
+  switch (DIF) {
+  case i_DIFlagZero:
+    return LLVMDIFlagZero;
+  case i_DIFlagPrivate:
+    return LLVMDIFlagPrivate;
+  case i_DIFlagProtected:
+    return LLVMDIFlagProtected;
+  case i_DIFlagPublic:
+    return LLVMDIFlagPublic;
+  case i_DIFlagFwdDecl:
+    return LLVMDIFlagFwdDecl;
+  case i_DIFlagAppleBlock:
+    return LLVMDIFlagAppleBlock;
+  case i_DIFlagReservedBit4:
+    return LLVMDIFlagReservedBit4;
+  case i_DIFlagVirtual:
+    return LLVMDIFlagVirtual;
+  case i_DIFlagArtificial:
+    return LLVMDIFlagArtificial;
+  case i_DIFlagExplicit:
+    return LLVMDIFlagExplicit;
+  case i_DIFlagPrototyped:
+    return LLVMDIFlagPrototyped;
+  case i_DIFlagObjcClassComplete:
+    return LLVMDIFlagObjcClassComplete;
+  case i_DIFlagObjectPointer:
+    return LLVMDIFlagObjectPointer;
+  case i_DIFlagVector:
+    return LLVMDIFlagVector;
+  case i_DIFlagStaticMember:
+    return LLVMDIFlagStaticMember;
+  case i_DIFlagLValueReference:
+    return LLVMDIFlagLValueReference;
+  case i_DIFlagRValueReference:
+    return LLVMDIFlagRValueReference;
+  case i_DIFlagReserved:
+    return LLVMDIFlagReserved;
+  case i_DIFlagSingleInheritance:
+    return LLVMDIFlagSingleInheritance;
+  case i_DIFlagMultipleInheritance:
+    return LLVMDIFlagMultipleInheritance;
+  case i_DIFlagVirtualInheritance:
+    return LLVMDIFlagVirtualInheritance;
+  case i_DIFlagIntroducedVirtual:
+    return LLVMDIFlagIntroducedVirtual;
+  case i_DIFlagBitField:
+    return LLVMDIFlagBitField;
+  case i_DIFlagNoReturn:
+    return LLVMDIFlagNoReturn;
+  case i_DIFlagTypePassByValue:
+    return LLVMDIFlagTypePassByValue;
+  case i_DIFlagTypePassByReference:
+    return LLVMDIFlagTypePassByReference;
+  case i_DIFlagEnumClass:
+    return LLVMDIFlagEnumClass;
+  case i_DIFlagFixedEnum:
+    return LLVMDIFlagFixedEnum;
+  case i_DIFlagThunk:
+    return LLVMDIFlagThunk;
+  case i_DIFlagNonTrivial:
+    return LLVMDIFlagNonTrivial;
+  case i_DIFlagBigEndian:
+    return LLVMDIFlagBigEndian;
+  case i_DIFlagLittleEndian:
+    return LLVMDIFlagLittleEndian;
+  case i_DIFlagIndirectVirtualBase:
+    return LLVMDIFlagIndirectVirtualBase;
+  case i_DIFlagAccessibility:
+    return LLVMDIFlagAccessibility;
+  case i_DIFlagPtrToMemberRep:
+    return LLVMDIFlagPtrToMemberRep;
+  }
+}
+
+CAMLprim value llvm_debug_metadata_version(value Unit) {
+  return Val_int(LLVMDebugMetadataVersion());
+}
+
+CAMLprim value llvm_get_module_debug_metadata_version(LLVMModuleRef Module) {
+  return Val_int(LLVMGetModuleDebugMetadataVersion(Module));
+}
+
+#define DIFlags_val(v) (*(LLVMDIFlags *)(Data_custom_val(v)))
+
+static struct custom_operations diflags_ops = {
+    (char *)"DebugInfo.lldiflags", custom_finalize_default,
+    custom_compare_default,        custom_hash_default,
+    custom_serialize_default,      custom_deserialize_default,
+    custom_compare_ext_default};
+
+static value alloc_diflags(LLVMDIFlags Flags) {
+  value V = alloc_custom(&diflags_ops, sizeof(LLVMDIFlags), 0, 1);
+  DIFlags_val(V) = Flags;
+  return V;
+}
+
+CAMLprim LLVMDIFlags llvm_diflags_get(value i_Flag) {
+  LLVMDIFlags Flags = map_DIFlag(Int_val(i_Flag));
+  return alloc_diflags(Flags);
+}
+
+CAMLprim LLVMDIFlags llvm_diflags_set(value Flags, value i_Flag) {
+  LLVMDIFlags FlagsNew = DIFlags_val(Flags) | map_DIFlag(Int_val(i_Flag));
+  return alloc_diflags(FlagsNew);
+}
+
+CAMLprim value llvm_diflags_test(value Flags, value i_Flag) {
+  LLVMDIFlags Flag = map_DIFlag(Int_val(i_Flag));
+  return Val_bool((DIFlags_val(Flags) & Flag) == Flag);
+}
+
+#define DIBuilder_val(v) (*(LLVMDIBuilderRef *)(Data_custom_val(v)))
+
+static void llvm_finalize_dibuilder(value B) {
+  LLVMDIBuilderFinalize(DIBuilder_val(B));
+  LLVMDisposeDIBuilder(DIBuilder_val(B));
+}
+
+static struct custom_operations dibuilder_ops = {
+    (char *)"DebugInfo.lldibuilder", llvm_finalize_dibuilder,
+    custom_compare_default,          custom_hash_default,
+    custom_serialize_default,        custom_deserialize_default,
+    custom_compare_ext_default};
+
+static value alloc_dibuilder(LLVMDIBuilderRef B) {
+  value V = alloc_custom(&dibuilder_ops, sizeof(LLVMDIBuilderRef), 0, 1);
+  DIBuilder_val(V) = B;
+  return V;
+}
+
+/* llmodule -> lldibuilder */
+CAMLprim value llvm_dibuilder(LLVMModuleRef M) {
+  return alloc_dibuilder(LLVMCreateDIBuilder(M));
+}
+
+CAMLprim value llvm_dibuild_finalize(value Builder) {
+  LLVMDIBuilderFinalize(DIBuilder_val(Builder));
+  return Val_unit;
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_compile_unit_native(
+    value Builder, value Lang, LLVMMetadataRef FileRef, value Producer,
+    value IsOptimized, value Flags, value RuntimeVer, value SplitName,
+    value Kind, value DWOId, value SplitDebugInline,
+    value DebugInfoForProfiling, value SysRoot, value SDK) {
+  return LLVMDIBuilderCreateCompileUnit(
+      DIBuilder_val(Builder), Int_val(Lang), FileRef, String_val(Producer),
+      caml_string_length(Producer), Bool_val(IsOptimized), String_val(Flags),
+      caml_string_length(Flags), Int_val(RuntimeVer), String_val(SplitName),
+      caml_string_length(SplitName), Int_val(Kind), Int_val(DWOId),
+      Bool_val(SplitDebugInline), Bool_val(DebugInfoForProfiling),
+      String_val(SysRoot), caml_string_length(SysRoot), String_val(SDK),
+      caml_string_length(SDK));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_compile_unit_bytecode(value *argv,
+                                                                   int argn) {
+  return llvm_dibuild_create_compile_unit_native(
+      argv[0],                  // Builder
+      argv[1],                  // Lang
+      (LLVMMetadataRef)argv[2], // FileRef
+      argv[3],                  // Producer
+      argv[4],                  // IsOptimized
+      argv[5],                  // Flags
+      argv[6],                  // RuntimeVer
+      argv[7],                  // SplitName
+      argv[8],                  // Kind
+      argv[9],                  // DWOId
+      argv[10],                 // SplitDebugInline
+      argv[11],                 // DebugInfoForProfiling
+      argv[12],                 // SysRoot
+      argv[13]                  // SDK
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_file(value Builder, value Filename,
+                                                  value Directory) {
+  return LLVMDIBuilderCreateFile(DIBuilder_val(Builder), String_val(Filename),
+                                 caml_string_length(Filename),
+                                 String_val(Directory),
+                                 caml_string_length(Directory));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_module_native(
+    value Builder, LLVMMetadataRef ParentScope, value Name, value ConfigMacros,
+    value IncludePath, value SysRoot) {
+  return LLVMDIBuilderCreateModule(
+      DIBuilder_val(Builder), ParentScope, String_val(Name),
+      caml_string_length(Name), String_val(ConfigMacros),
+      caml_string_length(ConfigMacros), String_val(IncludePath),
+      caml_string_length(IncludePath), String_val(SysRoot),
+      caml_string_length(SysRoot));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_module_bytecode(value *argv,
+                                                             int argn) {
+  return llvm_dibuild_create_module_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // ParentScope
+      argv[2],                  // Name
+      argv[3],                  // ConfigMacros
+      argv[4],                  // IncludePath
+      argv[5]                   // SysRoot
+  );
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_namespace(value Builder, LLVMMetadataRef ParentScope,
+                              value Name, value ExportSymbols) {
+  return LLVMDIBuilderCreateNameSpace(
+      DIBuilder_val(Builder), ParentScope, String_val(Name),
+      caml_string_length(Name), Bool_val(ExportSymbols));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_function_native(
+    value Builder, LLVMMetadataRef Scope, value Name, value LinkageName,
+    LLVMMetadataRef File, value LineNo, LLVMMetadataRef Ty, value IsLocalToUnit,
+    value IsDefinition, value ScopeLine, value Flags, value IsOptimized) {
+  return LLVMDIBuilderCreateFunction(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      String_val(LinkageName), caml_string_length(LinkageName), File,
+      Int_val(LineNo), Ty, Bool_val(IsLocalToUnit), Bool_val(IsDefinition),
+      Int_val(ScopeLine), DIFlags_val(Flags), Bool_val(IsOptimized));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_function_bytecode(value *argv,
+                                                               int argn) {
+  return llvm_dibuild_create_function_native(argv[0], // Builder,
+                                             (LLVMMetadataRef)argv[1], // Scope
+                                             argv[2],                  // Name
+                                             argv[3], // LinkageName
+                                             (LLVMMetadataRef)argv[4], // File
+                                             argv[5],                  // LineNo
+                                             (LLVMMetadataRef)argv[6], // Ty
+                                             argv[7],  // IsLocalUnit
+                                             argv[8],  // IsDefinition
+                                             argv[9],  // ScopeLine
+                                             argv[10], // Flags
+                                             argv[11]  // IsOptimized
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_lexical_block(
+    value Builder, LLVMMetadataRef Scope, LLVMMetadataRef File, value Line,
+    value Column) {
+  return LLVMDIBuilderCreateLexicalBlock(DIBuilder_val(Builder), Scope, File,
+                                         Int_val(Line), Int_val(Column));
+}
+
+CAMLprim LLVMMetadataRef llvm_metadata_null() { return (LLVMMetadataRef)NULL; }
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_debug_location(
+    LLVMContextRef Ctx, value Line, value Column, LLVMMetadataRef Scope,
+    LLVMMetadataRef InlinedAt) {
+  return LLVMDIBuilderCreateDebugLocation(Ctx, Int_val(Line), Int_val(Column),
+                                          Scope, InlinedAt);
+}
+
+CAMLprim value llvm_di_location_get_line(LLVMMetadataRef Location) {
+  return Val_int(LLVMDILocationGetLine(Location));
+}
+
+CAMLprim value llvm_di_location_get_column(LLVMMetadataRef Location) {
+  return Val_int(LLVMDILocationGetColumn(Location));
+}
+
+CAMLprim LLVMMetadataRef llvm_di_location_get_scope(LLVMMetadataRef Location) {
+  return LLVMDILocationGetScope(Location);
+}
+
+CAMLprim value llvm_di_location_get_inlined_at(LLVMMetadataRef Location) {
+  return (ptr_to_option(LLVMDILocationGetInlinedAt(Location)));
+}
+
+CAMLprim value llvm_di_scope_get_file(LLVMMetadataRef Scope) {
+  return (ptr_to_option(LLVMDIScopeGetFile(Scope)));
+}
+
+CAMLprim value llvm_di_file_get_directory(LLVMMetadataRef File) {
+  unsigned Len;
+  const char *Directory = LLVMDIFileGetDirectory(File, &Len);
+  return cstr_to_string(Directory, Len);
+}
+
+CAMLprim value llvm_di_file_get_filename(LLVMMetadataRef File) {
+  unsigned Len;
+  const char *Filename = LLVMDIFileGetFilename(File, &Len);
+  return cstr_to_string(Filename, Len);
+}
+
+CAMLprim value llvm_di_file_get_source(LLVMMetadataRef File) {
+  unsigned Len;
+  const char *Source = LLVMDIFileGetSource(File, &Len);
+  return cstr_to_string(Source, Len);
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_get_or_create_type_array(value Builder,
+                                                               value Data) {
+
+  return LLVMDIBuilderGetOrCreateTypeArray(DIBuilder_val(Builder),
+                                           (LLVMMetadataRef *)Op_val(Data),
+                                           Wosize_val(Data));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_subroutine_type(
+    value Builder, LLVMMetadataRef File, value ParameterTypes, value Flags) {
+
+  return LLVMDIBuilderCreateSubroutineType(
+      DIBuilder_val(Builder), File, (LLVMMetadataRef *)Op_val(ParameterTypes),
+      Wosize_val(ParameterTypes), DIFlags_val(Flags));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_enumerator(value Builder,
+                                                        value Name, value Value,
+                                                        value IsUnsigned) {
+  return LLVMDIBuilderCreateEnumerator(
+      DIBuilder_val(Builder), String_val(Name), caml_string_length(Name),
+      (int64_t)Int_val(Value), Bool_val(IsUnsigned));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_enumeration_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNumber, value SizeInBits, value AlignInBits, value Elements,
+    LLVMMetadataRef ClassTy) {
+  return LLVMDIBuilderCreateEnumerationType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
+      Int_val(AlignInBits), (LLVMMetadataRef *)Op_val(Elements),
+      Wosize_val(Elements), ClassTy);
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_enumeration_type_bytecode(value *argv, int argn) {
+  return llvm_dibuild_create_enumeration_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // Scope
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // File
+      argv[4],                  // LineNumber
+      argv[5],                  // SizeInBits
+      argv[6],                  // AlignInBits
+      argv[7],                  // Elements
+      (LLVMMetadataRef)argv[8]  // ClassTy
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_union_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNumber, value SizeInBits, value AlignInBits, value Flags,
+    value Elements, value RunTimeLanguage, value UniqueId) {
+
+  return LLVMDIBuilderCreateUnionType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
+      Int_val(AlignInBits), DIFlags_val(Flags),
+      (LLVMMetadataRef *)Op_val(Elements), Wosize_val(Elements),
+      Int_val(RunTimeLanguage), String_val(UniqueId),
+      caml_string_length(UniqueId));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_union_type_bytecode(value *argv,
+                                                                 int argn) {
+  return llvm_dibuild_create_union_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // Scope
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // File
+      argv[4],                  // LineNumber
+      argv[5],                  // SizeInBits
+      argv[6],                  // AlignInBits
+      argv[7],                  // Flags
+      argv[8],                  // Elements
+      argv[9],                  // RunTimeLanguage
+      argv[10]                  // UniqueId
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_array_type(value Builder,
+                                                        value Size,
+                                                        value AlignInBits,
+                                                        LLVMMetadataRef Ty,
+                                                        value Subscripts) {
+  return LLVMDIBuilderCreateArrayType(
+      DIBuilder_val(Builder), (uint64_t)Int_val(Size), Int_val(AlignInBits), Ty,
+      (LLVMMetadataRef *)Op_val(Subscripts), Wosize_val(Subscripts));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_vector_type(value Builder,
+                                                         value Size,
+                                                         value AlignInBits,
+                                                         LLVMMetadataRef Ty,
+                                                         value Subscripts) {
+  return LLVMDIBuilderCreateVectorType(
+      DIBuilder_val(Builder), (uint64_t)Int_val(Size), Int_val(AlignInBits), Ty,
+      (LLVMMetadataRef *)Op_val(Subscripts), Wosize_val(Subscripts));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_unspecified_type(value Builder,
+                                                              value Name) {
+  return LLVMDIBuilderCreateUnspecifiedType(
+      DIBuilder_val(Builder), String_val(Name), caml_string_length(Name));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_basic_type(
+    value Builder, value Name, value SizeInBits, value Encoding, value Flags) {
+
+  return LLVMDIBuilderCreateBasicType(
+      DIBuilder_val(Builder), String_val(Name), caml_string_length(Name),
+      (uint64_t)Int_val(SizeInBits), Int_val(Encoding), DIFlags_val(Flags));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_pointer_type_native(
+    value Builder, LLVMMetadataRef PointeeTy, value SizeInBits,
+    value AlignInBits, value AddressSpace, value Name) {
+  return LLVMDIBuilderCreatePointerType(
+      DIBuilder_val(Builder), PointeeTy, (uint64_t)Int_val(SizeInBits),
+      Int_val(AlignInBits), Int_val(AddressSpace), String_val(Name),
+      caml_string_length(Name));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_pointer_type_bytecode(value *argv,
+                                                                   int argn) {
+  return llvm_dibuild_create_pointer_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // PointeeTy
+      argv[2],                  // SizeInBits
+      argv[3],                  // AlignInBits
+      argv[4],                  // AddressSpace
+      argv[5]                   // Name
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_struct_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNumber, value SizeInBits, value AlignInBits, value Flags,
+    LLVMMetadataRef DerivedFrom, value Elements, value RunTimeLanguage,
+    LLVMMetadataRef VTableHolder, value UniqueId) {
+
+  return LLVMDIBuilderCreateStructType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
+      Int_val(AlignInBits), DIFlags_val(Flags), DerivedFrom,
+      (LLVMMetadataRef *)Op_val(Elements), Wosize_val(Elements),
+      Int_val(RunTimeLanguage), VTableHolder, String_val(UniqueId),
+      caml_string_length(UniqueId));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_struct_type_bytecode(value *argv,
+                                                                  int argn) {
+  return llvm_dibuild_create_struct_type_native(
+      argv[0],                   // Builder
+      (LLVMMetadataRef)argv[1],  // Scope
+      argv[2],                   // Name
+      (LLVMMetadataRef)argv[3],  // File
+      argv[4],                   // LineNumber
+      argv[5],                   // SizeInBits
+      argv[6],                   // AlignInBits
+      argv[7],                   // Flags
+      (LLVMMetadataRef)argv[8],  // DeriviedFrom
+      argv[9],                   // Elements
+      argv[10],                  // RunTimeLanguage
+      (LLVMMetadataRef)argv[11], // VTableHolder
+      argv[12]                   // UniqueId
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_member_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNumber, value SizeInBits, value AlignInBits, value OffsetInBits,
+    value Flags, LLVMMetadataRef Ty) {
+
+  return LLVMDIBuilderCreateMemberType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
+      Int_val(AlignInBits), (uint64_t)Int_val(OffsetInBits), DIFlags_val(Flags),
+      Ty);
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_member_type_bytecode(value *argv,
+                                                                  int argn) {
+  return llvm_dibuild_create_member_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // Scope
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // File
+      argv[4],                  // LineNumber
+      argv[5],                  // SizeInBits
+      argv[6],                  // AlignInBits
+      argv[7],                  // OffsetInBits
+      argv[8],                  // Flags
+      (LLVMMetadataRef)argv[9]  // Ty
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_static_member_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNumber, LLVMMetadataRef Type, value Flags,
+    LLVMValueRef ConstantVal, value AlignInBits) {
+
+  return LLVMDIBuilderCreateStaticMemberType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNumber), Type, DIFlags_val(Flags), ConstantVal,
+      Int_val(AlignInBits));
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_static_member_type_bytecode(value *argv, int argn) {
+  return llvm_dibuild_create_static_member_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // Scope
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // File
+      argv[4],                  // LineNumber
+      (LLVMMetadataRef)argv[5], // Type
+      argv[6],                  // Flags,
+      (LLVMValueRef)argv[7],    // ConstantVal
+      argv[8]                   // AlignInBits
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_member_pointer_type_native(
+    value Builder, LLVMMetadataRef PointeeType, LLVMMetadataRef ClassType,
+    uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags) {
+
+  return LLVMDIBuilderCreateMemberPointerType(
+      DIBuilder_val(Builder), PointeeType, ClassType,
+      (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits), Flags);
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_member_pointer_type_bytecode(value *argv, int argn) {
+  return llvm_dibuild_create_member_pointer_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // PointeeType
+      (LLVMMetadataRef)argv[2], // ClassType
+      argv[3],                  // SizeInBits
+      argv[4],                  // AlignInBits
+      argv[5]                   // Flags
+  );
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_object_pointer_type(value Builder, LLVMMetadataRef Type) {
+  return LLVMDIBuilderCreateObjectPointerType(DIBuilder_val(Builder), Type);
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_qualified_type(
+    value Builder, value Tag, LLVMMetadataRef Type) {
+
+  return LLVMDIBuilderCreateQualifiedType(DIBuilder_val(Builder), Int_val(Tag),
+                                          Type);
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_reference_type(
+    value Builder, value Tag, LLVMMetadataRef Type) {
+
+  return LLVMDIBuilderCreateReferenceType(DIBuilder_val(Builder), Int_val(Tag),
+                                          Type);
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_null_ptr_type(value Builder) {
+
+  return LLVMDIBuilderCreateNullPtrType(DIBuilder_val(Builder));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_typedef_native(
+    value Builder, LLVMMetadataRef Type, value Name, LLVMMetadataRef File,
+    value LineNo, LLVMMetadataRef Scope, value AlignInBits) {
+
+  return LLVMDIBuilderCreateTypedef(
+      DIBuilder_val(Builder), Type, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNo), Scope, Int_val(AlignInBits));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_typedef_bytecode(value *argv,
+                                                              int argn) {
+
+  return llvm_dibuild_create_typedef_native(argv[0],                  // Builder
+                                            (LLVMMetadataRef)argv[1], // Type
+                                            argv[2],                  // Name
+                                            (LLVMMetadataRef)argv[3], // File
+                                            argv[4],                  // LineNo
+                                            (LLVMMetadataRef)argv[5], // Scope
+                                            argv[6] // AlignInBits
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_inheritance_native(
+    value Builder, LLVMMetadataRef Ty, LLVMMetadataRef BaseTy, value BaseOffset,
+    value VBPtrOffset, value Flags) {
+
+  return LLVMDIBuilderCreateInheritance(DIBuilder_val(Builder), Ty, BaseTy,
+                                        (uint64_t)Int_val(BaseOffset),
+                                        Int_val(VBPtrOffset), Flags);
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_inheritance_bytecode(value *argv,
+                                                                  int arg) {
+
+  return llvm_dibuild_create_inheritance_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // Ty
+      (LLVMMetadataRef)argv[2], // BaseTy
+      argv[3],                  // BaseOffset
+      argv[4],                  // VBPtrOffset
+      argv[5]                   // Flags
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_forward_decl_native(
+    value Builder, value Tag, value Name, LLVMMetadataRef Scope,
+    LLVMMetadataRef File, value Line, value RuntimeLang, value SizeInBits,
+    value AlignInBits, value UniqueIdentifier) {
+  return LLVMDIBuilderCreateForwardDecl(
+      DIBuilder_val(Builder), Int_val(Tag), String_val(Name),
+      caml_string_length(Name), Scope, File, Int_val(Line),
+      Int_val(RuntimeLang), (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
+      String_val(UniqueIdentifier), caml_string_length(UniqueIdentifier));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_forward_decl_bytecode(value *argv,
+                                                                   int arg) {
+
+  return llvm_dibuild_create_forward_decl_native(
+      argv[0],                  // Builder
+      argv[1],                  // Tag
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // Scope
+      (LLVMMetadataRef)argv[4], // File
+      argv[5],                  // Line
+      argv[6],                  // RuntimeLang
+      argv[7],                  // SizeInBits
+      argv[8],                  // AlignInBits
+      argv[9]                   // UniqueIdentifier
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_replaceable_composite_type_native(
+    value Builder, value Tag, value Name, LLVMMetadataRef Scope,
+    LLVMMetadataRef File, value Line, value RuntimeLang, value SizeInBits,
+    value AlignInBits, value Flags, value UniqueIdentifier) {
+
+  return LLVMDIBuilderCreateReplaceableCompositeType(
+      DIBuilder_val(Builder), Int_val(Tag), String_val(Name),
+      caml_string_length(Name), Scope, File, Int_val(Line),
+      Int_val(RuntimeLang), (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
+      DIFlags_val(Flags), String_val(UniqueIdentifier),
+      caml_string_length(UniqueIdentifier));
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_replaceable_composite_type_bytecode(value *argv, int arg) {
+
+  return llvm_dibuild_create_replaceable_composite_type_native(
+      argv[0],                  // Builder
+      argv[1],                  // Tag
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // Scope
+      (LLVMMetadataRef)argv[4], // File
+      argv[5],                  // Line
+      argv[6],                  // RuntimeLang
+      argv[7],                  // SizeInBits
+      argv[8],                  // AlignInBits
+      argv[9],                  // Flags
+      argv[10]                  // UniqueIdentifier
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_bit_field_member_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNum, value SizeInBits, value OffsetInBits,
+    value StorageOffsetInBits, value Flags, LLVMMetadataRef Ty) {
+
+  return LLVMDIBuilderCreateBitFieldMemberType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNum), (uint64_t)Int_val(SizeInBits),
+      (uint64_t)Int_val(OffsetInBits), (uint64_t)Int_val(StorageOffsetInBits),
+      DIFlags_val(Flags), Ty);
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_bit_field_member_type_bytecode(value *argv, int arg) {
+
+  return llvm_dibuild_create_bit_field_member_type_native(
+      argv[0],                  // Builder
+      (LLVMMetadataRef)argv[1], // Scope
+      argv[2],                  // Name
+      (LLVMMetadataRef)argv[3], // File
+      argv[4],                  // LineNum
+      argv[5],                  // SizeInBits
+      argv[6],                  // OffsetInBits
+      argv[7],                  // StorageOffsetInBits
+      argv[8],                  // Flags
+      (LLVMMetadataRef)argv[9]  // Ty
+  );
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_class_type_native(
+    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
+    value LineNumber, value SizeInBits, value AlignInBits, value OffsetInBits,
+    value Flags, LLVMMetadataRef DerivedFrom, value Elements,
+    LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode,
+    value UniqueIdentifier) {
+
+  return LLVMDIBuilderCreateClassType(
+      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
+      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
+      Int_val(AlignInBits), (uint64_t)Int_val(OffsetInBits), DIFlags_val(Flags),
+      DerivedFrom, (LLVMMetadataRef *)Op_val(Elements), Wosize_val(Elements),
+      VTableHolder, TemplateParamsNode, String_val(UniqueIdentifier),
+      caml_string_length(UniqueIdentifier));
+}
+
+CAMLprim LLVMMetadataRef llvm_dibuild_create_class_type_bytecode(value *argv,
+                                                                 int arg) {
+
+  return llvm_dibuild_create_class_type_native(
+      argv[0],                   // Builder
+      (LLVMMetadataRef)argv[1],  // Scope
+      argv[2],                   // Name
+      (LLVMMetadataRef)argv[3],  // File
+      argv[4],                   // LineNumber
+      argv[5],                   // SizeInBits
+      argv[6],                   // AlignInBits
+      argv[7],                   // OffsetInBits
+      argv[8],                   // Flags
+      (LLVMMetadataRef)argv[9],  // DerivedFrom
+      argv[10],                  // Elements
+      (LLVMMetadataRef)argv[11], // VTableHolder
+      (LLVMMetadataRef)argv[12], // TemplateParamsNode
+      argv[13]                   // UniqueIdentifier
+  );
+}
+
+CAMLprim LLVMMetadataRef
+llvm_dibuild_create_artificial_type(value Builder, LLVMMetadataRef Type) {
+  return LLVMDIBuilderCreateArtificialType(DIBuilder_val(Builder), Type);
+}
+
+CAMLprim value llvm_di_type_get_name(LLVMMetadataRef DType) {
+  size_t Len;
+  const char *Name = LLVMDITypeGetName(DType, &Len);
+  return cstr_to_string(Name, Len);
+}
+
+CAMLprim value llvm_di_type_get_size_in_bits(LLVMMetadataRef DType) {
+  uint64_t Size = LLVMDITypeGetSizeInBits(DType);
+  return Val_int((int)Size);
+}
+
+CAMLprim value llvm_di_type_get_offset_in_bits(LLVMMetadataRef DType) {
+  uint64_t Size = LLVMDITypeGetOffsetInBits(DType);
+  return Val_int((int)Size);
+}
+
+CAMLprim value llvm_di_type_get_align_in_bits(LLVMMetadataRef DType) {
+  uint32_t Size = LLVMDITypeGetAlignInBits(DType);
+  return Val_int(Size);
+}
+
+CAMLprim value llvm_di_type_get_line(LLVMMetadataRef DType) {
+  unsigned Line = LLVMDITypeGetLine(DType);
+  return Val_int(Line);
+}
+
+CAMLprim value llvm_di_type_get_flags(LLVMMetadataRef DType) {
+  LLVMDIFlags Flags = LLVMDITypeGetLine(DType);
+  return alloc_diflags(Flags);
+}
+
+CAMLprim value llvm_get_subprogram(LLVMValueRef Func) {
+  return (ptr_to_option(LLVMGetSubprogram(Func)));
+}
+
+CAMLprim value llvm_set_subprogram(LLVMValueRef Func, LLVMMetadataRef SP) {
+  LLVMSetSubprogram(Func, SP);
+  return Val_unit;
+}
+
+CAMLprim value llvm_di_subprogram_get_line(LLVMMetadataRef Subprogram) {
+  return Int_val(LLVMDISubprogramGetLine(Subprogram));
+}
+
+CAMLprim value llvm_instr_get_debug_loc(LLVMValueRef Inst) {
+  return (ptr_to_option(LLVMInstructionGetDebugLoc(Inst)));
+}
+
+CAMLprim value llvm_instr_set_debug_loc(LLVMValueRef Inst,
+                                        LLVMMetadataRef Loc) {
+  LLVMInstructionSetDebugLoc(Inst, Loc);
+  return Val_unit;
+}
+
+CAMLprim value
+llvm_di_global_variable_expression_get_variable(LLVMMetadataRef GVE) {
+  return (ptr_to_option(LLVMDIGlobalVariableExpressionGetVariable(GVE)));
+}
+
+CAMLprim value llvm_di_variable_get_line(LLVMMetadataRef Variable) {
+  return Val_int(LLVMDIVariableGetLine(Variable));
+}
+
+CAMLprim value llvm_di_variable_get_file(LLVMMetadataRef Variable) {
+  return (ptr_to_option(LLVMDIVariableGetFile(Variable)));
+}
+
+CAMLprim value llvm_get_metadata_kind(LLVMMetadataRef Metadata) {
+  return Val_int(LLVMGetMetadataKind(Metadata));
+}

diff  --git a/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml
new file mode 100644
index 000000000000..0bcb7b6c6e83
--- /dev/null
+++ b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml
@@ -0,0 +1,547 @@
+(*===-- llvm_debuginfo.ml - LLVM OCaml Interface --------------*- OCaml -*-===*
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===----------------------------------------------------------------------===*)
+
+type lldibuilder
+
+(** Source languages known by DWARF. *)
+module DWARFSourceLanguageKind = struct
+  type t =
+    | C89
+    | C
+    | Ada83
+    | C_plus_plus
+    | Cobol74
+    | Cobol85
+    | Fortran77
+    | Fortran90
+    | Pascal83
+    | Modula2
+    (*  New in DWARF v3: *)
+    | LLVMJava
+    | C99
+    | Ada95
+    | Fortran95
+    | PLI
+    | ObjC
+    | ObjC_plus_plus
+    | UPC
+    | D
+    (*  New in DWARF v4: *)
+    | LLVMPython
+    (*  New in DWARF v5: *)
+    | LLVMOpenCL
+    | Go
+    | Modula3
+    | Haskell
+    | C_plus_plus_03
+    | C_plus_plus_11
+    | OCaml
+    | Rust
+    | C11
+    | Swift
+    | Julia
+    | Dylan
+    | C_plus_plus_14
+    | Fortran03
+    | Fortran08
+    | RenderScript
+    | BLISS
+    (*  Vendor extensions: *)
+    | LLVMMips_Assembler
+    | GOOGLE_RenderScript
+    | BORLAND_Delphi
+end
+
+module DIFlag = struct
+  type t =
+    | Zero
+    | Private
+    | Protected
+    | Public
+    | FwdDecl
+    | AppleBlock
+    | ReservedBit4
+    | Virtual
+    | Artificial
+    | Explicit
+    | Prototyped
+    | ObjcClassComplete
+    | ObjectPointer
+    | Vector
+    | StaticMember
+    | LValueReference
+    | RValueReference
+    | Reserved
+    | SingleInheritance
+    | MultipleInheritance
+    | VirtualInheritance
+    | IntroducedVirtual
+    | BitField
+    | NoReturn
+    | TypePassByValue
+    | TypePassByReference
+    | EnumClass
+    | FixedEnum
+    | Thunk
+    | NonTrivial
+    | BigEndian
+    | LittleEndian
+    | IndirectVirtualBase
+    | Accessibility
+    | PtrToMemberRep
+end
+
+type lldiflags
+
+external diflags_get : DIFlag.t -> lldiflags = "llvm_diflags_get"
+
+external diflags_set : lldiflags -> DIFlag.t -> lldiflags = "llvm_diflags_set"
+
+external diflags_test : lldiflags -> DIFlag.t -> bool = "llvm_diflags_test"
+
+(** The kind of metadata nodes. *)
+module MetadataKind = struct
+  type t =
+    | MDStringMetadataKind
+    | ConstantAsMetadataMetadataKind
+    | LocalAsMetadataMetadataKind
+    | DistinctMDOperandPlaceholderMetadataKind
+    | MDTupleMetadataKind
+    | DILocationMetadataKind
+    | DIExpressionMetadataKind
+    | DIGlobalVariableExpressionMetadataKind
+    | GenericDINodeMetadataKind
+    | DISubrangeMetadataKind
+    | DIEnumeratorMetadataKind
+    | DIBasicTypeMetadataKind
+    | DIDerivedTypeMetadataKind
+    | DICompositeTypeMetadataKind
+    | DISubroutineTypeMetadataKind
+    | DIFileMetadataKind
+    | DICompileUnitMetadataKind
+    | DISubprogramMetadataKind
+    | DILexicalBlockMetadataKind
+    | DILexicalBlockFileMetadataKind
+    | DINamespaceMetadataKind
+    | DIModuleMetadataKind
+    | DITemplateTypeParameterMetadataKind
+    | DITemplateValueParameterMetadataKind
+    | DIGlobalVariableMetadataKind
+    | DILocalVariableMetadataKind
+    | DILabelMetadataKind
+    | DIObjCPropertyMetadataKind
+    | DIImportedEntityMetadataKind
+    | DIMacroMetadataKind
+    | DIMacroFileMetadataKind
+    | DICommonBlockMetadataKind
+end
+
+(** The amount of debug information to emit. *)
+module DWARFEmissionKind = struct
+  type t = None | Full | LineTablesOnly
+end
+
+external debug_metadata_version : unit -> int = "llvm_debug_metadata_version"
+
+external get_module_debug_metadata_version : Llvm.llmodule -> int
+  = "llvm_get_module_debug_metadata_version"
+
+external dibuilder : Llvm.llmodule -> lldibuilder = "llvm_dibuilder"
+
+external dibuild_finalize : lldibuilder -> unit = "llvm_dibuild_finalize"
+
+(* See LLVMDIBuilderCreateCompileUnit for argument details. *)
+external dibuild_create_compile_unit :
+  lldibuilder ->
+  DWARFSourceLanguageKind.t ->
+  file_ref:Llvm.llmetadata ->
+  producer:string ->
+  is_optimized:bool ->
+  flags:string ->
+  runtime_ver:int ->
+  split_name:string ->
+  DWARFEmissionKind.t ->
+  dwoid:int ->
+  di_inlining:bool ->
+  di_profiling:bool ->
+  sys_root:string ->
+  sdk:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_compile_unit_bytecode" "llvm_dibuild_create_compile_unit_native"
+
+external dibuild_create_file :
+  lldibuilder -> filename:string -> directory:string -> Llvm.llmetadata
+  = "llvm_dibuild_create_file"
+
+external dibuild_create_module :
+  lldibuilder ->
+  parent_ref:Llvm.llmetadata ->
+  name:string ->
+  config_macros:string ->
+  include_path:string ->
+  sys_root:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_module_bytecode" "llvm_dibuild_create_module_native"
+
+external dibuild_create_namespace :
+  lldibuilder ->
+  parent_ref:Llvm.llmetadata ->
+  name:string ->
+  bool:string ->
+  Llvm.llmetadata = "llvm_dibuild_create_namespace"
+
+external dibuild_create_function :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  linkage_name:string ->
+  file:Llvm.llmetadata ->
+  line_no:int ->
+  ty:Llvm.llmetadata ->
+  is_local_to_unit:bool ->
+  is_definition:bool ->
+  scope_line:int ->
+  flags:lldiflags ->
+  is_optimized:bool ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_function_bytecode" "llvm_dibuild_create_function_native"
+
+external dibuild_create_lexical_block :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  file:Llvm.llmetadata ->
+  line:int ->
+  column:int ->
+  Llvm.llmetadata = "llvm_dibuild_create_lexical_block"
+
+external dibuild_create_debug_location_helper :
+  Llvm.llcontext ->
+  line:int ->
+  column:int ->
+  scope:Llvm.llmetadata ->
+  inlined_at:Llvm.llmetadata ->
+  Llvm.llmetadata = "llvm_dibuild_create_debug_location"
+
+external llmetadata_null : unit -> Llvm.llmetadata = "llvm_metadata_null"
+(** [llmetadata_null ()] llmetadata is a wrapper around "llvm::Metadata *".
+    This function returns a nullptr valued llmetadata. For example,
+    it can be useful to pass NULL to LLVMInstructionSetDebugLoc. *)
+
+let dibuild_create_debug_location ?(inlined_at = llmetadata_null ()) llctx ~line
+    ~column ~scope =
+  dibuild_create_debug_location_helper llctx line column scope inlined_at
+
+external di_location_get_line : location:Llvm.llmetadata -> int
+  = "llvm_di_location_get_line"
+
+external di_location_get_column : location:Llvm.llmetadata -> int
+  = "llvm_di_location_get_column"
+
+external di_location_get_scope : location:Llvm.llmetadata -> Llvm.llmetadata
+  = "llvm_di_location_get_scope"
+
+external di_location_get_inlined_at :
+  location:Llvm.llmetadata -> Llvm.llmetadata option
+  = "llvm_di_location_get_inlined_at"
+
+external di_scope_get_file : scope:Llvm.llmetadata -> Llvm.llmetadata option
+  = "llvm_di_scope_get_file"
+
+external di_file_get_directory : file:Llvm.llmetadata -> string
+  = "llvm_di_file_get_directory"
+
+external di_file_get_filename : file:Llvm.llmetadata -> string
+  = "llvm_di_file_get_filename"
+
+external di_file_get_source : file:Llvm.llmetadata -> string
+  = "llvm_di_file_get_source"
+
+external dibuild_get_or_create_type_array :
+  lldibuilder -> data:Llvm.llmetadata array -> Llvm.llmetadata
+  = "llvm_dibuild_get_or_create_type_array"
+
+external dibuild_create_subroutine_type :
+  lldibuilder ->
+  file:Llvm.llmetadata ->
+  param_types:Llvm.llmetadata array ->
+  lldiflags ->
+  Llvm.llmetadata = "llvm_dibuild_create_subroutine_type"
+
+external dibuild_create_enumerator :
+  lldibuilder -> name:string -> value:int -> is_unsigned:bool -> Llvm.llmetadata
+  = "llvm_dibuild_create_enumerator"
+
+external dibuild_create_enumeration_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  elements:Llvm.llmetadata array ->
+  class_ty:Llvm.llmetadata ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_enumeration_type_native" "llvm_dibuild_create_enumeration_type_bytecode"
+
+external dibuild_create_union_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  elements:Llvm.llmetadata array ->
+  run_time_language:int ->
+  unique_id:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_union_type_native" "llvm_dibuild_create_union_type_bytecode"
+
+external dibuild_create_array_type :
+  lldibuilder ->
+  size:int ->
+  align_in_bits:int ->
+  ty:Llvm.llmetadata ->
+  subscripts:Llvm.llmetadata array ->
+  Llvm.llmetadata = "llvm_dibuild_create_array_type"
+
+external dibuild_create_vector_type :
+  lldibuilder ->
+  size:int ->
+  align_in_bits:int ->
+  ty:Llvm.llmetadata ->
+  subscripts:Llvm.llmetadata array ->
+  Llvm.llmetadata = "llvm_dibuild_create_array_type"
+
+external dibuild_create_unspecified_type :
+  lldibuilder -> name:string -> Llvm.llmetadata
+  = "llvm_dibuild_create_unspecified_type"
+
+external dibuild_create_basic_type :
+  lldibuilder ->
+  name:string ->
+  size_in_bits:int ->
+  encoding:int ->
+  lldiflags ->
+  Llvm.llmetadata = "llvm_dibuild_create_basic_type"
+
+external dibuild_create_pointer_type :
+  lldibuilder ->
+  pointee_ty:Llvm.llmetadata ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  address_space:int ->
+  name:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_pointer_type_native" "llvm_dibuild_create_pointer_type_bytecode"
+
+external dibuild_create_struct_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  derived_from:Llvm.llmetadata ->
+  elements:Llvm.llmetadata array ->
+  run_time_lang:int ->
+  vtable_holder:Llvm.llmetadata ->
+  unique_id:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_struct_type_native" "llvm_dibuild_create_struct_type_bytecode"
+
+external dibuild_create_member_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  offset_in_bits:int ->
+  lldiflags ->
+  ty:Llvm.llmetadata ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_member_type_native" "llvm_dibuild_create_member_type_bytecode"
+
+external dibuild_create_static_member_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  ty:Llvm.llmetadata ->
+  lldiflags ->
+  const_val:Llvm.llvalue ->
+  align_in_bits:int ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_static_member_type_native" "llvm_dibuild_create_static_member_type_bytecode"
+
+external dibuild_create_member_pointer_type :
+  lldibuilder ->
+  pointee_type:Llvm.llmetadata ->
+  class_type:Llvm.llmetadata ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_member_pointer_type_native" "llvm_dibuild_create_member_pointer_type_bytecode"
+
+external dibuild_create_object_pointer_type :
+  lldibuilder -> Llvm.llmetadata -> Llvm.llmetadata
+  = "llvm_dibuild_create_object_pointer_type"
+
+external dibuild_create_qualified_type :
+  lldibuilder -> tag:int -> Llvm.llmetadata -> Llvm.llmetadata
+  = "llvm_dibuild_create_qualified_type"
+
+external dibuild_create_reference_type :
+  lldibuilder -> tag:int -> Llvm.llmetadata -> Llvm.llmetadata
+  = "llvm_dibuild_create_reference_type"
+
+external dibuild_create_null_ptr_type : lldibuilder -> Llvm.llmetadata
+  = "llvm_dibuild_create_null_ptr_type"
+
+external dibuild_create_typedef :
+  lldibuilder ->
+  ty:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_no:int ->
+  scope:Llvm.llmetadata ->
+  align_in_bits:int ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_typedef_native" "llvm_dibuild_create_typedef_bytecode"
+
+external dibuild_create_inheritance_native :
+  lldibuilder ->
+  ty:Llvm.llmetadata ->
+  base_ty:Llvm.llmetadata ->
+  base_offset:int ->
+  vb_ptr_offset:int ->
+  lldiflags ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_inheritance_native" "llvm_dibuild_create_inheritance_bytecode"
+
+external dibuild_create_forward_decl :
+  lldibuilder ->
+  tag:int ->
+  name:string ->
+  scope:Llvm.llmetadata ->
+  file:Llvm.llmetadata ->
+  line:int ->
+  runtime_lang:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  unique_identifier:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_forward_decl_native" "llvm_dibuild_create_forward_decl_bytecode"
+
+external dibuild_create_replaceable_composite_type :
+  lldibuilder ->
+  tag:int ->
+  name:string ->
+  scope:Llvm.llmetadata ->
+  file:Llvm.llmetadata ->
+  line:int ->
+  runtime_lang:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  unique_identifier:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_replaceable_composite_type_native" "llvm_dibuild_create_replaceable_composite_type_bytecode"
+
+external dibuild_create_bit_field_member_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_num:int ->
+  size_in_bits:int ->
+  offset_in_bits:int ->
+  storage_offset_in_bits:int ->
+  lldiflags ->
+  ty:Llvm.llmetadata ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_bit_field_member_type_native" "llvm_dibuild_create_bit_field_member_type_bytecode"
+
+external dibuild_create_class_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  offset_in_bits:int ->
+  lldiflags ->
+  derived_from:Llvm.llmetadata ->
+  elements:Llvm.llmetadata array ->
+  vtable_holder:Llvm.llmetadata ->
+  template_params_node:Llvm.llmetadata ->
+  unique_identifier:string ->
+  Llvm.llmetadata
+  = "llvm_dibuild_create_class_type_native" "llvm_dibuild_create_class_type_bytecode"
+
+external dibuild_create_artificial_type :
+  lldibuilder -> ty:Llvm.llmetadata -> Llvm.llmetadata
+  = "llvm_dibuild_create_artificial_type"
+
+external di_type_get_name : Llvm.llmetadata -> string = "llvm_di_type_get_name"
+
+external di_type_get_size_in_bits : Llvm.llmetadata -> int
+  = "llvm_di_type_get_size_in_bits"
+
+external di_type_get_offset_in_bits : Llvm.llmetadata -> int
+  = "llvm_di_type_get_offset_in_bits"
+
+external di_type_get_align_in_bits : Llvm.llmetadata -> int
+  = "llvm_di_type_get_align_in_bits"
+
+external di_type_get_line : Llvm.llmetadata -> int = "llvm_di_type_get_line"
+
+external di_type_get_flags : Llvm.llmetadata -> lldiflags
+  = "llvm_di_type_get_flags"
+
+external get_subprogram : Llvm.llvalue -> Llvm.llmetadata option
+  = "llvm_get_subprogram"
+
+external set_subprogram : Llvm.llvalue -> Llvm.llmetadata -> unit
+  = "llvm_set_subprogram"
+
+external di_subprogram_get_line : Llvm.llmetadata -> int
+  = "llvm_di_subprogram_get_line"
+
+external instr_get_debug_loc : Llvm.llvalue -> Llvm.llmetadata option
+  = "llvm_instr_get_debug_loc"
+
+external instr_set_debug_loc_helper : Llvm.llvalue -> Llvm.llmetadata -> unit
+  = "llvm_instr_set_debug_loc"
+
+let instr_set_debug_loc i mopt =
+  match mopt with
+  | None -> instr_set_debug_loc_helper i (llmetadata_null ())
+  | Some m -> instr_set_debug_loc_helper i m
+
+external di_global_variable_expression_get_variable :
+  Llvm.llmetadata -> Llvm.llmetadata option
+  = "llvm_di_global_variable_expression_get_variable"
+
+external di_variable_get_line : Llvm.llmetadata -> int
+  = "llvm_di_variable_get_line"
+
+external di_variable_get_file : Llvm.llmetadata -> Llvm.llmetadata option
+  = "llvm_di_variable_get_file"
+
+external get_metadata_kind : Llvm.llmetadata -> MetadataKind.t
+  = "llvm_get_metadata_kind"

diff  --git a/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli
new file mode 100644
index 000000000000..24e31c7e1ffd
--- /dev/null
+++ b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli
@@ -0,0 +1,593 @@
+(*===-- llvm_debuginfo.mli - LLVM OCaml Interface -------------*- OCaml -*-===*
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===----------------------------------------------------------------------===*)
+
+type lldibuilder
+
+(** Source languages known by DWARF. *)
+module DWARFSourceLanguageKind : sig
+  type t =
+    | C89
+    | C
+    | Ada83
+    | C_plus_plus
+    | Cobol74
+    | Cobol85
+    | Fortran77
+    | Fortran90
+    | Pascal83
+    | Modula2
+    (*  New in DWARF v3: *)
+    | LLVMJava
+    | C99
+    | Ada95
+    | Fortran95
+    | PLI
+    | ObjC
+    | ObjC_plus_plus
+    | UPC
+    | D
+    (*  New in DWARF v4: *)
+    | LLVMPython
+    (*  New in DWARF v5: *)
+    | LLVMOpenCL
+    | Go
+    | Modula3
+    | Haskell
+    | C_plus_plus_03
+    | C_plus_plus_11
+    | OCaml
+    | Rust
+    | C11
+    | Swift
+    | Julia
+    | Dylan
+    | C_plus_plus_14
+    | Fortran03
+    | Fortran08
+    | RenderScript
+    | BLISS
+    (*  Vendor extensions: *)
+    | LLVMMips_Assembler
+    | GOOGLE_RenderScript
+    | BORLAND_Delphi
+end
+
+module DIFlag : sig
+  type t =
+    | Zero
+    | Private
+    | Protected
+    | Public
+    | FwdDecl
+    | AppleBlock
+    | ReservedBit4
+    | Virtual
+    | Artificial
+    | Explicit
+    | Prototyped
+    | ObjcClassComplete
+    | ObjectPointer
+    | Vector
+    | StaticMember
+    | LValueReference
+    | RValueReference
+    | Reserved
+    | SingleInheritance
+    | MultipleInheritance
+    | VirtualInheritance
+    | IntroducedVirtual
+    | BitField
+    | NoReturn
+    | TypePassByValue
+    | TypePassByReference
+    | EnumClass
+    | FixedEnum
+    | Thunk
+    | NonTrivial
+    | BigEndian
+    | LittleEndian
+    | IndirectVirtualBase
+    | Accessibility
+    | PtrToMemberRep
+end
+
+type lldiflags
+(** An opaque type to represent OR of multiple DIFlag.t. *)
+
+val diflags_get : DIFlag.t -> lldiflags
+(** [diflags_set f] Construct an lldiflags value with a single flag [f]. *)
+
+val diflags_set : lldiflags -> DIFlag.t -> lldiflags
+(** [diflags_set fs f] Include flag [f] in [fs] and return the new value. *)
+
+val diflags_test : lldiflags -> DIFlag.t -> bool
+(** [diflags_test fs f] Does [fs] contain flag [f]? *)
+
+(** The kind of metadata nodes. *)
+module MetadataKind : sig
+  type t =
+    | MDStringMetadataKind
+    | ConstantAsMetadataMetadataKind
+    | LocalAsMetadataMetadataKind
+    | DistinctMDOperandPlaceholderMetadataKind
+    | MDTupleMetadataKind
+    | DILocationMetadataKind
+    | DIExpressionMetadataKind
+    | DIGlobalVariableExpressionMetadataKind
+    | GenericDINodeMetadataKind
+    | DISubrangeMetadataKind
+    | DIEnumeratorMetadataKind
+    | DIBasicTypeMetadataKind
+    | DIDerivedTypeMetadataKind
+    | DICompositeTypeMetadataKind
+    | DISubroutineTypeMetadataKind
+    | DIFileMetadataKind
+    | DICompileUnitMetadataKind
+    | DISubprogramMetadataKind
+    | DILexicalBlockMetadataKind
+    | DILexicalBlockFileMetadataKind
+    | DINamespaceMetadataKind
+    | DIModuleMetadataKind
+    | DITemplateTypeParameterMetadataKind
+    | DITemplateValueParameterMetadataKind
+    | DIGlobalVariableMetadataKind
+    | DILocalVariableMetadataKind
+    | DILabelMetadataKind
+    | DIObjCPropertyMetadataKind
+    | DIImportedEntityMetadataKind
+    | DIMacroMetadataKind
+    | DIMacroFileMetadataKind
+    | DICommonBlockMetadataKind
+end
+
+(** The amount of debug information to emit. *)
+module DWARFEmissionKind : sig
+  type t = None | Full | LineTablesOnly
+end
+
+val debug_metadata_version : unit -> int
+(** [debug_metadata_version ()] The current debug metadata version number *)
+
+val get_module_debug_metadata_version : Llvm.llmodule -> int
+(** [get_module_debug_metadata_version m] Version of metadata present in [m]. *)
+
+val dibuilder : Llvm.llmodule -> lldibuilder
+(** [dibuilder m] Create a debug info builder for [m]. *)
+
+val dibuild_finalize : lldibuilder -> unit
+(** [dibuild_finalize dib] Construct any deferred debug info descriptors. *)
+
+val dibuild_create_compile_unit :
+  lldibuilder ->
+  DWARFSourceLanguageKind.t ->
+  file_ref:Llvm.llmetadata ->
+  producer:string ->
+  is_optimized:bool ->
+  flags:string ->
+  runtime_ver:int ->
+  split_name:string ->
+  DWARFEmissionKind.t ->
+  dwoid:int ->
+  di_inlining:bool ->
+  di_profiling:bool ->
+  sys_root:string ->
+  sdk:string ->
+  Llvm.llmetadata
+(** [dibuild_create_compile_unit] A CompileUnit provides an anchor for all
+    debugging information generated during this instance of compilation.
+    See LLVMDIBuilderCreateCompileUnit. *)
+
+val dibuild_create_file :
+  lldibuilder -> filename:string -> directory:string -> Llvm.llmetadata
+(** [dibuild_create_file] Create a file descriptor to hold debugging information
+    for a file. See LLVMDIBuilderCreateFile. *)
+
+val dibuild_create_module :
+  lldibuilder ->
+  parent_ref:Llvm.llmetadata ->
+  name:string ->
+  config_macros:string ->
+  include_path:string ->
+  sys_root:string ->
+  Llvm.llmetadata
+(** [dibuild_create_module] Create a new descriptor for a module with the
+    specified parent scope. See LLVMDIBuilderCreateModule. *)
+
+val dibuild_create_namespace :
+  lldibuilder ->
+  parent_ref:Llvm.llmetadata ->
+  name:string ->
+  bool:string ->
+  Llvm.llmetadata
+(** [dibuild_create_namespace] Create a new descriptor for a namespace with
+    the specified parent scope. See LLVMDIBuilderCreateNameSpace *)
+
+val dibuild_create_function :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  linkage_name:string ->
+  file:Llvm.llmetadata ->
+  line_no:int ->
+  ty:Llvm.llmetadata ->
+  is_local_to_unit:bool ->
+  is_definition:bool ->
+  scope_line:int ->
+  flags:lldiflags ->
+  is_optimized:bool ->
+  Llvm.llmetadata
+(** [dibuild_create_function] Create a new descriptor for the specified
+    subprogram. See LLVMDIBuilderCreateFunction. *)
+
+val dibuild_create_lexical_block :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  file:Llvm.llmetadata ->
+  line:int ->
+  column:int ->
+  Llvm.llmetadata
+(** [dibuild_create_lexical_block] Create a descriptor for a lexical block with
+    the specified parent context. See LLVMDIBuilderCreateLexicalBlock *)
+
+val dibuild_create_debug_location :
+  ?inlined_at:Llvm.llmetadata ->
+  Llvm.llcontext ->
+  line:int ->
+  column:int ->
+  scope:Llvm.llmetadata ->
+  Llvm.llmetadata
+(** [dibuild_create] Create a new DebugLocation that describes a source
+    location. See LLVMDIBuilderCreateDebugLocation *)
+
+val di_location_get_line : location:Llvm.llmetadata -> int
+(** [di_location_get_line l] Get the line number of debug location [l]. *)
+
+val di_location_get_column : location:Llvm.llmetadata -> int
+(** [di_location_get_column l] Get the column number of debug location [l]. *)
+
+val di_location_get_scope : location:Llvm.llmetadata -> Llvm.llmetadata
+(** [di_location_get_scope l] Get the local scope associated with
+    debug location [l]. *)
+
+val di_location_get_inlined_at :
+  location:Llvm.llmetadata -> Llvm.llmetadata option
+(** [di_location_get_inlined_at l] Get the "inlined at" location associated with
+    debug location [l], if it exists. *)
+
+val di_scope_get_file : scope:Llvm.llmetadata -> Llvm.llmetadata option
+(** [di_scope_get_file l] Get the metadata of the file associated with scope [s]
+    if it exists. *)
+
+val di_file_get_directory : file:Llvm.llmetadata -> string
+(** [di_file_get_directory f] Get the directory of file [f]. *)
+
+val di_file_get_filename : file:Llvm.llmetadata -> string
+(** [di_file_get_filename f] Get the name of file [f]. *)
+
+val di_file_get_source : file:Llvm.llmetadata -> string
+(** [di_file_get_source f] Get the source of file [f]. *)
+
+val dibuild_get_or_create_type_array :
+  lldibuilder -> data:Llvm.llmetadata array -> Llvm.llmetadata
+(** [dibuild_get_or_create_type_array] Create a type array.
+    See LLVMDIBuilderGetOrCreateTypeArray. *)
+
+val di_global_variable_expression_get_variable :
+  Llvm.llmetadata -> Llvm.llmetadata option
+(** [di_global_variable_expression_get_variable gve] returns the debug variable
+    of [gve], which must be a [DIGlobalVariableExpression].
+    See LLVMDIGlobalVariableExpressionGetVariable. *)
+
+val di_variable_get_line : Llvm.llmetadata -> int
+(** [di_variable_get_line v] returns the line number of the variable [v].
+    See LLVMDIVariableGetLine. *)
+
+val di_variable_get_file : Llvm.llmetadata -> Llvm.llmetadata option
+(** [di_variable_get_file v] returns the file of the variable [v].
+    See LLVMDIVariableGetFile. *)
+
+val dibuild_create_subroutine_type :
+  lldibuilder ->
+  file:Llvm.llmetadata ->
+  param_types:Llvm.llmetadata array ->
+  lldiflags ->
+  Llvm.llmetadata
+(** [dibuild_create_subroutine_type] Create subroutine type.
+    See LLVMDIBuilderCreateSubroutineType *)
+
+val dibuild_create_enumerator :
+  lldibuilder -> name:string -> value:int -> is_unsigned:bool -> Llvm.llmetadata
+(** [dibuild_create_enumerator] Create debugging information entry for an
+    enumerator. See LLVMDIBuilderCreateEnumerator *)
+
+val dibuild_create_enumeration_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  elements:Llvm.llmetadata array ->
+  class_ty:Llvm.llmetadata ->
+  Llvm.llmetadata
+(** [dibuild_create_enumeration_type] Create debugging information entry for
+    an enumeration. See LLVMDIBuilderCreateEnumerationType. *)
+
+val dibuild_create_union_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  elements:Llvm.llmetadata array ->
+  run_time_language:int ->
+  unique_id:string ->
+  Llvm.llmetadata
+(** [dibuild_create_union_type] Create debugging information entry for a union.
+    See LLVMDIBuilderCreateUnionType. *)
+
+val dibuild_create_array_type :
+  lldibuilder ->
+  size:int ->
+  align_in_bits:int ->
+  ty:Llvm.llmetadata ->
+  subscripts:Llvm.llmetadata array ->
+  Llvm.llmetadata
+(** [dibuild_create_array_type] Create debugging information entry for an array.
+    See LLVMDIBuilderCreateArrayType. *)
+
+val dibuild_create_vector_type :
+  lldibuilder ->
+  size:int ->
+  align_in_bits:int ->
+  ty:Llvm.llmetadata ->
+  subscripts:Llvm.llmetadata array ->
+  Llvm.llmetadata
+(** [dibuild_create_vector_type] Create debugging information entry for a
+    vector type. See LLVMDIBuilderCreateVectorType. *)
+
+val dibuild_create_unspecified_type :
+  lldibuilder -> name:string -> Llvm.llmetadata
+(** [dibuild_create_unspecified_type] Create a DWARF unspecified type. *)
+
+val dibuild_create_basic_type :
+  lldibuilder ->
+  name:string ->
+  size_in_bits:int ->
+  encoding:int ->
+  lldiflags ->
+  Llvm.llmetadata
+(** [dibuild_create_basic_type] Create debugging information entry for a basic
+    type. See LLVMDIBuilderCreateBasicType. *)
+
+val dibuild_create_pointer_type :
+  lldibuilder ->
+  pointee_ty:Llvm.llmetadata ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  address_space:int ->
+  name:string ->
+  Llvm.llmetadata
+(** [dibuild_create_pointer_type] Create debugging information entry for a
+    pointer. See LLVMDIBuilderCreatePointerType. *)
+
+val dibuild_create_struct_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  derived_from:Llvm.llmetadata ->
+  elements:Llvm.llmetadata array ->
+  run_time_lang:int ->
+  vtable_holder:Llvm.llmetadata ->
+  unique_id:string ->
+  Llvm.llmetadata
+(** [dibuild_create_struct_type] Create debugging information entry for a
+    struct. See LLVMDIBuilderCreateStructType *)
+
+val dibuild_create_member_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  offset_in_bits:int ->
+  lldiflags ->
+  ty:Llvm.llmetadata ->
+  Llvm.llmetadata
+(** [dibuild_create_member_type] Create debugging information entry for a
+    member. See LLVMDIBuilderCreateMemberType. *)
+
+val dibuild_create_static_member_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  ty:Llvm.llmetadata ->
+  lldiflags ->
+  const_val:Llvm.llvalue ->
+  align_in_bits:int ->
+  Llvm.llmetadata
+(** [dibuild_create_static_member_type] Create debugging information entry for
+    a C++ static data member. See LLVMDIBuilderCreateStaticMemberType *)
+
+val dibuild_create_member_pointer_type :
+  lldibuilder ->
+  pointee_type:Llvm.llmetadata ->
+  class_type:Llvm.llmetadata ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  Llvm.llmetadata
+(** [dibuild_create_member_pointer_type] Create debugging information entry for
+    a pointer to member. See LLVMDIBuilderCreateMemberPointerType *)
+
+val dibuild_create_object_pointer_type :
+  lldibuilder -> Llvm.llmetadata -> Llvm.llmetadata
+(** [dibuild_create_object_pointer_type dib ty] Create a uniqued DIType* clone
+  with FlagObjectPointer and FlagArtificial set. [dib] is the dibuilder
+  value and [ty] the underlying type to which this pointer points. *)
+
+val dibuild_create_qualified_type :
+  lldibuilder -> tag:int -> Llvm.llmetadata -> Llvm.llmetadata
+(** [dibuild_create_qualified_type dib tag ty] Create debugging information
+    entry for a qualified type, e.g. 'const int'. [dib] is the dibuilder value,
+    [tag] identifyies the type and [ty] is the base type. *)
+
+val dibuild_create_reference_type :
+  lldibuilder -> tag:int -> Llvm.llmetadata -> Llvm.llmetadata
+(** [dibuild_create_reference_type dib tag ty] Create debugging information
+    entry for a reference type. [dib] is the dibuilder value, [tag] identifyies
+    the type and [ty] is the base type. *)
+
+val dibuild_create_null_ptr_type : lldibuilder -> Llvm.llmetadata
+(** [dibuild_create_null_ptr_type dib] Create C++11 nullptr type. *)
+
+val dibuild_create_typedef :
+  lldibuilder ->
+  ty:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_no:int ->
+  scope:Llvm.llmetadata ->
+  align_in_bits:int ->
+  Llvm.llmetadata
+(** [dibuild_create_typedef] Create debugging information entry for a typedef.
+    See LLVMDIBuilderCreateTypedef. *)
+
+val dibuild_create_inheritance_native :
+  lldibuilder ->
+  ty:Llvm.llmetadata ->
+  base_ty:Llvm.llmetadata ->
+  base_offset:int ->
+  vb_ptr_offset:int ->
+  lldiflags ->
+  Llvm.llmetadata
+(** [dibuild_create_inheritance_native] Create debugging information entry
+    to establish inheritance relationship between two types.
+    See LLVMDIBuilderCreateInheritance. *)
+
+val dibuild_create_forward_decl :
+  lldibuilder ->
+  tag:int ->
+  name:string ->
+  scope:Llvm.llmetadata ->
+  file:Llvm.llmetadata ->
+  line:int ->
+  runtime_lang:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  unique_identifier:string ->
+  Llvm.llmetadata
+(** [dibuild_create_forward_decl] Create a permanent forward-declared type.
+    See LLVMDIBuilderCreateForwardDecl. *)
+
+val dibuild_create_replaceable_composite_type :
+  lldibuilder ->
+  tag:int ->
+  name:string ->
+  scope:Llvm.llmetadata ->
+  file:Llvm.llmetadata ->
+  line:int ->
+  runtime_lang:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  lldiflags ->
+  unique_identifier:string ->
+  Llvm.llmetadata
+(** [dibuild_create_replaceable_composite_type] Create a temporary
+    forward-declared type. See LLVMDIBuilderCreateReplaceableCompositeType. *)
+
+val dibuild_create_bit_field_member_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_num:int ->
+  size_in_bits:int ->
+  offset_in_bits:int ->
+  storage_offset_in_bits:int ->
+  lldiflags ->
+  ty:Llvm.llmetadata ->
+  Llvm.llmetadata
+(** [dibuild_create_bit_field_member_type] Create debugging information entry
+    for a bit field member. See LLVMDIBuilderCreateBitFieldMemberType. *)
+
+val dibuild_create_class_type :
+  lldibuilder ->
+  scope:Llvm.llmetadata ->
+  name:string ->
+  file:Llvm.llmetadata ->
+  line_number:int ->
+  size_in_bits:int ->
+  align_in_bits:int ->
+  offset_in_bits:int ->
+  lldiflags ->
+  derived_from:Llvm.llmetadata ->
+  elements:Llvm.llmetadata array ->
+  vtable_holder:Llvm.llmetadata ->
+  template_params_node:Llvm.llmetadata ->
+  unique_identifier:string ->
+  Llvm.llmetadata
+(** [dibuild_create_class_type] Create debugging information entry for a class.
+    See LLVMDIBuilderCreateClassType. *)
+
+val dibuild_create_artificial_type :
+  lldibuilder -> ty:Llvm.llmetadata -> Llvm.llmetadata
+(** [dibuild_create_artificial_type dib ty] Create a uniqued DIType* clone with
+    FlagArtificial set.
+    [dib] is the dibuilder value and [ty] the underlying type. *)
+
+val di_type_get_name : Llvm.llmetadata -> string
+(** [di_type_get_name m] Get the name of DIType [m]. *)
+
+val di_type_get_size_in_bits : Llvm.llmetadata -> int
+(** [di_type_get_size_in_bits m] Get size in bits of DIType [m]. *)
+
+val di_type_get_offset_in_bits : Llvm.llmetadata -> int
+(** [di_type_get_offset_in_bits m] Get offset in bits of DIType [m]. *)
+
+val di_type_get_align_in_bits : Llvm.llmetadata -> int
+(** [di_type_get_align_in_bits m] Get alignment in bits of DIType [m]. *)
+
+val di_type_get_line : Llvm.llmetadata -> int
+(** [di_type_get_line m] Get source line where DIType [m] is declared. *)
+
+val di_type_get_flags : Llvm.llmetadata -> lldiflags
+(** [di_type_get_flags m] Get the flags associated with DIType [m]. *)
+
+val get_subprogram : Llvm.llvalue -> Llvm.llmetadata option
+(** [get_subprogram f] Get the metadata of the subprogram attached to
+    function [f]. *)
+
+val set_subprogram : Llvm.llvalue -> Llvm.llmetadata -> unit
+(** [set_subprogram f m] Set the subprogram [m] attached to function [f]. *)
+
+val di_subprogram_get_line : Llvm.llmetadata -> int
+(** [di_subprogram_get_line m] Get the line associated with subprogram [m]. *)
+
+val instr_get_debug_loc : Llvm.llvalue -> Llvm.llmetadata option
+(** [instr_get_debug_loc i] Get the debug location for instruction [i]. *)
+
+val instr_set_debug_loc : Llvm.llvalue -> Llvm.llmetadata option -> unit
+(** [instr_set_debug_loc i mopt] If [mopt] is None location metadata of [i]
+    is cleared, Otherwise location of [i] is set to the value in [mopt]. *)
+
+val get_metadata_kind : Llvm.llmetadata -> MetadataKind.t
+(** [get_metadata_kind] Obtain the enumerated type of a Metadata instance. *)

diff  --git a/llvm/bindings/ocaml/llvm/CMakeLists.txt b/llvm/bindings/ocaml/llvm/CMakeLists.txt
index 99ef1cbff233..5e6f74ec9c59 100644
--- a/llvm/bindings/ocaml/llvm/CMakeLists.txt
+++ b/llvm/bindings/ocaml/llvm/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_ocaml_library(llvm
   OCAML llvm
   C     llvm_ocaml
+  CFLAGS   "-I${CMAKE_CURRENT_SOURCE_DIR}/"
   LLVM  Core Support)
 
 configure_file(

diff  --git a/llvm/bindings/ocaml/llvm/META.llvm.in b/llvm/bindings/ocaml/llvm/META.llvm.in
index adafd788ebf4..991bbc060098 100644
--- a/llvm/bindings/ocaml/llvm/META.llvm.in
+++ b/llvm/bindings/ocaml/llvm/META.llvm.in
@@ -45,6 +45,14 @@ package "ipo" (
     archive(native) = "llvm_ipo.cmxa"
 )
 
+package "debuginfo" (
+    requires = "llvm"
+    version = "@PACKAGE_VERSION@"
+    description = "DebugInfo support for LLVM"
+    archive(byte) = "llvm_debuginfo.cma"
+    archive(native) = "llvm_debuginfo.cmxa"
+)
+
 package "irreader" (
     requires = "llvm"
     version  = "@PACKAGE_VERSION@"

diff  --git a/llvm/bindings/ocaml/llvm/llvm.ml b/llvm/bindings/ocaml/llvm/llvm.ml
index b1065d770867..4205dd864192 100644
--- a/llvm/bindings/ocaml/llvm/llvm.ml
+++ b/llvm/bindings/ocaml/llvm/llvm.ml
@@ -9,6 +9,7 @@
 
 type llcontext
 type llmodule
+type llmetadata
 type lltype
 type llvalue
 type lluse
@@ -332,6 +333,16 @@ module DiagnosticSeverity = struct
   | Note
 end
 
+module ModuleFlagBehavior = struct
+  type t =
+  | Error
+  | Warning
+  | Require
+  | Override
+  | Append
+  | AppendUnique
+end
+
 exception IoError of string
 
 let () = Callback.register_exception "Llvm.IoError" (IoError "")
@@ -431,6 +442,10 @@ external string_of_llmodule : llmodule -> string = "llvm_string_of_llmodule"
 external set_module_inline_asm : llmodule -> string -> unit
                                = "llvm_set_module_inline_asm"
 external module_context : llmodule -> llcontext = "LLVMGetModuleContext"
+external get_module_flag : llmodule -> string -> llmetadata option
+                         = "llvm_get_module_flag"
+external add_module_flag : llmodule -> ModuleFlagBehavior.t ->
+            string -> llmetadata -> unit = "llvm_add_module_flag"
 
 (*===-- Types -------------------------------------------------------------===*)
 external classify_type : lltype -> TypeKind.t = "llvm_classify_type"
@@ -577,6 +592,9 @@ external get_named_metadata : llmodule -> string -> llvalue array
                             = "llvm_get_namedmd"
 external add_named_metadata_operand : llmodule -> string -> llvalue -> unit
                                     = "llvm_append_namedmd"
+external value_as_metadata : llvalue -> llmetadata = "llvm_value_as_metadata"
+external metadata_as_value : llcontext -> llmetadata -> llvalue
+                        = "llvm_metadata_as_value"
 
 (*--... Operations on scalar constants .....................................--*)
 external const_int : lltype -> int -> llvalue = "llvm_const_int"
@@ -701,6 +719,8 @@ external dll_storage_class : llvalue -> DLLStorageClass.t = "llvm_dll_storage_cl
 external set_dll_storage_class : DLLStorageClass.t -> llvalue -> unit = "llvm_set_dll_storage_class"
 external alignment : llvalue -> int = "llvm_alignment"
 external set_alignment : int -> llvalue -> unit = "llvm_set_alignment"
+external global_copy_all_metadata : llvalue -> (llmdkind * llmetadata) array
+                                  = "llvm_global_copy_all_metadata"
 external is_global_constant : llvalue -> bool = "llvm_is_global_constant"
 external set_global_constant : bool -> llvalue -> unit
                              = "llvm_set_global_constant"

diff  --git a/llvm/bindings/ocaml/llvm/llvm.mli b/llvm/bindings/ocaml/llvm/llvm.mli
index 19ff22ef33e8..0a900f86f47e 100644
--- a/llvm/bindings/ocaml/llvm/llvm.mli
+++ b/llvm/bindings/ocaml/llvm/llvm.mli
@@ -24,6 +24,9 @@ type llcontext
     objects. See the [llvm::Module] class. *)
 type llmodule
 
+(** Opaque representation of Metadata nodes. See the [llvm::Metadata] class. *)
+type llmetadata
+
 (** Each value in the LLVM IR has a type, an instance of [lltype]. See the
     [llvm::Type] class. *)
 type lltype
@@ -367,6 +370,15 @@ module DiagnosticSeverity : sig
   | Note
 end
 
+module ModuleFlagBehavior :sig
+  type t =
+  | Error
+  | Warning
+  | Require
+  | Override
+  | Append
+  | AppendUnique
+end
 
 (** {6 Iteration} *)
 
@@ -531,7 +543,16 @@ val set_module_inline_asm : llmodule -> string -> unit
     See the method [llvm::Module::getContext] *)
 val module_context : llmodule -> llcontext
 
+(** [get_module_flag m k] Return the corresponding value if key [k] appears in
+    the module flags of [m], otherwise return None
+    See the method [llvm::Module::getModuleFlag] *)
+val get_module_flag : llmodule -> string -> llmetadata option
 
+(** [add_module_flag m b k v] Add a module-level flag b, with key [k] and
+    value [v] to the flags metadata of module [m]. It will create the 
+    module-level flags named metadata if it doesn't already exist. *)
+val add_module_flag : llmodule -> ModuleFlagBehavior.t ->
+                        string -> llmetadata -> unit
 (** {6 Types} *)
 
 (** [classify_type ty] returns the {!TypeKind.t} corresponding to the type [ty].
@@ -925,6 +946,13 @@ val get_named_metadata : llmodule -> string -> llvalue array
     [llvm::MDNode::addOperand()]. *)
 val add_named_metadata_operand : llmodule -> string -> llvalue -> unit
 
+(** Obtain a Metadata as a Value.
+    See the method [llvm::ValueAsMetadata::get()]. *)
+val value_as_metadata : llvalue -> llmetadata
+
+(** Obtain a Value as a Metadata.
+    See the method [llvm::MetadataAsValue::get()]. *)
+val metadata_as_value : llcontext -> llmetadata -> llvalue
 
 (** {7 Operations on scalar constants} *)
 
@@ -1384,6 +1412,12 @@ val alignment : llvalue -> int
     [n] bytes. See the method [llvm::GlobalValue::setAlignment]. *)
 val set_alignment : int -> llvalue -> unit
 
+(** [global_copy_all_metadata g] returns all the metadata associated with [g],
+    which must be an [Instruction] or [GlobalObject].
+    See the [llvm::Instruction::getAllMetadata()] and
+    [llvm::GlobalObject::getAllMetadata()] methods. *)
+val global_copy_all_metadata : llvalue -> (llmdkind * llmetadata) array
+
 
 (** {7 Operations on global variables} *)
 

diff  --git a/llvm/bindings/ocaml/llvm/llvm_ocaml.c b/llvm/bindings/ocaml/llvm/llvm_ocaml.c
index 1d68eb5e6d42..8994f524a1a8 100644
--- a/llvm/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/llvm/bindings/ocaml/llvm/llvm_ocaml.c
@@ -21,12 +21,12 @@
 #include "llvm-c/Core.h"
 #include "llvm-c/Support.h"
 #include "llvm/Config/llvm-config.h"
-#include "caml/alloc.h"
-#include "caml/custom.h"
 #include "caml/memory.h"
 #include "caml/fail.h"
 #include "caml/callback.h"
 
+#include "llvm_ocaml.h"
+
 value llvm_string_of_message(char* Message) {
   value String = caml_copy_string(Message);
   LLVMDisposeMessage(Message);
@@ -34,6 +34,27 @@ value llvm_string_of_message(char* Message) {
   return String;
 }
 
+CAMLprim value ptr_to_option(void *Ptr) {
+  CAMLparam0();
+  CAMLlocal1(Option);
+  if (!Ptr)
+    CAMLreturn(Val_int(0));
+  Option = caml_alloc_small(1, 0);
+  Store_field(Option, 0, (value)Ptr);
+  CAMLreturn(Option);
+}
+
+CAMLprim value cstr_to_string(const unsigned char *Str, unsigned Len) {
+  CAMLparam0();
+  CAMLlocal1(String);
+  if (Str) {
+    String = caml_alloc_initialized_string(Len, Str);
+  } else {
+    String = caml_alloc_string(0);
+  }
+  CAMLreturn(String);
+}
+
 void llvm_raise(value Prototype, char *Message) {
   CAMLparam1(Prototype);
   caml_raise_with_arg(Prototype, llvm_string_of_message(Message));
@@ -319,6 +340,20 @@ CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) {
   return Val_unit;
 }
 
+/* llmodule -> string -> llmetadata option */
+CAMLprim value llvm_get_module_flag(LLVMModuleRef M, value Key) {
+  return ptr_to_option(
+      LLVMGetModuleFlag(M, String_val(Key), caml_string_length(Key)));
+}
+
+CAMLprim value llvm_add_module_flag(LLVMModuleRef M,
+                                    LLVMModuleFlagBehavior Behaviour, value Key,
+                                    LLVMMetadataRef Val) {
+  LLVMAddModuleFlag(M, Int_val(Behaviour), String_val(Key),
+                    caml_string_length(Key), Val);
+  return Val_unit;
+}
+
 /*===-- Types -------------------------------------------------------------===*/
 
 /* lltype -> TypeKind.t */
@@ -870,6 +905,17 @@ CAMLprim value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val
   return Val_unit;
 }
 
+/* llvalue -> llmetadata */
+CAMLprim LLVMMetadataRef llvm_value_as_metadata(LLVMValueRef Val) {
+  return LLVMValueAsMetadata(Val);
+}
+
+/* llcontext -> llmetadata -> llvalue */
+CAMLprim LLVMValueRef llvm_metadata_as_value(LLVMContextRef C,
+                                             LLVMMetadataRef MD) {
+  return LLVMMetadataAsValue(C, MD);
+}
+
 /*--... Operations on scalar constants .....................................--*/
 
 /* lltype -> int -> llvalue */
@@ -1160,6 +1206,25 @@ CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
   return Val_unit;
 }
 
+/* llvalue -> (llmdkind * llmetadata) array */
+CAMLprim value llvm_global_copy_all_metadata(LLVMValueRef Global) {
+  CAMLparam0();
+  CAMLlocal2(Array, Pair);
+  size_t NumEntries;
+  LLVMValueMetadataEntry *Entries =
+      LLVMGlobalCopyAllMetadata(Global, &NumEntries);
+  Array = caml_alloc_tuple(NumEntries);
+  for (int i = 0; i < NumEntries; i++) {
+    Pair = caml_alloc_tuple(2);
+    Store_field(Pair, 0, Val_int(LLVMValueMetadataEntriesGetKind(Entries, i)));
+    Store_field(Pair, 1,
+                (value)LLVMValueMetadataEntriesGetMetadata(Entries, i));
+    Store_field(Array, i, Pair);
+  }
+  LLVMDisposeValueMetadataEntries(Entries);
+  CAMLreturn(Array);
+}
+
 /*--... Operations on uses .................................................--*/
 
 /* llvalue -> lluse option */

diff  --git a/llvm/bindings/ocaml/llvm/llvm_ocaml.h b/llvm/bindings/ocaml/llvm/llvm_ocaml.h
new file mode 100644
index 000000000000..0b39b4730360
--- /dev/null
+++ b/llvm/bindings/ocaml/llvm/llvm_ocaml.h
@@ -0,0 +1,30 @@
+/*===-- llvm_ocaml.h - LLVM OCaml Glue --------------------------*- C++ -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file glues LLVM's OCaml interface to its C interface. These functions *|
+|* are by and large transparent wrappers to the corresponding C functions.    *|
+|*                                                                            *|
+|* Note that these functions intentionally take liberties with the CAMLparamX *|
+|* macros, since most of the parameters are not GC heap objects.              *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_LLVM_OCAML_H
+#define LLVM_LLVM_OCAML_H
+
+#include "caml/alloc.h"
+#include "caml/custom.h"
+
+/* Convert a C pointer to an OCaml option */
+CAMLprim value ptr_to_option(void *Ptr);
+
+/* Convert a C string into an OCaml string */
+CAMLprim value cstr_to_string(const unsigned char *Str, unsigned Len);
+
+#endif // LLVM_LLVM_OCAML_H


        


More information about the llvm-commits mailing list