Module inkwell::debug_info

source ·
Expand description

Debug symbols - DebugInfoBuilder interface

Example usage

Setting up the module for holding debug info:

let context = Context::create();
let module = context.create_module("bin");

let debug_metadata_version = context.i32_type().const_int(3, false);
module.add_basic_value_flag(
    "Debug Info Version",
    inkwell::module::FlagBehavior::Warning,
    debug_metadata_version,
);
let builder = context.create_builder();
let (dibuilder, compile_unit) = module.create_debug_info_builder(
    true,
    /* language */ inkwell::debug_info::DWARFSourceLanguage::C,
    /* filename */ "source_file",
    /* directory */ ".",
    /* producer */ "my llvm compiler frontend",
    /* is_optimized */ false,
    /* compiler command line flags */ "",
    /* runtime_ver */ 0,
    /* split_name */ "",
    /* kind */ inkwell::debug_info::DWARFEmissionKind::Full,
    /* dwo_id */ 0,
    /* split_debug_inling */ false,
    /* debug_info_for_profiling */ false,
);

Creating function debug info

 let ditype = dibuilder.create_basic_type(
     "type_name",
     0_u64,
     0x00,
     inkwell::debug_info::DIFlags::Public,
 ).unwrap();
 let subroutine_type = dibuilder.create_subroutine_type(
     compile_unit.get_file(),
     /* return type */ Some(ditype.as_type()),
     /* parameter types */ &[],
     inkwell::debug_info::DIFlags::Public,
 );
 let func_scope: DISubprogram<'_> = dibuilder.create_function(
     /* scope */ compile_unit.as_debug_info_scope(),
     /* func name */ "main",
     /* linkage_name */ None,
     /* file */ compile_unit.get_file(),
     /* line_no */ 0,
     /* DIType */ subroutine_type,
     /* is_local_to_unit */ true,
     /* is_definition */ true,
     /* scope_line */ 0,
     /* flags */ inkwell::debug_info::DIFlags::Public,
     /* is_optimized */ false,
 );

The DISubprogram value must be attached to the generated FunctionValue:

/* after creating function: */
    let fn_val = module.add_function(fn_name_str, fn_type, None);
    fn_val.set_subprogram(func_scope);

Setting debug locations

let lexical_block = dibuilder.create_lexical_block(
        /* scope */ func_scope.as_debug_info_scope(),
        /* file */ compile_unit.get_file(),
        /* line_no */ 0,
        /* column_no */ 0);

let loc = dibuilder
    .create_debug_location(&context, /* line */ 0, /* column */ 0,
    /* current_scope */ lexical_block.as_debug_info_scope(),
    /* inlined_at */ None);
builder.set_current_debug_location(&context, loc);

// Create global variable
let gv = module.add_global(context.i64_type(), Some(inkwell::AddressSpace::Global), "gv");


let const_v = di.create_constant_expression(10);

let gv_debug = di.create_global_variable_expression(cu.get_file().as_debug_info_scope(), "gv", "", cu.get_file(), 1, ditype.as_type(), true, Some(const_v), None, 8);

let meta_value: inkwell::values::BasicMetadataValueEnum = gv_debug.as_metadata_value(&context).into();
let metadata = context.metadata_node(&[meta_value]);
gv.set_metadata(metadata, 0);//dbg

Finalize debug info

Before any kind of code generation (including verification passes; they generate code and validate debug info), do:

dibuilder.finalize();

Structs

  • A primitive debug info type created by create_basic_type method of DebugInfoBuilder
  • Compilation unit scope for debug info
  • A wrapper around an array of types, such as a union or struct.
  • A wrapper around a single type, such as a typedef or member type.
  • https://llvm.org/docs/LangRef.html#diexpression
  • Source file scope for debug info
  • Lexical block scope for debug info
  • Metadata representing a variable inside a scope
  • A debug location within the source code. Contains the following information:
  • Namespace scope for debug info
  • Any kind of debug information scope (i.e. visibility of a source code symbol). Scopes are created by special DebugInfoBuilder methods (eg create_lexical_block) and can be turned into a DIScope with the AsDIScope::as_debug_info_scope trait method.
  • Function body scope for debug info
  • Metadata representing the type of a function
  • Any kind of debug info type
  • A builder object to create debug info metadata. Used along with Builder while producing IR. Created by Module::create_debug_info_builder. See debug_info module level documentation for more.

Enums

  • The amount of debug information to emit. Corresponds to LLVMDWARFEmissionKind enum from LLVM.
  • Source languages known by DWARF. Corresponds to LLVMDWARFSourceLanguage enum from LLVM.

Traits

  • Specific scopes (i.e. DILexicalBlock) can be turned into a DIScope with the AsDIScope::as_debug_info_scope trait method.

Functions

Type Aliases