1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
|
(* RUN: rm -rf %t && mkdir -p %t && cp %s %t/debuginfo.ml && cp %S/Utils/Testsuite.ml %t/Testsuite.ml
* 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
* RUN: %t/executable | FileCheck %s
* 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
* RUN: %t/executable | FileCheck %s
* XFAIL: vg_leak
*)
open Testsuite
let context = Llvm.global_context ()
let filename = "di_test_file"
let directory = "di_test_dir"
let module_name = "di_test_module"
let null_metadata = Llvm_debuginfo.llmetadata_null ()
let string_of_metadata md =
Llvm.string_of_llvalue (Llvm.metadata_as_value context md)
let stdout_metadata md = Printf.printf "%s\n" (string_of_metadata md)
let prepare_target llmod =
Llvm_all_backends.initialize ();
let triple = Llvm_target.Target.default_triple () in
let lltarget = Llvm_target.Target.by_triple triple in
let llmachine = Llvm_target.TargetMachine.create ~triple lltarget in
let lldly =
Llvm_target.DataLayout.as_string
(Llvm_target.TargetMachine.data_layout llmachine)
in
let _ = Llvm.set_target_triple triple llmod in
let _ = Llvm.set_data_layout lldly llmod in
()
let new_module () =
let m = Llvm.create_module context module_name in
let () = prepare_target m in
m
let test_get_module () =
group "module_level_tests";
let m = new_module () in
let cur_ver = Llvm_debuginfo.debug_metadata_version () in
insist (cur_ver > 0);
let m_ver = Llvm_debuginfo.get_module_debug_metadata_version m in
(* We haven't added any debug info to the module *)
insist (m_ver = 0);
let dibuilder = Llvm_debuginfo.dibuilder m in
let di_version_key = "Debug Info Version" in
let ver =
Llvm.value_as_metadata @@ Llvm.const_int (Llvm.i32_type context) cur_ver
in
let () =
Llvm.add_module_flag m Llvm.ModuleFlagBehavior.Warning di_version_key ver
in
let file_di =
Llvm_debuginfo.dibuild_create_file dibuilder ~filename ~directory
in
stdout_metadata file_di;
(* CHECK: [[FILE_PTR:<0x[0-9a-f]*>]] = !DIFile(filename: "di_test_file", directory: "di_test_dir")
*)
insist
( Llvm_debuginfo.di_file_get_filename ~file:file_di = filename
&& Llvm_debuginfo.di_file_get_directory ~file:file_di = directory );
insist
( Llvm_debuginfo.get_metadata_kind file_di
= Llvm_debuginfo.MetadataKind.DIFileMetadataKind );
let cu_di =
Llvm_debuginfo.dibuild_create_compile_unit dibuilder
Llvm_debuginfo.DWARFSourceLanguageKind.C89 ~file_ref:file_di
~producer:"TestGen" ~is_optimized:false ~flags:"" ~runtime_ver:0
~split_name:"" Llvm_debuginfo.DWARFEmissionKind.LineTablesOnly ~dwoid:0
~di_inlining:false ~di_profiling:false ~sys_root:"" ~sdk:""
in
stdout_metadata cu_di;
(* 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)
*)
insist
( Llvm_debuginfo.get_metadata_kind cu_di
= Llvm_debuginfo.MetadataKind.DICompileUnitMetadataKind );
let m_di =
Llvm_debuginfo.dibuild_create_module dibuilder ~parent_ref:cu_di
~name:module_name ~config_macros:"" ~include_path:"" ~sys_root:""
in
insist
( Llvm_debuginfo.get_metadata_kind m_di
= Llvm_debuginfo.MetadataKind.DIModuleMetadataKind );
insist (Llvm_debuginfo.get_module_debug_metadata_version m = cur_ver);
stdout_metadata m_di;
(* CHECK: [[MODULE_PTR:<0x[0-9a-f]*>]] = !DIModule(scope: null, name: "di_test_module")
*)
(m, dibuilder, file_di, m_di)
let flags_zero = Llvm_debuginfo.diflags_get Llvm_debuginfo.DIFlag.Zero
let int_ty_di bits dibuilder =
Llvm_debuginfo.dibuild_create_basic_type dibuilder ~name:"int"
~size_in_bits:bits ~encoding:0x05
(* llvm::dwarf::DW_ATE_signed *) flags_zero
let test_get_function m dibuilder file_di m_di =
group "function_level_tests";
(* Create a function of type "void foo (int)". *)
let int_ty_di = int_ty_di 32 dibuilder in
stdout_metadata int_ty_di;
(* CHECK: [[INT32_PTR:<0x[0-9a-f]*>]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
*)
let param_types = [| null_metadata; int_ty_di |] in
let fty_di =
Llvm_debuginfo.dibuild_create_subroutine_type dibuilder ~file:file_di
~param_types flags_zero
in
insist
( Llvm_debuginfo.get_metadata_kind fty_di
= Llvm_debuginfo.MetadataKind.DISubroutineTypeMetadataKind );
(* To be able to print and verify the type array of the subroutine type,
* since we have no way to access it from fty_di, we build it again. *)
let fty_di_args =
Llvm_debuginfo.dibuild_get_or_create_type_array dibuilder ~data:param_types
in
stdout_metadata fty_di_args;
(* CHECK: [[FARGS_PTR:<0x[0-9a-f]*>]] = !{null, [[INT32_PTR]]}
*)
stdout_metadata fty_di;
(* CHECK: [[SBRTNTY_PTR:<0x[0-9a-f]*>]] = !DISubroutineType(types: [[FARGS_PTR]])
*)
(* Let's create the LLVM-IR function now. *)
let name = "tfun" in
let fty =
Llvm.function_type (Llvm.void_type context) [| Llvm.i32_type context |]
in
let f = Llvm.define_function name fty m in
let f_di =
Llvm_debuginfo.dibuild_create_function dibuilder ~scope:m_di ~name
~linkage_name:name ~file:file_di ~line_no:10 ~ty:fty_di
~is_local_to_unit:false ~is_definition:true ~scope_line:10
~flags:flags_zero ~is_optimized:false
in
stdout_metadata f_di;
(* 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]])
*)
Llvm_debuginfo.set_subprogram f f_di;
( match Llvm_debuginfo.get_subprogram f with
| Some f_di' -> insist (f_di = f_di')
| None -> insist false );
insist
( Llvm_debuginfo.get_metadata_kind f_di
= Llvm_debuginfo.MetadataKind.DISubprogramMetadataKind );
insist (Llvm_debuginfo.di_subprogram_get_line f_di = 10);
(fty, f, f_di)
let test_bbinstr fty f f_di file_di dibuilder =
group "basic_block and instructions tests";
(* Create this pattern:
* if (arg0 != 0) {
* foo(arg0);
* }
* return;
*)
let arg0 = (Llvm.params f).(0) in
let builder = Llvm.builder_at_end context (Llvm.entry_block f) in
let zero = Llvm.const_int (Llvm.i32_type context) 0 in
let cmpi = Llvm.build_icmp Llvm.Icmp.Ne zero arg0 "cmpi" builder in
let truebb = Llvm.append_block context "truebb" f in
let falsebb = Llvm.append_block context "falsebb" f in
let _ = Llvm.build_cond_br cmpi truebb falsebb builder in
let foodecl = Llvm.declare_function "foo" fty (Llvm.global_parent f) in
let _ =
Llvm.position_at_end truebb builder;
let scope =
Llvm_debuginfo.dibuild_create_lexical_block dibuilder ~scope:f_di
~file:file_di ~line:9 ~column:4
in
let file_of_f_di = Llvm_debuginfo.di_scope_get_file ~scope:f_di in
let file_of_scope = Llvm_debuginfo.di_scope_get_file ~scope in
insist
( match (file_of_f_di, file_of_scope) with
| Some file_of_f_di', Some file_of_scope' ->
file_of_f_di' = file_di && file_of_scope' = file_di
| _ -> false );
let foocall = Llvm.build_call fty foodecl [| arg0 |] "" builder in
let foocall_loc =
Llvm_debuginfo.dibuild_create_debug_location context ~line:10 ~column:12
~scope
in
Llvm_debuginfo.instr_set_debug_loc foocall (Some foocall_loc);
insist
( match Llvm_debuginfo.instr_get_debug_loc foocall with
| Some foocall_loc' -> foocall_loc' = foocall_loc
| None -> false );
stdout_metadata scope;
(* CHECK: [[BLOCK_PTR:<0x[0-9a-f]*>]] = distinct !DILexicalBlock(scope: [[SBPRG_PTR]], file: [[FILE_PTR]], line: 9, column: 4)
*)
stdout_metadata foocall_loc;
(* CHECK: !DILocation(line: 10, column: 12, scope: [[BLOCK_PTR]])
*)
insist
( Llvm_debuginfo.di_location_get_scope ~location:foocall_loc = scope
&& Llvm_debuginfo.di_location_get_line ~location:foocall_loc = 10
&& Llvm_debuginfo.di_location_get_column ~location:foocall_loc = 12 );
insist
( Llvm_debuginfo.get_metadata_kind foocall_loc
= Llvm_debuginfo.MetadataKind.DILocationMetadataKind
&& Llvm_debuginfo.get_metadata_kind scope
= Llvm_debuginfo.MetadataKind.DILexicalBlockMetadataKind );
Llvm.build_br falsebb builder
in
let _ =
Llvm.position_at_end falsebb builder;
Llvm.build_ret_void builder
in
(* Printf.printf "%s\n" (Llvm.string_of_llmodule (Llvm.global_parent f)); *)
()
let test_global_variable_expression dibuilder f_di m_di =
group "global variable expression tests";
let cexpr_di =
Llvm_debuginfo.dibuild_create_constant_value_expression dibuilder 0
in
stdout_metadata cexpr_di;
(* CHECK: [[DICEXPR:!DIExpression\(DW_OP_constu, 0, DW_OP_stack_value\)]]
*)
insist
( Llvm_debuginfo.get_metadata_kind cexpr_di
= Llvm_debuginfo.MetadataKind.DIExpressionMetadataKind );
let ty = int_ty_di 64 dibuilder in
stdout_metadata ty;
(* CHECK: [[INT64TY_PTR:<0x[0-9a-f]*>]] = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed)
*)
let gvexpr_di =
Llvm_debuginfo.dibuild_create_global_variable_expression dibuilder
~scope:m_di ~name:"my_global" ~linkage:"" ~file:f_di ~line:5 ~ty
~is_local_to_unit:true ~expr:cexpr_di ~decl:null_metadata ~align_in_bits:0
in
insist
( Llvm_debuginfo.get_metadata_kind gvexpr_di
= Llvm_debuginfo.MetadataKind.DIGlobalVariableExpressionMetadataKind );
( match
Llvm_debuginfo.di_global_variable_expression_get_variable gvexpr_di
with
| Some gvexpr_var_di ->
insist
( Llvm_debuginfo.get_metadata_kind gvexpr_var_di
= Llvm_debuginfo.MetadataKind.DIGlobalVariableMetadataKind );
stdout_metadata gvexpr_var_di
(* 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)
*)
| None -> insist false );
stdout_metadata gvexpr_di;
(* CHECK: [[GVEXP_PTR:<0x[0-9a-f]*>]] = !DIGlobalVariableExpression(var: [[GV_PTR]], expr: [[DICEXPR]])
*)
()
let test_variables f dibuilder file_di fun_di =
let entry_term = Option.get @@ (Llvm.block_terminator (Llvm.entry_block f)) in
group "Local and parameter variable tests";
let ty = int_ty_di 64 dibuilder in
stdout_metadata ty;
(* CHECK: [[INT64TY_PTR:<0x[0-9a-f]*>]] = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed)
*)
let auto_var =
Llvm_debuginfo.dibuild_create_auto_variable dibuilder ~scope:fun_di
~name:"my_local" ~file:file_di ~line:10 ~ty
~always_preserve:false flags_zero ~align_in_bits:0
in
stdout_metadata auto_var;
(* CHECK: [[LOCAL_VAR_PTR:<0x[0-9a-f]*>]] = !DILocalVariable(name: "my_local", scope: <{{0x[0-9a-f]*}}>, file: <{{0x[0-9a-f]*}}>, line: 10, type: [[INT64TY_PTR]])
*)
let builder = Llvm.builder_before context entry_term in
let all = Llvm.build_alloca (Llvm.i64_type context) "my_alloca" builder in
let scope =
Llvm_debuginfo.dibuild_create_lexical_block dibuilder ~scope:fun_di
~file:file_di ~line:9 ~column:4
in
let location =
Llvm_debuginfo.dibuild_create_debug_location
context ~line:10 ~column:12 ~scope
in
let vdi = Llvm_debuginfo.dibuild_insert_declare_before dibuilder ~storage:all
~var_info:auto_var ~expr:(Llvm_debuginfo.dibuild_expression dibuilder [||])
~location ~instr:entry_term
in
let () = Printf.printf "%s\n" (Llvm.string_of_llvalue vdi) in
(* CHECK: call void @llvm.dbg.declare(metadata ptr %my_alloca, metadata {{![0-9]+}}, metadata !DIExpression()), !dbg {{\![0-9]+}}
*)
let arg0 = (Llvm.params f).(0) in
let arg_var = Llvm_debuginfo.dibuild_create_parameter_variable dibuilder ~scope:fun_di
~name:"my_arg" ~argno:1 ~file:file_di ~line:10 ~ty
~always_preserve:false flags_zero
in
let argdi = Llvm_debuginfo.dibuild_insert_declare_before dibuilder ~storage:arg0
~var_info:arg_var ~expr:(Llvm_debuginfo.dibuild_expression dibuilder [||])
~location ~instr:entry_term
in
let () = Printf.printf "%s\n" (Llvm.string_of_llvalue argdi) in
(* CHECK: call void @llvm.dbg.declare(metadata i32 %0, metadata {{![0-9]+}}, metadata !DIExpression()), !dbg {{\![0-9]+}}
*)
()
let test_types dibuilder file_di m_di =
group "type tests";
let namespace_di =
Llvm_debuginfo.dibuild_create_namespace dibuilder ~parent_ref:m_di
~name:"NameSpace1" ~export_symbols:false
in
stdout_metadata namespace_di;
(* CHECK: [[NAMESPACE_PTR:<0x[0-9a-f]*>]] = !DINamespace(name: "NameSpace1", scope: [[MODULE_PTR]])
*)
let int64_ty_di = int_ty_di 64 dibuilder in
let structty_args = [| int64_ty_di; int64_ty_di; int64_ty_di |] in
let struct_ty_di =
Llvm_debuginfo.dibuild_create_struct_type dibuilder ~scope:namespace_di
~name:"StructType1" ~file:file_di ~line_number:20 ~size_in_bits:192
~align_in_bits:0 flags_zero ~derived_from:null_metadata
~elements:structty_args Llvm_debuginfo.DWARFSourceLanguageKind.C89
~vtable_holder:null_metadata ~unique_id:"StructType1"
in
(* Since there's no way to fetch the element types which is now
* a type array, we build that again for checking. *)
let structty_di_eltypes =
Llvm_debuginfo.dibuild_get_or_create_type_array dibuilder
~data:structty_args
in
stdout_metadata structty_di_eltypes;
(* CHECK: [[STRUCTELT_PTR:<0x[0-9a-f]*>]] = !{[[INT64TY_PTR]], [[INT64TY_PTR]], [[INT64TY_PTR]]}
*)
stdout_metadata struct_ty_di;
(* 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")
*)
insist
( Llvm_debuginfo.get_metadata_kind struct_ty_di
= Llvm_debuginfo.MetadataKind.DICompositeTypeMetadataKind );
let structptr_di =
Llvm_debuginfo.dibuild_create_pointer_type dibuilder
~pointee_ty:struct_ty_di ~size_in_bits:192 ~align_in_bits:0
~address_space:0 ~name:""
in
stdout_metadata structptr_di;
(* CHECK: [[STRUCTPTR_PTR:<0x[0-9a-f]*>]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[STRUCT_PTR]], size: 192, dwarfAddressSpace: 0)
*)
insist
( Llvm_debuginfo.get_metadata_kind structptr_di
= Llvm_debuginfo.MetadataKind.DIDerivedTypeMetadataKind );
let enumerator1 =
Llvm_debuginfo.dibuild_create_enumerator dibuilder ~name:"Test_A" ~value:0
~is_unsigned:true
in
stdout_metadata enumerator1;
(* CHECK: [[ENUMERATOR1_PTR:<0x[0-9a-f]*>]] = !DIEnumerator(name: "Test_A", value: 0, isUnsigned: true)
*)
let enumerator2 =
Llvm_debuginfo.dibuild_create_enumerator dibuilder ~name:"Test_B" ~value:1
~is_unsigned:true
in
stdout_metadata enumerator2;
(* CHECK: [[ENUMERATOR2_PTR:<0x[0-9a-f]*>]] = !DIEnumerator(name: "Test_B", value: 1, isUnsigned: true)
*)
let enumerator3 =
Llvm_debuginfo.dibuild_create_enumerator dibuilder ~name:"Test_C" ~value:2
~is_unsigned:true
in
insist
( Llvm_debuginfo.get_metadata_kind enumerator1
= Llvm_debuginfo.MetadataKind.DIEnumeratorMetadataKind
&& Llvm_debuginfo.get_metadata_kind enumerator2
= Llvm_debuginfo.MetadataKind.DIEnumeratorMetadataKind
&& Llvm_debuginfo.get_metadata_kind enumerator3
= Llvm_debuginfo.MetadataKind.DIEnumeratorMetadataKind );
stdout_metadata enumerator3;
(* CHECK: [[ENUMERATOR3_PTR:<0x[0-9a-f]*>]] = !DIEnumerator(name: "Test_C", value: 2, isUnsigned: true)
*)
let elements = [| enumerator1; enumerator2; enumerator3 |] in
let enumeration_ty_di =
Llvm_debuginfo.dibuild_create_enumeration_type dibuilder ~scope:namespace_di
~name:"EnumTest" ~file:file_di ~line_number:1 ~size_in_bits:64
~align_in_bits:0 ~elements ~class_ty:int64_ty_di
in
let elements_arr =
Llvm_debuginfo.dibuild_get_or_create_array dibuilder ~data:elements
in
stdout_metadata elements_arr;
(* CHECK: [[ELEMENTS_PTR:<0x[0-9a-f]*>]] = !{[[ENUMERATOR1_PTR]], [[ENUMERATOR2_PTR]], [[ENUMERATOR3_PTR]]}
*)
stdout_metadata enumeration_ty_di;
(* 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]])
*)
insist
( Llvm_debuginfo.get_metadata_kind enumeration_ty_di
= Llvm_debuginfo.MetadataKind.DICompositeTypeMetadataKind );
let int32_ty_di = int_ty_di 32 dibuilder in
let class_mem1 =
Llvm_debuginfo.dibuild_create_member_type dibuilder ~scope:namespace_di
~name:"Field1" ~file:file_di ~line_number:3 ~size_in_bits:32
~align_in_bits:0 ~offset_in_bits:0 flags_zero ~ty:int32_ty_di
in
stdout_metadata class_mem1;
(* 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)
*)
insist (Llvm_debuginfo.di_type_get_name class_mem1 = "Field1");
insist (Llvm_debuginfo.di_type_get_line class_mem1 = 3);
let class_mem2 =
Llvm_debuginfo.dibuild_create_member_type dibuilder ~scope:namespace_di
~name:"Field2" ~file:file_di ~line_number:4 ~size_in_bits:64
~align_in_bits:8 ~offset_in_bits:32 flags_zero ~ty:int64_ty_di
in
stdout_metadata class_mem2;
(* 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)
*)
insist (Llvm_debuginfo.di_type_get_offset_in_bits class_mem2 = 32);
insist (Llvm_debuginfo.di_type_get_size_in_bits class_mem2 = 64);
insist (Llvm_debuginfo.di_type_get_align_in_bits class_mem2 = 8);
let class_elements = [| class_mem1; class_mem2 |] in
insist
( Llvm_debuginfo.get_metadata_kind class_mem1
= Llvm_debuginfo.MetadataKind.DIDerivedTypeMetadataKind
&& Llvm_debuginfo.get_metadata_kind class_mem2
= Llvm_debuginfo.MetadataKind.DIDerivedTypeMetadataKind );
stdout_metadata
(Llvm_debuginfo.dibuild_get_or_create_type_array dibuilder
~data:class_elements);
(* CHECK: [[CLASSMEM_PTRS:<0x[0-9a-f]*>]] = !{[[MEMB1_PTR]], [[MEMB2_PTR]]}
*)
let classty_di =
Llvm_debuginfo.dibuild_create_class_type dibuilder ~scope:namespace_di
~name:"MyClass" ~file:file_di ~line_number:1 ~size_in_bits:96
~align_in_bits:0 ~offset_in_bits:0 flags_zero ~derived_from:null_metadata
~elements:class_elements ~vtable_holder:null_metadata
~template_params_node:null_metadata ~unique_identifier:"MyClass"
in
stdout_metadata classty_di;
(* [[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")
*)
insist
( Llvm_debuginfo.get_metadata_kind classty_di
= Llvm_debuginfo.MetadataKind.DICompositeTypeMetadataKind );
()
let () =
let m, dibuilder, file_di, m_di = test_get_module () in
let fty, f, fun_di = test_get_function m dibuilder file_di m_di in
let () = test_bbinstr fty f fun_di file_di dibuilder in
let () = test_global_variable_expression dibuilder file_di m_di in
let () = test_variables f dibuilder file_di fun_di in
let () = test_types dibuilder file_di m_di in
Llvm_debuginfo.dibuild_finalize dibuilder;
( match Llvm_analysis.verify_module m with
| Some err ->
prerr_endline ("Verification of module failed: " ^ err);
exit_status := 1
| None -> () );
exit !exit_status
|