authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-01 21:08:12-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-01 21:08:12-05:00
logf6cbb73c7402fc100bbfb26c1a35c9f23b3f36ff
tree6d62eb0f6b04292b98ef2bd92b40699a6c32da0a
parentc6ace9720c8666f893f236c00ea9b370b1b2bb70

rewrite scope implementation

* now there are not extra unused hash tables * each variable declaration opens a new scope inside a function

7 files changed, 420 insertions(+), 266 deletions(-)

src/all_types.hpp+74-23
...@@ -31,6 +31,7 @@ struct ConstExprValue;...@@ -31,6 +31,7 @@ struct ConstExprValue;
31struct IrInstruction;31struct IrInstruction;
32struct IrInstructionCast;32struct IrInstructionCast;
33struct IrBasicBlock;33struct IrBasicBlock;
34struct ScopeDecls;
3435
35struct IrExecutable {36struct IrExecutable {
36 ZigList<IrBasicBlock *> basic_block_list;37 ZigList<IrBasicBlock *> basic_block_list;
...@@ -251,8 +252,8 @@ struct AstNodeFnDef {...@@ -251,8 +252,8 @@ struct AstNodeFnDef {
251252
252 // populated by semantic analyzer253 // populated by semantic analyzer
253 TypeTableEntry *implicit_return_type;254 TypeTableEntry *implicit_return_type;
254 // the first child block context255 Scope *containing_scope;
255 Scope *scope;256 Scope *child_scope;
256};257};
257258
258struct AstNodeFnDecl {259struct AstNodeFnDecl {
...@@ -638,7 +639,7 @@ struct AstNodeStructDecl {...@@ -638,7 +639,7 @@ struct AstNodeStructDecl {
638 ZigList<AstNode *> decls;639 ZigList<AstNode *> decls;
639640
640 // populated by semantic analyzer641 // populated by semantic analyzer
641 Scope *scope;642 ScopeDecls *decls_scope;
642 TypeTableEntry *type_entry;643 TypeTableEntry *type_entry;
643 TypeTableEntry *generic_fn_type;644 TypeTableEntry *generic_fn_type;
644 bool skip;645 bool skip;
...@@ -884,7 +885,7 @@ struct TypeTableEntryStruct {...@@ -884,7 +885,7 @@ struct TypeTableEntryStruct {
884 uint64_t size_bytes;885 uint64_t size_bytes;
885 bool is_invalid; // true if any fields are invalid886 bool is_invalid; // true if any fields are invalid
886 bool is_slice;887 bool is_slice;
887 Scope *scope;888 ScopeDecls *decls_scope;
888889
889 // set this flag temporarily to detect infinite loops890 // set this flag temporarily to detect infinite loops
890 bool embedded_in_current;891 bool embedded_in_current;
...@@ -910,7 +911,7 @@ struct TypeTableEntryEnum {...@@ -910,7 +911,7 @@ struct TypeTableEntryEnum {
910 TypeTableEntry *tag_type;911 TypeTableEntry *tag_type;
911 TypeTableEntry *union_type;912 TypeTableEntry *union_type;
912913
913 Scope *scope;914 ScopeDecls *decls_scope;
914915
915 // set this flag temporarily to detect infinite loops916 // set this flag temporarily to detect infinite loops
916 bool embedded_in_current;917 bool embedded_in_current;
...@@ -926,7 +927,7 @@ struct TypeTableEntryUnion {...@@ -926,7 +927,7 @@ struct TypeTableEntryUnion {
926 TypeStructField *fields;927 TypeStructField *fields;
927 uint64_t size_bytes;928 uint64_t size_bytes;
928 bool is_invalid; // true if any fields are invalid929 bool is_invalid; // true if any fields are invalid
929 Scope *scope;930 ScopeDecls *decls_scope;
930931
931 // set this flag temporarily to detect infinite loops932 // set this flag temporarily to detect infinite loops
932 bool embedded_in_current;933 bool embedded_in_current;
...@@ -1044,7 +1045,7 @@ struct ImportTableEntry {...@@ -1044,7 +1045,7 @@ struct ImportTableEntry {
1044 ZigLLVMDIFile *di_file;1045 ZigLLVMDIFile *di_file;
1045 Buf *source_code;1046 Buf *source_code;
1046 ZigList<size_t> *line_offsets;1047 ZigList<size_t> *line_offsets;
1047 Scope *scope;1048 ScopeDecls *decls_scope;
1048 AstNode *c_import_node;1049 AstNode *c_import_node;
1049 bool any_imports_failed;1050 bool any_imports_failed;
10501051
...@@ -1070,8 +1071,6 @@ struct FnTableEntry {...@@ -1070,8 +1071,6 @@ struct FnTableEntry {
1070 AstNode *proto_node;1071 AstNode *proto_node;
1071 AstNode *fn_def_node;1072 AstNode *fn_def_node;
1072 ImportTableEntry *import_entry;1073 ImportTableEntry *import_entry;
1073 // Required to be a pre-order traversal of the AST. (parents must come before children)
1074 ZigList<Scope *> all_block_contexts;
1075 Buf symbol_name;1074 Buf symbol_name;
1076 TypeTableEntry *type_entry; // function type1075 TypeTableEntry *type_entry; // function type
1077 bool internal_linkage;1076 bool internal_linkage;
...@@ -1310,7 +1309,8 @@ struct VariableTableEntry {...@@ -1310,7 +1309,8 @@ struct VariableTableEntry {
1310 ZigLLVMDILocalVariable *di_loc_var;1309 ZigLLVMDILocalVariable *di_loc_var;
1311 size_t src_arg_index;1310 size_t src_arg_index;
1312 size_t gen_arg_index;1311 size_t gen_arg_index;
1313 Scope *scope;1312 Scope *parent_scope;
1313 Scope *child_scope;
1314 LLVMValueRef param_value_ref;1314 LLVMValueRef param_value_ref;
1315 bool force_depends_on_compile_var;1315 bool force_depends_on_compile_var;
1316 ImportTableEntry *import;1316 ImportTableEntry *import;
...@@ -1334,26 +1334,77 @@ struct LabelTableEntry {...@@ -1334,26 +1334,77 @@ struct LabelTableEntry {
1334struct Scope {1334struct Scope {
1335 AstNode *node;1335 AstNode *node;
13361336
1337 // any variables that are introduced by this scope1337 // if the scope has a parent, this is it. Every scope has a parent except
1338 // ScopeIdGlobal
1339 Scope *parent;
1340
1341 ZigLLVMDIScope *di_scope;
1342
1343 bool safety_off;
1344 AstNode *safety_set_node;
1345};
1346
1347// This scope comes from global declarations or from
1348// declarations in a container declaration
1349// NodeTypeRoot, NodeTypeContainerDecl
1350struct ScopeDecls {
1351 Scope base;
1352
1353 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> decl_table;
1354};
1355
1356// This scope comes from a container declaration such as a struct,
1357// enum, or union.
1358struct ScopeContainer {
1359 Scope base;
1360
1338 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> decl_table;1361 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> decl_table;
1339 HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> var_table;1362};
1363
1364// This scope comes from a block expression in user code.
1365// NodeTypeBlock
1366struct ScopeBlock {
1367 Scope base;
1368
1340 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table; 1369 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
1370};
13411371
1342 // if the block is inside a function, this is the function it is in:1372// This scope is created from every defer expression.
1343 FnTableEntry *fn_entry;1373// NodeTypeDefer
1374struct ScopeDefer {
1375 Scope base;
1376};
13441377
1345 // if the block has a parent, this is it1378// This scope is created for every variable declaration inside an IrExecutable
1346 Scope *parent;1379// NodeTypeVariableDeclaration, NodeTypeParamDecl
1380struct ScopeVarDecl {
1381 Scope base;
13471382
1348 // if break or continue is valid in this context, this is the loop node that1383 // The variable that creates this scope
1349 // it would pertain to1384 VariableTableEntry *var;
1350 AstNode *parent_loop_node;1385};
13511386
1352 ZigLLVMDIScope *di_scope;1387// This scope is created for a @cImport
1353 Buf *c_import_buf;1388// NodeTypeFnCallExpr
1389struct ScopeCImport {
1390 Scope base;
13541391
1355 bool safety_off;1392 Buf c_import_buf;
1356 AstNode *safety_set_node;1393};
1394
1395// This scope is created for a loop such as for or while in order to
1396// make break and continue statements work.
1397// NodeTypeForExpr or NodeTypeWhileExpr
1398struct ScopeLoop {
1399 Scope base;
1400};
1401
1402// This scope is created for a function definition.
1403// NodeTypeFnDef
1404struct ScopeFnBody {
1405 Scope base;
1406
1407 FnTableEntry *fn_entry;
1357};1408};
13581409
1359enum AtomicOrder {1410enum AtomicOrder {
src/analyze.cpp+172-146
...@@ -115,26 +115,24 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {...@@ -115,26 +115,24 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
115 return entry;115 return entry;
116}116}
117117
118static Scope **get_container_block_context_ptr(TypeTableEntry *type_entry) {118static ScopeDecls **get_container_scope_ptr(TypeTableEntry *type_entry) {
119 if (type_entry->id == TypeTableEntryIdStruct) {119 if (type_entry->id == TypeTableEntryIdStruct) {
120 return &type_entry->data.structure.scope;120 return &type_entry->data.structure.decls_scope;
121 } else if (type_entry->id == TypeTableEntryIdEnum) {121 } else if (type_entry->id == TypeTableEntryIdEnum) {
122 return &type_entry->data.enumeration.scope;122 return &type_entry->data.enumeration.decls_scope;
123 } else if (type_entry->id == TypeTableEntryIdUnion) {123 } else if (type_entry->id == TypeTableEntryIdUnion) {
124 return &type_entry->data.unionation.scope;124 return &type_entry->data.unionation.decls_scope;
125 }125 }
126 zig_unreachable();126 zig_unreachable();
127}127}
128128
129Scope *get_container_block_context(TypeTableEntry *type_entry) {129ScopeDecls *get_container_scope(TypeTableEntry *type_entry) {
130 return *get_container_block_context_ptr(type_entry);130 return *get_container_scope_ptr(type_entry);
131}131}
132132
133static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node,133static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node, Scope *parent_scope) {
134 Scope *parent_context)
135{
136 TypeTableEntry *entry = new_type_table_entry(id);134 TypeTableEntry *entry = new_type_table_entry(id);
137 *get_container_block_context_ptr(entry) = new_scope(source_node, parent_context);135 *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope);
138 return entry;136 return entry;
139}137}
140138
...@@ -766,11 +764,11 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {...@@ -766,11 +764,11 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
766 zig_unreachable();764 zig_unreachable();
767}765}
768766
769TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *context,767TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *scope,
770 ContainerKind kind, AstNode *decl_node, const char *name)768 ContainerKind kind, AstNode *decl_node, const char *name)
771{769{
772 TypeTableEntryId type_id = container_to_type(kind);770 TypeTableEntryId type_id = container_to_type(kind);
773 TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, context);771 TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope);
774772
775 switch (kind) {773 switch (kind) {
776 case ContainerKindStruct:774 case ContainerKindStruct:
...@@ -844,10 +842,10 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod...@@ -844,10 +842,10 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod
844 return result;842 return result;
845}843}
846844
847static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, Scope *context,845static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, Scope *scope,
848 AstNode *node)846 AstNode *node)
849{847{
850 IrInstruction *result = analyze_const_value(g, context, node, g->builtin_types.entry_type);848 IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type);
851 if (result->type_entry->id == TypeTableEntryIdInvalid)849 if (result->type_entry->id == TypeTableEntryIdInvalid)
852 return g->builtin_types.entry_invalid;850 return g->builtin_types.entry_invalid;
853851
...@@ -861,7 +859,7 @@ static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {...@@ -861,7 +859,7 @@ static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {
861}859}
862860
863// fn_table_entry is populated if and only if there is a function definition for this prototype861// fn_table_entry is populated if and only if there is a function definition for this prototype
864static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *import, Scope *context,862static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *import, Scope *scope,
865 TypeTableEntry *expected_type, AstNode *node, bool is_naked, bool is_cold, FnTableEntry *fn_table_entry)863 TypeTableEntry *expected_type, AstNode *node, bool is_naked, bool is_cold, FnTableEntry *fn_table_entry)
866{864{
867 assert(node->type == NodeTypeFnProto);865 assert(node->type == NodeTypeFnProto);
...@@ -888,7 +886,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -888,7 +886,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
888 if (fn_proto->skip) {886 if (fn_proto->skip) {
889 type_entry = g->builtin_types.entry_invalid;887 type_entry = g->builtin_types.entry_invalid;
890 } else {888 } else {
891 type_entry = analyze_type_expr(g, import, context, child->data.param_decl.type);889 type_entry = analyze_type_expr(g, import, scope, child->data.param_decl.type);
892 }890 }
893891
894 switch (type_entry->id) {892 switch (type_entry->id) {
...@@ -951,7 +949,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -951,7 +949,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
951 if (fn_proto->skip) {949 if (fn_proto->skip) {
952 fn_type_id.return_type = g->builtin_types.entry_invalid;950 fn_type_id.return_type = g->builtin_types.entry_invalid;
953 } else {951 } else {
954 fn_type_id.return_type = analyze_type_expr(g, import, context, fn_proto->return_type);952 fn_type_id.return_type = analyze_type_expr(g, import, scope, fn_proto->return_type);
955 }953 }
956 switch (fn_type_id.return_type->id) {954 switch (fn_type_id.return_type->id) {
957 case TypeTableEntryIdInvalid:955 case TypeTableEntryIdInvalid:
...@@ -1022,7 +1020,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -1022,7 +1020,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
1022}1020}
10231021
1024static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,1022static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,
1025 ImportTableEntry *import, Scope *containing_context)1023 ImportTableEntry *import, Scope *containing_scope)
1026{1024{
1027 assert(node->type == NodeTypeFnProto);1025 assert(node->type == NodeTypeFnProto);
1028 AstNodeFnProto *fn_proto = &node->data.fn_proto;1026 AstNodeFnProto *fn_proto = &node->data.fn_proto;
...@@ -1037,7 +1035,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t...@@ -1037,7 +1035,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
10371035
10381036
10391037
1040 TypeTableEntry *fn_type = analyze_fn_proto_type(g, import, containing_context, nullptr, node,1038 TypeTableEntry *fn_type = analyze_fn_proto_type(g, import, containing_scope, nullptr, node,
1041 fn_proto->is_nakedcc, fn_proto->is_coldcc, fn_table_entry);1039 fn_proto->is_nakedcc, fn_proto->is_coldcc, fn_table_entry);
10421040
1043 fn_table_entry->type_entry = fn_type;1041 fn_table_entry->type_entry = fn_type;
...@@ -1060,8 +1058,8 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t...@@ -1060,8 +1058,8 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
1060 }1058 }
10611059
1062 if (fn_table_entry->fn_def_node) {1060 if (fn_table_entry->fn_def_node) {
1063 Scope *context = new_scope(fn_table_entry->fn_def_node, containing_context);1061 fn_table_entry->fn_def_node->data.fn_def.containing_scope = create_fndef_scope(
1064 fn_table_entry->fn_def_node->data.fn_def.scope = context;1062 fn_table_entry->fn_def_node, containing_scope, fn_table_entry);
1065 }1063 }
10661064
1067 if (!fn_wants_full_static_eval(fn_table_entry)) {1065 if (!fn_wants_full_static_eval(fn_table_entry)) {
...@@ -1095,23 +1093,6 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t...@@ -1095,23 +1093,6 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
1095 ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim", "true");1093 ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim", "true");
1096 ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim-non-leaf", nullptr);1094 ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim-non-leaf", nullptr);
1097 }1095 }
1098
1099 if (fn_table_entry->fn_def_node) {
1100 // Add debug info.
1101 unsigned line_number = node->line + 1;
1102 unsigned scope_line = line_number;
1103 bool is_definition = fn_table_entry->fn_def_node != nullptr;
1104 unsigned flags = 0;
1105 bool is_optimized = g->is_release_build;
1106 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
1107 containing_context->di_scope, buf_ptr(&fn_table_entry->symbol_name), "",
1108 import->di_file, line_number,
1109 fn_type->di_type, fn_table_entry->internal_linkage,
1110 is_definition, scope_line, flags, is_optimized, nullptr);
1111
1112 fn_table_entry->fn_def_node->data.fn_def.scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
1113 ZigLLVMFnSetSubprogram(fn_table_entry->fn_value, subprogram);
1114 }
1115 }1096 }
1116}1097}
11171098
...@@ -1151,7 +1132,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1151,7 +1132,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1151 uint64_t biggest_align_in_bits = 0;1132 uint64_t biggest_align_in_bits = 0;
1152 uint64_t biggest_union_member_size_in_bits = 0;1133 uint64_t biggest_union_member_size_in_bits = 0;
11531134
1154 Scope *context = enum_type->data.enumeration.scope;1135 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
11551136
1156 // set temporary flag1137 // set temporary flag
1157 enum_type->data.enumeration.embedded_in_current = true;1138 enum_type->data.enumeration.embedded_in_current = true;
...@@ -1161,7 +1142,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1161,7 +1142,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1161 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);1142 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1162 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];1143 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
1163 type_enum_field->name = field_node->data.struct_field.name;1144 type_enum_field->name = field_node->data.struct_field.name;
1164 TypeTableEntry *field_type = analyze_type_expr(g, import, context,1145 TypeTableEntry *field_type = analyze_type_expr(g, import, scope,
1165 field_node->data.struct_field.type);1146 field_node->data.struct_field.type);
1166 type_enum_field->type_entry = field_type;1147 type_enum_field->type_entry = field_type;
1167 type_enum_field->value = i;1148 type_enum_field->value = i;
...@@ -1337,14 +1318,14 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1337,14 +1318,14 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1337 // this field should be set to true only during the recursive calls to resolve_struct_type1318 // this field should be set to true only during the recursive calls to resolve_struct_type
1338 struct_type->data.structure.embedded_in_current = true;1319 struct_type->data.structure.embedded_in_current = true;
13391320
1340 Scope *context = struct_type->data.structure.scope;1321 Scope *scope = &struct_type->data.structure.decls_scope->base;
13411322
1342 size_t gen_field_index = 0;1323 size_t gen_field_index = 0;
1343 for (size_t i = 0; i < field_count; i += 1) {1324 for (size_t i = 0; i < field_count; i += 1) {
1344 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);1325 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1345 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1326 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1346 type_struct_field->name = field_node->data.struct_field.name;1327 type_struct_field->name = field_node->data.struct_field.name;
1347 TypeTableEntry *field_type = analyze_type_expr(g, import, context,1328 TypeTableEntry *field_type = analyze_type_expr(g, import, scope,
1348 field_node->data.struct_field.type);1329 field_node->data.struct_field.type);
1349 type_struct_field->type_entry = field_type;1330 type_struct_field->type_entry = field_type;
1350 type_struct_field->src_index = i;1331 type_struct_field->src_index = i;
...@@ -1463,7 +1444,7 @@ static bool get_is_generic_fn(AstNode *proto_node) {...@@ -1463,7 +1444,7 @@ static bool get_is_generic_fn(AstNode *proto_node) {
1463}1444}
14641445
1465static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node,1446static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node,
1466 Scope *containing_context)1447 Scope *containing_scope)
1467{1448{
1468 assert(proto_node->type == NodeTypeFnProto);1449 assert(proto_node->type == NodeTypeFnProto);
14691450
...@@ -1515,7 +1496,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN...@@ -1515,7 +1496,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
15151496
15161497
1517 } else {1498 } else {
1518 resolve_function_proto(g, proto_node, fn_table_entry, import, containing_context);1499 resolve_function_proto(g, proto_node, fn_table_entry, import, containing_scope);
15191500
1520 if (!fn_wants_full_static_eval(fn_table_entry)) {1501 if (!fn_wants_full_static_eval(fn_table_entry)) {
1521 g->fn_protos.append(fn_table_entry);1502 g->fn_protos.append(fn_table_entry);
...@@ -1546,7 +1527,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN...@@ -1546,7 +1527,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
1546 }1527 }
1547}1528}
15481529
1549static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, Scope *scope,1530static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope,
1550 AstNode *node, Buf *name)1531 AstNode *node, Buf *name)
1551{1532{
1552 assert(import);1533 assert(import);
...@@ -1562,19 +1543,17 @@ static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, Scope *scop...@@ -1562,19 +1543,17 @@ static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, Scope *scop
1562 g->resolve_queue.append(node);1543 g->resolve_queue.append(node);
1563 }1544 }
15641545
1565 node->scope = scope;1546 node->scope = &decls_scope->base;
15661547
1567 auto entry = scope->decl_table.maybe_get(name);1548 auto entry = decls_scope->decl_table.put_unique(name, node);
1568 if (entry) {1549 if (entry) {
1569 AstNode *other_decl_node = entry->value;1550 AstNode *other_decl_node = entry->value;
1570 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redefinition of '%s'", buf_ptr(name)));1551 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redefinition of '%s'", buf_ptr(name)));
1571 add_error_note(g, msg, other_decl_node, buf_sprintf("previous definition is here"));1552 add_error_note(g, msg, other_decl_node, buf_sprintf("previous definition is here"));
1572 } else {
1573 scope->decl_table.put(name, node);
1574 }1553 }
1575}1554}
15761555
1577static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *node) {1556static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node) {
1578 assert(node->type == NodeTypeContainerDecl);1557 assert(node->type == NodeTypeContainerDecl);
15791558
1580 if (node->data.struct_decl.type_entry) {1559 if (node->data.struct_decl.type_entry) {
...@@ -1583,7 +1562,7 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, Scope *contex...@@ -1583,7 +1562,7 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, Scope *contex
1583 }1562 }
15841563
1585 Buf *name = node->data.struct_decl.name;1564 Buf *name = node->data.struct_decl.name;
1586 TypeTableEntry *container_type = get_partial_container_type(g, import, context,1565 TypeTableEntry *container_type = get_partial_container_type(g, import, &decls_scope->base,
1587 node->data.struct_decl.kind, node, buf_ptr(name));1566 node->data.struct_decl.kind, node, buf_ptr(name));
1588 node->data.struct_decl.type_entry = container_type;1567 node->data.struct_decl.type_entry = container_type;
15891568
...@@ -1591,8 +1570,8 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, Scope *contex...@@ -1591,8 +1570,8 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, Scope *contex
1591 for (size_t i = 0; i < node->data.struct_decl.decls.length; i += 1) {1570 for (size_t i = 0; i < node->data.struct_decl.decls.length; i += 1) {
1592 AstNode *child_node = node->data.struct_decl.decls.at(i);1571 AstNode *child_node = node->data.struct_decl.decls.at(i);
1593 get_as_top_level_decl(child_node)->parent_decl = node;1572 get_as_top_level_decl(child_node)->parent_decl = node;
1594 Scope *child_context = get_container_block_context(container_type);1573 ScopeDecls *child_scope = get_container_scope(container_type);
1595 scan_decls(g, import, child_context, child_node);1574 scan_decls(g, import, child_scope, child_node);
1596 }1575 }
1597}1576}
15981577
...@@ -1644,37 +1623,37 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {...@@ -1644,37 +1623,37 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1644 node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;1623 node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
1645}1624}
16461625
1647void scan_decls(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *node) {1626void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node) {
1648 switch (node->type) {1627 switch (node->type) {
1649 case NodeTypeRoot:1628 case NodeTypeRoot:
1650 for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {1629 for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
1651 AstNode *child = import->root->data.root.top_level_decls.at(i);1630 AstNode *child = import->root->data.root.top_level_decls.at(i);
1652 scan_decls(g, import, context, child);1631 scan_decls(g, import, decls_scope, child);
1653 }1632 }
1654 break;1633 break;
1655 case NodeTypeContainerDecl:1634 case NodeTypeContainerDecl:
1656 {1635 {
1657 Buf *name = node->data.struct_decl.name;1636 Buf *name = node->data.struct_decl.name;
1658 add_top_level_decl(g, import, context, node, name);1637 add_top_level_decl(g, import, decls_scope, node, name);
1659 if (node->data.struct_decl.generic_params.length == 0) {1638 if (node->data.struct_decl.generic_params.length == 0) {
1660 scan_struct_decl(g, import, context, node);1639 scan_struct_decl(g, import, decls_scope, node);
1661 }1640 }
1662 }1641 }
1663 break;1642 break;
1664 case NodeTypeFnDef:1643 case NodeTypeFnDef:
1665 node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = node;1644 node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = node;
1666 scan_decls(g, import, context, node->data.fn_def.fn_proto);1645 scan_decls(g, import, decls_scope, node->data.fn_def.fn_proto);
1667 break;1646 break;
1668 case NodeTypeVariableDeclaration:1647 case NodeTypeVariableDeclaration:
1669 {1648 {
1670 Buf *name = node->data.variable_declaration.symbol;1649 Buf *name = node->data.variable_declaration.symbol;
1671 add_top_level_decl(g, import, context, node, name);1650 add_top_level_decl(g, import, decls_scope, node, name);
1672 break;1651 break;
1673 }1652 }
1674 case NodeTypeTypeDecl:1653 case NodeTypeTypeDecl:
1675 {1654 {
1676 Buf *name = node->data.type_decl.symbol;1655 Buf *name = node->data.type_decl.symbol;
1677 add_top_level_decl(g, import, context, node, name);1656 add_top_level_decl(g, import, decls_scope, node, name);
1678 break;1657 break;
1679 }1658 }
1680 case NodeTypeFnProto:1659 case NodeTypeFnProto:
...@@ -1688,14 +1667,14 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *n...@@ -1688,14 +1667,14 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *n
1688 }1667 }
1689 count_inline_and_var_args(node);1668 count_inline_and_var_args(node);
16901669
1691 add_top_level_decl(g, import, context, node, fn_name);1670 add_top_level_decl(g, import, decls_scope, node, fn_name);
1692 break;1671 break;
1693 }1672 }
1694 case NodeTypeUse:1673 case NodeTypeUse:
1695 {1674 {
1696 TopLevelDecl *tld = get_as_top_level_decl(node);1675 TopLevelDecl *tld = get_as_top_level_decl(node);
1697 tld->import = import;1676 tld->import = import;
1698 node->scope = context;1677 node->scope = &decls_scope->base;
1699 g->use_queue.append(node);1678 g->use_queue.append(node);
1700 tld->import->use_decls.append(node);1679 tld->import->use_decls.append(node);
1701 break;1680 break;
...@@ -1816,70 +1795,65 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -1816,70 +1795,65 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
18161795
1817// Set name to nullptr to make the variable anonymous (not visible to programmer).1796// Set name to nullptr to make the variable anonymous (not visible to programmer).
1818// TODO merge with definition of add_local_var in ir.cpp1797// TODO merge with definition of add_local_var in ir.cpp
1819static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_node, ImportTableEntry *import,1798static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import,
1820 Scope *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node,1799 Scope *parent_scope, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node)
1821 bool shadowable)
1822{1800{
1823 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);1801 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
1824 variable_entry->type = type_entry;1802 variable_entry->type = type_entry;
1825 variable_entry->scope = context;1803 variable_entry->parent_scope = parent_scope;
1826 variable_entry->import = import;1804 variable_entry->import = import;
1827 variable_entry->shadowable = shadowable;1805 variable_entry->shadowable = false;
1828 variable_entry->mem_slot_index = SIZE_MAX;1806 variable_entry->mem_slot_index = SIZE_MAX;
18291807
1830 if (name) {1808 assert(name);
1831 buf_init_from_buf(&variable_entry->name, name);
18321809
1833 if (type_entry->id != TypeTableEntryIdInvalid) {1810 buf_init_from_buf(&variable_entry->name, name);
1834 VariableTableEntry *existing_var = find_variable(g, context, name);1811
1835 if (existing_var && !existing_var->shadowable) {1812 if (type_entry->id != TypeTableEntryIdInvalid) {
1836 ErrorMsg *msg = add_node_error(g, source_node,1813 VariableTableEntry *existing_var = find_variable(g, parent_scope, name);
1837 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));1814 if (existing_var && !existing_var->shadowable) {
1838 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));1815 ErrorMsg *msg = add_node_error(g, source_node,
1816 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
1817 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
1818 variable_entry->type = g->builtin_types.entry_invalid;
1819 } else {
1820 auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
1821 if (primitive_table_entry) {
1822 TypeTableEntry *type = primitive_table_entry->value;
1823 add_node_error(g, source_node,
1824 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
1839 variable_entry->type = g->builtin_types.entry_invalid;1825 variable_entry->type = g->builtin_types.entry_invalid;
1840 } else {1826 } else {
1841 auto primitive_table_entry = g->primitive_type_table.maybe_get(name);1827 AstNode *decl_node = find_decl(parent_scope, name);
1842 if (primitive_table_entry) {1828 if (decl_node && decl_node->type != NodeTypeVariableDeclaration) {
1843 TypeTableEntry *type = primitive_table_entry->value;1829 ErrorMsg *msg = add_node_error(g, source_node,
1844 add_node_error(g, source_node,1830 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
1845 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));1831 add_error_note(g, msg, decl_node, buf_sprintf("previous definition is here"));
1846 variable_entry->type = g->builtin_types.entry_invalid;1832 variable_entry->type = g->builtin_types.entry_invalid;
1847 } else {
1848 AstNode *decl_node = find_decl(context, name);
1849 if (decl_node && decl_node->type != NodeTypeVariableDeclaration) {
1850 ErrorMsg *msg = add_node_error(g, source_node,
1851 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
1852 add_error_note(g, msg, decl_node, buf_sprintf("previous definition is here"));
1853 variable_entry->type = g->builtin_types.entry_invalid;
1854 }
1855 }1833 }
1856 }1834 }
1857 }1835 }
1836 }
18581837
1859 context->var_table.put(&variable_entry->name, variable_entry);1838 Scope *child_scope;
1839 if (source_node->type == NodeTypeParamDecl) {
1840 child_scope = create_var_scope(source_node, parent_scope, variable_entry);
1860 } else {1841 } else {
1861 // TODO replace _anon with @anon and make sure all tests still pass1842 // it's already in the decls table
1862 buf_init_from_str(&variable_entry->name, "_anon");1843 child_scope = parent_scope;
1863 }
1864 if (context->fn_entry) {
1865 context->fn_entry->variable_list.append(variable_entry);
1866 }1844 }
18671845
1846
1868 variable_entry->src_is_const = is_const;1847 variable_entry->src_is_const = is_const;
1869 variable_entry->gen_is_const = is_const;1848 variable_entry->gen_is_const = is_const;
1870 variable_entry->decl_node = source_node;1849 variable_entry->decl_node = source_node;
1871 variable_entry->val_node = val_node;1850 variable_entry->val_node = val_node;
1851 variable_entry->child_scope = child_scope;
18721852
18731853
1874 return variable_entry;1854 return variable_entry;
1875}1855}
18761856
1877static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import,
1878 Scope *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node)
1879{
1880 return add_local_var_shadowable(g, source_node, import, context, name, type_entry, is_const, val_node, false);
1881}
1882
1883static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {1857static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1884 assert(node->type == NodeTypeVariableDeclaration);1858 assert(node->type == NodeTypeVariableDeclaration);
18851859
...@@ -1889,8 +1863,6 @@ static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node...@@ -1889,8 +1863,6 @@ static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node
1889 bool is_export = (var_decl->top_level_decl.visib_mod == VisibModExport);1863 bool is_export = (var_decl->top_level_decl.visib_mod == VisibModExport);
1890 bool is_extern = var_decl->is_extern;1864 bool is_extern = var_decl->is_extern;
18911865
1892 assert(!scope->fn_entry);
1893
1894 TypeTableEntry *explicit_type = nullptr;1866 TypeTableEntry *explicit_type = nullptr;
1895 if (var_decl->type) {1867 if (var_decl->type) {
1896 TypeTableEntry *proposed_type = analyze_type_expr(g, import, scope, var_decl->type);1868 TypeTableEntry *proposed_type = analyze_type_expr(g, import, scope, var_decl->type);
...@@ -1980,7 +1952,7 @@ void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {...@@ -1980,7 +1952,7 @@ void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {
1980 if (node->data.type_decl.override_type) {1952 if (node->data.type_decl.override_type) {
1981 entry = node->data.type_decl.override_type;1953 entry = node->data.type_decl.override_type;
1982 } else {1954 } else {
1983 TypeTableEntry *child_type = analyze_type_expr(g, import, import->scope, type_node);1955 TypeTableEntry *child_type = analyze_type_expr(g, import, &import->decls_scope->base, type_node);
1984 if (child_type->id == TypeTableEntryIdInvalid) {1956 if (child_type->id == TypeTableEntryIdInvalid) {
1985 entry = child_type;1957 entry = child_type;
1986 } else {1958 } else {
...@@ -2170,52 +2142,105 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -2170,52 +2142,105 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
2170 return false;2142 return false;
2171}2143}
21722144
2173Scope *new_scope(AstNode *node, Scope *parent) {2145ScopeDecls *create_decls_scope(AstNode *node, Scope *parent) {
2174 Scope *context = allocate<Scope>(1);2146 assert(node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl);
2175 context->node = node;2147 ScopeDecls *scope = allocate<ScopeDecls>(1);
2176 context->parent = parent;2148 scope->base.node = node;
2177 context->decl_table.init(1);2149 scope->base.parent = parent;
2178 context->var_table.init(1);2150 scope->decl_table.init(4);
2179 context->label_table.init(1);2151 return scope;
2152}
2153
2154Scope *create_block_scope(AstNode *node, Scope *parent) {
2155 assert(node->type == NodeTypeBlock);
2156 ScopeBlock *scope = allocate<ScopeBlock>(1);
2157 scope->base.node = node;
2158 scope->base.parent = parent;
2159 scope->label_table.init(1);
2160 return &scope->base;
2161}
21802162
2181 if (parent) {2163Scope *create_defer_scope(AstNode *node, Scope *parent) {
2182 context->parent_loop_node = parent->parent_loop_node;2164 assert(node->type == NodeTypeDefer);
2183 context->c_import_buf = parent->c_import_buf;2165 ScopeDefer *scope = allocate<ScopeDefer>(1);
2184 }2166 scope->base.node = node;
2167 scope->base.parent = parent;
2168 return &scope->base;
2169}
21852170
2186 if (node && node->type == NodeTypeFnDef) {2171Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {
2187 AstNode *fn_proto_node = node->data.fn_def.fn_proto;2172 assert(node->type == NodeTypeVariableDeclaration || node->type == NodeTypeParamDecl);
2188 context->fn_entry = fn_proto_node->data.fn_proto.fn_table_entry;2173 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
2189 } else if (parent) {2174 scope->base.node = node;
2190 context->fn_entry = parent->fn_entry;2175 scope->base.parent = parent;
2191 }2176 scope->var = var;
2177 return &scope->base;
2178}
21922179
2193 if (context->fn_entry) {2180Scope *create_cimport_scope(AstNode *node, Scope *parent) {
2194 context->fn_entry->all_block_contexts.append(context);2181 assert(node->type == NodeTypeFnCallExpr);
2195 }2182 ScopeCImport *scope = allocate<ScopeCImport>(1);
2183 scope->base.node = node;
2184 scope->base.parent = parent;
2185 buf_resize(&scope->c_import_buf, 0);
2186 return &scope->base;
2187}
2188
2189Scope *create_loop_scope(AstNode *node, Scope *parent) {
2190 assert(node->type == NodeTypeWhileExpr || node->type == NodeTypeForExpr);
2191 ScopeLoop *scope = allocate<ScopeLoop>(1);
2192 scope->base.node = node;
2193 scope->base.parent = parent;
2194 return &scope->base;
2195}
21962196
2197 return context;2197Scope *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) {
2198 assert(node->type == NodeTypeFnDef);
2199 ScopeFnBody *scope = allocate<ScopeFnBody>(1);
2200 scope->base.node = node;
2201 scope->base.parent = parent;
2202 scope->fn_entry = fn_entry;
2203 return &scope->base;
2198}2204}
21992205
2200AstNode *find_decl(Scope *context, Buf *name) {2206AstNode *find_decl(Scope *scope, Buf *name) {
2201 while (context) {2207 while (scope) {
2202 auto entry = context->decl_table.maybe_get(name);2208 if (scope->node->type == NodeTypeRoot ||
2203 if (entry) {2209 scope->node->type == NodeTypeContainerDecl)
2204 return entry->value;2210 {
2211 ScopeDecls *decls_scope = (ScopeDecls *)scope;
2212 auto entry = decls_scope->decl_table.maybe_get(name);
2213 if (entry)
2214 return entry->value;
2205 }2215 }
2206 context = context->parent;2216 scope = scope->parent;
2207 }2217 }
2208 return nullptr;2218 return nullptr;
2209}2219}
22102220
2211VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name) {2221VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) {
2212 Scope *context = orig_context;2222 while (scope) {
2213 while (context) {2223 if (scope->node->type == NodeTypeVariableDeclaration ||
2214 auto entry = context->var_table.maybe_get(name);2224 scope->node->type == NodeTypeParamDecl)
2215 if (entry) {2225 {
2216 return entry->value;2226 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
2227 if (buf_eql_buf(name, &var_scope->var->name))
2228 return var_scope->var;
2229 } else if (scope->node->type == NodeTypeRoot ||
2230 scope->node->type == NodeTypeContainerDecl)
2231 {
2232 ScopeDecls *decls_scope = (ScopeDecls *)scope;
2233 auto entry = decls_scope->decl_table.maybe_get(name);
2234 if (entry) {
2235 AstNode *decl_node = entry->value;
2236 if (decl_node->type == NodeTypeVariableDeclaration) {
2237 VariableTableEntry *var = decl_node->data.variable_declaration.variable;
2238 if (var)
2239 return var;
2240 }
2241 }
2217 }2242 }
2218 context = context->parent;2243 scope = scope->parent;
2219 }2244 }
22202245
2221 return nullptr;2246 return nullptr;
...@@ -2355,7 +2380,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2355,7 +2380,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2355 }2380 }
2356 fn_table_entry->anal_state = FnAnalStateProbing;2381 fn_table_entry->anal_state = FnAnalStateProbing;
23572382
2358 Scope *context = node->data.fn_def.scope;2383 Scope *child_scope = node->data.fn_def.containing_scope;
23592384
2360 TypeTableEntry *fn_type = fn_table_entry->type_entry;2385 TypeTableEntry *fn_type = fn_table_entry->type_entry;
2361 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;2386 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
...@@ -2381,16 +2406,20 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2381,16 +2406,20 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2381 add_node_error(g, param_decl_node, buf_sprintf("missing parameter name"));2406 add_node_error(g, param_decl_node, buf_sprintf("missing parameter name"));
2382 }2407 }
23832408
2384 VariableTableEntry *var = add_local_var(g, param_decl_node, import, context, param_decl->name,2409 VariableTableEntry *var = add_local_var(g, param_decl_node, import, child_scope, param_decl->name,
2385 type, true, nullptr);2410 type, true, nullptr);
2386 var->src_arg_index = i;2411 var->src_arg_index = i;
2387 param_decl_node->data.param_decl.variable = var;2412 param_decl_node->data.param_decl.variable = var;
2413 child_scope = var->child_scope;
2414 fn_table_entry->variable_list.append(var);
23882415
2389 if (fn_type->data.fn.gen_param_info) {2416 if (fn_type->data.fn.gen_param_info) {
2390 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;2417 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;
2391 }2418 }
2392 }2419 }
23932420
2421 node->data.fn_def.child_scope = child_scope;
2422
2394 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;2423 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;
23952424
2396 if (fn_type->data.fn.fn_type_id.is_extern && handle_is_ptr(expected_type)) {2425 if (fn_type->data.fn.fn_type_id.is_extern && handle_is_ptr(expected_type)) {
...@@ -2456,7 +2485,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -2456,7 +2485,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
2456 continue;2485 continue;
2457 }2486 }
2458 if (target_tld->visib_mod != VisibModPrivate) {2487 if (target_tld->visib_mod != VisibModPrivate) {
2459 auto existing_entry = tld->import->scope->decl_table.maybe_get(target_tld->name);2488 auto existing_entry = tld->import->decls_scope->decl_table.put_unique(target_tld->name, decl_node);
2460 if (existing_entry) {2489 if (existing_entry) {
2461 AstNode *existing_decl = existing_entry->value;2490 AstNode *existing_decl = existing_entry->value;
2462 if (existing_decl != decl_node) {2491 if (existing_decl != decl_node) {
...@@ -2466,8 +2495,6 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -2466,8 +2495,6 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
2466 add_error_note(g, msg, existing_decl, buf_sprintf("previous definition here"));2495 add_error_note(g, msg, existing_decl, buf_sprintf("previous definition here"));
2467 add_error_note(g, msg, decl_node, buf_sprintf("imported definition here"));2496 add_error_note(g, msg, decl_node, buf_sprintf("imported definition here"));
2468 }2497 }
2469 } else {
2470 tld->import->scope->decl_table.put(target_tld->name, decl_node);
2471 }2498 }
2472 }2499 }
2473 }2500 }
...@@ -2494,7 +2521,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {...@@ -2494,7 +2521,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {
2494 assert(node->type == NodeTypeUse);2521 assert(node->type == NodeTypeUse);
2495 TopLevelDecl *tld = get_as_top_level_decl(node);2522 TopLevelDecl *tld = get_as_top_level_decl(node);
24962523
2497 IrInstruction *result = analyze_const_value(g, tld->import->scope, node->data.use.expr,2524 IrInstruction *result = analyze_const_value(g, &tld->import->decls_scope->base, node->data.use.expr,
2498 g->builtin_types.entry_namespace);2525 g->builtin_types.entry_namespace);
2499 if (result->type_entry->id == TypeTableEntryIdInvalid)2526 if (result->type_entry->id == TypeTableEntryIdInvalid)
2500 tld->import->any_imports_failed = true;2527 tld->import->any_imports_failed = true;
...@@ -2553,8 +2580,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,...@@ -2553,8 +2580,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
2553 g->import_table.put(abs_full_path, import_entry);2580 g->import_table.put(abs_full_path, import_entry);
2554 g->import_queue.append(import_entry);2581 g->import_queue.append(import_entry);
25552582
2556 import_entry->scope = new_scope(import_entry->root, nullptr);2583 import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr);
2557 import_entry->scope->di_scope = ZigLLVMFileToScope(import_entry->di_file);
25582584
25592585
2560 assert(import_entry->root->type == NodeTypeRoot);2586 assert(import_entry->root->type == NodeTypeRoot);
...@@ -2581,7 +2607,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,...@@ -2581,7 +2607,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
2581void semantic_analyze(CodeGen *g) {2607void semantic_analyze(CodeGen *g) {
2582 for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) {2608 for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) {
2583 ImportTableEntry *import = g->import_queue.at(g->import_queue_index);2609 ImportTableEntry *import = g->import_queue.at(g->import_queue_index);
2584 scan_decls(g, import, import->scope, import->root);2610 scan_decls(g, import, import->decls_scope, import->root);
2585 }2611 }
25862612
2587 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {2613 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {
src/analyze.hpp+10-3
...@@ -15,7 +15,6 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);...@@ -15,7 +15,6 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
15ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);15ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
16TypeTableEntry *new_type_table_entry(TypeTableEntryId id);16TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
17TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);17TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
18Scope *new_scope(AstNode *node, Scope *parent);
19bool is_node_void_expr(AstNode *node);18bool is_node_void_expr(AstNode *node);
20uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);19uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
21TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);20TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);
...@@ -59,11 +58,19 @@ TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);...@@ -59,11 +58,19 @@ TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
59bool type_is_complete(TypeTableEntry *type_entry);58bool type_is_complete(TypeTableEntry *type_entry);
60void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry);59void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry);
61TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);60TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
62Scope *get_container_block_context(TypeTableEntry *type_entry);61ScopeDecls *get_container_scope(TypeTableEntry *type_entry);
63TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);62TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
64bool is_container_ref(TypeTableEntry *type_entry);63bool is_container_ref(TypeTableEntry *type_entry);
65void scan_decls(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *node);64void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node);
66void preview_use_decl(CodeGen *g, AstNode *node);65void preview_use_decl(CodeGen *g, AstNode *node);
67void resolve_use_decl(CodeGen *g, AstNode *node);66void resolve_use_decl(CodeGen *g, AstNode *node);
6867
68ScopeDecls *create_decls_scope(AstNode *node, Scope *parent);
69Scope *create_block_scope(AstNode *node, Scope *parent);
70Scope *create_defer_scope(AstNode *node, Scope *parent);
71Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);
72Scope *create_cimport_scope(AstNode *node, Scope *parent);
73Scope *create_loop_scope(AstNode *node, Scope *parent);
74Scope *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry);
75
69#endif76#endif
src/codegen.cpp+44-26
...@@ -227,9 +227,47 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) {...@@ -227,9 +227,47 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) {
227static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);227static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
228static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);228static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
229229
230static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
231 if (scope->di_scope)
232 return scope->di_scope;
233
234 if (scope->node->type == NodeTypeFnDef) {
235 assert(scope->parent);
236 ScopeFnBody *fn_scope = (ScopeFnBody *)scope;
237 FnTableEntry *fn_table_entry = fn_scope->fn_entry;
238 unsigned line_number = fn_table_entry->proto_node->line + 1;
239 unsigned scope_line = line_number;
240 bool is_definition = fn_table_entry->fn_def_node != nullptr;
241 unsigned flags = 0;
242 bool is_optimized = g->is_release_build;
243 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
244 get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "",
245 scope->node->owner->di_file, line_number,
246 fn_table_entry->type_entry->di_type, fn_table_entry->internal_linkage,
247 is_definition, scope_line, flags, is_optimized, nullptr);
248
249 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
250 ZigLLVMFnSetSubprogram(fn_table_entry->fn_value, subprogram);
251 } else if (scope->node->type == NodeTypeRoot ||
252 scope->node->type == NodeTypeContainerDecl)
253 {
254 scope->di_scope = ZigLLVMFileToScope(scope->node->owner->di_file);
255 } else {
256 assert(scope->parent);
257 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
258 get_di_scope(g, scope->parent),
259 scope->node->owner->di_file,
260 scope->node->line + 1,
261 scope->node->column + 1);
262 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
263 }
264
265 return scope->di_scope;
266}
267
230static void set_debug_source_node(CodeGen *g, AstNode *node) {268static void set_debug_source_node(CodeGen *g, AstNode *node) {
231 assert(node->scope);269 assert(node->scope);
232 ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->scope->di_scope);270 ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, get_di_scope(g, node->scope));
233}271}
234272
235static void clear_debug_source_node(CodeGen *g) {273static void clear_debug_source_node(CodeGen *g) {
...@@ -558,10 +596,9 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node,...@@ -558,10 +596,9 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node,
558}596}
559597
560static void gen_var_debug_decl(CodeGen *g, VariableTableEntry *var) {598static void gen_var_debug_decl(CodeGen *g, VariableTableEntry *var) {
561 Scope *scope = var->scope;
562 AstNode *source_node = var->decl_node;599 AstNode *source_node = var->decl_node;
563 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc(source_node->line + 1, source_node->column + 1,600 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc(source_node->line + 1, source_node->column + 1,
564 scope->di_scope);601 get_di_scope(g, var->parent_scope));
565 ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,602 ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,
566 LLVMGetInsertBlock(g->builder));603 LLVMGetInsertBlock(g->builder));
567}604}
...@@ -2133,8 +2170,7 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini...@@ -2133,8 +2170,7 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini
2133 assert(var->import);2170 assert(var->import);
2134 assert(type_entry);2171 assert(type_entry);
2135 bool is_local_to_unit = true;2172 bool is_local_to_unit = true;
2136 ZigLLVMCreateGlobalVariable(g->dbuilder,2173 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), buf_ptr(&var->name),
2137 var->scope->di_scope, buf_ptr(&var->name),
2138 buf_ptr(&var->name), var->import->di_file, var->decl_node->line + 1,2174 buf_ptr(&var->name), var->import->di_file, var->decl_node->line + 1,
2139 type_entry->di_type, is_local_to_unit, init_val);2175 type_entry->di_type, is_local_to_unit, init_val);
2140}2176}
...@@ -2328,24 +2364,6 @@ static void do_code_gen(CodeGen *g) {...@@ -2328,24 +2364,6 @@ static void do_code_gen(CodeGen *g) {
2328 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;2364 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
23292365
2330 build_all_basic_blocks(g, fn_table_entry);2366 build_all_basic_blocks(g, fn_table_entry);
2331
2332
2333 // Set up debug info for blocks
2334 for (size_t bc_i = 0; bc_i < fn_table_entry->all_block_contexts.length; bc_i += 1) {
2335 Scope *scope = fn_table_entry->all_block_contexts.at(bc_i);
2336
2337 if (!scope->di_scope) {
2338 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
2339 scope->parent->di_scope,
2340 import->di_file,
2341 scope->node->line + 1,
2342 scope->node->column + 1);
2343 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
2344 }
2345
2346
2347 }
2348
2349 clear_debug_source_node(g);2367 clear_debug_source_node(g);
23502368
2351 // allocate temporary stack data2369 // allocate temporary stack data
...@@ -2383,7 +2401,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2383,7 +2401,7 @@ static void do_code_gen(CodeGen *g) {
2383 if (var->is_inline)2401 if (var->is_inline)
2384 continue;2402 continue;
23852403
2386 if (var->scope->node->type == NodeTypeFnDef) {2404 if (var->parent_scope->node->type == NodeTypeFnDef) {
2387 assert(var->gen_arg_index != SIZE_MAX);2405 assert(var->gen_arg_index != SIZE_MAX);
2388 TypeTableEntry *gen_type;2406 TypeTableEntry *gen_type;
2389 if (handle_is_ptr(var->type)) {2407 if (handle_is_ptr(var->type)) {
...@@ -2395,7 +2413,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2395,7 +2413,7 @@ static void do_code_gen(CodeGen *g) {
2395 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);2413 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
2396 LLVMSetAlignment(var->value_ref, align_bytes);2414 LLVMSetAlignment(var->value_ref, align_bytes);
2397 }2415 }
2398 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, var->scope->di_scope,2416 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
2399 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,2417 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
2400 gen_type->di_type, !g->strip_debug_symbols, 0, var->gen_arg_index + 1);2418 gen_type->di_type, !g->strip_debug_symbols, 0, var->gen_arg_index + 1);
24012419
...@@ -2406,7 +2424,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2406,7 +2424,7 @@ static void do_code_gen(CodeGen *g) {
2406 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);2424 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
2407 LLVMSetAlignment(var->value_ref, align_bytes);2425 LLVMSetAlignment(var->value_ref, align_bytes);
24082426
2409 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, var->scope->di_scope,2427 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
2410 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,2428 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
2411 var->type->di_type, !g->strip_debug_symbols, 0);2429 var->type->di_type, !g->strip_debug_symbols, 0);
2412 }2430 }
src/hash_map.hpp+9
...@@ -61,6 +61,15 @@ public:...@@ -61,6 +61,15 @@ public:
61 }61 }
62 }62 }
6363
64 Entry *put_unique(const K &key, const V &value) {
65 // TODO make this more efficient
66 Entry *entry = internal_get(key);
67 if (entry)
68 return entry;
69 put(key, value);
70 return nullptr;
71 }
72
64 const V &get(const K &key) const {73 const V &get(const K &key) const {
65 Entry *entry = internal_get(key);74 Entry *entry = internal_get(key);
66 if (!entry)75 if (!entry)
src/ir.cpp+108-65
...@@ -1211,28 +1211,39 @@ static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instr...@@ -1211,28 +1211,39 @@ static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instr
1211 return new_instruction;1211 return new_instruction;
1212}1212}
12131213
1214static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_block, Scope *outer_block,1214static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
1215 bool gen_error_defers, bool gen_maybe_defers)1215 bool gen_error_defers, bool gen_maybe_defers)
1216{1216{
1217 while (inner_block != outer_block) {1217 while (inner_scope != outer_scope) {
1218 if (inner_block->node->type == NodeTypeDefer &&1218 if (inner_scope->node->type == NodeTypeDefer &&
1219 ((inner_block->node->data.defer.kind == ReturnKindUnconditional) ||1219 ((inner_scope->node->data.defer.kind == ReturnKindUnconditional) ||
1220 (gen_error_defers && inner_block->node->data.defer.kind == ReturnKindError) ||1220 (gen_error_defers && inner_scope->node->data.defer.kind == ReturnKindError) ||
1221 (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe)))1221 (gen_maybe_defers && inner_scope->node->data.defer.kind == ReturnKindMaybe)))
1222 {1222 {
1223 AstNode *defer_expr_node = inner_block->node->data.defer.expr;1223 AstNode *defer_expr_node = inner_scope->node->data.defer.expr;
1224 ir_gen_node(irb, defer_expr_node, defer_expr_node->scope);1224 ir_gen_node(irb, defer_expr_node, defer_expr_node->scope);
1225 }1225 }
1226 inner_block = inner_block->parent;1226 inner_scope = inner_scope->parent;
1227 }1227 }
1228}1228}
12291229
1230static FnTableEntry *scope_fn_entry(Scope *scope) {
1231 while (scope) {
1232 if (scope->node->type == NodeTypeFnDef) {
1233 ScopeFnBody *fn_scope = (ScopeFnBody *)scope;
1234 return fn_scope->fn_entry;
1235 }
1236 scope = scope->parent;
1237 }
1238 return nullptr;
1239}
1240
1230static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {1241static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {
1231 assert(node->type == NodeTypeReturnExpr);1242 assert(node->type == NodeTypeReturnExpr);
12321243
1233 Scope *scope = node->scope;1244 Scope *scope = node->scope;
12341245
1235 if (!scope->fn_entry) {1246 if (!scope_fn_entry(scope)) {
1236 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition"));1247 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition"));
1237 return irb->codegen->invalid_instruction;1248 return irb->codegen->invalid_instruction;
1238 }1249 }
...@@ -1243,7 +1254,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {...@@ -1243,7 +1254,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {
1243 {1254 {
1244 IrInstruction *return_value;1255 IrInstruction *return_value;
1245 if (expr_node) {1256 if (expr_node) {
1246 return_value = ir_gen_node(irb, expr_node, scope);1257 return_value = ir_gen_node(irb, expr_node, node->scope);
1247 } else {1258 } else {
1248 return_value = ir_build_const_void(irb, node);1259 return_value = ir_build_const_void(irb, node);
1249 }1260 }
...@@ -1264,11 +1275,11 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {...@@ -1264,11 +1275,11 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
1264 irb->current_basic_block = basic_block;1275 irb->current_basic_block = basic_block;
1265}1276}
12661277
1267static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope *scope,1278static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
1268 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)1279 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)
1269{1280{
1270 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);1281 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
1271 variable_entry->scope = scope;1282 variable_entry->parent_scope = parent_scope;
1272 variable_entry->import = node->owner;1283 variable_entry->import = node->owner;
1273 variable_entry->shadowable = is_shadowable;1284 variable_entry->shadowable = is_shadowable;
1274 variable_entry->mem_slot_index = SIZE_MAX;1285 variable_entry->mem_slot_index = SIZE_MAX;
...@@ -1277,7 +1288,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope...@@ -1277,7 +1288,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope
1277 if (name) {1288 if (name) {
1278 buf_init_from_buf(&variable_entry->name, name);1289 buf_init_from_buf(&variable_entry->name, name);
12791290
1280 VariableTableEntry *existing_var = find_variable(codegen, scope, name);1291 VariableTableEntry *existing_var = find_variable(codegen, parent_scope, name);
1281 if (existing_var && !existing_var->shadowable) {1292 if (existing_var && !existing_var->shadowable) {
1282 ErrorMsg *msg = add_node_error(codegen, node,1293 ErrorMsg *msg = add_node_error(codegen, node,
1283 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));1294 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
...@@ -1291,7 +1302,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope...@@ -1291,7 +1302,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope
1291 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));1302 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
1292 variable_entry->type = codegen->builtin_types.entry_invalid;1303 variable_entry->type = codegen->builtin_types.entry_invalid;
1293 } else {1304 } else {
1294 AstNode *decl_node = find_decl(scope, name);1305 AstNode *decl_node = find_decl(parent_scope, name);
1295 if (decl_node && decl_node->type != NodeTypeVariableDeclaration) {1306 if (decl_node && decl_node->type != NodeTypeVariableDeclaration) {
1296 ErrorMsg *msg = add_node_error(codegen, node,1307 ErrorMsg *msg = add_node_error(codegen, node,
1297 buf_sprintf("redefinition of '%s'", buf_ptr(name)));1308 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
...@@ -1301,28 +1312,32 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope...@@ -1301,28 +1312,32 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope
1301 }1312 }
1302 }1313 }
13031314
1304 scope->var_table.put(&variable_entry->name, variable_entry);
1305 } else {1315 } else {
1306 assert(is_shadowable);1316 assert(is_shadowable);
1307 // TODO replace _anon with @anon and make sure all tests still pass1317 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon"
1318 // might already be solved, let's just make sure it has test coverage
1319 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables
1308 buf_init_from_str(&variable_entry->name, "_anon");1320 buf_init_from_str(&variable_entry->name, "_anon");
1309 }1321 }
13101322
1311 variable_entry->src_is_const = src_is_const;1323 variable_entry->src_is_const = src_is_const;
1312 variable_entry->gen_is_const = gen_is_const;1324 variable_entry->gen_is_const = gen_is_const;
1313 variable_entry->decl_node = node;1325 variable_entry->decl_node = node;
1326 variable_entry->child_scope = create_var_scope(node, parent_scope, variable_entry);
13141327
1315 return variable_entry;1328 return variable_entry;
1316}1329}
13171330
1318// Set name to nullptr to make the variable anonymous (not visible to programmer).1331// Set name to nullptr to make the variable anonymous (not visible to programmer).
1319static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name,1332// After you call this function var->child_scope has the variable in scope
1333static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name,
1320 bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)1334 bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)
1321{1335{
1322 VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name,1336 VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name,
1323 src_is_const, gen_is_const, is_shadowable, is_inline);1337 src_is_const, gen_is_const, is_shadowable, is_inline);
1324 if (is_inline || gen_is_const)1338 if (is_inline || gen_is_const)
1325 var->mem_slot_index = exec_next_mem_slot(irb->exec);1339 var->mem_slot_index = exec_next_mem_slot(irb->exec);
1340 assert(var->child_scope);
1326 return var;1341 return var;
1327}1342}
13281343
...@@ -1330,7 +1345,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {...@@ -1330,7 +1345,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {
1330 assert(block_node->type == NodeTypeBlock);1345 assert(block_node->type == NodeTypeBlock);
13311346
1332 Scope *parent_scope = block_node->scope;1347 Scope *parent_scope = block_node->scope;
1333 Scope *outer_block_scope = new_scope(block_node, parent_scope);1348 Scope *outer_block_scope = create_block_scope(block_node, parent_scope);
1334 Scope *child_scope = outer_block_scope;1349 Scope *child_scope = outer_block_scope;
13351350
1336 IrInstruction *return_value = nullptr;1351 IrInstruction *return_value = nullptr;
...@@ -1341,6 +1356,9 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {...@@ -1341,6 +1356,9 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {
1341 // defer starts a new block context1356 // defer starts a new block context
1342 child_scope = statement_node->data.defer.child_block;1357 child_scope = statement_node->data.defer.child_block;
1343 assert(child_scope);1358 assert(child_scope);
1359 } else if (return_value->id == IrInstructionIdDeclVar) {
1360 IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)return_value;
1361 child_scope = decl_var_instruction->var->child_scope;
1344 }1362 }
1345 }1363 }
13461364
...@@ -1760,7 +1778,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1760,7 +1778,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
1760 if (arg0_value == irb->codegen->invalid_instruction)1778 if (arg0_value == irb->codegen->invalid_instruction)
1761 return arg0_value;1779 return arg0_value;
17621780
1763 if (node->scope->fn_entry) {1781 if (scope_fn_entry(node->scope)) {
1764 add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope"));1782 add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope"));
1765 return irb->codegen->invalid_instruction;1783 return irb->codegen->invalid_instruction;
1766 }1784 }
...@@ -1999,8 +2017,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {...@@ -1999,8 +2017,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
1999 bool is_const = variable_declaration->is_const;2017 bool is_const = variable_declaration->is_const;
2000 bool is_extern = variable_declaration->is_extern;2018 bool is_extern = variable_declaration->is_extern;
2001 bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline;2019 bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline;
2002 VariableTableEntry *var = ir_add_local_var(irb, node, node->scope,2020 VariableTableEntry *var = ir_create_var(irb, node, node->scope,
2003 variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);2021 variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);
2022 // we detect IrInstructionIdDeclVar in gen_block to make sure the next node
2023 // is inside var->child_scope
20042024
2005 if (!is_extern && !variable_declaration->expr) {2025 if (!is_extern && !variable_declaration->expr) {
2006 var->type = irb->codegen->builtin_types.entry_invalid;2026 var->type = irb->codegen->builtin_types.entry_invalid;
...@@ -2079,14 +2099,15 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -2079,14 +2099,15 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
2079 }2099 }
2080 bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline;2100 bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline;
20812101
2082 Scope *child_scope = new_scope(node, parent_scope);2102 Scope *child_scope = create_loop_scope(node, parent_scope);
2083 child_scope->parent_loop_node = node;
2084 elem_node->scope = child_scope;2103 elem_node->scope = child_scope;
20852104
2086 // TODO make it an error to write to element variable or i variable.2105 // TODO make it an error to write to element variable or i variable.
2087 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;2106 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
2088 node->data.for_expr.elem_var = ir_add_local_var(irb, elem_node, child_scope, elem_var_name,2107 node->data.for_expr.elem_var = ir_create_var(irb, elem_node, child_scope, elem_var_name,
2089 true, false, false, is_inline);2108 true, false, false, is_inline);
2109 child_scope = node->data.for_expr.elem_var->child_scope;
2110
2090 IrInstruction *undefined_value = ir_build_const_undefined(irb, elem_node);2111 IrInstruction *undefined_value = ir_build_const_undefined(irb, elem_node);
2091 ir_build_var_decl(irb, elem_node, node->data.for_expr.elem_var, elem_var_type, undefined_value); 2112 ir_build_var_decl(irb, elem_node, node->data.for_expr.elem_var, elem_var_type, undefined_value);
2092 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.elem_var);2113 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.elem_var);
...@@ -2096,13 +2117,15 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -2096,13 +2117,15 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
2096 index_var_source_node = index_node;2117 index_var_source_node = index_node;
2097 Buf *index_var_name = index_node->data.symbol_expr.symbol;2118 Buf *index_var_name = index_node->data.symbol_expr.symbol;
2098 index_node->scope = child_scope;2119 index_node->scope = child_scope;
2099 node->data.for_expr.index_var = ir_add_local_var(irb, index_node, child_scope, index_var_name,2120 node->data.for_expr.index_var = ir_create_var(irb, index_node, child_scope, index_var_name,
2100 true, false, false, is_inline);2121 true, false, false, is_inline);
2101 } else {2122 } else {
2102 index_var_source_node = node;2123 index_var_source_node = node;
2103 node->data.for_expr.index_var = ir_add_local_var(irb, node, child_scope, nullptr,2124 node->data.for_expr.index_var = ir_create_var(irb, node, child_scope, nullptr,
2104 true, false, true, is_inline);2125 true, false, true, is_inline);
2105 }2126 }
2127 child_scope = node->data.for_expr.index_var->child_scope;
2128
2106 IrInstruction *usize = ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_usize);2129 IrInstruction *usize = ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_usize);
2107 IrInstruction *zero = ir_build_const_usize(irb, node, 0);2130 IrInstruction *zero = ir_build_const_usize(irb, node, 0);
2108 IrInstruction *one = ir_build_const_usize(irb, node, 1);2131 IrInstruction *one = ir_build_const_usize(irb, node, 1);
...@@ -2159,10 +2182,11 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, AstNode *node) {...@@ -2159,10 +2182,11 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, AstNode *node) {
2159 if (!scope->parent)2182 if (!scope->parent)
2160 return ir_build_const_import(irb, node, node->owner);2183 return ir_build_const_import(irb, node, node->owner);
21612184
2162 if (scope->fn_entry && (!scope->parent->fn_entry ||2185 FnTableEntry *fn_entry = scope_fn_entry(scope);
2163 (scope->parent->parent && !scope->parent->parent->fn_entry)))2186 if (fn_entry && scope->parent && scope->parent->parent &&
2187 !scope_fn_entry(scope->parent->parent))
2164 {2188 {
2165 return ir_build_const_fn(irb, node, scope->fn_entry);2189 return ir_build_const_fn(irb, node, fn_entry);
2166 }2190 }
21672191
2168 if (scope->node->type == NodeTypeContainerDecl) {2192 if (scope->node->type == NodeTypeContainerDecl) {
...@@ -2308,15 +2332,15 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {...@@ -2308,15 +2332,15 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
2308 if (var_type == irb->codegen->invalid_instruction)2332 if (var_type == irb->codegen->invalid_instruction)
2309 return irb->codegen->invalid_instruction;2333 return irb->codegen->invalid_instruction;
2310 }2334 }
2311 Scope *child_scope = new_scope(node, node->scope);
2312 bool is_shadowable = false;2335 bool is_shadowable = false;
2313 bool is_const = var_decl->is_const;2336 bool is_const = var_decl->is_const;
2314 VariableTableEntry *var = ir_add_local_var(irb, node, child_scope,2337 VariableTableEntry *var = ir_create_var(irb, node, node->scope,
2315 var_decl->symbol, is_const, is_const, is_shadowable, is_inline);2338 var_decl->symbol, is_const, is_const, is_shadowable, is_inline);
2339
2316 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, node, expr_value, false);2340 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, node, expr_value, false);
2317 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, node, var_ptr_value);2341 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, node, var_ptr_value);
2318 ir_build_var_decl(irb, node, var, var_type, var_value); 2342 ir_build_var_decl(irb, node, var, var_type, var_value);
2319 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, child_scope);2343 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var->child_scope);
2320 if (then_expr_result == irb->codegen->invalid_instruction)2344 if (then_expr_result == irb->codegen->invalid_instruction)
2321 return then_expr_result;2345 return then_expr_result;
2322 IrBasicBlock *after_then_block = irb->current_basic_block;2346 IrBasicBlock *after_then_block = irb->current_basic_block;
...@@ -2360,11 +2384,11 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo...@@ -2360,11 +2384,11 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo
2360 Buf *var_name = var_symbol_node->data.symbol_expr.symbol;2384 Buf *var_name = var_symbol_node->data.symbol_expr.symbol;
2361 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr;2385 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr;
23622386
2363 child_scope = new_scope(switch_node, switch_node->scope);
2364 bool is_shadowable = false;2387 bool is_shadowable = false;
2365 bool is_const = true;2388 bool is_const = true;
2366 VariableTableEntry *var = ir_add_local_var(irb, var_symbol_node, child_scope,2389 VariableTableEntry *var = ir_create_var(irb, var_symbol_node, switch_node->scope,
2367 var_name, is_const, is_const, is_shadowable, is_inline);2390 var_name, is_const, is_const, is_shadowable, is_inline);
2391 child_scope = var->child_scope;
2368 IrInstruction *var_value;2392 IrInstruction *var_value;
2369 if (prong_value) {2393 if (prong_value) {
2370 IrInstruction *var_ptr_value = ir_build_switch_var(irb, var_symbol_node, target_value_ptr, prong_value);2394 IrInstruction *var_ptr_value = ir_build_switch_var(irb, var_symbol_node, target_value_ptr, prong_value);
...@@ -2542,14 +2566,25 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2542,14 +2566,25 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
2542 return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);2566 return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
2543}2567}
25442568
2545static LabelTableEntry *find_label(IrExecutable *exec, Scope *orig_context, Buf *name) {2569static LabelTableEntry *find_label(IrExecutable *exec, Scope *scope, Buf *name) {
2546 Scope *context = orig_context;2570 while (scope) {
2547 while (context) {2571 if (scope->node->type == NodeTypeBlock) {
2548 auto entry = context->label_table.maybe_get(name);2572 ScopeBlock *block_scope = (ScopeBlock *)scope;
2549 if (entry) {2573 auto entry = block_scope->label_table.maybe_get(name);
2550 return entry->value;2574 if (entry)
2575 return entry->value;
2551 }2576 }
2552 context = context->parent;2577 scope = scope->parent;
2578 }
2579
2580 return nullptr;
2581}
2582
2583static ScopeBlock *find_block_scope(IrExecutable *exec, Scope *scope) {
2584 while (scope) {
2585 if (scope->node->type == NodeTypeBlock)
2586 return (ScopeBlock *)scope;
2587 scope = scope->parent;
2553 }2588 }
2554 return nullptr;2589 return nullptr;
2555}2590}
...@@ -2571,7 +2606,8 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {...@@ -2571,7 +2606,8 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {
2571 add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here"));2606 add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here"));
2572 return irb->codegen->invalid_instruction;2607 return irb->codegen->invalid_instruction;
2573 } else {2608 } else {
2574 node->scope->label_table.put(label_name, label);2609 ScopeBlock *scope_block = find_block_scope(irb->exec, node->scope);
2610 scope_block->label_table.put(label_name, label);
2575 }2611 }
25762612
2577 bool is_inline = ir_should_inline(irb);2613 bool is_inline = ir_should_inline(irb);
...@@ -2778,9 +2814,9 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {...@@ -2778,9 +2814,9 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
2778 assert(fn_def_node->type == NodeTypeFnDef);2814 assert(fn_def_node->type == NodeTypeFnDef);
27792815
2780 AstNode *body_node = fn_def_node->data.fn_def.body;2816 AstNode *body_node = fn_def_node->data.fn_def.body;
2781 Scope *scope = fn_def_node->data.fn_def.scope;2817 Scope *child_scope = fn_def_node->data.fn_def.child_scope;
27822818
2783 return ir_gen(codegn, body_node, scope, ir_executable);2819 return ir_gen(codegn, body_node, child_scope, ir_executable);
2784}2820}
27852821
2786static IrInstruction *ir_eval_fn(IrAnalyze *ira, IrInstruction *source_instruction,2822static IrInstruction *ir_eval_fn(IrAnalyze *ira, IrInstruction *source_instruction,
...@@ -3023,8 +3059,10 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3023,8 +3059,10 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
3023 } else {3059 } else {
3024 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op);3060 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op);
3025 result->type_entry = wanted_type;3061 result->type_entry = wanted_type;
3026 if (need_alloca && source_instr->source_node->scope->fn_entry) {3062 if (need_alloca) {
3027 source_instr->source_node->scope->fn_entry->alloca_list.append(result);3063 FnTableEntry *fn_entry = scope_fn_entry(source_instr->source_node->scope);
3064 if (fn_entry)
3065 fn_entry->alloca_list.append(result);
3028 }3066 }
3029 return result;3067 return result;
3030 }3068 }
...@@ -3550,7 +3588,8 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst...@@ -3550,7 +3588,8 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst
3550 ir_link_new_instruction(value, source_instruction);3588 ir_link_new_instruction(value, source_instruction);
3551 return ptr_type;3589 return ptr_type;
3552 } else {3590 } else {
3553 FnTableEntry *fn_entry = source_instruction->source_node->scope->fn_entry;3591 FnTableEntry *fn_entry = scope_fn_entry(source_instruction->source_node->scope);
3592 assert(fn_entry);
3554 IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value);3593 IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value);
3555 fn_entry->alloca_list.append(new_instruction);3594 fn_entry->alloca_list.append(new_instruction);
3556 return ptr_type;3595 return ptr_type;
...@@ -4098,8 +4137,9 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -4098,8 +4137,9 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
4098 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);4137 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
40994138
4100 Scope *scope = decl_var_instruction->base.source_node->scope;4139 Scope *scope = decl_var_instruction->base.source_node->scope;
4101 if (scope->fn_entry)4140 FnTableEntry *fn_entry = scope_fn_entry(scope);
4102 scope->fn_entry->variable_list.append(var);4141 if (fn_entry)
4142 fn_entry->variable_list.append(var);
41034143
4104 return ira->codegen->builtin_types.entry_void;4144 return ira->codegen->builtin_types.entry_void;
4105}4145}
...@@ -4200,8 +4240,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -4200,8 +4240,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
4200 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,4240 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
4201 fn_entry, fn_ref, call_param_count, casted_args);4241 fn_entry, fn_ref, call_param_count, casted_args);
42024242
4203 if (type_has_bits(return_type) && handle_is_ptr(return_type))4243 if (type_has_bits(return_type) && handle_is_ptr(return_type)) {
4204 call_instruction->base.source_node->scope->fn_entry->alloca_list.append(new_call_instruction);4244 FnTableEntry *fn_entry = scope_fn_entry(call_instruction->base.source_node->scope);
4245 assert(fn_entry);
4246 fn_entry->alloca_list.append(new_call_instruction);
4247 }
42054248
4206 return ir_finish_anal(ira, return_type);4249 return ir_finish_anal(ira, return_type);
4207}4250}
...@@ -4732,7 +4775,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -4732,7 +4775,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
4732 return var->type;4775 return var->type;
47334776
4734 ConstExprValue *mem_slot = nullptr;4777 ConstExprValue *mem_slot = nullptr;
4735 if (var->scope->fn_entry) {4778 FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope);
4779 if (fn_entry) {
4736 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.4780 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
4737 if (var->mem_slot_index != SIZE_MAX)4781 if (var->mem_slot_index != SIZE_MAX)
4738 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];4782 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
...@@ -4879,9 +4923,8 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -4879,9 +4923,8 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
4879 IrInstruction *container_ptr, TypeTableEntry *container_type)4923 IrInstruction *container_ptr, TypeTableEntry *container_type)
4880{4924{
4881 if (!is_slice(bare_struct_type)) {4925 if (!is_slice(bare_struct_type)) {
4882 Scope *container_block_context = get_container_block_context(bare_struct_type);4926 ScopeDecls *container_scope = get_container_scope(bare_struct_type);
4883 assert(container_block_context);4927 auto entry = container_scope->decl_table.maybe_get(field_name);
4884 auto entry = container_block_context->decl_table.maybe_get(field_name);
4885 AstNode *fn_decl_node = entry ? entry->value : nullptr;4928 AstNode *fn_decl_node = entry ? entry->value : nullptr;
4886 if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) {4929 if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) {
4887 resolve_top_level_decl(ira->codegen, fn_decl_node, false);4930 resolve_top_level_decl(ira->codegen, fn_decl_node, false);
...@@ -5023,8 +5066,8 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -5023,8 +5066,8 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
5023 } else if (child_type->id == TypeTableEntryIdEnum) {5066 } else if (child_type->id == TypeTableEntryIdEnum) {
5024 zig_panic("TODO enum type field");5067 zig_panic("TODO enum type field");
5025 } else if (child_type->id == TypeTableEntryIdStruct) {5068 } else if (child_type->id == TypeTableEntryIdStruct) {
5026 Scope *container_block_context = get_container_block_context(child_type);5069 ScopeDecls *container_scope = get_container_scope(child_type);
5027 auto entry = container_block_context->decl_table.maybe_get(field_name);5070 auto entry = container_scope->decl_table.maybe_get(field_name);
5028 AstNode *decl_node = entry ? entry->value : nullptr;5071 AstNode *decl_node = entry ? entry->value : nullptr;
5029 if (decl_node) {5072 if (decl_node) {
5030 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;5073 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
...@@ -5055,7 +5098,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -5055,7 +5098,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
5055 ImportTableEntry *namespace_import = namespace_val->data.x_import;5098 ImportTableEntry *namespace_import = namespace_val->data.x_import;
50565099
5057 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;5100 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
5058 AstNode *decl_node = find_decl(namespace_import->scope, field_name);5101 AstNode *decl_node = find_decl(&namespace_import->decls_scope->base, field_name);
5059 if (!decl_node) {5102 if (!decl_node) {
5060 // we must now resolve all the use decls5103 // we must now resolve all the use decls
5061 for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {5104 for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {
...@@ -5066,7 +5109,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -5066,7 +5109,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
5066 }5109 }
5067 resolve_use_decl(ira->codegen, use_decl_node);5110 resolve_use_decl(ira->codegen, use_decl_node);
5068 }5111 }
5069 decl_node = find_decl(namespace_import->scope, field_name);5112 decl_node = find_decl(&namespace_import->decls_scope->base, field_name);
5070 }5113 }
5071 if (decl_node) {5114 if (decl_node) {
5072 TopLevelDecl *tld = get_as_top_level_decl(decl_node);5115 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
...@@ -5327,15 +5370,15 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,...@@ -5327,15 +5370,15 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
5327 if (target_type->id == TypeTableEntryIdBlock) {5370 if (target_type->id == TypeTableEntryIdBlock) {
5328 target_context = target_val->data.x_block;5371 target_context = target_val->data.x_block;
5329 } else if (target_type->id == TypeTableEntryIdFn) {5372 } else if (target_type->id == TypeTableEntryIdFn) {
5330 target_context = target_val->data.x_fn->fn_def_node->data.fn_def.scope;5373 target_context = target_val->data.x_fn->fn_def_node->data.fn_def.child_scope;
5331 } else if (target_type->id == TypeTableEntryIdMetaType) {5374 } else if (target_type->id == TypeTableEntryIdMetaType) {
5332 TypeTableEntry *type_arg = target_val->data.x_type;5375 TypeTableEntry *type_arg = target_val->data.x_type;
5333 if (type_arg->id == TypeTableEntryIdStruct) {5376 if (type_arg->id == TypeTableEntryIdStruct) {
5334 target_context = type_arg->data.structure.scope;5377 target_context = &type_arg->data.structure.decls_scope->base;
5335 } else if (type_arg->id == TypeTableEntryIdEnum) {5378 } else if (type_arg->id == TypeTableEntryIdEnum) {
5336 target_context = type_arg->data.enumeration.scope;5379 target_context = &type_arg->data.enumeration.decls_scope->base;
5337 } else if (type_arg->id == TypeTableEntryIdUnion) {5380 } else if (type_arg->id == TypeTableEntryIdUnion) {
5338 target_context = type_arg->data.unionation.scope;5381 target_context = &type_arg->data.unionation.decls_scope->base;
5339 } else {5382 } else {
5340 add_node_error(ira->codegen, target_instruction->source_node,5383 add_node_error(ira->codegen, target_instruction->source_node,
5341 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));5384 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
...@@ -5966,7 +6009,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi...@@ -5966,7 +6009,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi
5966 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,6009 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,
5967 abs_full_path, search_dir, import_target_path, import_code);6010 abs_full_path, search_dir, import_target_path, import_code);
59686011
5969 scan_decls(ira->codegen, target_import, target_import->scope, target_import->root);6012 scan_decls(ira->codegen, target_import, target_import->decls_scope, target_import->root);
59706013
5971 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);6014 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);
5972 out_val->data.x_import = target_import;6015 out_val->data.x_import = target_import;
...@@ -6021,7 +6064,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -6021,7 +6064,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
60216064
6022 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);6065 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
60236066
6024 FnTableEntry *fn_entry = instruction->source_node->scope->fn_entry;6067 FnTableEntry *fn_entry = scope_fn_entry(instruction->source_node->scope);
6025 bool outside_fn = (fn_entry == nullptr);6068 bool outside_fn = (fn_entry == nullptr);
60266069
6027 ConstExprValue const_val = {};6070 ConstExprValue const_val = {};
...@@ -6124,7 +6167,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -6124,7 +6167,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
6124 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);6167 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);
6125 const_val.data.x_array.size = elem_count;6168 const_val.data.x_array.size = elem_count;
61266169
6127 FnTableEntry *fn_entry = instruction->base.source_node->scope->fn_entry;6170 FnTableEntry *fn_entry = scope_fn_entry(instruction->base.source_node->scope);
6128 bool outside_fn = (fn_entry == nullptr);6171 bool outside_fn = (fn_entry == nullptr);
61296172
6130 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);6173 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);
src/parseh.cpp+3-3
...@@ -817,7 +817,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)...@@ -817,7 +817,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
817 const EnumDecl *enum_def = enum_decl->getDefinition();817 const EnumDecl *enum_def = enum_decl->getDefinition();
818 if (!enum_def) {818 if (!enum_def) {
819 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import,819 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import,
820 c->import->scope,820 &c->import->decls_scope->base,
821 ContainerKindEnum, c->source_node, buf_ptr(full_type_name));821 ContainerKindEnum, c->source_node, buf_ptr(full_type_name));
822 c->enum_type_table.put(bare_name, enum_type);822 c->enum_type_table.put(bare_name, enum_type);
823 c->decl_table.put(enum_decl, enum_type);823 c->decl_table.put(enum_decl, enum_type);
...@@ -842,7 +842,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)...@@ -842,7 +842,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
842842
843 if (pure_enum) {843 if (pure_enum) {
844 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import,844 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import,
845 c->import->scope,845 &c->import->decls_scope->base,
846 ContainerKindEnum, c->source_node, buf_ptr(full_type_name));846 ContainerKindEnum, c->source_node, buf_ptr(full_type_name));
847 c->enum_type_table.put(bare_name, enum_type);847 c->enum_type_table.put(bare_name, enum_type);
848 c->decl_table.put(enum_decl, enum_type);848 c->decl_table.put(enum_decl, enum_type);
...@@ -1002,7 +1002,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -1002,7 +1002,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
10021002
10031003
1004 TypeTableEntry *struct_type = get_partial_container_type(c->codegen, c->import,1004 TypeTableEntry *struct_type = get_partial_container_type(c->codegen, c->import,
1005 c->import->scope, ContainerKindStruct, c->source_node, buf_ptr(full_type_name));1005 &c->import->decls_scope->base, ContainerKindStruct, c->source_node, buf_ptr(full_type_name));
10061006
1007 c->struct_type_table.put(bare_name, struct_type);1007 c->struct_type_table.put(bare_name, struct_type);
1008 c->decl_table.put(record_decl, struct_type);1008 c->decl_table.put(record_decl, struct_type);