Commit fb1e3a5be9

Andrew Kelley <superjoe30@gmail.com>
2016-01-03 04:42:32
codegen: emit debug metadata for parameters
1 parent 258bc73
src/analyze.cpp
@@ -1898,6 +1898,9 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
                     variable_entry->decl_node = param_decl_node;
                     variable_entry->arg_index = i;
 
+                    alloc_codegen_node(param_decl_node);
+                    param_decl_node->codegen_node->data.param_decl_node.variable = variable_entry;
+
                     VariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);
                     if (!existing_entry) {
                         // unique definition
src/analyze.hpp
@@ -322,6 +322,10 @@ struct IfVarNode {
     BlockContext *block_context;
 };
 
+struct ParamDeclNode {
+    VariableTableEntry *variable;
+};
+
 struct CodeGenNode {
     union {
         TypeNode type_node; // for NodeTypeType
@@ -338,6 +342,7 @@ struct CodeGenNode {
         StructValFieldNode struct_val_field_node; // for NodeTypeStructValueField
         StructValExprNode struct_val_expr_node; // for NodeTypeStructValueExpr
         IfVarNode if_var_node; // for NodeTypeStructValueExpr
+        ParamDeclNode param_decl_node; // for NodeTypeParamDecl
     } data;
     ExprNode expr_node; // for all the expression nodes
 };
src/codegen.cpp
@@ -1530,7 +1530,8 @@ static void do_code_gen(CodeGen *g) {
             non_void_index += 1;
         }
 
-        build_label_blocks(g, fn_def_node->data.fn_def.body);
+        AstNode *body_node = fn_def_node->data.fn_def.body;
+        build_label_blocks(g, body_node);
 
         // Set up debug info for blocks and variables and
         // allocate all local variables
@@ -1593,6 +1594,22 @@ static void do_code_gen(CodeGen *g) {
             }
         }
 
+        // create debug variable declarations for parameters
+        for (int param_i = 0; param_i < fn_proto->params.length; param_i += 1) {
+            AstNode *param_decl = fn_proto->params.at(param_i);
+            assert(param_decl->type == NodeTypeParamDecl);
+
+            if (is_param_decl_type_void(g, param_decl))
+                continue;
+
+            VariableTableEntry *variable = param_decl->codegen_node->data.param_decl_node.variable;
+
+            LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(param_decl->line + 1, param_decl->column + 1,
+                    codegen_fn_def->block_context->di_scope);
+            LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc,
+                    entry_block);
+        }
+
         TypeTableEntry *implicit_return_type = codegen_fn_def->implicit_return_type;
         gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);
 
src/zig_llvm.cpp
@@ -387,6 +387,17 @@ void LLVMZigRestoreInsertPoint(LLVMBuilderRef builder, LLVMZigInsertionPoint *ip
     unwrap(builder)->restoreIP(*ip);
 }
 
+LLVMValueRef LLVMZigInsertDeclareAtEnd(LLVMZigDIBuilder *dibuilder, LLVMValueRef storage,
+        LLVMZigDILocalVariable *var_info, LLVMZigDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref)
+{
+    Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
+            unwrap(storage),
+            reinterpret_cast<DILocalVariable *>(var_info),
+            reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
+            reinterpret_cast<DILocation*>(debug_loc),
+            static_cast<BasicBlock*>(unwrap(basic_block_ref)));
+    return wrap(result);
+}
 
 LLVMValueRef LLVMZigInsertDeclare(LLVMZigDIBuilder *dibuilder, LLVMValueRef storage,
         LLVMZigDILocalVariable *var_info, LLVMZigDILocation *debug_loc, LLVMValueRef insert_before_instr)
src/zig_llvm.hpp
@@ -113,6 +113,8 @@ void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder);
 LLVMZigInsertionPoint *LLVMZigSaveInsertPoint(LLVMBuilderRef builder);
 void LLVMZigRestoreInsertPoint(LLVMBuilderRef builder, LLVMZigInsertionPoint *point);
 
+LLVMValueRef LLVMZigInsertDeclareAtEnd(LLVMZigDIBuilder *dibuilder, LLVMValueRef storage,
+        LLVMZigDILocalVariable *var_info, LLVMZigDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref);
 LLVMValueRef LLVMZigInsertDeclare(LLVMZigDIBuilder *dibuilder, LLVMValueRef storage,
         LLVMZigDILocalVariable *var_info, LLVMZigDILocation *debug_loc, LLVMValueRef insert_before_instr);
 LLVMZigDILocation *LLVMZigGetDebugLoc(unsigned line, unsigned col, LLVMZigDIScope *scope);