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