xref: /llvm-project/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c (revision a5fb2bbb2ad8488482843e2298fbe6f6a1d45bbd)
1 /*===-- debuginfo_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
2 |*                                                                            *|
3 |* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
4 |* Exceptions.                                                                *|
5 |* See https://llvm.org/LICENSE.txt for license information.                  *|
6 |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
7 |*                                                                            *|
8 |*===----------------------------------------------------------------------===*|
9 |*                                                                            *|
10 |* This file glues LLVM's OCaml interface to its C interface. These functions *|
11 |* are by and large transparent wrappers to the corresponding C functions.    *|
12 |*                                                                            *|
13 |* Note that these functions intentionally take liberties with the CAMLparamX *|
14 |* macros, since most of the parameters are not GC heap objects.              *|
15 |*                                                                            *|
16 \*===----------------------------------------------------------------------===*/
17 
18 #include <string.h>
19 
20 #include "caml/memory.h"
21 #include "caml/mlvalues.h"
22 #include "llvm-c/Core.h"
23 #include "llvm-c/DebugInfo.h"
24 #include "llvm-c/Support.h"
25 
26 #include "llvm_ocaml.h"
27 
28 // This is identical to the definition in llvm_debuginfo.ml:DIFlag.t
29 typedef enum {
30   i_DIFlagZero,
31   i_DIFlagPrivate,
32   i_DIFlagProtected,
33   i_DIFlagPublic,
34   i_DIFlagFwdDecl,
35   i_DIFlagAppleBlock,
36   i_DIFlagReservedBit4,
37   i_DIFlagVirtual,
38   i_DIFlagArtificial,
39   i_DIFlagExplicit,
40   i_DIFlagPrototyped,
41   i_DIFlagObjcClassComplete,
42   i_DIFlagObjectPointer,
43   i_DIFlagVector,
44   i_DIFlagStaticMember,
45   i_DIFlagLValueReference,
46   i_DIFlagRValueReference,
47   i_DIFlagReserved,
48   i_DIFlagSingleInheritance,
49   i_DIFlagMultipleInheritance,
50   i_DIFlagVirtualInheritance,
51   i_DIFlagIntroducedVirtual,
52   i_DIFlagBitField,
53   i_DIFlagNoReturn,
54   i_DIFlagTypePassByValue,
55   i_DIFlagTypePassByReference,
56   i_DIFlagEnumClass,
57   i_DIFlagFixedEnum,
58   i_DIFlagThunk,
59   i_DIFlagNonTrivial,
60   i_DIFlagBigEndian,
61   i_DIFlagLittleEndian,
62   i_DIFlagIndirectVirtualBase,
63   i_DIFlagAccessibility,
64   i_DIFlagPtrToMemberRep
65 } LLVMDIFlag_i;
66 
67 static LLVMDIFlags map_DIFlag(LLVMDIFlag_i DIF) {
68   switch (DIF) {
69   case i_DIFlagZero:
70     return LLVMDIFlagZero;
71   case i_DIFlagPrivate:
72     return LLVMDIFlagPrivate;
73   case i_DIFlagProtected:
74     return LLVMDIFlagProtected;
75   case i_DIFlagPublic:
76     return LLVMDIFlagPublic;
77   case i_DIFlagFwdDecl:
78     return LLVMDIFlagFwdDecl;
79   case i_DIFlagAppleBlock:
80     return LLVMDIFlagAppleBlock;
81   case i_DIFlagReservedBit4:
82     return LLVMDIFlagReservedBit4;
83   case i_DIFlagVirtual:
84     return LLVMDIFlagVirtual;
85   case i_DIFlagArtificial:
86     return LLVMDIFlagArtificial;
87   case i_DIFlagExplicit:
88     return LLVMDIFlagExplicit;
89   case i_DIFlagPrototyped:
90     return LLVMDIFlagPrototyped;
91   case i_DIFlagObjcClassComplete:
92     return LLVMDIFlagObjcClassComplete;
93   case i_DIFlagObjectPointer:
94     return LLVMDIFlagObjectPointer;
95   case i_DIFlagVector:
96     return LLVMDIFlagVector;
97   case i_DIFlagStaticMember:
98     return LLVMDIFlagStaticMember;
99   case i_DIFlagLValueReference:
100     return LLVMDIFlagLValueReference;
101   case i_DIFlagRValueReference:
102     return LLVMDIFlagRValueReference;
103   case i_DIFlagReserved:
104     return LLVMDIFlagReserved;
105   case i_DIFlagSingleInheritance:
106     return LLVMDIFlagSingleInheritance;
107   case i_DIFlagMultipleInheritance:
108     return LLVMDIFlagMultipleInheritance;
109   case i_DIFlagVirtualInheritance:
110     return LLVMDIFlagVirtualInheritance;
111   case i_DIFlagIntroducedVirtual:
112     return LLVMDIFlagIntroducedVirtual;
113   case i_DIFlagBitField:
114     return LLVMDIFlagBitField;
115   case i_DIFlagNoReturn:
116     return LLVMDIFlagNoReturn;
117   case i_DIFlagTypePassByValue:
118     return LLVMDIFlagTypePassByValue;
119   case i_DIFlagTypePassByReference:
120     return LLVMDIFlagTypePassByReference;
121   case i_DIFlagEnumClass:
122     return LLVMDIFlagEnumClass;
123   case i_DIFlagFixedEnum:
124     return LLVMDIFlagFixedEnum;
125   case i_DIFlagThunk:
126     return LLVMDIFlagThunk;
127   case i_DIFlagNonTrivial:
128     return LLVMDIFlagNonTrivial;
129   case i_DIFlagBigEndian:
130     return LLVMDIFlagBigEndian;
131   case i_DIFlagLittleEndian:
132     return LLVMDIFlagLittleEndian;
133   case i_DIFlagIndirectVirtualBase:
134     return LLVMDIFlagIndirectVirtualBase;
135   case i_DIFlagAccessibility:
136     return LLVMDIFlagAccessibility;
137   case i_DIFlagPtrToMemberRep:
138     return LLVMDIFlagPtrToMemberRep;
139   }
140 }
141 
142 /* unit -> int */
143 value llvm_debug_metadata_version(value Unit) {
144   return Val_int(LLVMDebugMetadataVersion());
145 }
146 
147 /* llmodule -> int */
148 value llvm_get_module_debug_metadata_version(value Module) {
149   return Val_int(LLVMGetModuleDebugMetadataVersion(Module_val(Module)));
150 }
151 
152 #define DIFlags_val(v) (*(LLVMDIFlags *)(Data_custom_val(v)))
153 
154 static struct custom_operations diflags_ops = {
155     (char *)"DebugInfo.lldiflags", custom_finalize_default,
156     custom_compare_default,        custom_hash_default,
157     custom_serialize_default,      custom_deserialize_default,
158     custom_compare_ext_default};
159 
160 static value alloc_diflags(LLVMDIFlags Flags) {
161   value V = caml_alloc_custom(&diflags_ops, sizeof(LLVMDIFlags), 0, 1);
162   DIFlags_val(V) = Flags;
163   return V;
164 }
165 
166 LLVMDIFlags llvm_diflags_get(value i_Flag) {
167   LLVMDIFlags Flags = map_DIFlag(Int_val(i_Flag));
168   return alloc_diflags(Flags);
169 }
170 
171 LLVMDIFlags llvm_diflags_set(value Flags, value i_Flag) {
172   LLVMDIFlags FlagsNew = DIFlags_val(Flags) | map_DIFlag(Int_val(i_Flag));
173   return alloc_diflags(FlagsNew);
174 }
175 
176 value llvm_diflags_test(value Flags, value i_Flag) {
177   LLVMDIFlags Flag = map_DIFlag(Int_val(i_Flag));
178   return Val_bool((DIFlags_val(Flags) & Flag) == Flag);
179 }
180 
181 #define DIBuilder_val(v) (*(LLVMDIBuilderRef *)(Data_custom_val(v)))
182 
183 static void llvm_finalize_dibuilder(value B) {
184   LLVMDIBuilderFinalize(DIBuilder_val(B));
185   LLVMDisposeDIBuilder(DIBuilder_val(B));
186 }
187 
188 static struct custom_operations dibuilder_ops = {
189     (char *)"DebugInfo.lldibuilder", llvm_finalize_dibuilder,
190     custom_compare_default,          custom_hash_default,
191     custom_serialize_default,        custom_deserialize_default,
192     custom_compare_ext_default};
193 
194 static value alloc_dibuilder(LLVMDIBuilderRef B) {
195   value V = caml_alloc_custom(&dibuilder_ops, sizeof(LLVMDIBuilderRef), 0, 1);
196   DIBuilder_val(V) = B;
197   return V;
198 }
199 
200 /* llmodule -> lldibuilder */
201 value llvm_dibuilder(value M) {
202   return alloc_dibuilder(LLVMCreateDIBuilder(Module_val(M)));
203 }
204 
205 value llvm_dibuild_finalize(value Builder) {
206   LLVMDIBuilderFinalize(DIBuilder_val(Builder));
207   return Val_unit;
208 }
209 
210 value llvm_dibuild_create_compile_unit_native(
211     value Builder, value Lang, value FileRef, value Producer, value IsOptimized,
212     value Flags, value RuntimeVer, value SplitName, value Kind, value DWOId,
213     value SplitDebugInline, value DebugInfoForProfiling, value SysRoot,
214     value SDK) {
215   return to_val(LLVMDIBuilderCreateCompileUnit(
216       DIBuilder_val(Builder), Int_val(Lang), Metadata_val(FileRef),
217       String_val(Producer), caml_string_length(Producer), Bool_val(IsOptimized),
218       String_val(Flags), caml_string_length(Flags), Int_val(RuntimeVer),
219       String_val(SplitName), caml_string_length(SplitName), Int_val(Kind),
220       Int_val(DWOId), Bool_val(SplitDebugInline),
221       Bool_val(DebugInfoForProfiling), String_val(SysRoot),
222       caml_string_length(SysRoot), String_val(SDK), caml_string_length(SDK)));
223 }
224 
225 value llvm_dibuild_create_compile_unit_bytecode(value *argv, int argn) {
226   return llvm_dibuild_create_compile_unit_native(
227       argv[0],  // Builder
228       argv[1],  // Lang
229       argv[2],  // FileRef
230       argv[3],  // Producer
231       argv[4],  // IsOptimized
232       argv[5],  // Flags
233       argv[6],  // RuntimeVer
234       argv[7],  // SplitName
235       argv[8],  // Kind
236       argv[9],  // DWOId
237       argv[10], // SplitDebugInline
238       argv[11], // DebugInfoForProfiling
239       argv[12], // SysRoot
240       argv[13]  // SDK
241   );
242 }
243 
244 value llvm_dibuild_create_file(value Builder, value Filename, value Directory) {
245   return to_val(LLVMDIBuilderCreateFile(
246       DIBuilder_val(Builder), String_val(Filename),
247       caml_string_length(Filename), String_val(Directory),
248       caml_string_length(Directory)));
249 }
250 
251 value llvm_dibuild_create_module_native(value Builder, value ParentScope,
252                                         value Name, value ConfigMacros,
253                                         value IncludePath, value SysRoot) {
254   return to_val(LLVMDIBuilderCreateModule(
255       DIBuilder_val(Builder), Metadata_val(ParentScope), String_val(Name),
256       caml_string_length(Name), String_val(ConfigMacros),
257       caml_string_length(ConfigMacros), String_val(IncludePath),
258       caml_string_length(IncludePath), String_val(SysRoot),
259       caml_string_length(SysRoot)));
260 }
261 
262 value llvm_dibuild_create_module_bytecode(value *argv, int argn) {
263   return llvm_dibuild_create_module_native(argv[0], // Builder
264                                            argv[1], // ParentScope
265                                            argv[2], // Name
266                                            argv[3], // ConfigMacros
267                                            argv[4], // IncludePath
268                                            argv[5]  // SysRoot
269   );
270 }
271 
272 value llvm_dibuild_create_namespace(value Builder, value ParentScope,
273                                     value Name, value ExportSymbols) {
274   return to_val(LLVMDIBuilderCreateNameSpace(
275       DIBuilder_val(Builder), Metadata_val(ParentScope), String_val(Name),
276       caml_string_length(Name), Bool_val(ExportSymbols)));
277 }
278 
279 value llvm_dibuild_create_function_native(value Builder, value Scope,
280                                           value Name, value LinkageName,
281                                           value File, value LineNo, value Ty,
282                                           value IsLocalToUnit,
283                                           value IsDefinition, value ScopeLine,
284                                           value Flags, value IsOptimized) {
285   return to_val(LLVMDIBuilderCreateFunction(
286       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
287       caml_string_length(Name), String_val(LinkageName),
288       caml_string_length(LinkageName), Metadata_val(File), Int_val(LineNo),
289       Metadata_val(Ty), Bool_val(IsLocalToUnit), Bool_val(IsDefinition),
290       Int_val(ScopeLine), DIFlags_val(Flags), Bool_val(IsOptimized)));
291 }
292 
293 value llvm_dibuild_create_function_bytecode(value *argv, int argn) {
294   return llvm_dibuild_create_function_native(argv[0],  // Builder,
295                                              argv[1],  // Scope
296                                              argv[2],  // Name
297                                              argv[3],  // LinkageName
298                                              argv[4],  // File
299                                              argv[5],  // LineNo
300                                              argv[6],  // Ty
301                                              argv[7],  // IsLocalUnit
302                                              argv[8],  // IsDefinition
303                                              argv[9],  // ScopeLine
304                                              argv[10], // Flags
305                                              argv[11]  // IsOptimized
306   );
307 }
308 
309 value llvm_dibuild_create_lexical_block(value Builder, value Scope, value File,
310                                         value Line, value Column) {
311   return to_val(LLVMDIBuilderCreateLexicalBlock(
312       DIBuilder_val(Builder), Metadata_val(Scope), Metadata_val(File),
313       Int_val(Line), Int_val(Column)));
314 }
315 
316 value llvm_metadata_null(value Unit) { return to_val(NULL); }
317 
318 value llvm_dibuild_create_debug_location(value Ctx, value Line, value Column,
319                                          value Scope, value InlinedAt) {
320   return to_val(LLVMDIBuilderCreateDebugLocation(
321       Context_val(Ctx), Int_val(Line), Int_val(Column), Metadata_val(Scope),
322       Metadata_val(InlinedAt)));
323 }
324 
325 value llvm_di_location_get_line(value Location) {
326   return Val_int(LLVMDILocationGetLine(Metadata_val(Location)));
327 }
328 
329 value llvm_di_location_get_column(value Location) {
330   return Val_int(LLVMDILocationGetColumn(Metadata_val(Location)));
331 }
332 
333 value llvm_di_location_get_scope(value Location) {
334   return to_val(LLVMDILocationGetScope(Metadata_val(Location)));
335 }
336 
337 value llvm_di_location_get_inlined_at(value Location) {
338   return ptr_to_option(LLVMDILocationGetInlinedAt(Metadata_val(Location)));
339 }
340 
341 value llvm_di_scope_get_file(value Scope) {
342   return ptr_to_option(LLVMDIScopeGetFile(Metadata_val(Scope)));
343 }
344 
345 value llvm_di_file_get_directory(value File) {
346   unsigned Len;
347   const char *Directory = LLVMDIFileGetDirectory(Metadata_val(File), &Len);
348   return cstr_to_string(Directory, Len);
349 }
350 
351 value llvm_di_file_get_filename(value File) {
352   unsigned Len;
353   const char *Filename = LLVMDIFileGetFilename(Metadata_val(File), &Len);
354   return cstr_to_string(Filename, Len);
355 }
356 
357 value llvm_di_file_get_source(value File) {
358   unsigned Len;
359   const char *Source = LLVMDIFileGetSource(Metadata_val(File), &Len);
360   return cstr_to_string(Source, Len);
361 }
362 
363 value llvm_dibuild_get_or_create_type_array(value Builder, value Data) {
364   mlsize_t Count = Wosize_val(Data);
365   LLVMMetadataRef *Temp = from_val_array(Data);
366   LLVMMetadataRef Metadata =
367       LLVMDIBuilderGetOrCreateTypeArray(DIBuilder_val(Builder), Temp, Count);
368   free(Temp);
369   return to_val(Metadata);
370 }
371 
372 value llvm_dibuild_get_or_create_array(value Builder, value Data) {
373   mlsize_t Count = Wosize_val(Data);
374   LLVMMetadataRef *Temp = from_val_array(Data);
375   LLVMMetadataRef Metadata =
376       LLVMDIBuilderGetOrCreateArray(DIBuilder_val(Builder), Temp, Count);
377   free(Temp);
378   return to_val(Metadata);
379 }
380 
381 value llvm_dibuild_create_subroutine_type(value Builder, value File,
382                                           value ParameterTypes, value Flags) {
383   mlsize_t Count = Wosize_val(ParameterTypes);
384   LLVMMetadataRef *Temp = from_val_array(ParameterTypes);
385   LLVMMetadataRef Metadata = LLVMDIBuilderCreateSubroutineType(
386       DIBuilder_val(Builder), Metadata_val(File), Temp,
387       Wosize_val(ParameterTypes), DIFlags_val(Flags));
388   free(Temp);
389   return to_val(Metadata);
390 }
391 
392 value llvm_dibuild_create_enumerator(value Builder, value Name, value Value,
393                                      value IsUnsigned) {
394   return to_val(LLVMDIBuilderCreateEnumerator(
395       DIBuilder_val(Builder), String_val(Name), caml_string_length(Name),
396       (int64_t)Int_val(Value), Bool_val(IsUnsigned)));
397 }
398 
399 value llvm_dibuild_create_enumeration_type_native(
400     value Builder, value Scope, value Name, value File, value LineNumber,
401     value SizeInBits, value AlignInBits, value Elements, value ClassTy) {
402   mlsize_t Count = Wosize_val(Elements);
403   LLVMMetadataRef *Temp = from_val_array(Elements);
404   LLVMMetadataRef Metadata = LLVMDIBuilderCreateEnumerationType(
405       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
406       caml_string_length(Name), Metadata_val(File), Int_val(LineNumber),
407       (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits), Temp, Count,
408       Metadata_val(ClassTy));
409   free(Temp);
410   return to_val(Metadata);
411 }
412 
413 value llvm_dibuild_create_enumeration_type_bytecode(value *argv, int argn) {
414   return llvm_dibuild_create_enumeration_type_native(argv[0], // Builder
415                                                      argv[1], // Scope
416                                                      argv[2], // Name
417                                                      argv[3], // File
418                                                      argv[4], // LineNumber
419                                                      argv[5], // SizeInBits
420                                                      argv[6], // AlignInBits
421                                                      argv[7], // Elements
422                                                      argv[8]  // ClassTy
423   );
424 }
425 
426 value llvm_dibuild_create_union_type_native(
427     value Builder, value Scope, value Name, value File, value LineNumber,
428     value SizeInBits, value AlignInBits, value Flags, value Elements,
429     value RunTimeLanguage, value UniqueId) {
430   LLVMMetadataRef *Temp = from_val_array(Elements);
431   LLVMMetadataRef Metadata = LLVMDIBuilderCreateUnionType(
432       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
433       caml_string_length(Name), Metadata_val(File), Int_val(LineNumber),
434       (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits), DIFlags_val(Flags),
435       Temp, Wosize_val(Elements), Int_val(RunTimeLanguage),
436       String_val(UniqueId), caml_string_length(UniqueId));
437   free(Temp);
438   return to_val(Metadata);
439 }
440 
441 value llvm_dibuild_create_union_type_bytecode(value *argv, int argn) {
442   return llvm_dibuild_create_union_type_native(argv[0], // Builder
443                                                argv[1], // Scope
444                                                argv[2], // Name
445                                                argv[3], // File
446                                                argv[4], // LineNumber
447                                                argv[5], // SizeInBits
448                                                argv[6], // AlignInBits
449                                                argv[7], // Flags
450                                                argv[8], // Elements
451                                                argv[9], // RunTimeLanguage
452                                                argv[10] // UniqueId
453   );
454 }
455 
456 value llvm_dibuild_create_array_type(value Builder, value Size,
457                                      value AlignInBits, value Ty,
458                                      value Subscripts) {
459   LLVMMetadataRef *Temp = from_val_array(Subscripts);
460   LLVMMetadataRef Metadata = LLVMDIBuilderCreateArrayType(
461       DIBuilder_val(Builder), (uint64_t)Int_val(Size), Int_val(AlignInBits),
462       Metadata_val(Ty), Temp, Wosize_val(Subscripts));
463   free(Temp);
464   return to_val(Metadata);
465 }
466 
467 value llvm_dibuild_create_vector_type(value Builder, value Size,
468                                       value AlignInBits, value Ty,
469                                       value Subscripts) {
470   LLVMMetadataRef *Temp = from_val_array(Subscripts);
471   LLVMMetadataRef Metadata = LLVMDIBuilderCreateVectorType(
472       DIBuilder_val(Builder), (uint64_t)Int_val(Size), Int_val(AlignInBits),
473       Metadata_val(Ty), Temp, Wosize_val(Subscripts));
474   free(Temp);
475   return to_val(Metadata);
476 }
477 
478 value llvm_dibuild_create_unspecified_type(value Builder, value Name) {
479   LLVMMetadataRef Metadata = LLVMDIBuilderCreateUnspecifiedType(
480       DIBuilder_val(Builder), String_val(Name), caml_string_length(Name));
481   return to_val(Metadata);
482 }
483 
484 value llvm_dibuild_create_basic_type(value Builder, value Name,
485                                      value SizeInBits, value Encoding,
486                                      value Flags) {
487   LLVMMetadataRef Metadata = LLVMDIBuilderCreateBasicType(
488       DIBuilder_val(Builder), String_val(Name), caml_string_length(Name),
489       (uint64_t)Int_val(SizeInBits), Int_val(Encoding), DIFlags_val(Flags));
490   return to_val(Metadata);
491 }
492 
493 value llvm_dibuild_create_pointer_type_native(value Builder, value PointeeTy,
494                                               value SizeInBits,
495                                               value AlignInBits,
496                                               value AddressSpace, value Name) {
497   LLVMMetadataRef Metadata = LLVMDIBuilderCreatePointerType(
498       DIBuilder_val(Builder), Metadata_val(PointeeTy),
499       (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
500       Int_val(AddressSpace), String_val(Name), caml_string_length(Name));
501   return to_val(Metadata);
502 }
503 
504 value llvm_dibuild_create_pointer_type_bytecode(value *argv, int argn) {
505   return llvm_dibuild_create_pointer_type_native(argv[0], // Builder
506                                                  argv[1], // PointeeTy
507                                                  argv[2], // SizeInBits
508                                                  argv[3], // AlignInBits
509                                                  argv[4], // AddressSpace
510                                                  argv[5]  // Name
511   );
512 }
513 
514 value llvm_dibuild_create_struct_type_native(
515     value Builder, value Scope, value Name, value File, value LineNumber,
516     value SizeInBits, value AlignInBits, value Flags, value DerivedFrom,
517     value Elements, value RunTimeLanguage, value VTableHolder, value UniqueId) {
518   LLVMMetadataRef *Temp = from_val_array(Elements);
519   LLVMMetadataRef Metadata = LLVMDIBuilderCreateStructType(
520       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
521       caml_string_length(Name), Metadata_val(File), Int_val(LineNumber),
522       (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits), DIFlags_val(Flags),
523       Metadata_val(DerivedFrom), Temp, Wosize_val(Elements),
524       Int_val(RunTimeLanguage), Metadata_val(VTableHolder),
525       String_val(UniqueId), caml_string_length(UniqueId));
526   free(Temp);
527   return to_val(Metadata);
528 }
529 
530 value llvm_dibuild_create_struct_type_bytecode(value *argv, int argn) {
531   return llvm_dibuild_create_struct_type_native(argv[0],  // Builder
532                                                 argv[1],  // Scope
533                                                 argv[2],  // Name
534                                                 argv[3],  // File
535                                                 argv[4],  // LineNumber
536                                                 argv[5],  // SizeInBits
537                                                 argv[6],  // AlignInBits
538                                                 argv[7],  // Flags
539                                                 argv[8],  // DeriviedFrom
540                                                 argv[9],  // Elements
541                                                 argv[10], // RunTimeLanguage
542                                                 argv[11], // VTableHolder
543                                                 argv[12]  // UniqueId
544   );
545 }
546 
547 value llvm_dibuild_create_member_type_native(value Builder, value Scope,
548                                              value Name, value File,
549                                              value LineNumber, value SizeInBits,
550                                              value AlignInBits,
551                                              value OffsetInBits, value Flags,
552                                              value Ty) {
553   LLVMMetadataRef Metadata = LLVMDIBuilderCreateMemberType(
554       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
555       caml_string_length(Name), Metadata_val(File), Int_val(LineNumber),
556       (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
557       (uint64_t)Int_val(OffsetInBits), DIFlags_val(Flags), Metadata_val(Ty));
558   return to_val(Metadata);
559 }
560 
561 value llvm_dibuild_create_member_type_bytecode(value *argv, int argn) {
562   return llvm_dibuild_create_member_type_native(argv[0], // Builder
563                                                 argv[1], // Scope
564                                                 argv[2], // Name
565                                                 argv[3], // File
566                                                 argv[4], // LineNumber
567                                                 argv[5], // SizeInBits
568                                                 argv[6], // AlignInBits
569                                                 argv[7], // OffsetInBits
570                                                 argv[8], // Flags
571                                                 argv[9]  // Ty
572   );
573 }
574 
575 value llvm_dibuild_create_static_member_type_native(
576     value Builder, value Scope, value Name, value File, value LineNumber,
577     value Type, value Flags, value ConstantVal, value AlignInBits) {
578   LLVMMetadataRef Metadata = LLVMDIBuilderCreateStaticMemberType(
579       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
580       caml_string_length(Name), Metadata_val(File), Int_val(LineNumber),
581       Metadata_val(Type), DIFlags_val(Flags), Value_val(ConstantVal),
582       Int_val(AlignInBits));
583   return to_val(Metadata);
584 }
585 
586 value llvm_dibuild_create_static_member_type_bytecode(value *argv, int argn) {
587   return llvm_dibuild_create_static_member_type_native(argv[0], // Builder
588                                                        argv[1], // Scope
589                                                        argv[2], // Name
590                                                        argv[3], // File
591                                                        argv[4], // LineNumber
592                                                        argv[5], // Type
593                                                        argv[6], // Flags,
594                                                        argv[7], // ConstantVal
595                                                        argv[8]  // AlignInBits
596   );
597 }
598 
599 value llvm_dibuild_create_member_pointer_type_native(
600     value Builder, value PointeeType, value ClassType, value SizeInBits,
601     value AlignInBits, value Flags) {
602   LLVMMetadataRef Metadata = LLVMDIBuilderCreateMemberPointerType(
603       DIBuilder_val(Builder), Metadata_val(PointeeType),
604       Metadata_val(ClassType), (uint64_t)Int_val(SizeInBits),
605       Int_val(AlignInBits), llvm_diflags_get(Flags));
606   return to_val(Metadata);
607 }
608 
609 value llvm_dibuild_create_member_pointer_type_bytecode(value *argv, int argn) {
610   return llvm_dibuild_create_member_pointer_type_native(argv[0], // Builder
611                                                         argv[1], // PointeeType
612                                                         argv[2], // ClassType
613                                                         argv[3], // SizeInBits
614                                                         argv[4], // AlignInBits
615                                                         argv[5]  // Flags
616   );
617 }
618 
619 value llvm_dibuild_create_object_pointer_type(value Builder, value Type,
620                                               value Implicit) {
621   LLVMMetadataRef Metadata = LLVMDIBuilderCreateObjectPointerType(
622       DIBuilder_val(Builder), Metadata_val(Type), Bool_val(Implicit));
623   return to_val(Metadata);
624 }
625 
626 value llvm_dibuild_create_qualified_type(value Builder, value Tag, value Type) {
627   LLVMMetadataRef Metadata = LLVMDIBuilderCreateQualifiedType(
628       DIBuilder_val(Builder), Int_val(Tag), Metadata_val(Type));
629   return to_val(Metadata);
630 }
631 
632 value llvm_dibuild_create_reference_type(value Builder, value Tag, value Type) {
633   LLVMMetadataRef Metadata = LLVMDIBuilderCreateReferenceType(
634       DIBuilder_val(Builder), Int_val(Tag), Metadata_val(Type));
635   return to_val(Metadata);
636 }
637 
638 value llvm_dibuild_create_null_ptr_type(value Builder) {
639   return to_val(LLVMDIBuilderCreateNullPtrType(DIBuilder_val(Builder)));
640 }
641 
642 value llvm_dibuild_create_typedef_native(value Builder, value Type, value Name,
643                                          value File, value LineNo, value Scope,
644                                          value AlignInBits) {
645   LLVMMetadataRef Metadata = LLVMDIBuilderCreateTypedef(
646       DIBuilder_val(Builder), Metadata_val(Type), String_val(Name),
647       caml_string_length(Name), Metadata_val(File), Int_val(LineNo),
648       Metadata_val(Scope), Int_val(AlignInBits));
649   return to_val(Metadata);
650 }
651 
652 value llvm_dibuild_create_typedef_bytecode(value *argv, int argn) {
653 
654   return llvm_dibuild_create_typedef_native(argv[0], // Builder
655                                             argv[1], // Type
656                                             argv[2], // Name
657                                             argv[3], // File
658                                             argv[4], // LineNo
659                                             argv[5], // Scope
660                                             argv[6]  // AlignInBits
661   );
662 }
663 
664 value llvm_dibuild_create_inheritance_native(value Builder, value Ty,
665                                              value BaseTy, value BaseOffset,
666                                              value VBPtrOffset, value Flags) {
667   LLVMMetadataRef Metadata = LLVMDIBuilderCreateInheritance(
668       DIBuilder_val(Builder), Metadata_val(Ty), Metadata_val(BaseTy),
669       (uint64_t)Int_val(BaseOffset), Int_val(VBPtrOffset), DIFlags_val(Flags));
670   return to_val(Metadata);
671 }
672 
673 value llvm_dibuild_create_inheritance_bytecode(value *argv, int arg) {
674   return llvm_dibuild_create_inheritance_native(argv[0], // Builder
675                                                 argv[1], // Ty
676                                                 argv[2], // BaseTy
677                                                 argv[3], // BaseOffset
678                                                 argv[4], // VBPtrOffset
679                                                 argv[5]  // Flags
680   );
681 }
682 
683 value llvm_dibuild_create_forward_decl_native(
684     value Builder, value Tag, value Name, value Scope, value File, value Line,
685     value RuntimeLang, value SizeInBits, value AlignInBits,
686     value UniqueIdentifier) {
687   LLVMMetadataRef Metadata = LLVMDIBuilderCreateForwardDecl(
688       DIBuilder_val(Builder), Int_val(Tag), String_val(Name),
689       caml_string_length(Name), Metadata_val(Scope), Metadata_val(File),
690       Int_val(Line), Int_val(RuntimeLang), (uint64_t)Int_val(SizeInBits),
691       Int_val(AlignInBits), String_val(UniqueIdentifier),
692       caml_string_length(UniqueIdentifier));
693   return to_val(Metadata);
694 }
695 
696 value llvm_dibuild_create_forward_decl_bytecode(value *argv, int arg) {
697 
698   return llvm_dibuild_create_forward_decl_native(argv[0], // Builder
699                                                  argv[1], // Tag
700                                                  argv[2], // Name
701                                                  argv[3], // Scope
702                                                  argv[4], // File
703                                                  argv[5], // Line
704                                                  argv[6], // RuntimeLang
705                                                  argv[7], // SizeInBits
706                                                  argv[8], // AlignInBits
707                                                  argv[9]  // UniqueIdentifier
708   );
709 }
710 
711 value llvm_dibuild_create_replaceable_composite_type_native(
712     value Builder, value Tag, value Name, value Scope, value File, value Line,
713     value RuntimeLang, value SizeInBits, value AlignInBits, value Flags,
714     value UniqueIdentifier) {
715   LLVMMetadataRef Metadata = LLVMDIBuilderCreateReplaceableCompositeType(
716       DIBuilder_val(Builder), Int_val(Tag), String_val(Name),
717       caml_string_length(Name), Metadata_val(Scope), Metadata_val(File),
718       Int_val(Line), Int_val(RuntimeLang), (uint64_t)Int_val(SizeInBits),
719       Int_val(AlignInBits), DIFlags_val(Flags), String_val(UniqueIdentifier),
720       caml_string_length(UniqueIdentifier));
721   return to_val(Metadata);
722 }
723 
724 value llvm_dibuild_create_replaceable_composite_type_bytecode(value *argv,
725                                                               int arg) {
726 
727   return llvm_dibuild_create_replaceable_composite_type_native(
728       argv[0], // Builder
729       argv[1], // Tag
730       argv[2], // Name
731       argv[3], // Scope
732       argv[4], // File
733       argv[5], // Line
734       argv[6], // RuntimeLang
735       argv[7], // SizeInBits
736       argv[8], // AlignInBits
737       argv[9], // Flags
738       argv[10] // UniqueIdentifier
739   );
740 }
741 
742 value llvm_dibuild_create_bit_field_member_type_native(
743     value Builder, value Scope, value Name, value File, value LineNum,
744     value SizeInBits, value OffsetInBits, value StorageOffsetInBits,
745     value Flags, value Ty) {
746   LLVMMetadataRef Metadata = LLVMDIBuilderCreateBitFieldMemberType(
747       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
748       caml_string_length(Name), Metadata_val(File), Int_val(LineNum),
749       (uint64_t)Int_val(SizeInBits), (uint64_t)Int_val(OffsetInBits),
750       (uint64_t)Int_val(StorageOffsetInBits), DIFlags_val(Flags),
751       Metadata_val(Ty));
752   return to_val(Metadata);
753 }
754 
755 value llvm_dibuild_create_bit_field_member_type_bytecode(value *argv, int arg) {
756 
757   return llvm_dibuild_create_bit_field_member_type_native(
758       argv[0], // Builder
759       argv[1], // Scope
760       argv[2], // Name
761       argv[3], // File
762       argv[4], // LineNum
763       argv[5], // SizeInBits
764       argv[6], // OffsetInBits
765       argv[7], // StorageOffsetInBits
766       argv[8], // Flags
767       argv[9]  // Ty
768   );
769 }
770 
771 value llvm_dibuild_create_class_type_native(
772     value Builder, value Scope, value Name, value File, value LineNumber,
773     value SizeInBits, value AlignInBits, value OffsetInBits, value Flags,
774     value DerivedFrom, value Elements, value VTableHolder,
775     value TemplateParamsNode, value UniqueIdentifier) {
776   LLVMMetadataRef *Temp = from_val_array(Elements);
777   LLVMMetadataRef Metadata = LLVMDIBuilderCreateClassType(
778       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
779       caml_string_length(Name), Metadata_val(File), Int_val(LineNumber),
780       (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
781       (uint64_t)Int_val(OffsetInBits), DIFlags_val(Flags),
782       Metadata_val(DerivedFrom), Temp, Wosize_val(Elements),
783       Metadata_val(VTableHolder), Metadata_val(TemplateParamsNode),
784       String_val(UniqueIdentifier), caml_string_length(UniqueIdentifier));
785   free(Temp);
786   return to_val(Metadata);
787 }
788 
789 value llvm_dibuild_create_class_type_bytecode(value *argv, int arg) {
790 
791   return llvm_dibuild_create_class_type_native(argv[0],  // Builder
792                                                argv[1],  // Scope
793                                                argv[2],  // Name
794                                                argv[3],  // File
795                                                argv[4],  // LineNumber
796                                                argv[5],  // SizeInBits
797                                                argv[6],  // AlignInBits
798                                                argv[7],  // OffsetInBits
799                                                argv[8],  // Flags
800                                                argv[9],  // DerivedFrom
801                                                argv[10], // Elements
802                                                argv[11], // VTableHolder
803                                                argv[12], // TemplateParamsNode
804                                                argv[13]  // UniqueIdentifier
805   );
806 }
807 
808 value llvm_dibuild_create_artificial_type(value Builder, value Type) {
809   LLVMMetadataRef Metadata = LLVMDIBuilderCreateArtificialType(
810       DIBuilder_val(Builder), Metadata_val(Type));
811   return to_val(Metadata);
812 }
813 
814 value llvm_di_type_get_name(value DType) {
815   size_t Len;
816   const char *Name = LLVMDITypeGetName(Metadata_val(DType), &Len);
817   return cstr_to_string(Name, Len);
818 }
819 
820 value llvm_di_type_get_size_in_bits(value DType) {
821   uint64_t Size = LLVMDITypeGetSizeInBits(Metadata_val(DType));
822   return Val_int((int)Size);
823 }
824 
825 value llvm_di_type_get_offset_in_bits(value DType) {
826   uint64_t Size = LLVMDITypeGetOffsetInBits(Metadata_val(DType));
827   return Val_int((int)Size);
828 }
829 
830 value llvm_di_type_get_align_in_bits(value DType) {
831   uint32_t Size = LLVMDITypeGetAlignInBits(Metadata_val(DType));
832   return Val_int(Size);
833 }
834 
835 value llvm_di_type_get_line(value DType) {
836   unsigned Line = LLVMDITypeGetLine(Metadata_val(DType));
837   return Val_int(Line);
838 }
839 
840 value llvm_di_type_get_flags(value DType) {
841   LLVMDIFlags Flags = LLVMDITypeGetFlags(Metadata_val(DType));
842   return alloc_diflags(Flags);
843 }
844 
845 value llvm_get_subprogram(value Func) {
846   return ptr_to_option(LLVMGetSubprogram(Value_val(Func)));
847 }
848 
849 value llvm_set_subprogram(value Func, value SP) {
850   LLVMSetSubprogram(Value_val(Func), Metadata_val(SP));
851   return Val_unit;
852 }
853 
854 value llvm_di_subprogram_get_line(value Subprogram) {
855   return Val_int(LLVMDISubprogramGetLine(Metadata_val(Subprogram)));
856 }
857 
858 value llvm_instr_get_debug_loc(value Inst) {
859   return ptr_to_option(LLVMInstructionGetDebugLoc(Value_val(Inst)));
860 }
861 
862 value llvm_instr_set_debug_loc(value Inst, value Loc) {
863   LLVMInstructionSetDebugLoc(Value_val(Inst), Metadata_val(Loc));
864   return Val_unit;
865 }
866 
867 value llvm_dibuild_create_constant_value_expression(value Builder,
868                                                     value Value) {
869   LLVMMetadataRef Metadata = LLVMDIBuilderCreateConstantValueExpression(
870       DIBuilder_val(Builder), (uint64_t)Int_val(Value));
871   return to_val(Metadata);
872 }
873 
874 value llvm_dibuild_create_global_variable_expression_native(
875     value Builder, value Scope, value Name, value Linkage, value File,
876     value Line, value Ty, value LocalToUnit, value Expr, value Decl,
877     value AlignInBits) {
878   LLVMMetadataRef Metadata = LLVMDIBuilderCreateGlobalVariableExpression(
879       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
880       caml_string_length(Name), String_val(Linkage),
881       caml_string_length(Linkage), Metadata_val(File), Int_val(Line),
882       Metadata_val(Ty), Bool_val(LocalToUnit), Metadata_val(Expr),
883       Metadata_val(Decl), Int_val(AlignInBits));
884   return to_val(Metadata);
885 }
886 
887 value llvm_dibuild_create_global_variable_expression_bytecode(value *argv,
888                                                               int arg) {
889 
890   return llvm_dibuild_create_global_variable_expression_native(
891       argv[0], // Builder
892       argv[1], // Scope
893       argv[2], // Name
894       argv[3], // Linkage
895       argv[4], // File
896       argv[5], // Line
897       argv[6], // Ty
898       argv[7], // LocalToUnit
899       argv[8], // Expr
900       argv[9], // Decl
901       argv[10] // AlignInBits
902   );
903 }
904 
905 value llvm_di_global_variable_expression_get_variable(value GVE) {
906   return ptr_to_option(
907       LLVMDIGlobalVariableExpressionGetVariable(Metadata_val(GVE)));
908 }
909 
910 value llvm_di_variable_get_line(value Variable) {
911   return Val_int(LLVMDIVariableGetLine(Metadata_val(Variable)));
912 }
913 
914 value llvm_di_variable_get_file(value Variable) {
915   return ptr_to_option(LLVMDIVariableGetFile(Metadata_val(Variable)));
916 }
917 
918 value llvm_get_metadata_kind(value Metadata) {
919   return Val_int(LLVMGetMetadataKind(Metadata_val(Metadata)));
920 }
921 
922 value llvm_dibuild_create_auto_variable_native(value Builder, value Scope,
923                                                value Name, value File,
924                                                value Line, value Ty,
925                                                value AlwaysPreserve,
926                                                value Flags, value AlignInBits) {
927   return to_val(LLVMDIBuilderCreateAutoVariable(
928       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
929       caml_string_length(Name), Metadata_val(File), Int_val(Line),
930       Metadata_val(Ty), Bool_val(AlwaysPreserve), DIFlags_val(Flags),
931       Int_val(AlignInBits)));
932 }
933 
934 value llvm_dibuild_create_auto_variable_bytecode(value *argv, int arg) {
935 
936   return llvm_dibuild_create_auto_variable_native(argv[0], // Builder
937                                                   argv[1], // Scope
938                                                   argv[2], // Name
939                                                   argv[3], // File
940                                                   argv[4], // Line
941                                                   argv[5], // Ty
942                                                   argv[6], // AlwaysPreserve
943                                                   argv[7], // Flags
944                                                   argv[8]  // AlignInBits
945   );
946 }
947 
948 value llvm_dibuild_create_parameter_variable_native(
949     value Builder, value Scope, value Name, value ArgNo, value File, value Line,
950     value Ty, value AlwaysPreserve, value Flags) {
951   LLVMMetadataRef Metadata = LLVMDIBuilderCreateParameterVariable(
952       DIBuilder_val(Builder), Metadata_val(Scope), String_val(Name),
953       caml_string_length(Name), (unsigned)Int_val(ArgNo), Metadata_val(File),
954       Int_val(Line), Metadata_val(Ty), Bool_val(AlwaysPreserve),
955       DIFlags_val(Flags));
956   return to_val(Metadata);
957 }
958 
959 value llvm_dibuild_create_parameter_variable_bytecode(value *argv, int arg) {
960   return llvm_dibuild_create_parameter_variable_native(
961       argv[0], // Builder
962       argv[1], // Scope
963       argv[2], // Name
964       argv[3], // ArgNo
965       argv[4], // File
966       argv[5], // Line
967       argv[6], // Ty
968       argv[7], // AlwaysPreserve
969       argv[8]  // Flags
970   );
971 }
972 
973 value llvm_dibuild_insert_declare_before_native(value Builder, value Storage,
974                                                 value VarInfo, value Expr,
975                                                 value DebugLoc, value Instr) {
976   LLVMDbgRecordRef Value = LLVMDIBuilderInsertDeclareRecordBefore(
977       DIBuilder_val(Builder), Value_val(Storage), Metadata_val(VarInfo),
978       Metadata_val(Expr), Metadata_val(DebugLoc), Value_val(Instr));
979   return to_val(Value);
980 }
981 
982 value llvm_dibuild_insert_declare_before_bytecode(value *argv, int arg) {
983 
984   return llvm_dibuild_insert_declare_before_native(argv[0], // Builder
985                                                    argv[1], // Storage
986                                                    argv[2], // VarInfo
987                                                    argv[3], // Expr
988                                                    argv[4], // DebugLoc
989                                                    argv[5]  // Instr
990   );
991 }
992 
993 value llvm_dibuild_insert_declare_at_end_native(value Builder, value Storage,
994                                                 value VarInfo, value Expr,
995                                                 value DebugLoc, value Block) {
996   LLVMDbgRecordRef Value = LLVMDIBuilderInsertDeclareRecordAtEnd(
997       DIBuilder_val(Builder), Value_val(Storage), Metadata_val(VarInfo),
998       Metadata_val(Expr), Metadata_val(DebugLoc), BasicBlock_val(Block));
999   return to_val(Value);
1000 }
1001 
1002 value llvm_dibuild_insert_declare_at_end_bytecode(value *argv, int arg) {
1003   return llvm_dibuild_insert_declare_at_end_native(argv[0], // Builder
1004                                                    argv[1], // Storage
1005                                                    argv[2], // VarInfo
1006                                                    argv[3], // Expr
1007                                                    argv[4], // DebugLoc
1008                                                    argv[5]  // Block
1009   );
1010 }
1011 
1012 value llvm_dibuild_expression(value Builder, value Addr) {
1013   return to_val(LLVMDIBuilderCreateExpression(
1014       DIBuilder_val(Builder), (uint64_t *)Op_val(Addr), Wosize_val(Addr)));
1015 }
1016 
1017 /* llmodule -> bool */
1018 value llvm_is_new_dbg_info_format(value Module) {
1019   return Val_bool(LLVMIsNewDbgInfoFormat(Module_val(Module)));
1020 }
1021 
1022 /* llmodule -> bool -> unit */
1023 value llvm_set_is_new_dbg_info_format(value Module, value UseNewFormat) {
1024   LLVMSetIsNewDbgInfoFormat(Module_val(Module), Bool_val(UseNewFormat));
1025   return Val_unit;
1026 }
1027