| author | |
| committer | |
| log | 9c9ea935191190471c1b2fd30c8cffde74421456 |
| tree | fe709fbb92cb58cc6027883e37fe55a7cb916798 |
| parent | 1279fe0caaa83dd9f573dfe3c359098143224abc |
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); |
| 794 | 795 | ||
| 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; |
| 803 | 798 | ||
| ... | @@ -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; | ||
| 840 | 836 | ||
| 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 | } |
| 103 | 103 | ||
| 104 | static void add_debug_source_node(CodeGen *g, AstNode *node) { | 104 | static void add_debug_source_node(CodeGen *g, AstNode *node) { |
| 105 | // TODO g->block_scopes.last() is not always correct and should probably integrate with BlockContext | 105 | 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 | } |
| 108 | 108 | ||
| 109 | static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) { | 109 | static 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) { |
| 484 | static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) { | 484 | static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) { |
| 485 | assert(block_node->type == NodeTypeBlock); | 485 | assert(block_node->type == NodeTypeBlock); |
| 486 | 486 | ||
| 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); | ||
| 494 | 488 | ||
| 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 | } |
| 508 | 502 | ||
| 509 | g->block_scopes.pop(); | ||
| 510 | |||
| 511 | return return_value; | 503 | return return_value; |
| 512 | } | 504 | } |
| 513 | 505 | ||
| ... | @@ -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 |
| 654 | static void do_code_gen(CodeGen *g) { | 646 | static void do_code_gen(CodeGen *g) { |
| 655 | assert(!g->errors.length); | 647 | assert(!g->errors.length); |
| 656 | 648 | ||
| 657 | g->block_scopes.append(LLVMZigCompileUnitToScope(g->compile_unit)); | ||
| 658 | |||
| 659 | |||
| 660 | // Generate function prototypes | 649 | // 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); |
| 720 | 709 | ||
| 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); |
| 725 | 712 | ||
| ... | @@ -728,6 +715,9 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -728,6 +715,9 @@ static void do_code_gen(CodeGen *g) { |
| 728 | 715 | ||
| 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) { |
| 746 | 736 | ||
| 747 | build_label_blocks(g, fn_def_node->data.fn_def.body); | 737 | build_label_blocks(g, fn_def_node->data.fn_def.body); |
| 748 | 738 | ||
| 739 | // Set up debug info for blocks and variables and | ||
| 749 | // allocate all local variables | 740 | // 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); |
| 752 | 743 | ||
| 753 | // skip the block context for function parameters | 744 | 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 | } |
| 757 | 752 | ||
| 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; |
| 767 | 764 | ||
| 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 | } |
| 772 | 784 | ||
| 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); |
| 775 | 787 | ||
| 776 | g->block_scopes.pop(); | ||
| 777 | |||
| 778 | } | 788 | } |
| 779 | assert(!g->errors.length); | 789 | assert(!g->errors.length); |
| 780 | 790 |
src/semantic_info.hpp+11-1| ... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
| 14 | #include "errmsg.hpp" | 14 | #include "errmsg.hpp" |
| 15 | 15 | ||
| 16 | struct FnTableEntry; | 16 | struct FnTableEntry; |
| 17 | struct BlockContext; | ||
| 17 | 18 | ||
| 18 | struct TypeTableEntry { | 19 | struct 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; | ||
| 100 | 100 | ||
| 101 | // The function definitions this module includes. There must be a corresponding | 101 | // 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 pointer | 127 | 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 | }; |
| 129 | 132 | ||
| 130 | struct BlockContext { | 133 | struct BlockContext { |
| ... | @@ -132,6 +135,7 @@ struct BlockContext { | ... | @@ -132,6 +135,7 @@ struct BlockContext { |
| 132 | BlockContext *root; // always points to the BlockContext with the NodeTypeFnDef | 135 | BlockContext *root; // always points to the BlockContext with the NodeTypeFnDef |
| 133 | BlockContext *parent; // nullptr when this is the root | 136 | 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 | }; |
| 136 | 140 | ||
| 137 | struct TypeNode { | 141 | struct 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 | }; |
| 151 | 156 | ||
| ... | @@ -160,6 +165,10 @@ struct AssignNode { | ... | @@ -160,6 +165,10 @@ struct AssignNode { |
| 160 | LocalVariableTableEntry *var_entry; | 165 | LocalVariableTableEntry *var_entry; |
| 161 | }; | 166 | }; |
| 162 | 167 | ||
| 168 | struct BlockNode { | ||
| 169 | BlockContext *block_context; | ||
| 170 | }; | ||
| 171 | |||
| 163 | struct CodeGenNode { | 172 | struct CodeGenNode { |
| 164 | union { | 173 | union { |
| 165 | TypeNode type_node; // for NodeTypeType | 174 | TypeNode type_node; // for NodeTypeType |
| ... | @@ -167,6 +176,7 @@ struct CodeGenNode { | ... | @@ -167,6 +176,7 @@ struct CodeGenNode { |
| 167 | FnProtoNode fn_proto_node; // for NodeTypeFnProto | 176 | FnProtoNode fn_proto_node; // for NodeTypeFnProto |
| 168 | LabelTableEntry *label_entry; // for NodeTypeGoto and NodeTypeLabel | 177 | LabelTableEntry *label_entry; // for NodeTypeGoto and NodeTypeLabel |
| 169 | AssignNode assign_node; // for NodeTypeBinOpExpr where op is BinOpTypeAssign | 178 | 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 nodes | 181 | 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 | } |
| 191 | 191 | ||
| 192 | unsigned LLVMZigTag_DW_auto_variable(void) { | ||
| 193 | return dwarf::DW_TAG_auto_variable; | ||
| 194 | } | ||
| 195 | |||
| 196 | unsigned LLVMZigTag_DW_arg_variable(void) { | ||
| 197 | return dwarf::DW_TAG_arg_variable; | ||
| 198 | } | ||
| 199 | |||
| 192 | LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) { | 200 | LLVMZigDIBuilder *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 | } |
| 213 | 221 | ||
| 214 | /* | 222 | |
| 215 | LLVMZigDILocalVariable * | 223 | LLVMZigDILocalVariable *LLVMZigCreateLocalVariable(LLVMZigDIBuilder *dbuilder, unsigned tag, |
| 216 | 224 | 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 | } | ||
| 224 | 239 | ||
| 225 | LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block) { | 240 | LLVMZigDIScope *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; |
| 22 | struct LLVMZigDILexicalBlock; | 22 | struct LLVMZigDILexicalBlock; |
| 23 | struct LLVMZigDISubprogram; | 23 | struct LLVMZigDISubprogram; |
| 24 | struct LLVMZigDISubroutineType; | 24 | struct LLVMZigDISubroutineType; |
| 25 | struct LLVMZigDILocalVariable; | ||
| 25 | struct LLVMZigInsertionPoint; | 26 | struct LLVMZigInsertionPoint; |
| 26 | 27 | ||
| 27 | void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R); | 28 | void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R); |
| ... | @@ -54,6 +55,8 @@ LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder | ... | @@ -54,6 +55,8 @@ LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder |
| 54 | unsigned LLVMZigEncoding_DW_ATE_unsigned(void); | 55 | unsigned LLVMZigEncoding_DW_ATE_unsigned(void); |
| 55 | unsigned LLVMZigEncoding_DW_ATE_signed(void); | 56 | unsigned LLVMZigEncoding_DW_ATE_signed(void); |
| 56 | unsigned LLVMZigLang_DW_LANG_C99(void); | 57 | unsigned LLVMZigLang_DW_LANG_C99(void); |
| 58 | unsigned LLVMZigTag_DW_auto_variable(void); | ||
| 59 | unsigned LLVMZigTag_DW_arg_variable(void); | ||
| 57 | 60 | ||
| 58 | LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved); | 61 | LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved); |
| 59 | 62 | ||
| ... | @@ -64,6 +67,10 @@ LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit); | ... | @@ -64,6 +67,10 @@ LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit); |
| 64 | LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile); | 67 | LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile); |
| 65 | LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram); | 68 | LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram); |
| 66 | 69 | ||
| 70 | LLVMZigDILocalVariable *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 | |||
| 67 | LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLVMZigDIScope *scope, | 74 | LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLVMZigDIScope *scope, |
| 68 | LLVMZigDIFile *file, unsigned line, unsigned col); | 75 | LLVMZigDIFile *file, unsigned line, unsigned col); |
| 69 | 76 |