Commit 20eb749ad6

Andrew Kelley <superjoe30@gmail.com>
2016-09-05 07:32:23
generate debug info for global constants
See #41
1 parent 4e7effd
src/all_types.hpp
@@ -1336,6 +1336,7 @@ struct VariableTableEntry {
     BlockContext *block_context;
     LLVMValueRef param_value_ref;
     bool force_depends_on_compile_var;
+    ImportTableEntry *import;
 };
 
 struct ErrorTableEntry {
src/analyze.cpp
@@ -3757,6 +3757,7 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor
     VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
     variable_entry->type = type_entry;
     variable_entry->block_context = context;
+    variable_entry->import = import;
 
     if (name) {
         buf_init_from_buf(&variable_entry->name, name);
src/codegen.cpp
@@ -3954,6 +3954,19 @@ static void build_label_blocks(CodeGen *g, FnTableEntry *fn) {
     LLVMPositionBuilderAtEnd(g->builder, entry_block);
 }
 
+static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef init_val,
+    TypeTableEntry *type_entry)
+{
+    assert(var->is_const);
+    assert(var->import);
+    assert(type_entry);
+    bool is_local_to_unit = true;
+    LLVMZigCreateGlobalVariable(g->dbuilder,
+        var->block_context->di_scope, buf_ptr(&var->name),
+        buf_ptr(&var->name), var->import->di_file, var->decl_node->line + 1,
+        type_entry->di_type, is_local_to_unit, init_val);
+}
+
 static void do_code_gen(CodeGen *g) {
     assert(!g->errors.length);
 
@@ -3967,10 +3980,29 @@ static void do_code_gen(CodeGen *g) {
     for (int i = 0; i < g->global_vars.length; i += 1) {
         VariableTableEntry *var = g->global_vars.at(i);
 
-        if (var->type->id == TypeTableEntryIdNumLitFloat ||
-            var->type->id == TypeTableEntryIdNumLitInt ||
-            !type_has_bits(var->type))
-        {
+        if (var->type->id == TypeTableEntryIdNumLitFloat) {
+            // Generate debug info for it but that's it.
+            ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val;
+            assert(const_val->ok);
+            TypeTableEntry *var_type = g->builtin_types.entry_f64;
+            LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
+            gen_global_var(g, var, init_val, var_type);
+            continue;
+        }
+
+        if (var->type->id == TypeTableEntryIdNumLitInt) {
+            // Generate debug info for it but that's it.
+            ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val;
+            assert(const_val->ok);
+            TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
+                g->builtin_types.entry_isize : g->builtin_types.entry_usize;
+            LLVMValueRef init_val = LLVMConstInt(var_type->type_ref,
+                bignum_to_twos_complement(&const_val->data.x_bignum), false);
+            gen_global_var(g, var, init_val, var_type);
+            continue;
+        }
+
+        if (!type_has_bits(var->type)) {
             continue;
         }
 
@@ -3981,6 +4013,8 @@ static void do_code_gen(CodeGen *g) {
         if (var->decl_node->data.variable_declaration.is_extern) {
             global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name));
 
+            // TODO debug info for the extern variable
+
             LLVMSetLinkage(global_value, LLVMExternalLinkage);
         } else {
             AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
@@ -3999,6 +4033,11 @@ static void do_code_gen(CodeGen *g) {
             LLVMSetInitializer(global_value, init_val);
             LLVMSetLinkage(global_value, LLVMInternalLinkage);
             LLVMSetUnnamedAddr(global_value, true);
+
+            // TODO debug info for function pointers
+            if (var->is_const && var->type->id != TypeTableEntryIdFn) {
+                gen_global_var(g, var, init_val, var->type);
+            }
         }
 
         LLVMSetGlobalConstant(global_value, var->is_const);
src/zig_llvm.cpp
@@ -401,6 +401,22 @@ LLVMZigDILocalVariable *LLVMZigCreateAutoVariable(LLVMZigDIBuilder *dbuilder,
     return reinterpret_cast<LLVMZigDILocalVariable*>(result);
 }
 
+LLVMZigDIGlobalVariable *LLVMZigCreateGlobalVariable(LLVMZigDIBuilder *dbuilder,
+    LLVMZigDIScope *scope, const char *name, const char *linkage_name, LLVMZigDIFile *file,
+    unsigned line_no, LLVMZigDIType *di_type, bool is_local_to_unit, LLVMValueRef constant_val)
+{
+    DIGlobalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariable(
+        reinterpret_cast<DIScope*>(scope),
+        name,
+        linkage_name,
+        reinterpret_cast<DIFile*>(file),
+        line_no,
+        reinterpret_cast<DIType*>(di_type),
+        is_local_to_unit,
+        reinterpret_cast<llvm::Constant *>(constant_val));
+    return reinterpret_cast<LLVMZigDIGlobalVariable*>(result);
+}
+
 LLVMZigDILocalVariable *LLVMZigCreateParameterVariable(LLVMZigDIBuilder *dbuilder,
         LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,
         LLVMZigDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
src/zig_llvm.hpp
@@ -23,6 +23,7 @@ struct LLVMZigDILexicalBlock;
 struct LLVMZigDISubprogram;
 struct LLVMZigDISubroutineType;
 struct LLVMZigDILocalVariable;
+struct LLVMZigDIGlobalVariable;
 struct LLVMZigDILocation;
 struct LLVMZigDIEnumerator;
 struct LLVMZigInsertionPoint;
@@ -125,6 +126,10 @@ LLVMZigDILocalVariable *LLVMZigCreateAutoVariable(LLVMZigDIBuilder *dbuilder,
         LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,
         LLVMZigDIType *type, bool always_preserve, unsigned flags);
 
+LLVMZigDIGlobalVariable *LLVMZigCreateGlobalVariable(LLVMZigDIBuilder *dbuilder,
+    LLVMZigDIScope *scope, const char *name, const char *linkage_name, LLVMZigDIFile *file,
+    unsigned line_no, LLVMZigDIType *di_type, bool is_local_to_unit, LLVMValueRef constant_val);
+
 LLVMZigDILocalVariable *LLVMZigCreateParameterVariable(LLVMZigDIBuilder *dbuilder,
         LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,
         LLVMZigDIType *type, bool always_preserve, unsigned flags, unsigned arg_no);