mirror of
https://github.com/ziglang/zig.git
synced 2024-11-30 00:52:52 +00:00
debug symbols implemented; debugging with gdb works
This commit is contained in:
parent
ca836191e1
commit
c7f4cadbc7
@ -40,7 +40,6 @@ readable, safe, optimal, and concise code to solve any computing problem.
|
||||
|
||||
## Roadmap
|
||||
|
||||
* Add debugging symbols.
|
||||
* Debug/Release mode.
|
||||
* C style comments.
|
||||
* Unit tests.
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/DIBuilder.h>
|
||||
#include <llvm/IR/DiagnosticInfo.h>
|
||||
#include <llvm/IR/DiagnosticPrinter.h>
|
||||
@ -62,6 +63,8 @@ struct CodeGen {
|
||||
LLVMTargetMachineRef target_machine;
|
||||
Buf in_file;
|
||||
Buf in_dir;
|
||||
ZigList<llvm::DIScope *> block_scopes;
|
||||
llvm::DIFile *di_file;
|
||||
};
|
||||
|
||||
struct TypeNode {
|
||||
@ -375,6 +378,12 @@ void semantic_analyze(CodeGen *g) {
|
||||
|
||||
static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node);
|
||||
|
||||
static void add_debug_source_node(CodeGen *g, AstNode *node) {
|
||||
llvm::unwrap(g->builder)->SetCurrentDebugLocation(llvm::DebugLoc::get(
|
||||
node->line + 1, node->column + 1,
|
||||
g->block_scopes.last()));
|
||||
}
|
||||
|
||||
static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
|
||||
assert(fn_call_node->type == NodeTypeFnCall);
|
||||
|
||||
@ -403,6 +412,7 @@ static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
|
||||
param_values[i] = gen_expr(g, expr_node);
|
||||
}
|
||||
|
||||
add_debug_source_node(g, fn_call_node);
|
||||
LLVMValueRef result = LLVMBuildCall(g->builder, fn_table_entry->fn_value,
|
||||
param_values, actual_param_count, "");
|
||||
|
||||
@ -464,6 +474,10 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node) {
|
||||
static void gen_block(CodeGen *g, AstNode *block_node) {
|
||||
assert(block_node->type == NodeTypeBlock);
|
||||
|
||||
llvm::DILexicalBlock *di_block = g->dbuilder->createLexicalBlock(g->block_scopes.last(),
|
||||
g->di_file, block_node->line + 1, block_node->column + 1);
|
||||
g->block_scopes.append(di_block);
|
||||
|
||||
for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
|
||||
AstNode *statement_node = block_node->data.block.statements.at(i);
|
||||
assert(statement_node->type == NodeTypeStatement);
|
||||
@ -472,6 +486,8 @@ static void gen_block(CodeGen *g, AstNode *block_node) {
|
||||
{
|
||||
AstNode *expr_node = statement_node->data.statement.data.retrn.expression;
|
||||
LLVMValueRef value = gen_expr(g, expr_node);
|
||||
|
||||
add_debug_source_node(g, statement_node);
|
||||
LLVMBuildRet(g->builder, value);
|
||||
break;
|
||||
}
|
||||
@ -483,9 +499,13 @@ static void gen_block(CodeGen *g, AstNode *block_node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g->block_scopes.pop();
|
||||
}
|
||||
|
||||
static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto, llvm::DIFile *unit) {
|
||||
static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto,
|
||||
llvm::DIFile *di_file)
|
||||
{
|
||||
llvm::SmallVector<llvm::Metadata *, 8> types;
|
||||
|
||||
llvm::DIType *return_type = to_llvm_debug_type(fn_proto->return_type);
|
||||
@ -497,7 +517,7 @@ static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProt
|
||||
types.push_back(param_type);
|
||||
}
|
||||
|
||||
return g->dbuilder->createSubroutineType(unit, g->dbuilder->getOrCreateTypeArray(types));
|
||||
return g->dbuilder->createSubroutineType(di_file, g->dbuilder->getOrCreateTypeArray(types));
|
||||
}
|
||||
|
||||
void code_gen(CodeGen *g) {
|
||||
@ -509,6 +529,10 @@ void code_gen(CodeGen *g) {
|
||||
buf_ptr(&g->in_file), buf_ptr(&g->in_dir),
|
||||
buf_ptr(producer), is_optimized, flags, runtime_version);
|
||||
|
||||
g->block_scopes.append(g->compile_unit);
|
||||
|
||||
g->di_file = g->dbuilder->createFile(g->compile_unit->getFilename(), g->compile_unit->getDirectory());
|
||||
|
||||
auto it = g->fn_defs.entry_iterator();
|
||||
for (;;) {
|
||||
auto *entry = it.next();
|
||||
@ -540,19 +564,18 @@ void code_gen(CodeGen *g) {
|
||||
LLVMAddFunctionAttr(fn, LLVMNoUnwindAttribute);
|
||||
|
||||
// Add debug info.
|
||||
llvm::DIFile *unit = g->dbuilder->createFile(g->compile_unit->getFilename(),
|
||||
g->compile_unit->getDirectory());
|
||||
llvm::DIScope *fn_scope = unit;
|
||||
llvm::DIScope *fn_scope = g->di_file;
|
||||
unsigned line_number = fn_def_node->line + 1;
|
||||
unsigned scope_line = line_number;
|
||||
bool is_definition = true;
|
||||
unsigned flags = 0;
|
||||
llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(llvm::unwrap(fn));
|
||||
g->dbuilder->createFunction(
|
||||
fn_scope, buf_ptr(&fn_proto->name), "", unit, line_number,
|
||||
create_di_function_type(g, fn_proto, unit), internal_linkage,
|
||||
llvm::DISubprogram *subprogram = g->dbuilder->createFunction(
|
||||
fn_scope, buf_ptr(&fn_proto->name), "", g->di_file, line_number,
|
||||
create_di_function_type(g, fn_proto, g->di_file), internal_linkage,
|
||||
is_definition, scope_line, flags, is_optimized, unwrapped_function);
|
||||
|
||||
g->block_scopes.append(subprogram);
|
||||
|
||||
|
||||
LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");
|
||||
|
Loading…
Reference in New Issue
Block a user