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....@@ -40,7 +40,6 @@ readable, safe, optimal, and concise code to solve any computing problem.
4040
41## Roadmap41## Roadmap
4242
43 * Add debugging symbols.
44 * Debug/Release mode.43 * Debug/Release mode.
45 * C style comments.44 * C style comments.
46 * Unit tests.45 * Unit tests.
src/codegen.cpp+31-8
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
1313
14#include <stdio.h>14#include <stdio.h>
1515
16#include <llvm/IR/IRBuilder.h>
16#include <llvm/IR/DIBuilder.h>17#include <llvm/IR/DIBuilder.h>
17#include <llvm/IR/DiagnosticInfo.h>18#include <llvm/IR/DiagnosticInfo.h>
18#include <llvm/IR/DiagnosticPrinter.h>19#include <llvm/IR/DiagnosticPrinter.h>
...@@ -62,6 +63,8 @@ struct CodeGen {...@@ -62,6 +63,8 @@ struct CodeGen {
62 LLVMTargetMachineRef target_machine;63 LLVMTargetMachineRef target_machine;
63 Buf in_file;64 Buf in_file;
64 Buf in_dir;65 Buf in_dir;
66 ZigList<llvm::DIScope *> block_scopes;
67 llvm::DIFile *di_file;
65};68};
6669
67struct TypeNode {70struct TypeNode {
...@@ -375,6 +378,12 @@ void semantic_analyze(CodeGen *g) {...@@ -375,6 +378,12 @@ void semantic_analyze(CodeGen *g) {
375378
376static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node);379static 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
378static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {387static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
379 assert(fn_call_node->type == NodeTypeFnCall);388 assert(fn_call_node->type == NodeTypeFnCall);
380389
...@@ -403,6 +412,7 @@ static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {...@@ -403,6 +412,7 @@ static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
403 param_values[i] = gen_expr(g, expr_node);412 param_values[i] = gen_expr(g, expr_node);
404 }413 }
405414
415 add_debug_source_node(g, fn_call_node);
406 LLVMValueRef result = LLVMBuildCall(g->builder, fn_table_entry->fn_value,416 LLVMValueRef result = LLVMBuildCall(g->builder, fn_table_entry->fn_value,
407 param_values, actual_param_count, "");417 param_values, actual_param_count, "");
408418
...@@ -464,6 +474,10 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node) {...@@ -464,6 +474,10 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node) {
464static void gen_block(CodeGen *g, AstNode *block_node) {474static void gen_block(CodeGen *g, AstNode *block_node) {
465 assert(block_node->type == NodeTypeBlock);475 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
467 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {481 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
468 AstNode *statement_node = block_node->data.block.statements.at(i);482 AstNode *statement_node = block_node->data.block.statements.at(i);
469 assert(statement_node->type == NodeTypeStatement);483 assert(statement_node->type == NodeTypeStatement);
...@@ -472,6 +486,8 @@ static void gen_block(CodeGen *g, AstNode *block_node) {...@@ -472,6 +486,8 @@ static void gen_block(CodeGen *g, AstNode *block_node) {
472 {486 {
473 AstNode *expr_node = statement_node->data.statement.data.retrn.expression;487 AstNode *expr_node = statement_node->data.statement.data.retrn.expression;
474 LLVMValueRef value = gen_expr(g, expr_node);488 LLVMValueRef value = gen_expr(g, expr_node);
489
490 add_debug_source_node(g, statement_node);
475 LLVMBuildRet(g->builder, value);491 LLVMBuildRet(g->builder, value);
476 break;492 break;
477 }493 }
...@@ -483,9 +499,13 @@ static void gen_block(CodeGen *g, AstNode *block_node) {...@@ -483,9 +499,13 @@ static void gen_block(CodeGen *g, AstNode *block_node) {
483 }499 }
484 }500 }
485 }501 }
502
503 g->block_scopes.pop();
486}504}
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{
489 llvm::SmallVector<llvm::Metadata *, 8> types;509 llvm::SmallVector<llvm::Metadata *, 8> types;
490510
491 llvm::DIType *return_type = to_llvm_debug_type(fn_proto->return_type);511 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...@@ -497,7 +517,7 @@ static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProt
497 types.push_back(param_type);517 types.push_back(param_type);
498 }518 }
499519
500 return g->dbuilder->createSubroutineType(unit, g->dbuilder->getOrCreateTypeArray(types));520 return g->dbuilder->createSubroutineType(di_file, g->dbuilder->getOrCreateTypeArray(types));
501}521}
502522
503void code_gen(CodeGen *g) {523void code_gen(CodeGen *g) {
...@@ -509,6 +529,10 @@ void code_gen(CodeGen *g) {...@@ -509,6 +529,10 @@ void code_gen(CodeGen *g) {
509 buf_ptr(&g->in_file), buf_ptr(&g->in_dir),529 buf_ptr(&g->in_file), buf_ptr(&g->in_dir),
510 buf_ptr(producer), is_optimized, flags, runtime_version);530 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
512 auto it = g->fn_defs.entry_iterator();536 auto it = g->fn_defs.entry_iterator();
513 for (;;) {537 for (;;) {
514 auto *entry = it.next();538 auto *entry = it.next();
...@@ -540,19 +564,18 @@ void code_gen(CodeGen *g) {...@@ -540,19 +564,18 @@ void code_gen(CodeGen *g) {
540 LLVMAddFunctionAttr(fn, LLVMNoUnwindAttribute);564 LLVMAddFunctionAttr(fn, LLVMNoUnwindAttribute);
541565
542 // Add debug info.566 // Add debug info.
543 llvm::DIFile *unit = g->dbuilder->createFile(g->compile_unit->getFilename(),567 llvm::DIScope *fn_scope = g->di_file;
544 g->compile_unit->getDirectory());
545 llvm::DIScope *fn_scope = unit;
546 unsigned line_number = fn_def_node->line + 1;568 unsigned line_number = fn_def_node->line + 1;
547 unsigned scope_line = line_number;569 unsigned scope_line = line_number;
548 bool is_definition = true;570 bool is_definition = true;
549 unsigned flags = 0;571 unsigned flags = 0;
550 llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(llvm::unwrap(fn));572 llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(llvm::unwrap(fn));
551 g->dbuilder->createFunction(573 llvm::DISubprogram *subprogram = g->dbuilder->createFunction(
552 fn_scope, buf_ptr(&fn_proto->name), "", unit, line_number,574 fn_scope, buf_ptr(&fn_proto->name), "", g->di_file, line_number,
553 create_di_function_type(g, fn_proto, unit), internal_linkage, 575 create_di_function_type(g, fn_proto, g->di_file), internal_linkage,
554 is_definition, scope_line, flags, is_optimized, unwrapped_function);576 is_definition, scope_line, flags, is_optimized, unwrapped_function);
555577
578 g->block_scopes.append(subprogram);
556579
557580
558 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");581 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");