[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Bindings / OCaml / debuginfo.ml
blobd07d7592fb2637a06a795ce3f0c43dcb3ff157d6
1 (* RUN: rm -rf %t && mkdir -p %t && cp %s %t/debuginfo.ml && cp %S/Utils/Testsuite.ml %t/Testsuite.ml
2 * RUN: %ocamlc -g -w +A -package llvm.all_backends -package llvm.target -package llvm.analysis -package llvm.debuginfo -I %t/ -linkpkg %t/Testsuite.ml %t/debuginfo.ml -o %t/executable
3 * RUN: %t/executable | FileCheck %s
4 * RUN: %ocamlopt -g -w +A -package llvm.all_backends -package llvm.target -package llvm.analysis -package llvm.debuginfo -I %t/ -linkpkg %t/Testsuite.ml %t/debuginfo.ml -o %t/executable
5 * RUN: %t/executable | FileCheck %s
6 * XFAIL: vg_leak
7 *)
9 open Testsuite
11 let context = Llvm.global_context ()
13 let filename = "di_test_file"
15 let directory = "di_test_dir"
17 let module_name = "di_test_module"
19 let null_metadata = Llvm_debuginfo.llmetadata_null ()
21 let string_of_metadata md =
22 Llvm.string_of_llvalue (Llvm.metadata_as_value context md)
24 let stdout_metadata md = Printf.printf "%s\n" (string_of_metadata md)
26 let prepare_target llmod =
27 Llvm_all_backends.initialize ();
28 let triple = Llvm_target.Target.default_triple () in
29 let lltarget = Llvm_target.Target.by_triple triple in
30 let llmachine = Llvm_target.TargetMachine.create ~triple lltarget in
31 let lldly =
32 Llvm_target.DataLayout.as_string
33 (Llvm_target.TargetMachine.data_layout llmachine)
35 let _ = Llvm.set_target_triple triple llmod in
36 let _ = Llvm.set_data_layout lldly llmod in
39 let new_module () =
40 let m = Llvm.create_module context module_name in
41 let () = prepare_target m in
44 let test_get_module () =
45 group "module_level_tests";
46 let m = new_module () in
47 let cur_ver = Llvm_debuginfo.debug_metadata_version () in
48 insist (cur_ver > 0);
49 let m_ver = Llvm_debuginfo.get_module_debug_metadata_version m in
50 (* We haven't added any debug info to the module *)
51 insist (m_ver = 0);
52 let dibuilder = Llvm_debuginfo.dibuilder m in
53 let di_version_key = "Debug Info Version" in
54 let ver =
55 Llvm.value_as_metadata @@ Llvm.const_int (Llvm.i32_type context) cur_ver
57 let () =
58 Llvm.add_module_flag m Llvm.ModuleFlagBehavior.Warning di_version_key ver
60 let file_di =
61 Llvm_debuginfo.dibuild_create_file dibuilder ~filename ~directory
63 stdout_metadata file_di;
64 (* CHECK: [[FILE_PTR:<0x[0-9a-f]*>]] = !DIFile(filename: "di_test_file", directory: "di_test_dir")
66 insist
67 ( Llvm_debuginfo.di_file_get_filename ~file:file_di = filename
68 && Llvm_debuginfo.di_file_get_directory ~file:file_di = directory );
69 insist
70 ( Llvm_debuginfo.get_metadata_kind file_di
71 = Llvm_debuginfo.MetadataKind.DIFileMetadataKind );
72 let cu_di =
73 Llvm_debuginfo.dibuild_create_compile_unit dibuilder
74 Llvm_debuginfo.DWARFSourceLanguageKind.C89 ~file_ref:file_di
75 ~producer:"TestGen" ~is_optimized:false ~flags:"" ~runtime_ver:0
76 ~split_name:"" Llvm_debuginfo.DWARFEmissionKind.LineTablesOnly ~dwoid:0
77 ~di_inlining:false ~di_profiling:false ~sys_root:"" ~sdk:""
79 stdout_metadata cu_di;
80 (* CHECK: [[CMPUNIT_PTR:<0x[0-9a-f]*>]] = distinct !DICompileUnit(language: DW_LANG_C89, file: [[FILE_PTR]], producer: "TestGen", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false)
82 insist
83 ( Llvm_debuginfo.get_metadata_kind cu_di
84 = Llvm_debuginfo.MetadataKind.DICompileUnitMetadataKind );
85 let m_di =
86 Llvm_debuginfo.dibuild_create_module dibuilder ~parent_ref:cu_di
87 ~name:module_name ~config_macros:"" ~include_path:"" ~sys_root:""
89 insist
90 ( Llvm_debuginfo.get_metadata_kind m_di
91 = Llvm_debuginfo.MetadataKind.DIModuleMetadataKind );
92 insist (Llvm_debuginfo.get_module_debug_metadata_version m = cur_ver);
93 stdout_metadata m_di;
94 (* CHECK: [[MODULE_PTR:<0x[0-9a-f]*>]] = !DIModule(scope: null, name: "di_test_module")
96 (m, dibuilder, file_di, m_di)
98 let flags_zero = Llvm_debuginfo.diflags_get Llvm_debuginfo.DIFlag.Zero
100 let int_ty_di bits dibuilder =
101 Llvm_debuginfo.dibuild_create_basic_type dibuilder ~name:"int"
102 ~size_in_bits:bits ~encoding:0x05
103 (* llvm::dwarf::DW_ATE_signed *) flags_zero
105 let test_get_function m dibuilder file_di m_di =
106 group "function_level_tests";
108 (* Create a function of type "void foo (int)". *)
109 let int_ty_di = int_ty_di 32 dibuilder in
110 stdout_metadata int_ty_di;
111 (* CHECK: [[INT32_PTR:<0x[0-9a-f]*>]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
113 let param_types = [| null_metadata; int_ty_di |] in
114 let fty_di =
115 Llvm_debuginfo.dibuild_create_subroutine_type dibuilder ~file:file_di
116 ~param_types flags_zero
118 insist
119 ( Llvm_debuginfo.get_metadata_kind fty_di
120 = Llvm_debuginfo.MetadataKind.DISubroutineTypeMetadataKind );
121 (* To be able to print and verify the type array of the subroutine type,
122 * since we have no way to access it from fty_di, we build it again. *)
123 let fty_di_args =
124 Llvm_debuginfo.dibuild_get_or_create_type_array dibuilder ~data:param_types
126 stdout_metadata fty_di_args;
127 (* CHECK: [[FARGS_PTR:<0x[0-9a-f]*>]] = !{null, [[INT32_PTR]]}
129 stdout_metadata fty_di;
130 (* CHECK: [[SBRTNTY_PTR:<0x[0-9a-f]*>]] = !DISubroutineType(types: [[FARGS_PTR]])
132 (* Let's create the LLVM-IR function now. *)
133 let name = "tfun" in
134 let fty =
135 Llvm.function_type (Llvm.void_type context) [| Llvm.i32_type context |]
137 let f = Llvm.define_function name fty m in
138 let f_di =
139 Llvm_debuginfo.dibuild_create_function dibuilder ~scope:m_di ~name
140 ~linkage_name:name ~file:file_di ~line_no:10 ~ty:fty_di
141 ~is_local_to_unit:false ~is_definition:true ~scope_line:10
142 ~flags:flags_zero ~is_optimized:false
144 stdout_metadata f_di;
145 (* CHECK: [[SBPRG_PTR:<0x[0-9a-f]*>]] = distinct !DISubprogram(name: "tfun", linkageName: "tfun", scope: [[MODULE_PTR]], file: [[FILE_PTR]], line: 10, type: [[SBRTNTY_PTR]], scopeLine: 10, spFlags: DISPFlagDefinition, unit: [[CMPUNIT_PTR]], retainedNodes: {{<0x[0-9a-f]*>}})
147 Llvm_debuginfo.set_subprogram f f_di;
148 ( match Llvm_debuginfo.get_subprogram f with
149 | Some f_di' -> insist (f_di = f_di')
150 | None -> insist false );
151 insist
152 ( Llvm_debuginfo.get_metadata_kind f_di
153 = Llvm_debuginfo.MetadataKind.DISubprogramMetadataKind );
154 insist (Llvm_debuginfo.di_subprogram_get_line f_di = 10);
155 (f, f_di)
157 let test_bbinstr f f_di file_di dibuilder =
158 group "basic_block and instructions tests";
159 (* Create this pattern:
160 * if (arg0 != 0) {
161 * foo(arg0);
163 * return;
165 let arg0 = (Llvm.params f).(0) in
166 let builder = Llvm.builder_at_end context (Llvm.entry_block f) in
167 let zero = Llvm.const_int (Llvm.i32_type context) 0 in
168 let cmpi = Llvm.build_icmp Llvm.Icmp.Ne zero arg0 "cmpi" builder in
169 let truebb = Llvm.append_block context "truebb" f in
170 let falsebb = Llvm.append_block context "falsebb" f in
171 let _ = Llvm.build_cond_br cmpi truebb falsebb builder in
172 let foodecl =
173 Llvm.declare_function "foo"
174 (Llvm.element_type (Llvm.type_of f))
175 (Llvm.global_parent f)
177 let _ =
178 Llvm.position_at_end truebb builder;
179 let scope =
180 Llvm_debuginfo.dibuild_create_lexical_block dibuilder ~scope:f_di
181 ~file:file_di ~line:9 ~column:4
183 let file_of_f_di = Llvm_debuginfo.di_scope_get_file ~scope:f_di in
184 let file_of_scope = Llvm_debuginfo.di_scope_get_file ~scope in
185 insist
186 ( match (file_of_f_di, file_of_scope) with
187 | Some file_of_f_di', Some file_of_scope' ->
188 file_of_f_di' = file_di && file_of_scope' = file_di
189 | _ -> false );
190 let foocall = Llvm.build_call foodecl [| arg0 |] "" builder in
191 let foocall_loc =
192 Llvm_debuginfo.dibuild_create_debug_location context ~line:10 ~column:12
193 ~scope
195 Llvm_debuginfo.instr_set_debug_loc foocall (Some foocall_loc);
196 insist
197 ( match Llvm_debuginfo.instr_get_debug_loc foocall with
198 | Some foocall_loc' -> foocall_loc' = foocall_loc
199 | None -> false );
200 stdout_metadata scope;
201 (* CHECK: [[BLOCK_PTR:<0x[0-9a-f]*>]] = distinct !DILexicalBlock(scope: [[SBPRG_PTR]], file: [[FILE_PTR]], line: 9, column: 4)
203 stdout_metadata foocall_loc;
204 (* CHECK: !DILocation(line: 10, column: 12, scope: [[BLOCK_PTR]])
206 insist
207 ( Llvm_debuginfo.di_location_get_scope ~location:foocall_loc = scope
208 && Llvm_debuginfo.di_location_get_line ~location:foocall_loc = 10
209 && Llvm_debuginfo.di_location_get_column ~location:foocall_loc = 12 );
210 insist
211 ( Llvm_debuginfo.get_metadata_kind foocall_loc
212 = Llvm_debuginfo.MetadataKind.DILocationMetadataKind
213 && Llvm_debuginfo.get_metadata_kind scope
214 = Llvm_debuginfo.MetadataKind.DILexicalBlockMetadataKind );
215 Llvm.build_br falsebb builder
217 let _ =
218 Llvm.position_at_end falsebb builder;
219 Llvm.build_ret_void builder
221 (* Printf.printf "%s\n" (Llvm.string_of_llmodule (Llvm.global_parent f)); *)
224 let test_global_variable_expression dibuilder f_di m_di =
225 group "global variable expression tests";
226 let cexpr_di =
227 Llvm_debuginfo.dibuild_create_constant_value_expression dibuilder 0
229 stdout_metadata cexpr_di;
230 (* CHECK: [[DICEXPR:!DIExpression\(DW_OP_constu, 0, DW_OP_stack_value\)]]
232 insist
233 ( Llvm_debuginfo.get_metadata_kind cexpr_di
234 = Llvm_debuginfo.MetadataKind.DIExpressionMetadataKind );
235 let ty = int_ty_di 64 dibuilder in
236 stdout_metadata ty;
237 (* CHECK: [[INT64TY_PTR:<0x[0-9a-f]*>]] = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed)
239 let gvexpr_di =
240 Llvm_debuginfo.dibuild_create_global_variable_expression dibuilder
241 ~scope:m_di ~name:"my_global" ~linkage:"" ~file:f_di ~line:5 ~ty
242 ~is_local_to_unit:true ~expr:cexpr_di ~decl:null_metadata ~align_in_bits:0
244 insist
245 ( Llvm_debuginfo.get_metadata_kind gvexpr_di
246 = Llvm_debuginfo.MetadataKind.DIGlobalVariableExpressionMetadataKind );
247 ( match
248 Llvm_debuginfo.di_global_variable_expression_get_variable gvexpr_di
249 with
250 | Some gvexpr_var_di ->
251 insist
252 ( Llvm_debuginfo.get_metadata_kind gvexpr_var_di
253 = Llvm_debuginfo.MetadataKind.DIGlobalVariableMetadataKind );
254 stdout_metadata gvexpr_var_di
255 (* CHECK: [[GV_PTR:<0x[0-9a-f]*>]] = distinct !DIGlobalVariable(name: "my_global", scope: [[MODULE_PTR]], file: [[FILE_PTR]], line: 5, type: [[INT64TY_PTR]], isLocal: true, isDefinition: true)
257 | None -> insist false );
258 stdout_metadata gvexpr_di;
259 (* CHECK: [[GVEXP_PTR:<0x[0-9a-f]*>]] = !DIGlobalVariableExpression(var: [[GV_PTR]], expr: [[DICEXPR]])
263 let test_types dibuilder file_di m_di =
264 group "type tests";
265 let namespace_di =
266 Llvm_debuginfo.dibuild_create_namespace dibuilder ~parent_ref:m_di
267 ~name:"NameSpace1" ~export_symbols:false
269 stdout_metadata namespace_di;
270 (* CHECK: [[NAMESPACE_PTR:<0x[0-9a-f]*>]] = !DINamespace(name: "NameSpace1", scope: [[MODULE_PTR]])
272 let int64_ty_di = int_ty_di 64 dibuilder in
273 let structty_args = [| int64_ty_di; int64_ty_di; int64_ty_di |] in
274 let struct_ty_di =
275 Llvm_debuginfo.dibuild_create_struct_type dibuilder ~scope:namespace_di
276 ~name:"StructType1" ~file:file_di ~line_number:20 ~size_in_bits:192
277 ~align_in_bits:0 flags_zero ~derived_from:null_metadata
278 ~elements:structty_args Llvm_debuginfo.DWARFSourceLanguageKind.C89
279 ~vtable_holder:null_metadata ~unique_id:"StructType1"
281 (* Since there's no way to fetch the element types which is now
282 * a type array, we build that again for checking. *)
283 let structty_di_eltypes =
284 Llvm_debuginfo.dibuild_get_or_create_type_array dibuilder
285 ~data:structty_args
287 stdout_metadata structty_di_eltypes;
288 (* CHECK: [[STRUCTELT_PTR:<0x[0-9a-f]*>]] = !{[[INT64TY_PTR]], [[INT64TY_PTR]], [[INT64TY_PTR]]}
290 stdout_metadata struct_ty_di;
291 (* CHECK: [[STRUCT_PTR:<0x[0-9a-f]*>]] = !DICompositeType(tag: DW_TAG_structure_type, name: "StructType1", scope: [[NAMESPACE_PTR]], file: [[FILE_PTR]], line: 20, size: 192, elements: [[STRUCTELT_PTR]], identifier: "StructType1")
293 insist
294 ( Llvm_debuginfo.get_metadata_kind struct_ty_di
295 = Llvm_debuginfo.MetadataKind.DICompositeTypeMetadataKind );
296 let structptr_di =
297 Llvm_debuginfo.dibuild_create_pointer_type dibuilder
298 ~pointee_ty:struct_ty_di ~size_in_bits:192 ~align_in_bits:0
299 ~address_space:0 ~name:""
301 stdout_metadata structptr_di;
302 (* CHECK: [[STRUCTPTR_PTR:<0x[0-9a-f]*>]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[STRUCT_PTR]], size: 192, dwarfAddressSpace: 0)
304 insist
305 ( Llvm_debuginfo.get_metadata_kind structptr_di
306 = Llvm_debuginfo.MetadataKind.DIDerivedTypeMetadataKind );
307 let enumerator1 =
308 Llvm_debuginfo.dibuild_create_enumerator dibuilder ~name:"Test_A" ~value:0
309 ~is_unsigned:true
311 stdout_metadata enumerator1;
312 (* CHECK: [[ENUMERATOR1_PTR:<0x[0-9a-f]*>]] = !DIEnumerator(name: "Test_A", value: 0, isUnsigned: true)
314 let enumerator2 =
315 Llvm_debuginfo.dibuild_create_enumerator dibuilder ~name:"Test_B" ~value:1
316 ~is_unsigned:true
318 stdout_metadata enumerator2;
319 (* CHECK: [[ENUMERATOR2_PTR:<0x[0-9a-f]*>]] = !DIEnumerator(name: "Test_B", value: 1, isUnsigned: true)
321 let enumerator3 =
322 Llvm_debuginfo.dibuild_create_enumerator dibuilder ~name:"Test_C" ~value:2
323 ~is_unsigned:true
325 insist
326 ( Llvm_debuginfo.get_metadata_kind enumerator1
327 = Llvm_debuginfo.MetadataKind.DIEnumeratorMetadataKind
328 && Llvm_debuginfo.get_metadata_kind enumerator2
329 = Llvm_debuginfo.MetadataKind.DIEnumeratorMetadataKind
330 && Llvm_debuginfo.get_metadata_kind enumerator3
331 = Llvm_debuginfo.MetadataKind.DIEnumeratorMetadataKind );
332 stdout_metadata enumerator3;
333 (* CHECK: [[ENUMERATOR3_PTR:<0x[0-9a-f]*>]] = !DIEnumerator(name: "Test_C", value: 2, isUnsigned: true)
335 let elements = [| enumerator1; enumerator2; enumerator3 |] in
336 let enumeration_ty_di =
337 Llvm_debuginfo.dibuild_create_enumeration_type dibuilder ~scope:namespace_di
338 ~name:"EnumTest" ~file:file_di ~line_number:1 ~size_in_bits:64
339 ~align_in_bits:0 ~elements ~class_ty:int64_ty_di
341 let elements_arr =
342 Llvm_debuginfo.dibuild_get_or_create_array dibuilder ~data:elements
344 stdout_metadata elements_arr;
345 (* CHECK: [[ELEMENTS_PTR:<0x[0-9a-f]*>]] = !{[[ENUMERATOR1_PTR]], [[ENUMERATOR2_PTR]], [[ENUMERATOR3_PTR]]}
347 stdout_metadata enumeration_ty_di;
348 (* CHECK: [[ENUMERATION_PTR:<0x[0-9a-f]*>]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EnumTest", scope: [[NAMESPACE_PTR]], file: [[FILE_PTR]], line: 1, baseType: [[INT64TY_PTR]], size: 64, elements: [[ELEMENTS_PTR]])
350 insist
351 ( Llvm_debuginfo.get_metadata_kind enumeration_ty_di
352 = Llvm_debuginfo.MetadataKind.DICompositeTypeMetadataKind );
353 let int32_ty_di = int_ty_di 32 dibuilder in
354 let class_mem1 =
355 Llvm_debuginfo.dibuild_create_member_type dibuilder ~scope:namespace_di
356 ~name:"Field1" ~file:file_di ~line_number:3 ~size_in_bits:32
357 ~align_in_bits:0 ~offset_in_bits:0 flags_zero ~ty:int32_ty_di
359 stdout_metadata class_mem1;
360 (* CHECK: [[MEMB1_PTR:<0x[0-9a-f]*>]] = !DIDerivedType(tag: DW_TAG_member, name: "Field1", scope: [[NAMESPACE_PTR]], file: [[FILE_PTR]], line: 3, baseType: [[INT32_PTR]], size: 32)
362 insist (Llvm_debuginfo.di_type_get_name class_mem1 = "Field1");
363 insist (Llvm_debuginfo.di_type_get_line class_mem1 = 3);
364 let class_mem2 =
365 Llvm_debuginfo.dibuild_create_member_type dibuilder ~scope:namespace_di
366 ~name:"Field2" ~file:file_di ~line_number:4 ~size_in_bits:64
367 ~align_in_bits:8 ~offset_in_bits:32 flags_zero ~ty:int64_ty_di
369 stdout_metadata class_mem2;
370 (* CHECK: [[MEMB2_PTR:<0x[0-9a-f]*>]] = !DIDerivedType(tag: DW_TAG_member, name: "Field2", scope: [[NAMESPACE_PTR]], file: [[FILE_PTR]], line: 4, baseType: [[INT64TY_PTR]], size: 64, align: 8, offset: 32)
372 insist (Llvm_debuginfo.di_type_get_offset_in_bits class_mem2 = 32);
373 insist (Llvm_debuginfo.di_type_get_size_in_bits class_mem2 = 64);
374 insist (Llvm_debuginfo.di_type_get_align_in_bits class_mem2 = 8);
375 let class_elements = [| class_mem1; class_mem2 |] in
376 insist
377 ( Llvm_debuginfo.get_metadata_kind class_mem1
378 = Llvm_debuginfo.MetadataKind.DIDerivedTypeMetadataKind
379 && Llvm_debuginfo.get_metadata_kind class_mem2
380 = Llvm_debuginfo.MetadataKind.DIDerivedTypeMetadataKind );
381 stdout_metadata
382 (Llvm_debuginfo.dibuild_get_or_create_type_array dibuilder
383 ~data:class_elements);
384 (* CHECK: [[CLASSMEM_PTRS:<0x[0-9a-f]*>]] = !{[[MEMB1_PTR]], [[MEMB2_PTR]]}
386 let classty_di =
387 Llvm_debuginfo.dibuild_create_class_type dibuilder ~scope:namespace_di
388 ~name:"MyClass" ~file:file_di ~line_number:1 ~size_in_bits:96
389 ~align_in_bits:0 ~offset_in_bits:0 flags_zero ~derived_from:null_metadata
390 ~elements:class_elements ~vtable_holder:null_metadata
391 ~template_params_node:null_metadata ~unique_identifier:"MyClass"
393 stdout_metadata classty_di;
394 (* [[CLASS_PTR:<0x[0-9a-f]*>]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass", scope: [[NAMESPACE_PTR]], file: [[FILE_PTR]], line: 1, size: 96, elements: [[CLASSMEM_PTRS]], identifier: "MyClass")
396 insist
397 ( Llvm_debuginfo.get_metadata_kind classty_di
398 = Llvm_debuginfo.MetadataKind.DICompositeTypeMetadataKind );
401 let () =
402 let m, dibuilder, file_di, m_di = test_get_module () in
403 let f, fun_di = test_get_function m dibuilder file_di m_di in
404 let () = test_bbinstr f fun_di file_di dibuilder in
405 let () = test_global_variable_expression dibuilder file_di m_di in
406 let () = test_types dibuilder file_di m_di in
407 Llvm_debuginfo.dibuild_finalize dibuilder;
408 ( match Llvm_analysis.verify_module m with
409 | Some err ->
410 prerr_endline ("Verification of module failed: " ^ err);
411 exit_status := 1
412 | None -> () );
413 exit !exit_status