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

Gets the version of debug metadata produced by the current LLVM version.

Type Definitions