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
29typedef 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
67static 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
142value llvm_debug_metadata_version(value Unit) {
143  return Val_int(LLVMDebugMetadataVersion());
144}
145
146value llvm_get_module_debug_metadata_version(LLVMModuleRef Module) {
147  return Val_int(LLVMGetModuleDebugMetadataVersion(Module));
148}
149
150#define DIFlags_val(v) (*(LLVMDIFlags *)(Data_custom_val(v)))
151
152static struct custom_operations diflags_ops = {
153    (char *)"DebugInfo.lldiflags", custom_finalize_default,
154    custom_compare_default,        custom_hash_default,
155    custom_serialize_default,      custom_deserialize_default,
156    custom_compare_ext_default};
157
158static value alloc_diflags(LLVMDIFlags Flags) {
159  value V = alloc_custom(&diflags_ops, sizeof(LLVMDIFlags), 0, 1);
160  DIFlags_val(V) = Flags;
161  return V;
162}
163
164LLVMDIFlags llvm_diflags_get(value i_Flag) {
165  LLVMDIFlags Flags = map_DIFlag(Int_val(i_Flag));
166  return alloc_diflags(Flags);
167}
168
169LLVMDIFlags llvm_diflags_set(value Flags, value i_Flag) {
170  LLVMDIFlags FlagsNew = DIFlags_val(Flags) | map_DIFlag(Int_val(i_Flag));
171  return alloc_diflags(FlagsNew);
172}
173
174value llvm_diflags_test(value Flags, value i_Flag) {
175  LLVMDIFlags Flag = map_DIFlag(Int_val(i_Flag));
176  return Val_bool((DIFlags_val(Flags) & Flag) == Flag);
177}
178
179#define DIBuilder_val(v) (*(LLVMDIBuilderRef *)(Data_custom_val(v)))
180
181static void llvm_finalize_dibuilder(value B) {
182  LLVMDIBuilderFinalize(DIBuilder_val(B));
183  LLVMDisposeDIBuilder(DIBuilder_val(B));
184}
185
186static struct custom_operations dibuilder_ops = {
187    (char *)"DebugInfo.lldibuilder", llvm_finalize_dibuilder,
188    custom_compare_default,          custom_hash_default,
189    custom_serialize_default,        custom_deserialize_default,
190    custom_compare_ext_default};
191
192static value alloc_dibuilder(LLVMDIBuilderRef B) {
193  value V = alloc_custom(&dibuilder_ops, sizeof(LLVMDIBuilderRef), 0, 1);
194  DIBuilder_val(V) = B;
195  return V;
196}
197
198/* llmodule -> lldibuilder */
199value llvm_dibuilder(LLVMModuleRef M) {
200  return alloc_dibuilder(LLVMCreateDIBuilder(M));
201}
202
203value llvm_dibuild_finalize(value Builder) {
204  LLVMDIBuilderFinalize(DIBuilder_val(Builder));
205  return Val_unit;
206}
207
208LLVMMetadataRef llvm_dibuild_create_compile_unit_native(
209    value Builder, value Lang, LLVMMetadataRef FileRef, value Producer,
210    value IsOptimized, value Flags, value RuntimeVer, value SplitName,
211    value Kind, value DWOId, value SplitDebugInline,
212    value DebugInfoForProfiling, value SysRoot, value SDK) {
213  return LLVMDIBuilderCreateCompileUnit(
214      DIBuilder_val(Builder), Int_val(Lang), FileRef, String_val(Producer),
215      caml_string_length(Producer), Bool_val(IsOptimized), String_val(Flags),
216      caml_string_length(Flags), Int_val(RuntimeVer), String_val(SplitName),
217      caml_string_length(SplitName), Int_val(Kind), Int_val(DWOId),
218      Bool_val(SplitDebugInline), Bool_val(DebugInfoForProfiling),
219      String_val(SysRoot), caml_string_length(SysRoot), String_val(SDK),
220      caml_string_length(SDK));
221}
222
223LLVMMetadataRef llvm_dibuild_create_compile_unit_bytecode(value *argv,
224                                                          int argn) {
225  return llvm_dibuild_create_compile_unit_native(
226      argv[0],                  // Builder
227      argv[1],                  // Lang
228      (LLVMMetadataRef)argv[2], // FileRef
229      argv[3],                  // Producer
230      argv[4],                  // IsOptimized
231      argv[5],                  // Flags
232      argv[6],                  // RuntimeVer
233      argv[7],                  // SplitName
234      argv[8],                  // Kind
235      argv[9],                  // DWOId
236      argv[10],                 // SplitDebugInline
237      argv[11],                 // DebugInfoForProfiling
238      argv[12],                 // SysRoot
239      argv[13]                  // SDK
240  );
241}
242
243LLVMMetadataRef llvm_dibuild_create_file(value Builder, value Filename,
244                                         value Directory) {
245  return LLVMDIBuilderCreateFile(DIBuilder_val(Builder), String_val(Filename),
246                                 caml_string_length(Filename),
247                                 String_val(Directory),
248                                 caml_string_length(Directory));
249}
250
251LLVMMetadataRef
252llvm_dibuild_create_module_native(value Builder, LLVMMetadataRef ParentScope,
253                                  value Name, value ConfigMacros,
254                                  value IncludePath, value SysRoot) {
255  return LLVMDIBuilderCreateModule(
256      DIBuilder_val(Builder), ParentScope, String_val(Name),
257      caml_string_length(Name), String_val(ConfigMacros),
258      caml_string_length(ConfigMacros), String_val(IncludePath),
259      caml_string_length(IncludePath), String_val(SysRoot),
260      caml_string_length(SysRoot));
261}
262
263LLVMMetadataRef llvm_dibuild_create_module_bytecode(value *argv, int argn) {
264  return llvm_dibuild_create_module_native(
265      argv[0],                  // Builder
266      (LLVMMetadataRef)argv[1], // ParentScope
267      argv[2],                  // Name
268      argv[3],                  // ConfigMacros
269      argv[4],                  // IncludePath
270      argv[5]                   // SysRoot
271  );
272}
273
274LLVMMetadataRef llvm_dibuild_create_namespace(value Builder,
275                                              LLVMMetadataRef ParentScope,
276                                              value Name, value ExportSymbols) {
277  return LLVMDIBuilderCreateNameSpace(
278      DIBuilder_val(Builder), ParentScope, String_val(Name),
279      caml_string_length(Name), Bool_val(ExportSymbols));
280}
281
282LLVMMetadataRef llvm_dibuild_create_function_native(
283    value Builder, LLVMMetadataRef Scope, value Name, value LinkageName,
284    LLVMMetadataRef File, value LineNo, LLVMMetadataRef Ty, value IsLocalToUnit,
285    value IsDefinition, value ScopeLine, value Flags, value IsOptimized) {
286  return LLVMDIBuilderCreateFunction(
287      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
288      String_val(LinkageName), caml_string_length(LinkageName), File,
289      Int_val(LineNo), Ty, Bool_val(IsLocalToUnit), Bool_val(IsDefinition),
290      Int_val(ScopeLine), DIFlags_val(Flags), Bool_val(IsOptimized));
291}
292
293LLVMMetadataRef llvm_dibuild_create_function_bytecode(value *argv, int argn) {
294  return llvm_dibuild_create_function_native(argv[0], // Builder,
295                                             (LLVMMetadataRef)argv[1], // Scope
296                                             argv[2],                  // Name
297                                             argv[3], // LinkageName
298                                             (LLVMMetadataRef)argv[4], // File
299                                             argv[5],                  // LineNo
300                                             (LLVMMetadataRef)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
309LLVMMetadataRef llvm_dibuild_create_lexical_block(value Builder,
310                                                  LLVMMetadataRef Scope,
311                                                  LLVMMetadataRef File,
312                                                  value Line, value Column) {
313  return LLVMDIBuilderCreateLexicalBlock(DIBuilder_val(Builder), Scope, File,
314                                         Int_val(Line), Int_val(Column));
315}
316
317LLVMMetadataRef llvm_metadata_null() { return (LLVMMetadataRef)NULL; }
318
319LLVMMetadataRef llvm_dibuild_create_debug_location(LLVMContextRef Ctx,
320                                                   value Line, value Column,
321                                                   LLVMMetadataRef Scope,
322                                                   LLVMMetadataRef InlinedAt) {
323  return LLVMDIBuilderCreateDebugLocation(Ctx, Int_val(Line), Int_val(Column),
324                                          Scope, InlinedAt);
325}
326
327value llvm_di_location_get_line(LLVMMetadataRef Location) {
328  return Val_int(LLVMDILocationGetLine(Location));
329}
330
331value llvm_di_location_get_column(LLVMMetadataRef Location) {
332  return Val_int(LLVMDILocationGetColumn(Location));
333}
334
335LLVMMetadataRef llvm_di_location_get_scope(LLVMMetadataRef Location) {
336  return LLVMDILocationGetScope(Location);
337}
338
339value llvm_di_location_get_inlined_at(LLVMMetadataRef Location) {
340  return (ptr_to_option(LLVMDILocationGetInlinedAt(Location)));
341}
342
343value llvm_di_scope_get_file(LLVMMetadataRef Scope) {
344  return (ptr_to_option(LLVMDIScopeGetFile(Scope)));
345}
346
347value llvm_di_file_get_directory(LLVMMetadataRef File) {
348  unsigned Len;
349  const char *Directory = LLVMDIFileGetDirectory(File, &Len);
350  return cstr_to_string(Directory, Len);
351}
352
353value llvm_di_file_get_filename(LLVMMetadataRef File) {
354  unsigned Len;
355  const char *Filename = LLVMDIFileGetFilename(File, &Len);
356  return cstr_to_string(Filename, Len);
357}
358
359value llvm_di_file_get_source(LLVMMetadataRef File) {
360  unsigned Len;
361  const char *Source = LLVMDIFileGetSource(File, &Len);
362  return cstr_to_string(Source, Len);
363}
364
365LLVMMetadataRef llvm_dibuild_get_or_create_type_array(value Builder,
366                                                      value Data) {
367
368  return LLVMDIBuilderGetOrCreateTypeArray(DIBuilder_val(Builder),
369                                           (LLVMMetadataRef *)Op_val(Data),
370                                           Wosize_val(Data));
371}
372
373LLVMMetadataRef llvm_dibuild_get_or_create_array(value Builder, value Data) {
374
375  return LLVMDIBuilderGetOrCreateArray(DIBuilder_val(Builder),
376                                       (LLVMMetadataRef *)Op_val(Data),
377                                       Wosize_val(Data));
378}
379
380LLVMMetadataRef llvm_dibuild_create_subroutine_type(value Builder,
381                                                    LLVMMetadataRef File,
382                                                    value ParameterTypes,
383                                                    value Flags) {
384
385  return LLVMDIBuilderCreateSubroutineType(
386      DIBuilder_val(Builder), File, (LLVMMetadataRef *)Op_val(ParameterTypes),
387      Wosize_val(ParameterTypes), DIFlags_val(Flags));
388}
389
390LLVMMetadataRef llvm_dibuild_create_enumerator(value Builder, value Name,
391                                               value Value, value IsUnsigned) {
392  return LLVMDIBuilderCreateEnumerator(
393      DIBuilder_val(Builder), String_val(Name), caml_string_length(Name),
394      (int64_t)Int_val(Value), Bool_val(IsUnsigned));
395}
396
397LLVMMetadataRef llvm_dibuild_create_enumeration_type_native(
398    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
399    value LineNumber, value SizeInBits, value AlignInBits, value Elements,
400    LLVMMetadataRef ClassTy) {
401  return LLVMDIBuilderCreateEnumerationType(
402      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
403      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
404      Int_val(AlignInBits), (LLVMMetadataRef *)Op_val(Elements),
405      Wosize_val(Elements), ClassTy);
406}
407
408LLVMMetadataRef llvm_dibuild_create_enumeration_type_bytecode(value *argv,
409                                                              int argn) {
410  return llvm_dibuild_create_enumeration_type_native(
411      argv[0],                  // Builder
412      (LLVMMetadataRef)argv[1], // Scope
413      argv[2],                  // Name
414      (LLVMMetadataRef)argv[3], // File
415      argv[4],                  // LineNumber
416      argv[5],                  // SizeInBits
417      argv[6],                  // AlignInBits
418      argv[7],                  // Elements
419      (LLVMMetadataRef)argv[8]  // ClassTy
420  );
421}
422
423LLVMMetadataRef llvm_dibuild_create_union_type_native(
424    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
425    value LineNumber, value SizeInBits, value AlignInBits, value Flags,
426    value Elements, value RunTimeLanguage, value UniqueId) {
427
428  return LLVMDIBuilderCreateUnionType(
429      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
430      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
431      Int_val(AlignInBits), DIFlags_val(Flags),
432      (LLVMMetadataRef *)Op_val(Elements), Wosize_val(Elements),
433      Int_val(RunTimeLanguage), String_val(UniqueId),
434      caml_string_length(UniqueId));
435}
436
437LLVMMetadataRef llvm_dibuild_create_union_type_bytecode(value *argv, int argn) {
438  return llvm_dibuild_create_union_type_native(
439      argv[0],                  // Builder
440      (LLVMMetadataRef)argv[1], // Scope
441      argv[2],                  // Name
442      (LLVMMetadataRef)argv[3], // File
443      argv[4],                  // LineNumber
444      argv[5],                  // SizeInBits
445      argv[6],                  // AlignInBits
446      argv[7],                  // Flags
447      argv[8],                  // Elements
448      argv[9],                  // RunTimeLanguage
449      argv[10]                  // UniqueId
450  );
451}
452
453LLVMMetadataRef llvm_dibuild_create_array_type(value Builder, value Size,
454                                               value AlignInBits,
455                                               LLVMMetadataRef Ty,
456                                               value Subscripts) {
457  return LLVMDIBuilderCreateArrayType(
458      DIBuilder_val(Builder), (uint64_t)Int_val(Size), Int_val(AlignInBits), Ty,
459      (LLVMMetadataRef *)Op_val(Subscripts), Wosize_val(Subscripts));
460}
461
462LLVMMetadataRef llvm_dibuild_create_vector_type(value Builder, value Size,
463                                                value AlignInBits,
464                                                LLVMMetadataRef Ty,
465                                                value Subscripts) {
466  return LLVMDIBuilderCreateVectorType(
467      DIBuilder_val(Builder), (uint64_t)Int_val(Size), Int_val(AlignInBits), Ty,
468      (LLVMMetadataRef *)Op_val(Subscripts), Wosize_val(Subscripts));
469}
470
471LLVMMetadataRef llvm_dibuild_create_unspecified_type(value Builder,
472                                                     value Name) {
473  return LLVMDIBuilderCreateUnspecifiedType(
474      DIBuilder_val(Builder), String_val(Name), caml_string_length(Name));
475}
476
477LLVMMetadataRef llvm_dibuild_create_basic_type(value Builder, value Name,
478                                               value SizeInBits, value Encoding,
479                                               value Flags) {
480
481  return LLVMDIBuilderCreateBasicType(
482      DIBuilder_val(Builder), String_val(Name), caml_string_length(Name),
483      (uint64_t)Int_val(SizeInBits), Int_val(Encoding), DIFlags_val(Flags));
484}
485
486LLVMMetadataRef llvm_dibuild_create_pointer_type_native(
487    value Builder, LLVMMetadataRef PointeeTy, value SizeInBits,
488    value AlignInBits, value AddressSpace, value Name) {
489  return LLVMDIBuilderCreatePointerType(
490      DIBuilder_val(Builder), PointeeTy, (uint64_t)Int_val(SizeInBits),
491      Int_val(AlignInBits), Int_val(AddressSpace), String_val(Name),
492      caml_string_length(Name));
493}
494
495LLVMMetadataRef llvm_dibuild_create_pointer_type_bytecode(value *argv,
496                                                          int argn) {
497  return llvm_dibuild_create_pointer_type_native(
498      argv[0],                  // Builder
499      (LLVMMetadataRef)argv[1], // PointeeTy
500      argv[2],                  // SizeInBits
501      argv[3],                  // AlignInBits
502      argv[4],                  // AddressSpace
503      argv[5]                   // Name
504  );
505}
506
507LLVMMetadataRef llvm_dibuild_create_struct_type_native(
508    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
509    value LineNumber, value SizeInBits, value AlignInBits, value Flags,
510    LLVMMetadataRef DerivedFrom, value Elements, value RunTimeLanguage,
511    LLVMMetadataRef VTableHolder, value UniqueId) {
512
513  return LLVMDIBuilderCreateStructType(
514      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
515      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
516      Int_val(AlignInBits), DIFlags_val(Flags), DerivedFrom,
517      (LLVMMetadataRef *)Op_val(Elements), Wosize_val(Elements),
518      Int_val(RunTimeLanguage), VTableHolder, String_val(UniqueId),
519      caml_string_length(UniqueId));
520}
521
522LLVMMetadataRef llvm_dibuild_create_struct_type_bytecode(value *argv,
523                                                         int argn) {
524  return llvm_dibuild_create_struct_type_native(
525      argv[0],                   // Builder
526      (LLVMMetadataRef)argv[1],  // Scope
527      argv[2],                   // Name
528      (LLVMMetadataRef)argv[3],  // File
529      argv[4],                   // LineNumber
530      argv[5],                   // SizeInBits
531      argv[6],                   // AlignInBits
532      argv[7],                   // Flags
533      (LLVMMetadataRef)argv[8],  // DeriviedFrom
534      argv[9],                   // Elements
535      argv[10],                  // RunTimeLanguage
536      (LLVMMetadataRef)argv[11], // VTableHolder
537      argv[12]                   // UniqueId
538  );
539}
540
541LLVMMetadataRef llvm_dibuild_create_member_type_native(
542    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
543    value LineNumber, value SizeInBits, value AlignInBits, value OffsetInBits,
544    value Flags, LLVMMetadataRef Ty) {
545
546  return LLVMDIBuilderCreateMemberType(
547      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
548      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
549      Int_val(AlignInBits), (uint64_t)Int_val(OffsetInBits), DIFlags_val(Flags),
550      Ty);
551}
552
553LLVMMetadataRef llvm_dibuild_create_member_type_bytecode(value *argv,
554                                                         int argn) {
555  return llvm_dibuild_create_member_type_native(
556      argv[0],                  // Builder
557      (LLVMMetadataRef)argv[1], // Scope
558      argv[2],                  // Name
559      (LLVMMetadataRef)argv[3], // File
560      argv[4],                  // LineNumber
561      argv[5],                  // SizeInBits
562      argv[6],                  // AlignInBits
563      argv[7],                  // OffsetInBits
564      argv[8],                  // Flags
565      (LLVMMetadataRef)argv[9]  // Ty
566  );
567}
568
569LLVMMetadataRef llvm_dibuild_create_static_member_type_native(
570    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
571    value LineNumber, LLVMMetadataRef Type, value Flags,
572    LLVMValueRef ConstantVal, value AlignInBits) {
573
574  return LLVMDIBuilderCreateStaticMemberType(
575      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
576      File, Int_val(LineNumber), Type, DIFlags_val(Flags), ConstantVal,
577      Int_val(AlignInBits));
578}
579
580LLVMMetadataRef llvm_dibuild_create_static_member_type_bytecode(value *argv,
581                                                                int argn) {
582  return llvm_dibuild_create_static_member_type_native(
583      argv[0],                  // Builder
584      (LLVMMetadataRef)argv[1], // Scope
585      argv[2],                  // Name
586      (LLVMMetadataRef)argv[3], // File
587      argv[4],                  // LineNumber
588      (LLVMMetadataRef)argv[5], // Type
589      argv[6],                  // Flags,
590      (LLVMValueRef)argv[7],    // ConstantVal
591      argv[8]                   // AlignInBits
592  );
593}
594
595LLVMMetadataRef llvm_dibuild_create_member_pointer_type_native(
596    value Builder, LLVMMetadataRef PointeeType, LLVMMetadataRef ClassType,
597    uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags) {
598
599  return LLVMDIBuilderCreateMemberPointerType(
600      DIBuilder_val(Builder), PointeeType, ClassType,
601      (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits), Flags);
602}
603
604LLVMMetadataRef llvm_dibuild_create_member_pointer_type_bytecode(value *argv,
605                                                                 int argn) {
606  return llvm_dibuild_create_member_pointer_type_native(
607      argv[0],                  // Builder
608      (LLVMMetadataRef)argv[1], // PointeeType
609      (LLVMMetadataRef)argv[2], // ClassType
610      argv[3],                  // SizeInBits
611      argv[4],                  // AlignInBits
612      argv[5]                   // Flags
613  );
614}
615
616LLVMMetadataRef llvm_dibuild_create_object_pointer_type(value Builder,
617                                                        LLVMMetadataRef Type) {
618  return LLVMDIBuilderCreateObjectPointerType(DIBuilder_val(Builder), Type);
619}
620
621LLVMMetadataRef llvm_dibuild_create_qualified_type(value Builder, value Tag,
622                                                   LLVMMetadataRef Type) {
623
624  return LLVMDIBuilderCreateQualifiedType(DIBuilder_val(Builder), Int_val(Tag),
625                                          Type);
626}
627
628LLVMMetadataRef llvm_dibuild_create_reference_type(value Builder, value Tag,
629                                                   LLVMMetadataRef Type) {
630
631  return LLVMDIBuilderCreateReferenceType(DIBuilder_val(Builder), Int_val(Tag),
632                                          Type);
633}
634
635LLVMMetadataRef llvm_dibuild_create_null_ptr_type(value Builder) {
636
637  return LLVMDIBuilderCreateNullPtrType(DIBuilder_val(Builder));
638}
639
640LLVMMetadataRef llvm_dibuild_create_typedef_native(
641    value Builder, LLVMMetadataRef Type, value Name, LLVMMetadataRef File,
642    value LineNo, LLVMMetadataRef Scope, value AlignInBits) {
643
644  return LLVMDIBuilderCreateTypedef(
645      DIBuilder_val(Builder), Type, String_val(Name), caml_string_length(Name),
646      File, Int_val(LineNo), Scope, Int_val(AlignInBits));
647}
648
649LLVMMetadataRef llvm_dibuild_create_typedef_bytecode(value *argv, int argn) {
650
651  return llvm_dibuild_create_typedef_native(argv[0],                  // Builder
652                                            (LLVMMetadataRef)argv[1], // Type
653                                            argv[2],                  // Name
654                                            (LLVMMetadataRef)argv[3], // File
655                                            argv[4],                  // LineNo
656                                            (LLVMMetadataRef)argv[5], // Scope
657                                            argv[6] // AlignInBits
658  );
659}
660
661LLVMMetadataRef
662llvm_dibuild_create_inheritance_native(value Builder, LLVMMetadataRef Ty,
663                                       LLVMMetadataRef BaseTy, value BaseOffset,
664                                       value VBPtrOffset, value Flags) {
665
666  return LLVMDIBuilderCreateInheritance(DIBuilder_val(Builder), Ty, BaseTy,
667                                        (uint64_t)Int_val(BaseOffset),
668                                        Int_val(VBPtrOffset), Flags);
669}
670
671LLVMMetadataRef llvm_dibuild_create_inheritance_bytecode(value *argv, int arg) {
672
673  return llvm_dibuild_create_inheritance_native(
674      argv[0],                  // Builder
675      (LLVMMetadataRef)argv[1], // Ty
676      (LLVMMetadataRef)argv[2], // BaseTy
677      argv[3],                  // BaseOffset
678      argv[4],                  // VBPtrOffset
679      argv[5]                   // Flags
680  );
681}
682
683LLVMMetadataRef llvm_dibuild_create_forward_decl_native(
684    value Builder, value Tag, value Name, LLVMMetadataRef Scope,
685    LLVMMetadataRef File, value Line, value RuntimeLang, value SizeInBits,
686    value AlignInBits, value UniqueIdentifier) {
687  return LLVMDIBuilderCreateForwardDecl(
688      DIBuilder_val(Builder), Int_val(Tag), String_val(Name),
689      caml_string_length(Name), Scope, File, Int_val(Line),
690      Int_val(RuntimeLang), (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
691      String_val(UniqueIdentifier), caml_string_length(UniqueIdentifier));
692}
693
694LLVMMetadataRef llvm_dibuild_create_forward_decl_bytecode(value *argv,
695                                                          int arg) {
696
697  return llvm_dibuild_create_forward_decl_native(
698      argv[0],                  // Builder
699      argv[1],                  // Tag
700      argv[2],                  // Name
701      (LLVMMetadataRef)argv[3], // Scope
702      (LLVMMetadataRef)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
711LLVMMetadataRef llvm_dibuild_create_replaceable_composite_type_native(
712    value Builder, value Tag, value Name, LLVMMetadataRef Scope,
713    LLVMMetadataRef File, value Line, value RuntimeLang, value SizeInBits,
714    value AlignInBits, value Flags, value UniqueIdentifier) {
715
716  return LLVMDIBuilderCreateReplaceableCompositeType(
717      DIBuilder_val(Builder), Int_val(Tag), String_val(Name),
718      caml_string_length(Name), Scope, File, Int_val(Line),
719      Int_val(RuntimeLang), (uint64_t)Int_val(SizeInBits), Int_val(AlignInBits),
720      DIFlags_val(Flags), String_val(UniqueIdentifier),
721      caml_string_length(UniqueIdentifier));
722}
723
724LLVMMetadataRef
725llvm_dibuild_create_replaceable_composite_type_bytecode(value *argv, 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      (LLVMMetadataRef)argv[3], // Scope
732      (LLVMMetadataRef)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
742LLVMMetadataRef llvm_dibuild_create_bit_field_member_type_native(
743    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
744    value LineNum, value SizeInBits, value OffsetInBits,
745    value StorageOffsetInBits, value Flags, LLVMMetadataRef Ty) {
746
747  return LLVMDIBuilderCreateBitFieldMemberType(
748      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
749      File, Int_val(LineNum), (uint64_t)Int_val(SizeInBits),
750      (uint64_t)Int_val(OffsetInBits), (uint64_t)Int_val(StorageOffsetInBits),
751      DIFlags_val(Flags), Ty);
752}
753
754LLVMMetadataRef llvm_dibuild_create_bit_field_member_type_bytecode(value *argv,
755                                                                   int arg) {
756
757  return llvm_dibuild_create_bit_field_member_type_native(
758      argv[0],                  // Builder
759      (LLVMMetadataRef)argv[1], // Scope
760      argv[2],                  // Name
761      (LLVMMetadataRef)argv[3], // File
762      argv[4],                  // LineNum
763      argv[5],                  // SizeInBits
764      argv[6],                  // OffsetInBits
765      argv[7],                  // StorageOffsetInBits
766      argv[8],                  // Flags
767      (LLVMMetadataRef)argv[9]  // Ty
768  );
769}
770
771LLVMMetadataRef llvm_dibuild_create_class_type_native(
772    value Builder, LLVMMetadataRef Scope, value Name, LLVMMetadataRef File,
773    value LineNumber, value SizeInBits, value AlignInBits, value OffsetInBits,
774    value Flags, LLVMMetadataRef DerivedFrom, value Elements,
775    LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode,
776    value UniqueIdentifier) {
777
778  return LLVMDIBuilderCreateClassType(
779      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
780      File, Int_val(LineNumber), (uint64_t)Int_val(SizeInBits),
781      Int_val(AlignInBits), (uint64_t)Int_val(OffsetInBits), DIFlags_val(Flags),
782      DerivedFrom, (LLVMMetadataRef *)Op_val(Elements), Wosize_val(Elements),
783      VTableHolder, TemplateParamsNode, String_val(UniqueIdentifier),
784      caml_string_length(UniqueIdentifier));
785}
786
787LLVMMetadataRef llvm_dibuild_create_class_type_bytecode(value *argv, int arg) {
788
789  return llvm_dibuild_create_class_type_native(
790      argv[0],                   // Builder
791      (LLVMMetadataRef)argv[1],  // Scope
792      argv[2],                   // Name
793      (LLVMMetadataRef)argv[3],  // File
794      argv[4],                   // LineNumber
795      argv[5],                   // SizeInBits
796      argv[6],                   // AlignInBits
797      argv[7],                   // OffsetInBits
798      argv[8],                   // Flags
799      (LLVMMetadataRef)argv[9],  // DerivedFrom
800      argv[10],                  // Elements
801      (LLVMMetadataRef)argv[11], // VTableHolder
802      (LLVMMetadataRef)argv[12], // TemplateParamsNode
803      argv[13]                   // UniqueIdentifier
804  );
805}
806
807LLVMMetadataRef llvm_dibuild_create_artificial_type(value Builder,
808                                                    LLVMMetadataRef Type) {
809  return LLVMDIBuilderCreateArtificialType(DIBuilder_val(Builder), Type);
810}
811
812value llvm_di_type_get_name(LLVMMetadataRef DType) {
813  size_t Len;
814  const char *Name = LLVMDITypeGetName(DType, &Len);
815  return cstr_to_string(Name, Len);
816}
817
818value llvm_di_type_get_size_in_bits(LLVMMetadataRef DType) {
819  uint64_t Size = LLVMDITypeGetSizeInBits(DType);
820  return Val_int((int)Size);
821}
822
823value llvm_di_type_get_offset_in_bits(LLVMMetadataRef DType) {
824  uint64_t Size = LLVMDITypeGetOffsetInBits(DType);
825  return Val_int((int)Size);
826}
827
828value llvm_di_type_get_align_in_bits(LLVMMetadataRef DType) {
829  uint32_t Size = LLVMDITypeGetAlignInBits(DType);
830  return Val_int(Size);
831}
832
833value llvm_di_type_get_line(LLVMMetadataRef DType) {
834  unsigned Line = LLVMDITypeGetLine(DType);
835  return Val_int(Line);
836}
837
838value llvm_di_type_get_flags(LLVMMetadataRef DType) {
839  LLVMDIFlags Flags = LLVMDITypeGetLine(DType);
840  return alloc_diflags(Flags);
841}
842
843value llvm_get_subprogram(LLVMValueRef Func) {
844  return (ptr_to_option(LLVMGetSubprogram(Func)));
845}
846
847value llvm_set_subprogram(LLVMValueRef Func, LLVMMetadataRef SP) {
848  LLVMSetSubprogram(Func, SP);
849  return Val_unit;
850}
851
852value llvm_di_subprogram_get_line(LLVMMetadataRef Subprogram) {
853  return Val_int(LLVMDISubprogramGetLine(Subprogram));
854}
855
856value llvm_instr_get_debug_loc(LLVMValueRef Inst) {
857  return (ptr_to_option(LLVMInstructionGetDebugLoc(Inst)));
858}
859
860value llvm_instr_set_debug_loc(LLVMValueRef Inst, LLVMMetadataRef Loc) {
861  LLVMInstructionSetDebugLoc(Inst, Loc);
862  return Val_unit;
863}
864
865LLVMMetadataRef llvm_dibuild_create_constant_value_expression(value Builder,
866                                                              value Value) {
867  return LLVMDIBuilderCreateConstantValueExpression(DIBuilder_val(Builder),
868                                                    (int64_t)Int_val(Value));
869}
870
871LLVMMetadataRef llvm_dibuild_create_global_variable_expression_native(
872    value Builder, LLVMMetadataRef Scope, value Name, value Linkage,
873    LLVMMetadataRef File, value Line, LLVMMetadataRef Ty, value LocalToUnit,
874    LLVMMetadataRef Expr, LLVMMetadataRef Decl, value AlignInBits) {
875  return LLVMDIBuilderCreateGlobalVariableExpression(
876      DIBuilder_val(Builder), Scope, String_val(Name), caml_string_length(Name),
877      String_val(Linkage), caml_string_length(Linkage), File, Int_val(Line), Ty,
878      Bool_val(LocalToUnit), Expr, Decl, Int_val(AlignInBits));
879}
880
881LLVMMetadataRef
882llvm_dibuild_create_global_variable_expression_bytecode(value *argv, int arg) {
883
884  return llvm_dibuild_create_global_variable_expression_native(
885      argv[0],                  // Builder
886      (LLVMMetadataRef)argv[1], // Scope
887      argv[2],                  // Name
888      argv[3],                  // Linkage
889      (LLVMMetadataRef)argv[4], // File
890      argv[5],                  // Line
891      (LLVMMetadataRef)argv[6], // Ty
892      argv[7],                  // LocalToUnit
893      (LLVMMetadataRef)argv[8], // Expr
894      (LLVMMetadataRef)argv[9], // Decl
895      argv[10]                  // AlignInBits
896  );
897}
898
899value llvm_di_global_variable_expression_get_variable(LLVMMetadataRef GVE) {
900  return (ptr_to_option(LLVMDIGlobalVariableExpressionGetVariable(GVE)));
901}
902
903value llvm_di_variable_get_line(LLVMMetadataRef Variable) {
904  return Val_int(LLVMDIVariableGetLine(Variable));
905}
906
907value llvm_di_variable_get_file(LLVMMetadataRef Variable) {
908  return (ptr_to_option(LLVMDIVariableGetFile(Variable)));
909}
910
911value llvm_get_metadata_kind(LLVMMetadataRef Metadata) {
912  return Val_int(LLVMGetMetadataKind(Metadata));
913}
914