| author | |
| committer | |
| log | 20eb749ad6983d74ce8285a725d84248d41fca00 |
| tree | 9444a3a8983dad943ca9f07c998f170fe98a06b8 |
| parent | 4e7effd3d38894f4d00bb0bb51ed34e237a4167e |
See #415 files changed, 66 insertions(+), 4 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -1336,6 +1336,7 @@ struct VariableTableEntry { |
| 1336 | 1336 | BlockContext *block_context; |
| 1337 | 1337 | LLVMValueRef param_value_ref; |
| 1338 | 1338 | bool force_depends_on_compile_var; |
| 1339 | ImportTableEntry *import; | |
| 1339 | 1340 | }; |
| 1340 | 1341 | |
| 1341 | 1342 | struct ErrorTableEntry { |
src/analyze.cpp+1| ... | ... | @@ -3757,6 +3757,7 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor |
| 3757 | 3757 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 3758 | 3758 | variable_entry->type = type_entry; |
| 3759 | 3759 | variable_entry->block_context = context; |
| 3760 | variable_entry->import = import; | |
| 3760 | 3761 | |
| 3761 | 3762 | if (name) { |
| 3762 | 3763 | buf_init_from_buf(&variable_entry->name, name); |
src/codegen.cpp+43-4| ... | ... | @@ -3954,6 +3954,19 @@ static void build_label_blocks(CodeGen *g, FnTableEntry *fn) { |
| 3954 | 3954 | LLVMPositionBuilderAtEnd(g->builder, entry_block); |
| 3955 | 3955 | } |
| 3956 | 3956 | |
| 3957 | static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef init_val, | |
| 3958 | TypeTableEntry *type_entry) | |
| 3959 | { | |
| 3960 | assert(var->is_const); | |
| 3961 | assert(var->import); | |
| 3962 | assert(type_entry); | |
| 3963 | bool is_local_to_unit = true; | |
| 3964 | LLVMZigCreateGlobalVariable(g->dbuilder, | |
| 3965 | var->block_context->di_scope, buf_ptr(&var->name), | |
| 3966 | buf_ptr(&var->name), var->import->di_file, var->decl_node->line + 1, | |
| 3967 | type_entry->di_type, is_local_to_unit, init_val); | |
| 3968 | } | |
| 3969 | ||
| 3957 | 3970 | static void do_code_gen(CodeGen *g) { |
| 3958 | 3971 | assert(!g->errors.length); |
| 3959 | 3972 | |
| ... | ... | @@ -3967,10 +3980,29 @@ static void do_code_gen(CodeGen *g) { |
| 3967 | 3980 | for (int i = 0; i < g->global_vars.length; i += 1) { |
| 3968 | 3981 | VariableTableEntry *var = g->global_vars.at(i); |
| 3969 | 3982 | |
| 3970 | if (var->type->id == TypeTableEntryIdNumLitFloat || | |
| 3971 | var->type->id == TypeTableEntryIdNumLitInt || | |
| 3972 | !type_has_bits(var->type)) | |
| 3973 | { | |
| 3983 | if (var->type->id == TypeTableEntryIdNumLitFloat) { | |
| 3984 | // Generate debug info for it but that's it. | |
| 3985 | ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val; | |
| 3986 | assert(const_val->ok); | |
| 3987 | TypeTableEntry *var_type = g->builtin_types.entry_f64; | |
| 3988 | LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float); | |
| 3989 | gen_global_var(g, var, init_val, var_type); | |
| 3990 | continue; | |
| 3991 | } | |
| 3992 | ||
| 3993 | if (var->type->id == TypeTableEntryIdNumLitInt) { | |
| 3994 | // Generate debug info for it but that's it. | |
| 3995 | ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val; | |
| 3996 | assert(const_val->ok); | |
| 3997 | TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ? | |
| 3998 | g->builtin_types.entry_isize : g->builtin_types.entry_usize; | |
| 3999 | LLVMValueRef init_val = LLVMConstInt(var_type->type_ref, | |
| 4000 | bignum_to_twos_complement(&const_val->data.x_bignum), false); | |
| 4001 | gen_global_var(g, var, init_val, var_type); | |
| 4002 | continue; | |
| 4003 | } | |
| 4004 | ||
| 4005 | if (!type_has_bits(var->type)) { | |
| 3974 | 4006 | continue; |
| 3975 | 4007 | } |
| 3976 | 4008 | |
| ... | ... | @@ -3981,6 +4013,8 @@ static void do_code_gen(CodeGen *g) { |
| 3981 | 4013 | if (var->decl_node->data.variable_declaration.is_extern) { |
| 3982 | 4014 | global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name)); |
| 3983 | 4015 | |
| 4016 | // TODO debug info for the extern variable | |
| 4017 | ||
| 3984 | 4018 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| 3985 | 4019 | } else { |
| 3986 | 4020 | AstNode *expr_node = var->decl_node->data.variable_declaration.expr; |
| ... | ... | @@ -3999,6 +4033,11 @@ static void do_code_gen(CodeGen *g) { |
| 3999 | 4033 | LLVMSetInitializer(global_value, init_val); |
| 4000 | 4034 | LLVMSetLinkage(global_value, LLVMInternalLinkage); |
| 4001 | 4035 | LLVMSetUnnamedAddr(global_value, true); |
| 4036 | ||
| 4037 | // TODO debug info for function pointers | |
| 4038 | if (var->is_const && var->type->id != TypeTableEntryIdFn) { | |
| 4039 | gen_global_var(g, var, init_val, var->type); | |
| 4040 | } | |
| 4002 | 4041 | } |
| 4003 | 4042 | |
| 4004 | 4043 | LLVMSetGlobalConstant(global_value, var->is_const); |
src/zig_llvm.cpp+16| ... | ... | @@ -401,6 +401,22 @@ LLVMZigDILocalVariable *LLVMZigCreateAutoVariable(LLVMZigDIBuilder *dbuilder, |
| 401 | 401 | return reinterpret_cast<LLVMZigDILocalVariable*>(result); |
| 402 | 402 | } |
| 403 | 403 | |
| 404 | LLVMZigDIGlobalVariable *LLVMZigCreateGlobalVariable(LLVMZigDIBuilder *dbuilder, | |
| 405 | LLVMZigDIScope *scope, const char *name, const char *linkage_name, LLVMZigDIFile *file, | |
| 406 | unsigned line_no, LLVMZigDIType *di_type, bool is_local_to_unit, LLVMValueRef constant_val) | |
| 407 | { | |
| 408 | DIGlobalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariable( | |
| 409 | reinterpret_cast<DIScope*>(scope), | |
| 410 | name, | |
| 411 | linkage_name, | |
| 412 | reinterpret_cast<DIFile*>(file), | |
| 413 | line_no, | |
| 414 | reinterpret_cast<DIType*>(di_type), | |
| 415 | is_local_to_unit, | |
| 416 | reinterpret_cast<llvm::Constant *>(constant_val)); | |
| 417 | return reinterpret_cast<LLVMZigDIGlobalVariable*>(result); | |
| 418 | } | |
| 419 | ||
| 404 | 420 | LLVMZigDILocalVariable *LLVMZigCreateParameterVariable(LLVMZigDIBuilder *dbuilder, |
| 405 | 421 | LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no, |
| 406 | 422 | LLVMZigDIType *type, bool always_preserve, unsigned flags, unsigned arg_no) |
src/zig_llvm.hpp+5| ... | ... | @@ -23,6 +23,7 @@ struct LLVMZigDILexicalBlock; |
| 23 | 23 | struct LLVMZigDISubprogram; |
| 24 | 24 | struct LLVMZigDISubroutineType; |
| 25 | 25 | struct LLVMZigDILocalVariable; |
| 26 | struct LLVMZigDIGlobalVariable; | |
| 26 | 27 | struct LLVMZigDILocation; |
| 27 | 28 | struct LLVMZigDIEnumerator; |
| 28 | 29 | struct LLVMZigInsertionPoint; |
| ... | ... | @@ -125,6 +126,10 @@ LLVMZigDILocalVariable *LLVMZigCreateAutoVariable(LLVMZigDIBuilder *dbuilder, |
| 125 | 126 | LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no, |
| 126 | 127 | LLVMZigDIType *type, bool always_preserve, unsigned flags); |
| 127 | 128 | |
| 129 | LLVMZigDIGlobalVariable *LLVMZigCreateGlobalVariable(LLVMZigDIBuilder *dbuilder, | |
| 130 | LLVMZigDIScope *scope, const char *name, const char *linkage_name, LLVMZigDIFile *file, | |
| 131 | unsigned line_no, LLVMZigDIType *di_type, bool is_local_to_unit, LLVMValueRef constant_val); | |
| 132 | ||
| 128 | 133 | LLVMZigDILocalVariable *LLVMZigCreateParameterVariable(LLVMZigDIBuilder *dbuilder, |
| 129 | 134 | LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no, |
| 130 | 135 | LLVMZigDIType *type, bool always_preserve, unsigned flags, unsigned arg_no); |