generate debug info for global constants

See #41
This commit is contained in:
Andrew Kelley 2016-09-04 22:32:23 -07:00
parent 4e7effd3d3
commit 20eb749ad6
5 changed files with 66 additions and 4 deletions

View File

@ -1336,6 +1336,7 @@ struct VariableTableEntry {
BlockContext *block_context;
LLVMValueRef param_value_ref;
bool force_depends_on_compile_var;
ImportTableEntry *import;
};
struct ErrorTableEntry {

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);