authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-24 19:54:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-24 19:54:38-07:00
logc7f4cadbc77a6b85fb568e9ae8dcf210009f6f03
tree4af39db85a6da8ce719c99dc4b2d4a01f50ea3ee
parentca836191e199603056fc2c5f854f8e134f98af4d

debug symbols implemented; debugging with gdb works


2 files changed, 31 insertions(+), 9 deletions(-)

README.md-1
......@@ -40,7 +40,6 @@ readable, safe, optimal, and concise code to solve any computing problem.
4040
4141## Roadmap
4242
43 * Add debugging symbols.
4443 * Debug/Release mode.
4544 * C style comments.
4645 * Unit tests.
src/codegen.cpp+31-8
......@@ -13,6 +13,7 @@
1313
1414#include <stdio.h>
1515
16#include <llvm/IR/IRBuilder.h>
1617#include <llvm/IR/DIBuilder.h>
1718#include <llvm/IR/DiagnosticInfo.h>
1819#include <llvm/IR/DiagnosticPrinter.h>
......@@ -62,6 +63,8 @@ struct CodeGen {
6263 LLVMTargetMachineRef target_machine;
6364 Buf in_file;
6465 Buf in_dir;
66 ZigList<llvm::DIScope *> block_scopes;
67 llvm::DIFile *di_file;
6568};
6669
6770struct TypeNode {
......@@ -375,6 +378,12 @@ void semantic_analyze(CodeGen *g) {
375378
376379static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node);
377380
381static void add_debug_source_node(CodeGen *g, AstNode *node) {
382 llvm::unwrap(g->builder)->SetCurrentDebugLocation(llvm::DebugLoc::get(
383 node->line + 1, node->column + 1,
384 g->block_scopes.last()));
385}
386
378387static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
379388 assert(fn_call_node->type == NodeTypeFnCall);
380389
......@@ -403,6 +412,7 @@ static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
403412 param_values[i] = gen_expr(g, expr_node);
404413 }
405414
415 add_debug_source_node(g, fn_call_node);
406416 LLVMValueRef result = LLVMBuildCall(g->builder, fn_table_entry->fn_value,
407417 param_values, actual_param_count, "");
408418
......@@ -464,6 +474,10 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node) {
464474static void gen_block(CodeGen *g, AstNode *block_node) {
465475 assert(block_node->type == NodeTypeBlock);
466476
477 llvm::DILexicalBlock *di_block = g->dbuilder->createLexicalBlock(g->block_scopes.last(),
478 g->di_file, block_node->line + 1, block_node->column + 1);
479 g->block_scopes.append(di_block);
480
467481 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
468482 AstNode *statement_node = block_node->data.block.statements.at(i);
469483 assert(statement_node->type == NodeTypeStatement);
......@@ -472,6 +486,8 @@ static void gen_block(CodeGen *g, AstNode *block_node) {
472486 {
473487 AstNode *expr_node = statement_node->data.statement.data.retrn.expression;
474488 LLVMValueRef value = gen_expr(g, expr_node);
489
490 add_debug_source_node(g, statement_node);
475491 LLVMBuildRet(g->builder, value);
476492 break;
477493 }
......@@ -483,9 +499,13 @@ static void gen_block(CodeGen *g, AstNode *block_node) {
483499 }
484500 }
485501 }
502
503 g->block_scopes.pop();
486504}
487505
488static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto, llvm::DIFile *unit) {
506static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto,
507 llvm::DIFile *di_file)
508{
489509 llvm::SmallVector<llvm::Metadata *, 8> types;
490510
491511 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
497517 types.push_back(param_type);
498518 }
499519
500 return g->dbuilder->createSubroutineType(unit, g->dbuilder->getOrCreateTypeArray(types));
520 return g->dbuilder->createSubroutineType(di_file, g->dbuilder->getOrCreateTypeArray(types));
501521}
502522
503523void code_gen(CodeGen *g) {
......@@ -509,6 +529,10 @@ void code_gen(CodeGen *g) {
509529 buf_ptr(&g->in_file), buf_ptr(&g->in_dir),
510530 buf_ptr(producer), is_optimized, flags, runtime_version);
511531
532 g->block_scopes.append(g->compile_unit);
533
534 g->di_file = g->dbuilder->createFile(g->compile_unit->getFilename(), g->compile_unit->getDirectory());
535
512536 auto it = g->fn_defs.entry_iterator();
513537 for (;;) {
514538 auto *entry = it.next();
......@@ -540,19 +564,18 @@ void code_gen(CodeGen *g) {
540564 LLVMAddFunctionAttr(fn, LLVMNoUnwindAttribute);
541565
542566 // Add debug info.
543 llvm::DIFile *unit = g->dbuilder->createFile(g->compile_unit->getFilename(),
544 g->compile_unit->getDirectory());
545 llvm::DIScope *fn_scope = unit;
567 llvm::DIScope *fn_scope = g->di_file;
546568 unsigned line_number = fn_def_node->line + 1;
547569 unsigned scope_line = line_number;
548570 bool is_definition = true;
549571 unsigned flags = 0;
550572 llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(llvm::unwrap(fn));
551 g->dbuilder->createFunction(
552 fn_scope, buf_ptr(&fn_proto->name), "", unit, line_number,
553 create_di_function_type(g, fn_proto, unit), internal_linkage,
573 llvm::DISubprogram *subprogram = g->dbuilder->createFunction(
574 fn_scope, buf_ptr(&fn_proto->name), "", g->di_file, line_number,
575 create_di_function_type(g, fn_proto, g->di_file), internal_linkage,
554576 is_definition, scope_line, flags, is_optimized, unwrapped_function);
555577
578 g->block_scopes.append(subprogram);
556579
557580
558581 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");