authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-07 22:11:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-07 22:11:04-07:00
log9c9ea935191190471c1b2fd30c8cffde74421456
treefe709fbb92cb58cc6027883e37fe55a7cb916798
parent1279fe0caaa83dd9f573dfe3c359098143224abc

integrate debug scopes with block context


5 files changed, 80 insertions(+), 42 deletions(-)

src/analyze.cpp+4-8
...@@ -443,10 +443,13 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -443,10 +443,13 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
443 TypeTableEntry *expected_type, AstNode *node)443 TypeTableEntry *expected_type, AstNode *node)
444{444{
445 TypeTableEntry *return_type = nullptr;445 TypeTableEntry *return_type = nullptr;
446 assert(!node->codegen_node);
447 node->codegen_node = allocate<CodeGenNode>(1);
446 switch (node->type) {448 switch (node->type) {
447 case NodeTypeBlock:449 case NodeTypeBlock:
448 {450 {
449 BlockContext *child_context = new_block_context(node, context);451 BlockContext *child_context = new_block_context(node, context);
452 node->codegen_node->data.block_node.block_context = child_context;
450 return_type = g->builtin_types.entry_void;453 return_type = g->builtin_types.entry_void;
451 for (int i = 0; i < node->data.block.statements.length; i += 1) {454 for (int i = 0; i < node->data.block.statements.length; i += 1) {
452 AstNode *child = node->data.block.statements.at(i);455 AstNode *child = node->data.block.statements.at(i);
...@@ -538,8 +541,6 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -538,8 +541,6 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
538 FnTableEntry *fn_table_entry = get_context_fn_entry(context);541 FnTableEntry *fn_table_entry = get_context_fn_entry(context);
539 auto table_entry = fn_table_entry->label_table.maybe_get(&node->data.go_to.name);542 auto table_entry = fn_table_entry->label_table.maybe_get(&node->data.go_to.name);
540 if (table_entry) {543 if (table_entry) {
541 assert(!node->codegen_node);
542 node->codegen_node = allocate<CodeGenNode>(1);
543 node->codegen_node->data.label_entry = table_entry->value;544 node->codegen_node->data.label_entry = table_entry->value;
544 table_entry->value->used = true;545 table_entry->value->used = true;
545 } else {546 } else {
...@@ -792,12 +793,6 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -792,12 +793,6 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
792 assert(return_type);793 assert(return_type);
793 check_type_compatibility(g, node, expected_type, return_type);794 check_type_compatibility(g, node, expected_type, return_type);
794795
795 if (node->codegen_node) {
796 assert(node->type == NodeTypeGoto);
797 } else {
798 assert(node->type != NodeTypeGoto);
799 node->codegen_node = allocate<CodeGenNode>(1);
800 }
801 node->codegen_node->expr_node.type_entry = return_type;796 node->codegen_node->expr_node.type_entry = return_type;
802 node->codegen_node->expr_node.block_context = context;797 node->codegen_node->expr_node.block_context = context;
803798
...@@ -837,6 +832,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -837,6 +832,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
837 variable_entry->type = type;832 variable_entry->type = type;
838 variable_entry->is_const = true;833 variable_entry->is_const = true;
839 variable_entry->decl_node = param_decl_node;834 variable_entry->decl_node = param_decl_node;
835 variable_entry->arg_index = i;
840836
841 LocalVariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);837 LocalVariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);
842 if (!existing_entry) {838 if (!existing_entry) {
src/codegen.cpp+33-23
...@@ -102,8 +102,8 @@ static int count_non_void_params(CodeGen *g, ZigList<AstNode *> *params) {...@@ -102,8 +102,8 @@ static int count_non_void_params(CodeGen *g, ZigList<AstNode *> *params) {
102}102}
103103
104static void add_debug_source_node(CodeGen *g, AstNode *node) {104static void add_debug_source_node(CodeGen *g, AstNode *node) {
105 // TODO g->block_scopes.last() is not always correct and should probably integrate with BlockContext105 LLVMZigSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1,
106 LLVMZigSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, g->block_scopes.last());106 g->cur_block_context->di_scope);
107}107}
108108
109static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) {109static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) {
...@@ -484,13 +484,7 @@ static LLVMValueRef gen_if_expr(CodeGen *g, AstNode *node) {...@@ -484,13 +484,7 @@ static LLVMValueRef gen_if_expr(CodeGen *g, AstNode *node) {
484static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) {484static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) {
485 assert(block_node->type == NodeTypeBlock);485 assert(block_node->type == NodeTypeBlock);
486486
487 ImportTableEntry *import = g->cur_fn->import_entry;487 g->cur_block_context = block_node->codegen_node->data.block_node.block_context;
488
489 LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder, g->block_scopes.last(),
490 import->di_file, block_node->line + 1, block_node->column + 1);
491 g->block_scopes.append(LLVMZigLexicalBlockToScope(di_block));
492
493 add_debug_source_node(g, block_node);
494488
495 LLVMValueRef return_value;489 LLVMValueRef return_value;
496 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {490 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
...@@ -506,8 +500,6 @@ static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *i...@@ -506,8 +500,6 @@ static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *i
506 }500 }
507 }501 }
508502
509 g->block_scopes.pop();
510
511 return return_value;503 return return_value;
512}504}
513505
...@@ -654,9 +646,6 @@ static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnPro...@@ -654,9 +646,6 @@ static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnPro
654static void do_code_gen(CodeGen *g) {646static void do_code_gen(CodeGen *g) {
655 assert(!g->errors.length);647 assert(!g->errors.length);
656648
657 g->block_scopes.append(LLVMZigCompileUnitToScope(g->compile_unit));
658
659
660 // Generate function prototypes649 // Generate function prototypes
661 for (int i = 0; i < g->fn_protos.length; i += 1) {650 for (int i = 0; i < g->fn_protos.length; i += 1) {
662 FnTableEntry *fn_table_entry = g->fn_protos.at(i);651 FnTableEntry *fn_table_entry = g->fn_protos.at(i);
...@@ -718,8 +707,6 @@ static void do_code_gen(CodeGen *g) {...@@ -718,8 +707,6 @@ static void do_code_gen(CodeGen *g) {
718 create_di_function_type(g, fn_proto, import->di_file), fn_table_entry->internal_linkage, 707 create_di_function_type(g, fn_proto, import->di_file), fn_table_entry->internal_linkage,
719 is_definition, scope_line, flags, is_optimized, fn);708 is_definition, scope_line, flags, is_optimized, fn);
720709
721 g->block_scopes.append(LLVMZigSubprogramToScope(subprogram));
722
723 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");710 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");
724 LLVMPositionBuilderAtEnd(g->builder, entry_block);711 LLVMPositionBuilderAtEnd(g->builder, entry_block);
725712
...@@ -728,6 +715,9 @@ static void do_code_gen(CodeGen *g) {...@@ -728,6 +715,9 @@ static void do_code_gen(CodeGen *g) {
728715
729 FnDefNode *codegen_fn_def = &codegen_node->data.fn_def_node;716 FnDefNode *codegen_fn_def = &codegen_node->data.fn_def_node;
730 assert(codegen_fn_def);717 assert(codegen_fn_def);
718
719 codegen_fn_def->block_context->di_scope = LLVMZigSubprogramToScope(subprogram);
720
731 int non_void_param_count = count_non_void_params(g, &fn_proto->params);721 int non_void_param_count = count_non_void_params(g, &fn_proto->params);
732 assert(non_void_param_count == (int)LLVMCountParams(fn));722 assert(non_void_param_count == (int)LLVMCountParams(fn));
733 LLVMValueRef *params = allocate<LLVMValueRef>(non_void_param_count);723 LLVMValueRef *params = allocate<LLVMValueRef>(non_void_param_count);
...@@ -746,15 +736,22 @@ static void do_code_gen(CodeGen *g) {...@@ -746,15 +736,22 @@ static void do_code_gen(CodeGen *g) {
746736
747 build_label_blocks(g, fn_def_node->data.fn_def.body);737 build_label_blocks(g, fn_def_node->data.fn_def.body);
748738
739 // Set up debug info for blocks and variables and
749 // allocate all local variables740 // allocate all local variables
750 for (int i = 0; i < codegen_fn_def->all_block_contexts.length; i += 1) {741 for (int i = 0; i < codegen_fn_def->all_block_contexts.length; i += 1) {
751 BlockContext *block_context = codegen_fn_def->all_block_contexts.at(i);742 BlockContext *block_context = codegen_fn_def->all_block_contexts.at(i);
752743
753 // skip the block context for function parameters744 if (block_context->parent) {
754 if (block_context->node->type == NodeTypeFnDef) {745 LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder,
755 continue;746 block_context->parent->di_scope,
747 import->di_file,
748 block_context->node->line + 1,
749 block_context->node->column + 1);
750 block_context->di_scope = LLVMZigLexicalBlockToScope(di_block);
756 }751 }
757752
753 g->cur_block_context = block_context;
754
758 auto it = block_context->variable_table.entry_iterator();755 auto it = block_context->variable_table.entry_iterator();
759 for (;;) {756 for (;;) {
760 auto *entry = it.next();757 auto *entry = it.next();
...@@ -765,16 +762,29 @@ static void do_code_gen(CodeGen *g) {...@@ -765,16 +762,29 @@ static void do_code_gen(CodeGen *g) {
765 if (var->type == g->builtin_types.entry_void)762 if (var->type == g->builtin_types.entry_void)
766 continue;763 continue;
767764
768 add_debug_source_node(g, var->decl_node);765 unsigned tag;
769 var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));766 unsigned arg_no;
767 if (block_context->node->type == NodeTypeFnDef) {
768 tag = LLVMZigTag_DW_arg_variable();
769 arg_no = var->arg_index + 1;
770 } else {
771 tag = LLVMZigTag_DW_auto_variable();
772 arg_no = 0;
773
774 add_debug_source_node(g, var->decl_node);
775 var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));
776 }
777
778 var->di_loc_var = LLVMZigCreateLocalVariable(g->dbuilder, tag,
779 block_context->di_scope, buf_ptr(&var->name),
780 import->di_file, var->decl_node->line + 1,
781 var->type->di_type, !g->strip_debug_symbols, 0, arg_no);
770 }782 }
771 }783 }
772784
773 TypeTableEntry *implicit_return_type = codegen_fn_def->implicit_return_type;785 TypeTableEntry *implicit_return_type = codegen_fn_def->implicit_return_type;
774 gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);786 gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);
775787
776 g->block_scopes.pop();
777
778 }788 }
779 assert(!g->errors.length);789 assert(!g->errors.length);
780790
src/semantic_info.hpp+11-1
...@@ -14,6 +14,7 @@...@@ -14,6 +14,7 @@
14#include "errmsg.hpp"14#include "errmsg.hpp"
1515
16struct FnTableEntry;16struct FnTableEntry;
17struct BlockContext;
1718
18struct TypeTableEntry {19struct TypeTableEntry {
19 LLVMTypeRef type_ref;20 LLVMTypeRef type_ref;
...@@ -96,7 +97,6 @@ struct CodeGen {...@@ -96,7 +97,6 @@ struct CodeGen {
96 bool is_native_target;97 bool is_native_target;
97 Buf *root_source_dir;98 Buf *root_source_dir;
98 Buf *root_out_name;99 Buf *root_out_name;
99 ZigList<LLVMZigDIScope *> block_scopes;
100100
101 // The function definitions this module includes. There must be a corresponding101 // The function definitions this module includes. There must be a corresponding
102 // fn_protos entry.102 // fn_protos entry.
...@@ -108,6 +108,7 @@ struct CodeGen {...@@ -108,6 +108,7 @@ struct CodeGen {
108 OutType out_type;108 OutType out_type;
109 FnTableEntry *cur_fn;109 FnTableEntry *cur_fn;
110 LLVMBasicBlockRef cur_basic_block;110 LLVMBasicBlockRef cur_basic_block;
111 BlockContext *cur_block_context;
111 bool c_stdint_used;112 bool c_stdint_used;
112 AstNode *root_export_decl;113 AstNode *root_export_decl;
113 int version_major;114 int version_major;
...@@ -125,6 +126,8 @@ struct LocalVariableTableEntry {...@@ -125,6 +126,8 @@ struct LocalVariableTableEntry {
125 bool is_const;126 bool is_const;
126 bool is_ptr; // if true, value_ref is a pointer127 bool is_ptr; // if true, value_ref is a pointer
127 AstNode *decl_node;128 AstNode *decl_node;
129 LLVMZigDILocalVariable *di_loc_var;
130 int arg_index;
128};131};
129132
130struct BlockContext {133struct BlockContext {
...@@ -132,6 +135,7 @@ struct BlockContext {...@@ -132,6 +135,7 @@ struct BlockContext {
132 BlockContext *root; // always points to the BlockContext with the NodeTypeFnDef135 BlockContext *root; // always points to the BlockContext with the NodeTypeFnDef
133 BlockContext *parent; // nullptr when this is the root136 BlockContext *parent; // nullptr when this is the root
134 HashMap<Buf *, LocalVariableTableEntry *, buf_hash, buf_eql_buf> variable_table;137 HashMap<Buf *, LocalVariableTableEntry *, buf_hash, buf_eql_buf> variable_table;
138 LLVMZigDIScope *di_scope;
135};139};
136140
137struct TypeNode {141struct TypeNode {
...@@ -146,6 +150,7 @@ struct FnDefNode {...@@ -146,6 +150,7 @@ struct FnDefNode {
146 TypeTableEntry *implicit_return_type;150 TypeTableEntry *implicit_return_type;
147 BlockContext *block_context;151 BlockContext *block_context;
148 bool skip;152 bool skip;
153 // Required to be a pre-order traversal of the AST. (parents must come before children)
149 ZigList<BlockContext *> all_block_contexts;154 ZigList<BlockContext *> all_block_contexts;
150};155};
151156
...@@ -160,6 +165,10 @@ struct AssignNode {...@@ -160,6 +165,10 @@ struct AssignNode {
160 LocalVariableTableEntry *var_entry;165 LocalVariableTableEntry *var_entry;
161};166};
162167
168struct BlockNode {
169 BlockContext *block_context;
170};
171
163struct CodeGenNode {172struct CodeGenNode {
164 union {173 union {
165 TypeNode type_node; // for NodeTypeType174 TypeNode type_node; // for NodeTypeType
...@@ -167,6 +176,7 @@ struct CodeGenNode {...@@ -167,6 +176,7 @@ struct CodeGenNode {
167 FnProtoNode fn_proto_node; // for NodeTypeFnProto176 FnProtoNode fn_proto_node; // for NodeTypeFnProto
168 LabelTableEntry *label_entry; // for NodeTypeGoto and NodeTypeLabel177 LabelTableEntry *label_entry; // for NodeTypeGoto and NodeTypeLabel
169 AssignNode assign_node; // for NodeTypeBinOpExpr where op is BinOpTypeAssign178 AssignNode assign_node; // for NodeTypeBinOpExpr where op is BinOpTypeAssign
179 BlockNode block_node; // for NodeTypeBlock
170 } data;180 } data;
171 ExprNode expr_node; // for all the expression nodes181 ExprNode expr_node; // for all the expression nodes
172};182};
src/zig_llvm.cpp+25-10
...@@ -189,6 +189,14 @@ unsigned LLVMZigLang_DW_LANG_C99(void) {...@@ -189,6 +189,14 @@ unsigned LLVMZigLang_DW_LANG_C99(void) {
189 return dwarf::DW_LANG_C99;189 return dwarf::DW_LANG_C99;
190}190}
191191
192unsigned LLVMZigTag_DW_auto_variable(void) {
193 return dwarf::DW_TAG_auto_variable;
194}
195
196unsigned LLVMZigTag_DW_arg_variable(void) {
197 return dwarf::DW_TAG_arg_variable;
198}
199
192LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {200LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
193 DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);201 DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);
194 return reinterpret_cast<LLVMZigDIBuilder *>(di_builder);202 return reinterpret_cast<LLVMZigDIBuilder *>(di_builder);
...@@ -211,16 +219,23 @@ LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLV...@@ -211,16 +219,23 @@ LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLV
211 return reinterpret_cast<LLVMZigDILexicalBlock*>(result);219 return reinterpret_cast<LLVMZigDILexicalBlock*>(result);
212}220}
213221
214/*222
215LLVMZigDILocalVariable *223LLVMZigDILocalVariable *LLVMZigCreateLocalVariable(LLVMZigDIBuilder *dbuilder, unsigned tag,
216224 LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,
217 DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope,225 LLVMZigDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
218 StringRef Name, DIFile *File,226{
219 unsigned LineNo, DIType *Ty,227 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createLocalVariable(
220 bool AlwaysPreserve = false,228 tag,
221 unsigned Flags = 0,229 reinterpret_cast<DIScope*>(scope),
222 unsigned ArgNo = 0);230 name,
223 */231 reinterpret_cast<DIFile*>(file),
232 line_no,
233 reinterpret_cast<DIType*>(type),
234 always_preserve,
235 flags,
236 arg_no);
237 return reinterpret_cast<LLVMZigDILocalVariable*>(result);
238}
224239
225LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block) {240LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block) {
226 DIScope *scope = reinterpret_cast<DILexicalBlock*>(lexical_block);241 DIScope *scope = reinterpret_cast<DILexicalBlock*>(lexical_block);
src/zig_llvm.hpp+7
...@@ -22,6 +22,7 @@ struct LLVMZigDIFile;...@@ -22,6 +22,7 @@ struct LLVMZigDIFile;
22struct LLVMZigDILexicalBlock;22struct LLVMZigDILexicalBlock;
23struct LLVMZigDISubprogram;23struct LLVMZigDISubprogram;
24struct LLVMZigDISubroutineType;24struct LLVMZigDISubroutineType;
25struct LLVMZigDILocalVariable;
25struct LLVMZigInsertionPoint;26struct LLVMZigInsertionPoint;
2627
27void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);28void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
...@@ -54,6 +55,8 @@ LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder...@@ -54,6 +55,8 @@ LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder
54unsigned LLVMZigEncoding_DW_ATE_unsigned(void);55unsigned LLVMZigEncoding_DW_ATE_unsigned(void);
55unsigned LLVMZigEncoding_DW_ATE_signed(void);56unsigned LLVMZigEncoding_DW_ATE_signed(void);
56unsigned LLVMZigLang_DW_LANG_C99(void);57unsigned LLVMZigLang_DW_LANG_C99(void);
58unsigned LLVMZigTag_DW_auto_variable(void);
59unsigned LLVMZigTag_DW_arg_variable(void);
5760
58LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);61LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
5962
...@@ -64,6 +67,10 @@ LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit);...@@ -64,6 +67,10 @@ LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit);
64LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile);67LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile);
65LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram);68LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram);
6669
70LLVMZigDILocalVariable *LLVMZigCreateLocalVariable(LLVMZigDIBuilder *dbuilder, unsigned tag,
71 LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,
72 LLVMZigDIType *type, bool always_preserve, unsigned flags, unsigned arg_no);
73
67LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLVMZigDIScope *scope,74LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLVMZigDIScope *scope,
68 LLVMZigDIFile *file, unsigned line, unsigned col);75 LLVMZigDIFile *file, unsigned line, unsigned col);
6976