Define new type in LLVM IR using OCaml bindings

Viewed 154

I'm trying to implement statically typed language with user defined types using LLVM and OCaml, but I don't know how to actually add newtype definition into a LLVM module.

I've looked into OCaml documentation and haven't found any function for that. I've tried answer from LLVM: Defining a new type via OCaml bindings, but it doesn't work.

Example code that I've tried:

  let c = Llvm.create_context () in
  let m = Llvm.create_module c "MainModule" in

  let llar = [| Llvm.i16_type c; Llvm.float_type c; |] in

  let value_t = Llvm.struct_type c llar in
  ignore (Llvm.declare_global value_t "value_t" m);

  let llvalue_t = Llvm.named_struct_type c "value_t" in
  Llvm.struct_set_body llvalue_t llar true;

  ignore (Llvm.struct_type c llar);

Compiled output:

; ModuleID = 'MainModule'
source_filename = "MainModule"

@value_t = external global { i16, float }
1 Answers

OCaml code:

let () =
  let c = Llvm.create_context () in
  let m = Llvm.create_module c "MainModule" in


  let struct1 = Llvm.named_struct_type c "B" in
  Llvm.struct_set_body struct1 [| Llvm.pointer_type struct1; Llvm.i32_type c|] false;

  let struct2 = Llvm.struct_type c [| Llvm.i32_type c; Llvm.pointer_type (Llvm.i8_type c) |] in


  let main_t = Llvm.function_type (Llvm.void_type c) [| struct1; struct2 |] in
  let _main = Llvm.declare_function "main" main_t m in


  Llvm.print_module "./main.ll" 

generated LLVM IR:

; ModuleID = 'MainModule'
source_filename = "MainModule"

%B = type { %B*, i32 }

declare void @main(%B, { i32, i8* })

And this OCaml code:

let () =
  let c = Llvm.create_context () in
  let m = Llvm.create_module c "MainModule" in


  let struct1 = Llvm.named_struct_type c "B" in
  Llvm.struct_set_body struct1 [| Llvm.pointer_type struct1; Llvm.i32_type c|] false;

  let _struct2 = Llvm.struct_type c [| Llvm.i32_type c; Llvm.pointer_type (Llvm.i8_type c) |] in


  Llvm.print_module "./main.ll" m

generated LLVM IR:

; ModuleID = 'MainModule'
source_filename = "MainModule"

So from what i understand, new type declaration is automatically inserted into the module where the struct is used. And it's not only in OCaml bindings, but in C++ you have StructType::create(LLVMContext &Context, StringRef Name), which serves the same purpose.

Related