authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-14 23:10:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-14 23:10:18-07:00
log83b68c9f13c90dfbbd2735cde4ef570ac50476c0
treee662b59bea4462299688db4c103a6ea27fd35b25
parent52e19b4a9b6e6140bae3c20c6f1fef36dca20aa7

add global variable support

closes #12

4 files changed, 79 insertions(+), 46 deletions(-)

src/analyze.cpp+41-26
...@@ -575,11 +575,11 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {...@@ -575,11 +575,11 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
575 context->parent = parent;575 context->parent = parent;
576 context->variable_table.init(8);576 context->variable_table.init(8);
577577
578 if (parent) {578 if (node && node->type == NodeTypeFnDef) {
579 context->fn_entry = parent->fn_entry;
580 } else if (node && node->type == NodeTypeFnDef) {
581 AstNode *fn_proto_node = node->data.fn_def.fn_proto;579 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
582 context->fn_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry;580 context->fn_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry;
581 } else if (parent) {
582 context->fn_entry = parent->fn_entry;
583 }583 }
584584
585 if (context->fn_entry) {585 if (context->fn_entry) {
...@@ -589,16 +589,26 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {...@@ -589,16 +589,26 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
589 return context;589 return context;
590}590}
591591
592LocalVariableTableEntry *find_local_variable(BlockContext *context, Buf *name) {592static VariableTableEntry *find_local_variable(BlockContext *context, Buf *name) {
593 while (true) {593 while (context && context->fn_entry) {
594 auto entry = context->variable_table.maybe_get(name);594 auto entry = context->variable_table.maybe_get(name);
595 if (entry != nullptr)595 if (entry != nullptr)
596 return entry->value;596 return entry->value;
597597
598 context = context->parent;598 context = context->parent;
599 if (context == nullptr)
600 return nullptr;
601 }599 }
600 return nullptr;
601}
602
603VariableTableEntry *find_variable(BlockContext *context, Buf *name) {
604 while (context) {
605 auto entry = context->variable_table.maybe_get(name);
606 if (entry != nullptr)
607 return entry->value;
608
609 context = context->parent;
610 }
611 return nullptr;
602}612}
603613
604static void get_struct_field(TypeTableEntry *struct_type, Buf *name, TypeStructField **out_tsf, int *out_i) {614static void get_struct_field(TypeTableEntry *struct_type, Buf *name, TypeStructField **out_tsf, int *out_i) {
...@@ -728,14 +738,13 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i...@@ -728,14 +738,13 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i
728 return return_type;738 return return_type;
729}739}
730740
731static TypeTableEntry *analyze_variable_name(CodeGen *g, BlockContext *context,741static TypeTableEntry *analyze_variable_name(CodeGen *g, ImportTableEntry *import, BlockContext *context,
732 AstNode *node, Buf *variable_name)742 AstNode *node, Buf *variable_name)
733{743{
734 LocalVariableTableEntry *local_variable = find_local_variable(context, variable_name);744 VariableTableEntry *var = find_variable(context, variable_name);
735 if (local_variable) {745 if (var) {
736 return local_variable->type;746 return var->type;
737 } else {747 } else {
738 // TODO: check global variables also
739 add_node_error(g, node,748 add_node_error(g, node,
740 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));749 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
741 return g->builtin_types.entry_invalid;750 return g->builtin_types.entry_invalid;
...@@ -919,7 +928,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,...@@ -919,7 +928,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
919 TypeTableEntry *expected_rhs_type = nullptr;928 TypeTableEntry *expected_rhs_type = nullptr;
920 if (lhs_node->type == NodeTypeSymbol) {929 if (lhs_node->type == NodeTypeSymbol) {
921 Buf *name = &lhs_node->data.symbol;930 Buf *name = &lhs_node->data.symbol;
922 LocalVariableTableEntry *var = find_local_variable(context, name);931 VariableTableEntry *var = find_variable(context, name);
923 if (var) {932 if (var) {
924 if (var->is_const) {933 if (var->is_const) {
925 add_node_error(g, lhs_node,934 add_node_error(g, lhs_node,
...@@ -1065,8 +1074,8 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,...@@ -1065,8 +1074,8 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
1065 zig_unreachable();1074 zig_unreachable();
1066}1075}
10671076
1068static TypeTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import, BlockContext *context,1077static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,
1069 TypeTableEntry *expected_type, AstNode *node)1078 BlockContext *context, TypeTableEntry *expected_type, AstNode *node)
1070{1079{
1071 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;1080 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
10721081
...@@ -1102,20 +1111,21 @@ static TypeTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry...@@ -1102,20 +1111,21 @@ static TypeTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry
1102 TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type;1111 TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type;
1103 assert(type != nullptr); // should have been caught by the parser1112 assert(type != nullptr); // should have been caught by the parser
11041113
1105 LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol);1114 VariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol);
1106 if (existing_variable) {1115 if (existing_variable) {
1107 add_node_error(g, node,1116 add_node_error(g, node,
1108 buf_sprintf("redeclaration of variable '%s'", buf_ptr(&variable_declaration->symbol)));1117 buf_sprintf("redeclaration of variable '%s'", buf_ptr(&variable_declaration->symbol)));
1109 } else {1118 } else {
1110 LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1);1119 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
1111 buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol);1120 buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol);
1112 variable_entry->type = type;1121 variable_entry->type = type;
1113 variable_entry->is_const = variable_declaration->is_const;1122 variable_entry->is_const = variable_declaration->is_const;
1114 variable_entry->is_ptr = true;1123 variable_entry->is_ptr = true;
1115 variable_entry->decl_node = node;1124 variable_entry->decl_node = node;
1116 context->variable_table.put(&variable_entry->name, variable_entry);1125 context->variable_table.put(&variable_entry->name, variable_entry);
1126 return variable_entry;
1117 }1127 }
1118 return g->builtin_types.entry_void;1128 return nullptr;
1119}1129}
11201130
1121static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1131static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
...@@ -1200,7 +1210,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -1200,7 +1210,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
1200 break;1210 break;
1201 }1211 }
1202 case NodeTypeVariableDeclaration:1212 case NodeTypeVariableDeclaration:
1203 return_type = analyze_variable_declaration(g, import, context, expected_type, node);1213 analyze_variable_declaration(g, import, context, expected_type, node);
1214 return_type = g->builtin_types.entry_void;
1204 break;1215 break;
1205 case NodeTypeGoto:1216 case NodeTypeGoto:
1206 {1217 {
...@@ -1220,7 +1231,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -1220,7 +1231,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
1220 {1231 {
1221 for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) {1232 for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) {
1222 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i);1233 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i);
1223 analyze_variable_name(g, context, node, &asm_output->variable_name);1234 analyze_variable_name(g, import, context, node, &asm_output->variable_name);
1224 }1235 }
1225 for (int i = 0; i < node->data.asm_expr.input_list.length; i += 1) {1236 for (int i = 0; i < node->data.asm_expr.input_list.length; i += 1) {
1226 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);1237 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
...@@ -1330,7 +1341,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -1330,7 +1341,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
13301341
1331 case NodeTypeSymbol:1342 case NodeTypeSymbol:
1332 {1343 {
1333 return_type = analyze_variable_name(g, context, node, &node->data.symbol);1344 return_type = analyze_variable_name(g, import, context, node, &node->data.symbol);
1334 break;1345 break;
1335 }1346 }
1336 case NodeTypeCastExpr:1347 case NodeTypeCastExpr:
...@@ -1429,7 +1440,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -1429,7 +1440,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
1429 assert(fn_proto_node->type == NodeTypeFnProto);1440 assert(fn_proto_node->type == NodeTypeFnProto);
14301441
1431 alloc_codegen_node(node);1442 alloc_codegen_node(node);
1432 BlockContext *context = new_block_context(node, nullptr);1443 BlockContext *context = new_block_context(node, import->block_context);
1433 node->codegen_node->data.fn_def_node.block_context = context;1444 node->codegen_node->data.fn_def_node.block_context = context;
14341445
1435 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;1446 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;
...@@ -1442,14 +1453,14 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -1442,14 +1453,14 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
1442 assert(param_decl->type->type == NodeTypeType);1453 assert(param_decl->type->type == NodeTypeType);
1443 TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry;1454 TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry;
14441455
1445 LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1);1456 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
1446 buf_init_from_buf(&variable_entry->name, &param_decl->name);1457 buf_init_from_buf(&variable_entry->name, &param_decl->name);
1447 variable_entry->type = type;1458 variable_entry->type = type;
1448 variable_entry->is_const = true;1459 variable_entry->is_const = true;
1449 variable_entry->decl_node = param_decl_node;1460 variable_entry->decl_node = param_decl_node;
1450 variable_entry->arg_index = i;1461 variable_entry->arg_index = i;
14511462
1452 LocalVariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);1463 VariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);
1453 if (!existing_entry) {1464 if (!existing_entry) {
1454 // unique definition1465 // unique definition
1455 context->variable_table.put(&variable_entry->name, variable_entry);1466 context->variable_table.put(&variable_entry->name, variable_entry);
...@@ -1505,8 +1516,12 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -1505,8 +1516,12 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
1505 // nothing to do1516 // nothing to do
1506 break;1517 break;
1507 case NodeTypeVariableDeclaration:1518 case NodeTypeVariableDeclaration:
1508 analyze_variable_declaration(g, import, import->block_context, nullptr, node);1519 {
1509 break;1520 VariableTableEntry *var = analyze_variable_declaration(g, import, import->block_context,
1521 nullptr, node);
1522 g->global_vars.append(var);
1523 break;
1524 }
1510 case NodeTypeDirective:1525 case NodeTypeDirective:
1511 case NodeTypeParamDecl:1526 case NodeTypeParamDecl:
1512 case NodeTypeFnProto:1527 case NodeTypeFnProto:
src/analyze.hpp+7-5
...@@ -16,6 +16,7 @@...@@ -16,6 +16,7 @@
16struct FnTableEntry;16struct FnTableEntry;
17struct BlockContext;17struct BlockContext;
18struct TypeTableEntry;18struct TypeTableEntry;
19struct VariableTableEntry;
1920
20struct TypeTableEntryPointer {21struct TypeTableEntryPointer {
21 TypeTableEntry *pointer_child;22 TypeTableEntry *pointer_child;
...@@ -177,6 +178,7 @@ struct CodeGen {...@@ -177,6 +178,7 @@ struct CodeGen {
177 // The function prototypes this module includes. In the case of external declarations,178 // The function prototypes this module includes. In the case of external declarations,
178 // there will not be a corresponding fn_defs entry.179 // there will not be a corresponding fn_defs entry.
179 ZigList<FnTableEntry *> fn_protos;180 ZigList<FnTableEntry *> fn_protos;
181 ZigList<VariableTableEntry *> global_vars;
180182
181 OutType out_type;183 OutType out_type;
182 FnTableEntry *cur_fn;184 FnTableEntry *cur_fn;
...@@ -192,7 +194,7 @@ struct CodeGen {...@@ -192,7 +194,7 @@ struct CodeGen {
192 ImportTableEntry *root_import;194 ImportTableEntry *root_import;
193};195};
194196
195struct LocalVariableTableEntry {197struct VariableTableEntry {
196 Buf name;198 Buf name;
197 TypeTableEntry *type;199 TypeTableEntry *type;
198 LLVMValueRef value_ref;200 LLVMValueRef value_ref;
...@@ -204,10 +206,10 @@ struct LocalVariableTableEntry {...@@ -204,10 +206,10 @@ struct LocalVariableTableEntry {
204};206};
205207
206struct BlockContext {208struct BlockContext {
207 AstNode *node; // either NodeTypeFnDef or NodeTypeBlock or null for module scope209 AstNode *node; // either NodeTypeFnDef or NodeTypeBlock or NodeTypeRoot
208 FnTableEntry *fn_entry; // null at the module scope210 FnTableEntry *fn_entry; // null at the module scope
209 BlockContext *parent; // null when this is the root211 BlockContext *parent; // null when this is the root
210 HashMap<Buf *, LocalVariableTableEntry *, buf_hash, buf_eql_buf> variable_table;212 HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table;
211 ZigList<AstNode *> cast_expr_alloca_list;213 ZigList<AstNode *> cast_expr_alloca_list;
212 LLVMZigDIScope *di_scope;214 LLVMZigDIScope *di_scope;
213};215};
...@@ -234,7 +236,7 @@ struct ExprNode {...@@ -234,7 +236,7 @@ struct ExprNode {
234};236};
235237
236struct AssignNode {238struct AssignNode {
237 LocalVariableTableEntry *var_entry;239 VariableTableEntry *var_entry;
238};240};
239241
240struct BlockNode {242struct BlockNode {
...@@ -295,7 +297,7 @@ void semantic_analyze(CodeGen *g);...@@ -295,7 +297,7 @@ void semantic_analyze(CodeGen *g);
295void add_node_error(CodeGen *g, AstNode *node, Buf *msg);297void add_node_error(CodeGen *g, AstNode *node, Buf *msg);
296TypeTableEntry *new_type_table_entry(TypeTableEntryId id);298TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
297TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);299TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
298LocalVariableTableEntry *find_local_variable(BlockContext *context, Buf *name);300VariableTableEntry *find_variable(BlockContext *context, Buf *name);
299BlockContext *new_block_context(AstNode *node, BlockContext *parent);301BlockContext *new_block_context(AstNode *node, BlockContext *parent);
300302
301#endif303#endif
src/codegen.cpp+28-12
...@@ -558,7 +558,7 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) {...@@ -558,7 +558,7 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) {
558 LLVMValueRef target_ref;558 LLVMValueRef target_ref;
559 TypeTableEntry *op1_type;559 TypeTableEntry *op1_type;
560 if (lhs_node->type == NodeTypeSymbol) {560 if (lhs_node->type == NodeTypeSymbol) {
561 LocalVariableTableEntry *var = find_local_variable(node->codegen_node->expr_node.block_context,561 VariableTableEntry *var = find_variable(node->codegen_node->expr_node.block_context,
562 &lhs_node->data.symbol);562 &lhs_node->data.symbol);
563563
564 // semantic checking ensures no variables are constant564 // semantic checking ensures no variables are constant
...@@ -807,7 +807,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) {...@@ -807,7 +807,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) {
807 buf_append_char(&constraint_buf, ',');807 buf_append_char(&constraint_buf, ',');
808 }808 }
809809
810 LocalVariableTableEntry *variable = find_local_variable(810 VariableTableEntry *variable = find_variable(
811 node->codegen_node->expr_node.block_context,811 node->codegen_node->expr_node.block_context,
812 &asm_output->variable_name);812 &asm_output->variable_name);
813 assert(variable);813 assert(variable);
...@@ -851,7 +851,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -851,7 +851,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
851 return gen_return_expr(g, node);851 return gen_return_expr(g, node);
852 case NodeTypeVariableDeclaration:852 case NodeTypeVariableDeclaration:
853 {853 {
854 LocalVariableTableEntry *variable = find_local_variable(854 VariableTableEntry *variable = find_variable(
855 node->codegen_node->expr_node.block_context,855 node->codegen_node->expr_node.block_context,
856 &node->data.variable_declaration.symbol);856 &node->data.variable_declaration.symbol);
857857
...@@ -940,13 +940,14 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -940,13 +940,14 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
940 }940 }
941 case NodeTypeSymbol:941 case NodeTypeSymbol:
942 {942 {
943 LocalVariableTableEntry *variable = find_local_variable(943 VariableTableEntry *variable = find_variable(
944 node->codegen_node->expr_node.block_context,944 node->codegen_node->expr_node.block_context,
945 &node->data.symbol);945 &node->data.symbol);
946 assert(variable);946 assert(variable);
947 if (variable->type->id == TypeTableEntryIdVoid) {947 if (variable->type->id == TypeTableEntryIdVoid) {
948 return nullptr;948 return nullptr;
949 } else if (variable->is_ptr) {949 } else if (variable->is_ptr) {
950 assert(variable->value_ref);
950 if (variable->type->id == TypeTableEntryIdArray) {951 if (variable->type->id == TypeTableEntryIdArray) {
951 return variable->value_ref;952 return variable->value_ref;
952 } else if (variable->type->id == TypeTableEntryIdStruct) {953 } else if (variable->type->id == TypeTableEntryIdStruct) {
...@@ -1035,9 +1036,25 @@ static LLVMAttribute to_llvm_fn_attr(FnAttrId attr_id) {...@@ -1035,9 +1036,25 @@ static LLVMAttribute to_llvm_fn_attr(FnAttrId attr_id) {
1035static void do_code_gen(CodeGen *g) {1036static void do_code_gen(CodeGen *g) {
1036 assert(!g->errors.length);1037 assert(!g->errors.length);
10371038
1039 // Generate module level variables
1040 for (int i = 0; i < g->global_vars.length; i += 1) {
1041 VariableTableEntry *var = g->global_vars.at(i);
1042
1043 LLVMValueRef init_val = gen_expr(g, var->decl_node->data.variable_declaration.expr);
1044
1045 // TODO if the global is exported, set external linkage
1046 LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), "");
1047 LLVMSetLinkage(global_value, LLVMPrivateLinkage);
1048 LLVMSetInitializer(global_value, init_val);
1049 LLVMSetGlobalConstant(global_value, var->is_const);
1050 LLVMSetUnnamedAddr(global_value, true);
1051
1052 var->value_ref = global_value;
1053 }
1054
1038 // Generate function prototypes1055 // Generate function prototypes
1039 for (int i = 0; i < g->fn_protos.length; i += 1) {1056 for (int fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) {
1040 FnTableEntry *fn_table_entry = g->fn_protos.at(i);1057 FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i);
10411058
1042 AstNode *proto_node = fn_table_entry->proto_node;1059 AstNode *proto_node = fn_table_entry->proto_node;
1043 assert(proto_node->type == NodeTypeFnProto);1060 assert(proto_node->type == NodeTypeFnProto);
...@@ -1090,14 +1107,13 @@ static void do_code_gen(CodeGen *g) {...@@ -1090,14 +1107,13 @@ static void do_code_gen(CodeGen *g) {
1090 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1107 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
10911108
1092 // Add debug info.1109 // Add debug info.
1093 LLVMZigDIScope *fn_scope = LLVMZigFileToScope(import->di_file);
1094 unsigned line_number = fn_def_node->line + 1;1110 unsigned line_number = fn_def_node->line + 1;
1095 unsigned scope_line = line_number;1111 unsigned scope_line = line_number;
1096 bool is_definition = true;1112 bool is_definition = true;
1097 unsigned flags = 0;1113 unsigned flags = 0;
1098 bool is_optimized = g->build_type == CodeGenBuildTypeRelease;1114 bool is_optimized = g->build_type == CodeGenBuildTypeRelease;
1099 LLVMZigDISubprogram *subprogram = LLVMZigCreateFunction(g->dbuilder,1115 LLVMZigDISubprogram *subprogram = LLVMZigCreateFunction(g->dbuilder,
1100 fn_scope, buf_ptr(&fn_proto->name), "", import->di_file, line_number,1116 import->block_context->di_scope, buf_ptr(&fn_proto->name), "", import->di_file, line_number,
1101 create_di_function_type(g, fn_proto, import->di_file), fn_table_entry->internal_linkage, 1117 create_di_function_type(g, fn_proto, import->di_file), fn_table_entry->internal_linkage,
1102 is_definition, scope_line, flags, is_optimized, fn);1118 is_definition, scope_line, flags, is_optimized, fn);
11031119
...@@ -1123,7 +1139,7 @@ static void do_code_gen(CodeGen *g) {...@@ -1123,7 +1139,7 @@ static void do_code_gen(CodeGen *g) {
1123 assert(param_decl->type == NodeTypeParamDecl);1139 assert(param_decl->type == NodeTypeParamDecl);
1124 if (is_param_decl_type_void(g, param_decl))1140 if (is_param_decl_type_void(g, param_decl))
1125 continue;1141 continue;
1126 LocalVariableTableEntry *parameter_variable = fn_def_node->codegen_node->data.fn_def_node.block_context->variable_table.get(&param_decl->data.param_decl.name);1142 VariableTableEntry *parameter_variable = fn_def_node->codegen_node->data.fn_def_node.block_context->variable_table.get(&param_decl->data.param_decl.name);
1127 parameter_variable->value_ref = params[non_void_index];1143 parameter_variable->value_ref = params[non_void_index];
1128 non_void_index += 1;1144 non_void_index += 1;
1129 }1145 }
...@@ -1135,7 +1151,7 @@ static void do_code_gen(CodeGen *g) {...@@ -1135,7 +1151,7 @@ static void do_code_gen(CodeGen *g) {
1135 for (int bc_i = 0; bc_i < fn_table_entry->all_block_contexts.length; bc_i += 1) {1151 for (int bc_i = 0; bc_i < fn_table_entry->all_block_contexts.length; bc_i += 1) {
1136 BlockContext *block_context = fn_table_entry->all_block_contexts.at(bc_i);1152 BlockContext *block_context = fn_table_entry->all_block_contexts.at(bc_i);
11371153
1138 if (block_context->parent) {1154 if (!block_context->di_scope) {
1139 LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder,1155 LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder,
1140 block_context->parent->di_scope,1156 block_context->parent->di_scope,
1141 import->di_file,1157 import->di_file,
...@@ -1152,7 +1168,7 @@ static void do_code_gen(CodeGen *g) {...@@ -1152,7 +1168,7 @@ static void do_code_gen(CodeGen *g) {
1152 if (!entry)1168 if (!entry)
1153 break;1169 break;
11541170
1155 LocalVariableTableEntry *var = entry->value;1171 VariableTableEntry *var = entry->value;
1156 if (var->type->id == TypeTableEntryIdVoid)1172 if (var->type->id == TypeTableEntryIdVoid)
1157 continue;1173 continue;
11581174
...@@ -1530,7 +1546,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src...@@ -1530,7 +1546,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src
1530 import_entry->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));1546 import_entry->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
1531 g->import_table.put(full_path, import_entry);1547 g->import_table.put(full_path, import_entry);
15321548
1533 import_entry->block_context = new_block_context(nullptr, nullptr);1549 import_entry->block_context = new_block_context(import_entry->root, nullptr);
1534 import_entry->block_context->di_scope = LLVMZigFileToScope(import_entry->di_file);1550 import_entry->block_context->di_scope = LLVMZigFileToScope(import_entry->di_file);
15351551
15361552
std/std.zig+3-3
...@@ -1,3 +1,6 @@...@@ -1,3 +1,6 @@
1const SYS_write : isize = 1;
2const stdout_fileno : isize = 1;
3
1fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {4fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
2 var result : isize;5 var result : isize;
3 asm volatile ("6 asm volatile ("
...@@ -13,15 +16,12 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {...@@ -13,15 +16,12 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
13 return result;16 return result;
14}17}
1518
16// TODO constants for SYS_write and stdout_fileno
17pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {19pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {
18 const SYS_write : isize = 1;
19 return syscall3(SYS_write, fd, buf as isize, count as isize);20 return syscall3(SYS_write, fd, buf as isize, count as isize);
20}21}
2122
22// TODO error handling23// TODO error handling
23// TODO handle buffering and flushing24// TODO handle buffering and flushing
24pub fn print_str(str : string) -> isize {25pub fn print_str(str : string) -> isize {
25 const stdout_fileno : isize = 1;
26 return write(stdout_fileno, str.ptr, str.len);26 return write(stdout_fileno, str.ptr, str.len);
27}27}