| author | |
| committer | |
| log | e50ced44a2cf6268c19df901ad56b367d8d802fe |
| tree | b4bd67b3a0a8bdbc853dba760c0d66a406e11d4a |
| parent | 2e6aa6d813cf3fd4180b8c9ffc671b4bcee54586 |
11 files changed, 168 insertions(+), 197 deletions(-)
CMakeLists.txt+1-1| ... | @@ -38,7 +38,6 @@ include_directories( | ... | @@ -38,7 +38,6 @@ include_directories( |
| 38 | ) | 38 | ) |
| 39 | 39 | ||
| 40 | set(ZIG_SOURCES | 40 | set(ZIG_SOURCES |
| 41 | "${CMAKE_SOURCE_DIR}/src/ir.cpp" | ||
| 42 | "${CMAKE_SOURCE_DIR}/src/analyze.cpp" | 41 | "${CMAKE_SOURCE_DIR}/src/analyze.cpp" |
| 43 | "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" | 42 | "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" |
| 44 | "${CMAKE_SOURCE_DIR}/src/bignum.cpp" | 43 | "${CMAKE_SOURCE_DIR}/src/bignum.cpp" |
| ... | @@ -48,6 +47,7 @@ set(ZIG_SOURCES | ... | @@ -48,6 +47,7 @@ set(ZIG_SOURCES |
| 48 | "${CMAKE_SOURCE_DIR}/src/errmsg.cpp" | 47 | "${CMAKE_SOURCE_DIR}/src/errmsg.cpp" |
| 49 | "${CMAKE_SOURCE_DIR}/src/error.cpp" | 48 | "${CMAKE_SOURCE_DIR}/src/error.cpp" |
| 50 | "${CMAKE_SOURCE_DIR}/src/eval.cpp" | 49 | "${CMAKE_SOURCE_DIR}/src/eval.cpp" |
| 50 | "${CMAKE_SOURCE_DIR}/src/ir.cpp" | ||
| 51 | "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" | 51 | "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" |
| 52 | "${CMAKE_SOURCE_DIR}/src/link.cpp" | 52 | "${CMAKE_SOURCE_DIR}/src/link.cpp" |
| 53 | "${CMAKE_SOURCE_DIR}/src/main.cpp" | 53 | "${CMAKE_SOURCE_DIR}/src/main.cpp" |
doc/langref.md+6-5| ... | @@ -7,7 +7,7 @@ Root = many(TopLevelItem) "EOF" | ... | @@ -7,7 +7,7 @@ Root = many(TopLevelItem) "EOF" |
| 7 | 7 | ||
| 8 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | 8 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl |
| 9 | 9 | ||
| 10 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | ContainerDecl | GlobalVarDecl | TypeDecl | UseDecl) | 10 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl) |
| 11 | 11 | ||
| 12 | TypeDecl = "type" Symbol "=" TypeExpr ";" | 12 | TypeDecl = "type" Symbol "=" TypeExpr ";" |
| 13 | 13 | ||
| ... | @@ -17,9 +17,7 @@ GlobalVarDecl = VariableDeclaration ";" | ... | @@ -17,9 +17,7 @@ GlobalVarDecl = VariableDeclaration ";" |
| 17 | 17 | ||
| 18 | VariableDeclaration = option("inline") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression | 18 | VariableDeclaration = option("inline") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression |
| 19 | 19 | ||
| 20 | ContainerDecl = ("struct" | "enum" | "union") Symbol option(ParamDeclList) "{" many(StructMember) "}" | 20 | StructMember = (StructField | FnDef | GlobalVarDecl) |
| 21 | |||
| 22 | StructMember = (StructField | FnDef | GlobalVarDecl | ContainerDecl) | ||
| 23 | 21 | ||
| 24 | StructField = Symbol option(":" Expression) ",") | 22 | StructField = Symbol option(":" Expression) ",") |
| 25 | 23 | ||
| ... | @@ -143,7 +141,7 @@ StructLiteralField = "." Symbol "=" Expression | ... | @@ -143,7 +141,7 @@ StructLiteralField = "." Symbol "=" Expression |
| 143 | 141 | ||
| 144 | PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%" | "??" | "-%" | 142 | PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%" | "??" | "-%" |
| 145 | 143 | ||
| 146 | PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | 144 | PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl |
| 147 | 145 | ||
| 148 | ArrayType = "[" option(Expression) "]" option("const") TypeExpr | 146 | ArrayType = "[" option(Expression) "]" option("const") TypeExpr |
| 149 | 147 | ||
| ... | @@ -152,6 +150,9 @@ GotoExpression = option("inline") "goto" Symbol | ... | @@ -152,6 +150,9 @@ GotoExpression = option("inline") "goto" Symbol |
| 152 | GroupedExpression = "(" Expression ")" | 150 | GroupedExpression = "(" Expression ")" |
| 153 | 151 | ||
| 154 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" | 152 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" |
| 153 | |||
| 154 | ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}" | ||
| 155 | |||
| 155 | ``` | 156 | ``` |
| 156 | 157 | ||
| 157 | ## Operator Precedence | 158 | ## Operator Precedence |
src/all_types.hpp+3-7| ... | @@ -44,6 +44,7 @@ struct IrGotoItem { | ... | @@ -44,6 +44,7 @@ struct IrGotoItem { |
| 44 | 44 | ||
| 45 | struct IrExecutable { | 45 | struct IrExecutable { |
| 46 | ZigList<IrBasicBlock *> basic_block_list; | 46 | ZigList<IrBasicBlock *> basic_block_list; |
| 47 | Buf *name; | ||
| 47 | size_t mem_slot_count; | 48 | size_t mem_slot_count; |
| 48 | size_t next_debug_id; | 49 | size_t next_debug_id; |
| 49 | size_t *backward_branch_count; | 50 | size_t *backward_branch_count; |
| ... | @@ -195,7 +196,6 @@ struct Tld { | ... | @@ -195,7 +196,6 @@ struct Tld { |
| 195 | // set this flag temporarily to detect infinite loops | 196 | // set this flag temporarily to detect infinite loops |
| 196 | bool dep_loop_flag; | 197 | bool dep_loop_flag; |
| 197 | TldResolution resolution; | 198 | TldResolution resolution; |
| 198 | Tld *parent_tld; | ||
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| 201 | struct TldVar { | 201 | struct TldVar { |
| ... | @@ -594,12 +594,8 @@ enum ContainerKind { | ... | @@ -594,12 +594,8 @@ enum ContainerKind { |
| 594 | ContainerKindUnion, | 594 | ContainerKindUnion, |
| 595 | }; | 595 | }; |
| 596 | 596 | ||
| 597 | struct AstNodeStructDecl { | 597 | struct AstNodeContainerDecl { |
| 598 | VisibMod visib_mod; | ||
| 599 | Buf *name; | ||
| 600 | ContainerKind kind; | 598 | ContainerKind kind; |
| 601 | ZigList<AstNode *> generic_params; | ||
| 602 | bool generic_params_is_var_args; // always an error but it can happen from parsing | ||
| 603 | ZigList<AstNode *> fields; | 599 | ZigList<AstNode *> fields; |
| 604 | ZigList<AstNode *> decls; | 600 | ZigList<AstNode *> decls; |
| 605 | }; | 601 | }; |
| ... | @@ -722,7 +718,7 @@ struct AstNode { | ... | @@ -722,7 +718,7 @@ struct AstNode { |
| 722 | AstNodeGoto goto_expr; | 718 | AstNodeGoto goto_expr; |
| 723 | AstNodeAsmExpr asm_expr; | 719 | AstNodeAsmExpr asm_expr; |
| 724 | AstNodeFieldAccessExpr field_access_expr; | 720 | AstNodeFieldAccessExpr field_access_expr; |
| 725 | AstNodeStructDecl struct_decl; | 721 | AstNodeContainerDecl container_decl; |
| 726 | AstNodeStructField struct_field; | 722 | AstNodeStructField struct_field; |
| 727 | AstNodeStringLiteral string_literal; | 723 | AstNodeStringLiteral string_literal; |
| 728 | AstNodeCharLiteral char_literal; | 724 | AstNodeCharLiteral char_literal; |
src/analyze.cpp+61-86| ... | @@ -831,10 +831,7 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { | ... | @@ -831,10 +831,7 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { |
| 831 | zig_unreachable(); | 831 | zig_unreachable(); |
| 832 | } | 832 | } |
| 833 | 833 | ||
| 834 | TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *scope, | 834 | TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name) { |
| 835 | ContainerKind kind, AstNode *decl_node, const char *name) | ||
| 836 | { | ||
| 837 | |||
| 838 | TypeTableEntryId type_id = container_to_type(kind); | 835 | TypeTableEntryId type_id = container_to_type(kind); |
| 839 | TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); | 836 | TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); |
| 840 | 837 | ||
| ... | @@ -852,6 +849,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, | ... | @@ -852,6 +849,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, |
| 852 | 849 | ||
| 853 | unsigned line = decl_node->line; | 850 | unsigned line = decl_node->line; |
| 854 | 851 | ||
| 852 | ImportTableEntry *import = get_scope_import(scope); | ||
| 855 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name); | 853 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name); |
| 856 | entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, | 854 | entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 857 | ZigLLVMTag_DW_structure_type(), name, | 855 | ZigLLVMTag_DW_structure_type(), name, |
| ... | @@ -862,15 +860,6 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, | ... | @@ -862,15 +860,6 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, |
| 862 | return entry; | 860 | return entry; |
| 863 | } | 861 | } |
| 864 | 862 | ||
| 865 | static TypeTableEntry *get_partial_container_type_tld(CodeGen *g, Scope *scope, TldContainer *tld_container) { | ||
| 866 | ImportTableEntry *import = tld_container->base.import; | ||
| 867 | AstNode *container_node = tld_container->base.source_node; | ||
| 868 | assert(container_node->type == NodeTypeContainerDecl); | ||
| 869 | ContainerKind kind = container_node->data.struct_decl.kind; | ||
| 870 | return get_partial_container_type(g, import, scope, kind, container_node, buf_ptr(tld_container->base.name)); | ||
| 871 | } | ||
| 872 | |||
| 873 | |||
| 874 | TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) { | 863 | TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) { |
| 875 | if (type_entry->id == TypeTableEntryIdTypeDecl) { | 864 | if (type_entry->id == TypeTableEntryIdTypeDecl) { |
| 876 | return type_entry->data.type_decl.canonical_type; | 865 | return type_entry->data.type_decl.canonical_type; |
| ... | @@ -879,15 +868,15 @@ TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) { | ... | @@ -879,15 +868,15 @@ TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) { |
| 879 | } | 868 | } |
| 880 | } | 869 | } |
| 881 | 870 | ||
| 882 | static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry) { | 871 | static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry, Buf *type_name) { |
| 883 | size_t backward_branch_count = 0; | 872 | size_t backward_branch_count = 0; |
| 884 | return ir_eval_const_value(g, scope, node, type_entry, | 873 | return ir_eval_const_value(g, scope, node, type_entry, |
| 885 | &backward_branch_count, default_backward_branch_quota, | 874 | &backward_branch_count, default_backward_branch_quota, |
| 886 | nullptr, nullptr, node); | 875 | nullptr, nullptr, node, type_name); |
| 887 | } | 876 | } |
| 888 | 877 | ||
| 889 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { | 878 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { |
| 890 | IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type); | 879 | IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); |
| 891 | if (result->type_entry->id == TypeTableEntryIdInvalid) | 880 | if (result->type_entry->id == TypeTableEntryIdInvalid) |
| 892 | return g->builtin_types.entry_invalid; | 881 | return g->builtin_types.entry_invalid; |
| 893 | 882 | ||
| ... | @@ -1069,7 +1058,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1069,7 +1058,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1069 | assert(decl_node->type == NodeTypeContainerDecl); | 1058 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1070 | assert(enum_type->di_type); | 1059 | assert(enum_type->di_type); |
| 1071 | 1060 | ||
| 1072 | uint32_t field_count = decl_node->data.struct_decl.fields.length; | 1061 | uint32_t field_count = decl_node->data.container_decl.fields.length; |
| 1073 | 1062 | ||
| 1074 | enum_type->data.enumeration.src_field_count = field_count; | 1063 | enum_type->data.enumeration.src_field_count = field_count; |
| 1075 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | 1064 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| ... | @@ -1091,7 +1080,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1091,7 +1080,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1091 | 1080 | ||
| 1092 | size_t gen_field_index = 0; | 1081 | size_t gen_field_index = 0; |
| 1093 | for (uint32_t i = 0; i < field_count; i += 1) { | 1082 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 1094 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); | 1083 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1095 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 1084 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 1096 | type_enum_field->name = field_node->data.struct_field.name; | 1085 | type_enum_field->name = field_node->data.struct_field.name; |
| 1097 | TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); | 1086 | TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); |
| ... | @@ -1201,7 +1190,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1201,7 +1190,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1201 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref); | 1190 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref); |
| 1202 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, | 1191 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, |
| 1203 | ZigLLVMFileToScope(import->di_file), | 1192 | ZigLLVMFileToScope(import->di_file), |
| 1204 | buf_ptr(decl_node->data.struct_decl.name), | 1193 | buf_ptr(&enum_type->name), |
| 1205 | import->di_file, decl_node->line + 1, | 1194 | import->di_file, decl_node->line + 1, |
| 1206 | debug_size_in_bits, | 1195 | debug_size_in_bits, |
| 1207 | debug_align_in_bits, | 1196 | debug_align_in_bits, |
| ... | @@ -1217,7 +1206,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1217,7 +1206,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1217 | uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); | 1206 | uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); |
| 1218 | uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref); | 1207 | uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref); |
| 1219 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, | 1208 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, |
| 1220 | ZigLLVMFileToScope(import->di_file), buf_ptr(decl_node->data.struct_decl.name), | 1209 | ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), |
| 1221 | import->di_file, decl_node->line + 1, | 1210 | import->di_file, decl_node->line + 1, |
| 1222 | tag_debug_size_in_bits, | 1211 | tag_debug_size_in_bits, |
| 1223 | tag_debug_align_in_bits, | 1212 | tag_debug_align_in_bits, |
| ... | @@ -1257,7 +1246,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1257,7 +1246,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1257 | assert(decl_node->type == NodeTypeContainerDecl); | 1246 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1258 | assert(struct_type->di_type); | 1247 | assert(struct_type->di_type); |
| 1259 | 1248 | ||
| 1260 | size_t field_count = decl_node->data.struct_decl.fields.length; | 1249 | size_t field_count = decl_node->data.container_decl.fields.length; |
| 1261 | 1250 | ||
| 1262 | struct_type->data.structure.src_field_count = field_count; | 1251 | struct_type->data.structure.src_field_count = field_count; |
| 1263 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); | 1252 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); |
| ... | @@ -1274,7 +1263,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1274,7 +1263,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1274 | 1263 | ||
| 1275 | size_t gen_field_index = 0; | 1264 | size_t gen_field_index = 0; |
| 1276 | for (size_t i = 0; i < field_count; i += 1) { | 1265 | for (size_t i = 0; i < field_count; i += 1) { |
| 1277 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); | 1266 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1278 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1267 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1279 | type_struct_field->name = field_node->data.struct_field.name; | 1268 | type_struct_field->name = field_node->data.struct_field.name; |
| 1280 | TypeTableEntry *field_type = analyze_type_expr(g, scope, | 1269 | TypeTableEntry *field_type = analyze_type_expr(g, scope, |
| ... | @@ -1316,7 +1305,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1316,7 +1305,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1316 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); | 1305 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 1317 | 1306 | ||
| 1318 | for (size_t i = 0; i < field_count; i += 1) { | 1307 | for (size_t i = 0; i < field_count; i += 1) { |
| 1319 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); | 1308 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1320 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1309 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1321 | gen_field_index = type_struct_field->gen_index; | 1310 | gen_field_index = type_struct_field->gen_index; |
| 1322 | if (gen_field_index == SIZE_MAX) { | 1311 | if (gen_field_index == SIZE_MAX) { |
| ... | @@ -1348,7 +1337,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1348,7 +1337,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1348 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref); | 1337 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref); |
| 1349 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, | 1338 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, |
| 1350 | ZigLLVMFileToScope(import->di_file), | 1339 | ZigLLVMFileToScope(import->di_file), |
| 1351 | buf_ptr(decl_node->data.struct_decl.name), | 1340 | buf_ptr(&struct_type->name), |
| 1352 | import->di_file, decl_node->line + 1, | 1341 | import->di_file, decl_node->line + 1, |
| 1353 | debug_size_in_bits, | 1342 | debug_size_in_bits, |
| 1354 | debug_align_in_bits, | 1343 | debug_align_in_bits, |
| ... | @@ -1364,14 +1353,28 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { | ... | @@ -1364,14 +1353,28 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { |
| 1364 | zig_panic("TODO"); | 1353 | zig_panic("TODO"); |
| 1365 | } | 1354 | } |
| 1366 | 1355 | ||
| 1367 | static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { | 1356 | static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) { |
| 1368 | if (tld->parent_tld) { | 1357 | if (!scope) |
| 1369 | get_fully_qualified_decl_name(buf, tld->parent_tld, sep); | 1358 | return; |
| 1370 | buf_append_char(buf, sep); | 1359 | |
| 1371 | buf_append_buf(buf, tld->name); | 1360 | if (scope->id == ScopeIdDecls) { |
| 1372 | } else { | 1361 | get_fully_qualified_decl_name_internal(buf, scope->parent, sep); |
| 1373 | buf_init_from_buf(buf, tld->name); | 1362 | |
| 1363 | ScopeDecls *scope_decls = (ScopeDecls *)scope; | ||
| 1364 | if (scope_decls->container_type) { | ||
| 1365 | buf_append_buf(buf, &scope_decls->container_type->name); | ||
| 1366 | buf_append_char(buf, sep); | ||
| 1367 | } | ||
| 1368 | return; | ||
| 1374 | } | 1369 | } |
| 1370 | |||
| 1371 | get_fully_qualified_decl_name_internal(buf, scope->parent, sep); | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { | ||
| 1375 | buf_resize(buf, 0); | ||
| 1376 | get_fully_qualified_decl_name_internal(buf, tld->parent_scope, sep); | ||
| 1377 | buf_append_buf(buf, tld->name); | ||
| 1375 | } | 1378 | } |
| 1376 | 1379 | ||
| 1377 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) { | 1380 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) { |
| ... | @@ -1401,6 +1404,17 @@ FnTableEntry *create_fn(AstNode *proto_node) { | ... | @@ -1401,6 +1404,17 @@ FnTableEntry *create_fn(AstNode *proto_node) { |
| 1401 | return fn_entry; | 1404 | return fn_entry; |
| 1402 | } | 1405 | } |
| 1403 | 1406 | ||
| 1407 | static bool scope_is_root_decls(Scope *scope) { | ||
| 1408 | while (scope) { | ||
| 1409 | if (scope->id == ScopeIdDecls) { | ||
| 1410 | ScopeDecls *scope_decls = (ScopeDecls *)scope; | ||
| 1411 | return (scope_decls->container_type == nullptr); | ||
| 1412 | } | ||
| 1413 | scope = scope->parent; | ||
| 1414 | } | ||
| 1415 | zig_unreachable(); | ||
| 1416 | } | ||
| 1417 | |||
| 1404 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | 1418 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 1405 | ImportTableEntry *import = tld_fn->base.import; | 1419 | ImportTableEntry *import = tld_fn->base.import; |
| 1406 | AstNode *proto_node = tld_fn->base.source_node; | 1420 | AstNode *proto_node = tld_fn->base.source_node; |
| ... | @@ -1448,9 +1462,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -1448,9 +1462,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 1448 | if (fn_def_node) | 1462 | if (fn_def_node) |
| 1449 | g->fn_defs.append(fn_table_entry); | 1463 | g->fn_defs.append(fn_table_entry); |
| 1450 | 1464 | ||
| 1451 | Tld *parent_tld = tld_fn->base.parent_tld; | 1465 | bool is_main_fn = scope_is_root_decls(tld_fn->base.parent_scope) && |
| 1452 | bool is_main_fn = !parent_tld && (import == g->root_import) && | 1466 | (import == g->root_import) && buf_eql_str(&fn_table_entry->symbol_name, "main"); |
| 1453 | buf_eql_str(&fn_table_entry->symbol_name, "main"); | ||
| 1454 | if (is_main_fn) | 1467 | if (is_main_fn) |
| 1455 | g->main_fn = fn_table_entry; | 1468 | g->main_fn = fn_table_entry; |
| 1456 | 1469 | ||
| ... | @@ -1480,23 +1493,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | ... | @@ -1480,23 +1493,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 1480 | } | 1493 | } |
| 1481 | } | 1494 | } |
| 1482 | 1495 | ||
| 1483 | static void scan_struct_decl(CodeGen *g, ScopeDecls *decls_scope, TldContainer *tld_container) { | ||
| 1484 | assert(!tld_container->type_entry); | ||
| 1485 | |||
| 1486 | AstNode *container_node = tld_container->base.source_node; | ||
| 1487 | assert(container_node->type == NodeTypeContainerDecl); | ||
| 1488 | |||
| 1489 | TypeTableEntry *container_type = get_partial_container_type_tld(g, &decls_scope->base, tld_container); | ||
| 1490 | tld_container->type_entry = container_type; | ||
| 1491 | |||
| 1492 | // handle the member function definitions independently | ||
| 1493 | for (size_t i = 0; i < container_node->data.struct_decl.decls.length; i += 1) { | ||
| 1494 | AstNode *child_node = container_node->data.struct_decl.decls.at(i); | ||
| 1495 | ScopeDecls *child_scope = get_container_scope(container_type); | ||
| 1496 | scan_decls(g, tld_container->base.import, child_scope, child_node, &tld_container->base); | ||
| 1497 | } | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | static void preview_error_value_decl(CodeGen *g, AstNode *node) { | 1496 | static void preview_error_value_decl(CodeGen *g, AstNode *node) { |
| 1501 | assert(node->type == NodeTypeErrorValueDecl); | 1497 | assert(node->type == NodeTypeErrorValueDecl); |
| 1502 | 1498 | ||
| ... | @@ -1525,7 +1521,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) { | ... | @@ -1525,7 +1521,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) { |
| 1525 | } | 1521 | } |
| 1526 | 1522 | ||
| 1527 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, | 1523 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, |
| 1528 | Scope *parent_scope, Tld *parent_tld) | 1524 | Scope *parent_scope) |
| 1529 | { | 1525 | { |
| 1530 | tld->id = id; | 1526 | tld->id = id; |
| 1531 | tld->name = name; | 1527 | tld->name = name; |
| ... | @@ -1533,40 +1529,25 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source | ... | @@ -1533,40 +1529,25 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source |
| 1533 | tld->source_node = source_node; | 1529 | tld->source_node = source_node; |
| 1534 | tld->import = source_node->owner; | 1530 | tld->import = source_node->owner; |
| 1535 | tld->parent_scope = parent_scope; | 1531 | tld->parent_scope = parent_scope; |
| 1536 | tld->parent_tld = parent_tld; | ||
| 1537 | } | 1532 | } |
| 1538 | 1533 | ||
| 1539 | void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node, Tld *parent_tld) { | 1534 | void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 1540 | switch (node->type) { | 1535 | switch (node->type) { |
| 1541 | case NodeTypeRoot: | 1536 | case NodeTypeRoot: |
| 1542 | for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) { | 1537 | for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) { |
| 1543 | AstNode *child = import->root->data.root.top_level_decls.at(i); | 1538 | AstNode *child = node->data.root.top_level_decls.at(i); |
| 1544 | scan_decls(g, import, decls_scope, child, parent_tld); | 1539 | scan_decls(g, decls_scope, child); |
| 1545 | } | ||
| 1546 | break; | ||
| 1547 | case NodeTypeContainerDecl: | ||
| 1548 | { | ||
| 1549 | Buf *name = node->data.struct_decl.name; | ||
| 1550 | VisibMod visib_mod = node->data.struct_decl.visib_mod; | ||
| 1551 | TldContainer *tld_container = allocate<TldContainer>(1); | ||
| 1552 | init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, &decls_scope->base, parent_tld); | ||
| 1553 | add_top_level_decl(g, decls_scope, &tld_container->base); | ||
| 1554 | if (node->data.struct_decl.generic_params.length == 0) { | ||
| 1555 | scan_struct_decl(g, decls_scope, tld_container); | ||
| 1556 | } else { | ||
| 1557 | zig_panic("TODO all structs anonymous?"); | ||
| 1558 | } | ||
| 1559 | } | 1540 | } |
| 1560 | break; | 1541 | break; |
| 1561 | case NodeTypeFnDef: | 1542 | case NodeTypeFnDef: |
| 1562 | scan_decls(g, import, decls_scope, node->data.fn_def.fn_proto, parent_tld); | 1543 | scan_decls(g, decls_scope, node->data.fn_def.fn_proto); |
| 1563 | break; | 1544 | break; |
| 1564 | case NodeTypeVariableDeclaration: | 1545 | case NodeTypeVariableDeclaration: |
| 1565 | { | 1546 | { |
| 1566 | Buf *name = node->data.variable_declaration.symbol; | 1547 | Buf *name = node->data.variable_declaration.symbol; |
| 1567 | VisibMod visib_mod = node->data.variable_declaration.visib_mod; | 1548 | VisibMod visib_mod = node->data.variable_declaration.visib_mod; |
| 1568 | TldVar *tld_var = allocate<TldVar>(1); | 1549 | TldVar *tld_var = allocate<TldVar>(1); |
| 1569 | init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base, parent_tld); | 1550 | init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base); |
| 1570 | add_top_level_decl(g, decls_scope, &tld_var->base); | 1551 | add_top_level_decl(g, decls_scope, &tld_var->base); |
| 1571 | break; | 1552 | break; |
| 1572 | } | 1553 | } |
| ... | @@ -1575,7 +1556,7 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A | ... | @@ -1575,7 +1556,7 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A |
| 1575 | Buf *name = node->data.type_decl.symbol; | 1556 | Buf *name = node->data.type_decl.symbol; |
| 1576 | VisibMod visib_mod = node->data.type_decl.visib_mod; | 1557 | VisibMod visib_mod = node->data.type_decl.visib_mod; |
| 1577 | TldTypeDef *tld_typedef = allocate<TldTypeDef>(1); | 1558 | TldTypeDef *tld_typedef = allocate<TldTypeDef>(1); |
| 1578 | init_tld(&tld_typedef->base, TldIdTypeDef, name, visib_mod, node, &decls_scope->base, parent_tld); | 1559 | init_tld(&tld_typedef->base, TldIdTypeDef, name, visib_mod, node, &decls_scope->base); |
| 1579 | add_top_level_decl(g, decls_scope, &tld_typedef->base); | 1560 | add_top_level_decl(g, decls_scope, &tld_typedef->base); |
| 1580 | break; | 1561 | break; |
| 1581 | } | 1562 | } |
| ... | @@ -1590,13 +1571,14 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A | ... | @@ -1590,13 +1571,14 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A |
| 1590 | 1571 | ||
| 1591 | VisibMod visib_mod = node->data.fn_proto.visib_mod; | 1572 | VisibMod visib_mod = node->data.fn_proto.visib_mod; |
| 1592 | TldFn *tld_fn = allocate<TldFn>(1); | 1573 | TldFn *tld_fn = allocate<TldFn>(1); |
| 1593 | init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base, parent_tld); | 1574 | init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base); |
| 1594 | add_top_level_decl(g, decls_scope, &tld_fn->base); | 1575 | add_top_level_decl(g, decls_scope, &tld_fn->base); |
| 1595 | break; | 1576 | break; |
| 1596 | } | 1577 | } |
| 1597 | case NodeTypeUse: | 1578 | case NodeTypeUse: |
| 1598 | { | 1579 | { |
| 1599 | g->use_queue.append(node); | 1580 | g->use_queue.append(node); |
| 1581 | ImportTableEntry *import = get_scope_import(&decls_scope->base); | ||
| 1600 | import->use_decls.append(node); | 1582 | import->use_decls.append(node); |
| 1601 | break; | 1583 | break; |
| 1602 | } | 1584 | } |
| ... | @@ -1604,6 +1586,7 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A | ... | @@ -1604,6 +1586,7 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A |
| 1604 | // error value declarations do not depend on other top level decls | 1586 | // error value declarations do not depend on other top level decls |
| 1605 | preview_error_value_decl(g, node); | 1587 | preview_error_value_decl(g, node); |
| 1606 | break; | 1588 | break; |
| 1589 | case NodeTypeContainerDecl: | ||
| 1607 | case NodeTypeParamDecl: | 1590 | case NodeTypeParamDecl: |
| 1608 | case NodeTypeFnDecl: | 1591 | case NodeTypeFnDecl: |
| 1609 | case NodeTypeReturnExpr: | 1592 | case NodeTypeReturnExpr: |
| ... | @@ -1787,7 +1770,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -1787,7 +1770,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 1787 | if (explicit_type && explicit_type->id == TypeTableEntryIdInvalid) { | 1770 | if (explicit_type && explicit_type->id == TypeTableEntryIdInvalid) { |
| 1788 | implicit_type = explicit_type; | 1771 | implicit_type = explicit_type; |
| 1789 | } else if (var_decl->expr) { | 1772 | } else if (var_decl->expr) { |
| 1790 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type); | 1773 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol); |
| 1791 | assert(init_value); | 1774 | assert(init_value); |
| 1792 | implicit_type = init_value->type_entry; | 1775 | implicit_type = init_value->type_entry; |
| 1793 | 1776 | ||
| ... | @@ -1837,13 +1820,6 @@ static void resolve_decl_typedef(CodeGen *g, TldTypeDef *tld_typedef) { | ... | @@ -1837,13 +1820,6 @@ static void resolve_decl_typedef(CodeGen *g, TldTypeDef *tld_typedef) { |
| 1837 | void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) { | 1820 | void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) { |
| 1838 | if (tld->resolution != TldResolutionUnresolved) | 1821 | if (tld->resolution != TldResolutionUnresolved) |
| 1839 | return; | 1822 | return; |
| 1840 | if (pointer_only && tld->id == TldIdContainer) { | ||
| 1841 | g->resolve_queue.append(tld); | ||
| 1842 | return; | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | ImportTableEntry *import = tld->import; | ||
| 1846 | assert(import); | ||
| 1847 | 1823 | ||
| 1848 | if (tld->dep_loop_flag) { | 1824 | if (tld->dep_loop_flag) { |
| 1849 | add_node_error(g, tld->source_node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name))); | 1825 | add_node_error(g, tld->source_node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name))); |
| ... | @@ -2222,7 +2198,6 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -2222,7 +2198,6 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 2222 | FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; | 2198 | FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; |
| 2223 | AstNode *param_decl_node = get_param_decl_node(fn_table_entry, i); | 2199 | AstNode *param_decl_node = get_param_decl_node(fn_table_entry, i); |
| 2224 | AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl; | 2200 | AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl; |
| 2225 | |||
| 2226 | 2201 | ||
| 2227 | TypeTableEntry *param_type = param_info->type; | 2202 | TypeTableEntry *param_type = param_info->type; |
| 2228 | bool is_noalias = param_info->is_noalias; | 2203 | bool is_noalias = param_info->is_noalias; |
| ... | @@ -2350,7 +2325,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) { | ... | @@ -2350,7 +2325,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) { |
| 2350 | assert(node->type == NodeTypeUse); | 2325 | assert(node->type == NodeTypeUse); |
| 2351 | 2326 | ||
| 2352 | IrInstruction *result = analyze_const_value(g, &node->owner->decls_scope->base, | 2327 | IrInstruction *result = analyze_const_value(g, &node->owner->decls_scope->base, |
| 2353 | node->data.use.expr, g->builtin_types.entry_namespace); | 2328 | node->data.use.expr, g->builtin_types.entry_namespace, nullptr); |
| 2354 | 2329 | ||
| 2355 | if (result->type_entry->id == TypeTableEntryIdInvalid) | 2330 | if (result->type_entry->id == TypeTableEntryIdInvalid) |
| 2356 | node->owner->any_imports_failed = true; | 2331 | node->owner->any_imports_failed = true; |
| ... | @@ -2438,7 +2413,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, | ... | @@ -2438,7 +2413,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, |
| 2438 | void semantic_analyze(CodeGen *g) { | 2413 | void semantic_analyze(CodeGen *g) { |
| 2439 | for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) { | 2414 | for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) { |
| 2440 | ImportTableEntry *import = g->import_queue.at(g->import_queue_index); | 2415 | ImportTableEntry *import = g->import_queue.at(g->import_queue_index); |
| 2441 | scan_decls(g, import, import->decls_scope, import->root, nullptr); | 2416 | scan_decls(g, import->decls_scope, import->root); |
| 2442 | } | 2417 | } |
| 2443 | 2418 | ||
| 2444 | for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) { | 2419 | for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) { |
src/analyze.hpp+3-5| ... | @@ -26,8 +26,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); | ... | @@ -26,8 +26,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); |
| 26 | TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type); | 26 | TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type); |
| 27 | TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size); | 27 | TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size); |
| 28 | TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const); | 28 | TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const); |
| 29 | TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *scope, | 29 | TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name); |
| 30 | ContainerKind kind, AstNode *decl_node, const char *name); | ||
| 31 | TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); | 30 | TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); |
| 32 | TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); | 31 | TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); |
| 33 | TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry); | 32 | TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry); |
| ... | @@ -60,13 +59,12 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name); | ... | @@ -60,13 +59,12 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name); |
| 60 | ScopeDecls *get_container_scope(TypeTableEntry *type_entry); | 59 | ScopeDecls *get_container_scope(TypeTableEntry *type_entry); |
| 61 | TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name); | 60 | TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name); |
| 62 | bool is_container_ref(TypeTableEntry *type_entry); | 61 | bool is_container_ref(TypeTableEntry *type_entry); |
| 63 | void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node, Tld *parent_tld); | 62 | void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node); |
| 64 | void preview_use_decl(CodeGen *g, AstNode *node); | 63 | void preview_use_decl(CodeGen *g, AstNode *node); |
| 65 | void resolve_use_decl(CodeGen *g, AstNode *node); | 64 | void resolve_use_decl(CodeGen *g, AstNode *node); |
| 66 | FnTableEntry *scope_fn_entry(Scope *scope); | 65 | FnTableEntry *scope_fn_entry(Scope *scope); |
| 67 | ImportTableEntry *get_scope_import(Scope *scope); | 66 | ImportTableEntry *get_scope_import(Scope *scope); |
| 68 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, | 67 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, Scope *parent_scope); |
| 69 | Scope *parent_scope, Tld *parent_tld); | ||
| 70 | VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, | 68 | VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, |
| 71 | TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value); | 69 | TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value); |
| 72 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); | 70 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); |
src/ast_render.cpp+4-6| ... | @@ -585,13 +585,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -585,13 +585,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 585 | break; | 585 | break; |
| 586 | case NodeTypeContainerDecl: | 586 | case NodeTypeContainerDecl: |
| 587 | { | 587 | { |
| 588 | const char *struct_name = buf_ptr(node->data.struct_decl.name); | 588 | const char *container_str = container_string(node->data.container_decl.kind); |
| 589 | const char *pub_str = visib_mod_string(node->data.struct_decl.visib_mod); | 589 | fprintf(ar->f, "%s {\n", container_str); |
| 590 | const char *container_str = container_string(node->data.struct_decl.kind); | ||
| 591 | fprintf(ar->f, "%s%s %s {\n", pub_str, container_str, struct_name); | ||
| 592 | ar->indent += ar->indent_size; | 590 | ar->indent += ar->indent_size; |
| 593 | for (size_t field_i = 0; field_i < node->data.struct_decl.fields.length; field_i += 1) { | 591 | for (size_t field_i = 0; field_i < node->data.container_decl.fields.length; field_i += 1) { |
| 594 | AstNode *field_node = node->data.struct_decl.fields.at(field_i); | 592 | AstNode *field_node = node->data.container_decl.fields.at(field_i); |
| 595 | assert(field_node->type == NodeTypeStructField); | 593 | assert(field_node->type == NodeTypeStructField); |
| 596 | print_indent(ar); | 594 | print_indent(ar); |
| 597 | print_symbol(ar, field_node->data.struct_field.name); | 595 | print_symbol(ar, field_node->data.struct_field.name); |
src/ir.cpp+59-31| ... | @@ -2306,6 +2306,8 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld | ... | @@ -2306,6 +2306,8 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 2306 | return irb->codegen->invalid_instruction; | 2306 | return irb->codegen->invalid_instruction; |
| 2307 | 2307 | ||
| 2308 | switch (tld->id) { | 2308 | switch (tld->id) { |
| 2309 | case TldIdContainer: | ||
| 2310 | zig_unreachable(); | ||
| 2309 | case TldIdVar: | 2311 | case TldIdVar: |
| 2310 | { | 2312 | { |
| 2311 | TldVar *tld_var = (TldVar *)tld; | 2313 | TldVar *tld_var = (TldVar *)tld; |
| ... | @@ -2327,16 +2329,6 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld | ... | @@ -2327,16 +2329,6 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 2327 | else | 2329 | else |
| 2328 | return ref_instruction; | 2330 | return ref_instruction; |
| 2329 | } | 2331 | } |
| 2330 | case TldIdContainer: | ||
| 2331 | { | ||
| 2332 | TldContainer *tld_container = (TldContainer *)tld; | ||
| 2333 | |||
| 2334 | IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, tld_container->type_entry); | ||
| 2335 | if (lval != LValPurposeNone) | ||
| 2336 | return ir_build_ref(irb, scope, source_node, ref_instruction); | ||
| 2337 | else | ||
| 2338 | return ref_instruction; | ||
| 2339 | } | ||
| 2340 | case TldIdTypeDef: | 2332 | case TldIdTypeDef: |
| 2341 | { | 2333 | { |
| 2342 | TldTypeDef *tld_typedef = (TldTypeDef *)tld; | 2334 | TldTypeDef *tld_typedef = (TldTypeDef *)tld; |
| ... | @@ -3861,6 +3853,52 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN | ... | @@ -3861,6 +3853,52 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN |
| 3861 | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); | 3853 | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 3862 | } | 3854 | } |
| 3863 | 3855 | ||
| 3856 | static const char *container_string(ContainerKind kind) { | ||
| 3857 | switch (kind) { | ||
| 3858 | case ContainerKindEnum: return "enum"; | ||
| 3859 | case ContainerKindStruct: return "struct"; | ||
| 3860 | case ContainerKindUnion: return "union"; | ||
| 3861 | } | ||
| 3862 | zig_unreachable(); | ||
| 3863 | } | ||
| 3864 | |||
| 3865 | static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | ||
| 3866 | assert(node->type == NodeTypeContainerDecl); | ||
| 3867 | |||
| 3868 | ContainerKind kind = node->data.container_decl.kind; | ||
| 3869 | Buf *name; | ||
| 3870 | if (irb->exec->name) { | ||
| 3871 | name = irb->exec->name; | ||
| 3872 | } else { | ||
| 3873 | FnTableEntry *fn_entry = exec_fn_entry(irb->exec); | ||
| 3874 | if (fn_entry) { | ||
| 3875 | zig_panic("TODO name the container inside the function"); | ||
| 3876 | } else { | ||
| 3877 | name = buf_sprintf("(anonymous %s at %s:%zu:%zu)", container_string(kind), | ||
| 3878 | buf_ptr(node->owner->path), node->line + 1, node->column + 1); | ||
| 3879 | } | ||
| 3880 | } | ||
| 3881 | |||
| 3882 | |||
| 3883 | VisibMod visib_mod = VisibModPub; | ||
| 3884 | TldContainer *tld_container = allocate<TldContainer>(1); | ||
| 3885 | init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, parent_scope); | ||
| 3886 | |||
| 3887 | TypeTableEntry *container_type = get_partial_container_type(irb->codegen, parent_scope, kind, node, buf_ptr(name)); | ||
| 3888 | ScopeDecls *child_scope = get_container_scope(container_type); | ||
| 3889 | |||
| 3890 | tld_container->type_entry = container_type; | ||
| 3891 | tld_container->decls_scope = child_scope; | ||
| 3892 | |||
| 3893 | for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { | ||
| 3894 | AstNode *child_node = node->data.container_decl.decls.at(i); | ||
| 3895 | scan_decls(irb->codegen, child_scope, child_node); | ||
| 3896 | } | ||
| 3897 | irb->codegen->resolve_queue.append(&tld_container->base); | ||
| 3898 | |||
| 3899 | return ir_build_const_type(irb, parent_scope, node, container_type); | ||
| 3900 | } | ||
| 3901 | |||
| 3864 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, | 3902 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 3865 | LValPurpose lval) | 3903 | LValPurpose lval) |
| 3866 | { | 3904 | { |
| ... | @@ -3872,6 +3910,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -3872,6 +3910,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 3872 | case NodeTypeUse: | 3910 | case NodeTypeUse: |
| 3873 | case NodeTypeSwitchProng: | 3911 | case NodeTypeSwitchProng: |
| 3874 | case NodeTypeSwitchRange: | 3912 | case NodeTypeSwitchRange: |
| 3913 | case NodeTypeStructField: | ||
| 3875 | zig_unreachable(); | 3914 | zig_unreachable(); |
| 3876 | case NodeTypeBlock: | 3915 | case NodeTypeBlock: |
| 3877 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); | 3916 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); |
| ... | @@ -3941,11 +3980,11 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -3941,11 +3980,11 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 3941 | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); | 3980 | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); |
| 3942 | case NodeTypeUnwrapErrorExpr: | 3981 | case NodeTypeUnwrapErrorExpr: |
| 3943 | return ir_lval_wrap(irb, scope, ir_gen_err_ok_or(irb, scope, node), lval); | 3982 | return ir_lval_wrap(irb, scope, ir_gen_err_ok_or(irb, scope, node), lval); |
| 3983 | case NodeTypeContainerDecl: | ||
| 3984 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); | ||
| 3944 | case NodeTypeFnProto: | 3985 | case NodeTypeFnProto: |
| 3945 | case NodeTypeFnDef: | 3986 | case NodeTypeFnDef: |
| 3946 | case NodeTypeFnDecl: | 3987 | case NodeTypeFnDecl: |
| 3947 | case NodeTypeContainerDecl: | ||
| 3948 | case NodeTypeStructField: | ||
| 3949 | case NodeTypeErrorValueDecl: | 3988 | case NodeTypeErrorValueDecl: |
| 3950 | case NodeTypeTypeDecl: | 3989 | case NodeTypeTypeDecl: |
| 3951 | zig_panic("TODO more IR gen for node types"); | 3990 | zig_panic("TODO more IR gen for node types"); |
| ... | @@ -4558,9 +4597,10 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un | ... | @@ -4558,9 +4597,10 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un |
| 4558 | 4597 | ||
| 4559 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 4598 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 4560 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 4599 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 4561 | FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node) | 4600 | FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name) |
| 4562 | { | 4601 | { |
| 4563 | IrExecutable ir_executable = {0}; | 4602 | IrExecutable ir_executable = {0}; |
| 4603 | ir_executable.name = exec_name; | ||
| 4564 | ir_executable.is_inline = true; | 4604 | ir_executable.is_inline = true; |
| 4565 | ir_executable.fn_entry = fn_entry; | 4605 | ir_executable.fn_entry = fn_entry; |
| 4566 | ir_executable.c_import_buf = c_import_buf; | 4606 | ir_executable.c_import_buf = c_import_buf; |
| ... | @@ -4577,6 +4617,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node | ... | @@ -4577,6 +4617,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 4577 | fprintf(stderr, "}\n"); | 4617 | fprintf(stderr, "}\n"); |
| 4578 | } | 4618 | } |
| 4579 | IrExecutable analyzed_executable = {0}; | 4619 | IrExecutable analyzed_executable = {0}; |
| 4620 | analyzed_executable.name = exec_name; | ||
| 4580 | analyzed_executable.is_inline = true; | 4621 | analyzed_executable.is_inline = true; |
| 4581 | analyzed_executable.fn_entry = fn_entry; | 4622 | analyzed_executable.fn_entry = fn_entry; |
| 4582 | analyzed_executable.c_import_buf = c_import_buf; | 4623 | analyzed_executable.c_import_buf = c_import_buf; |
| ... | @@ -6017,7 +6058,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -6017,7 +6058,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 6017 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; | 6058 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; |
| 6018 | IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, | 6059 | IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 6019 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, | 6060 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 6020 | nullptr, call_instruction->base.source_node); | 6061 | nullptr, call_instruction->base.source_node, nullptr); |
| 6021 | if (result->type_entry->id == TypeTableEntryIdInvalid) | 6062 | if (result->type_entry->id == TypeTableEntryIdInvalid) |
| 6022 | return ira->codegen->builtin_types.entry_invalid; | 6063 | return ira->codegen->builtin_types.entry_invalid; |
| 6023 | 6064 | ||
| ... | @@ -6772,6 +6813,8 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source | ... | @@ -6772,6 +6813,8 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source |
| 6772 | return ira->codegen->builtin_types.entry_invalid; | 6813 | return ira->codegen->builtin_types.entry_invalid; |
| 6773 | 6814 | ||
| 6774 | switch (tld->id) { | 6815 | switch (tld->id) { |
| 6816 | case TldIdContainer: | ||
| 6817 | zig_unreachable(); | ||
| 6775 | case TldIdVar: | 6818 | case TldIdVar: |
| 6776 | { | 6819 | { |
| 6777 | TldVar *tld_var = (TldVar *)tld; | 6820 | TldVar *tld_var = (TldVar *)tld; |
| ... | @@ -6794,21 +6837,6 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source | ... | @@ -6794,21 +6837,6 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source |
| 6794 | return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, | 6837 | return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, |
| 6795 | depends_on_compile_var, ConstPtrSpecialNone, ptr_is_const); | 6838 | depends_on_compile_var, ConstPtrSpecialNone, ptr_is_const); |
| 6796 | } | 6839 | } |
| 6797 | case TldIdContainer: | ||
| 6798 | { | ||
| 6799 | TldContainer *tld_container = (TldContainer *)tld; | ||
| 6800 | assert(tld_container->type_entry); | ||
| 6801 | |||
| 6802 | // TODO instead of allocating this every time, put it in the tld value and we can reference | ||
| 6803 | // the same one every time | ||
| 6804 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | ||
| 6805 | const_val->special = ConstValSpecialStatic; | ||
| 6806 | const_val->data.x_type = tld_container->type_entry; | ||
| 6807 | |||
| 6808 | bool ptr_is_const = true; | ||
| 6809 | return ir_analyze_const_ptr(ira, source_instruction, const_val, ira->codegen->builtin_types.entry_type, | ||
| 6810 | depends_on_compile_var, ConstPtrSpecialNone, ptr_is_const); | ||
| 6811 | } | ||
| 6812 | case TldIdTypeDef: | 6840 | case TldIdTypeDef: |
| 6813 | { | 6841 | { |
| 6814 | TldTypeDef *tld_typedef = (TldTypeDef *)tld; | 6842 | TldTypeDef *tld_typedef = (TldTypeDef *)tld; |
| ... | @@ -7928,7 +7956,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi | ... | @@ -7928,7 +7956,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi |
| 7928 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, | 7956 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, |
| 7929 | abs_full_path, search_dir, import_target_path, import_code); | 7957 | abs_full_path, search_dir, import_target_path, import_code); |
| 7930 | 7958 | ||
| 7931 | scan_decls(ira->codegen, target_import, target_import->decls_scope, target_import->root, nullptr); | 7959 | scan_decls(ira->codegen, target_import->decls_scope, target_import->root); |
| 7932 | 7960 | ||
| 7933 | ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var); | 7961 | ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var); |
| 7934 | out_val->data.x_import = target_import; | 7962 | out_val->data.x_import = target_import; |
| ... | @@ -8303,7 +8331,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc | ... | @@ -8303,7 +8331,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc |
| 8303 | TypeTableEntry *void_type = ira->codegen->builtin_types.entry_void; | 8331 | TypeTableEntry *void_type = ira->codegen->builtin_types.entry_void; |
| 8304 | IrInstruction *result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, | 8332 | IrInstruction *result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, |
| 8305 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, | 8333 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, |
| 8306 | &cimport_scope->buf, block_node); | 8334 | &cimport_scope->buf, block_node, nullptr); |
| 8307 | if (result->type_entry->id == TypeTableEntryIdInvalid) | 8335 | if (result->type_entry->id == TypeTableEntryIdInvalid) |
| 8308 | return ira->codegen->builtin_types.entry_invalid; | 8336 | return ira->codegen->builtin_types.entry_invalid; |
| 8309 | 8337 |
src/ir.hpp+1-1| ... | @@ -15,7 +15,7 @@ IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry); | ... | @@ -15,7 +15,7 @@ IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry); |
| 15 | 15 | ||
| 16 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 16 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 17 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 17 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 18 | FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node); | 18 | FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name); |
| 19 | 19 | ||
| 20 | TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, | 20 | TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, |
| 21 | TypeTableEntry *expected_type, AstNode *expected_type_source_node); | 21 | TypeTableEntry *expected_type, AstNode *expected_type_source_node); |
src/parseh.cpp+8-14| ... | @@ -120,7 +120,7 @@ static const char *decl_name(const Decl *decl) { | ... | @@ -120,7 +120,7 @@ static const char *decl_name(const Decl *decl) { |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) { | 122 | static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) { |
| 123 | init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base, nullptr); | 123 | init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base); |
| 124 | tld->resolution = TldResolutionOk; | 124 | tld->resolution = TldResolutionOk; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| ... | @@ -184,7 +184,7 @@ static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *n | ... | @@ -184,7 +184,7 @@ static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *n |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | 186 | ||
| 187 | static void add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { | 187 | static Tld *add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { |
| 188 | ConstExprValue *var_value = allocate<ConstExprValue>(1); | 188 | ConstExprValue *var_value = allocate<ConstExprValue>(1); |
| 189 | var_value->special = ConstValSpecialStatic; | 189 | var_value->special = ConstValSpecialStatic; |
| 190 | var_value->data.x_type = type_entry; | 190 | var_value->data.x_type = type_entry; |
| ... | @@ -192,15 +192,11 @@ static void add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { | ... | @@ -192,15 +192,11 @@ static void add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { |
| 192 | add_global(c, &tld_var->base); | 192 | add_global(c, &tld_var->base); |
| 193 | 193 | ||
| 194 | c->global_type_table.put(name, type_entry); | 194 | c->global_type_table.put(name, type_entry); |
| 195 | return &tld_var->base; | ||
| 195 | } | 196 | } |
| 196 | 197 | ||
| 197 | static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) { | 198 | static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) { |
| 198 | TldContainer *tld_container = allocate<TldContainer>(1); | 199 | return add_const_type(c, &type_entry->name, type_entry); |
| 199 | parseh_init_tld(c, &tld_container->base, TldIdContainer, &type_entry->name); | ||
| 200 | tld_container->type_entry = type_entry; | ||
| 201 | |||
| 202 | add_global(c, &tld_container->base); | ||
| 203 | return &tld_container->base; | ||
| 204 | } | 200 | } |
| 205 | 201 | ||
| 206 | static Tld *add_typedef_tld(Context *c, TypeTableEntry *type_decl) { | 202 | static Tld *add_typedef_tld(Context *c, TypeTableEntry *type_decl) { |
| ... | @@ -690,8 +686,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -690,8 +686,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 690 | 686 | ||
| 691 | const EnumDecl *enum_def = enum_decl->getDefinition(); | 687 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 692 | if (!enum_def) { | 688 | if (!enum_def) { |
| 693 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, | 689 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 694 | &c->import->decls_scope->base, | ||
| 695 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); | 690 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); |
| 696 | c->enum_type_table.put(bare_name, enum_type); | 691 | c->enum_type_table.put(bare_name, enum_type); |
| 697 | c->decl_table.put(enum_decl, enum_type); | 692 | c->decl_table.put(enum_decl, enum_type); |
| ... | @@ -715,8 +710,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -715,8 +710,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 715 | TypeTableEntry *tag_type_entry = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl); | 710 | TypeTableEntry *tag_type_entry = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl); |
| 716 | 711 | ||
| 717 | if (pure_enum) { | 712 | if (pure_enum) { |
| 718 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, | 713 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 719 | &c->import->decls_scope->base, | ||
| 720 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); | 714 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); |
| 721 | c->enum_type_table.put(bare_name, enum_type); | 715 | c->enum_type_table.put(bare_name, enum_type); |
| 722 | c->decl_table.put(enum_decl, enum_type); | 716 | c->decl_table.put(enum_decl, enum_type); |
| ... | @@ -855,8 +849,8 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -855,8 +849,8 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 855 | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); | 849 | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); |
| 856 | 850 | ||
| 857 | 851 | ||
| 858 | TypeTableEntry *struct_type = get_partial_container_type(c->codegen, c->import, | 852 | TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 859 | &c->import->decls_scope->base, ContainerKindStruct, c->source_node, buf_ptr(full_type_name)); | 853 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name)); |
| 860 | 854 | ||
| 861 | c->struct_type_table.put(bare_name, struct_type); | 855 | c->struct_type_table.put(bare_name, struct_type); |
| 862 | c->decl_table.put(record_decl, struct_type); | 856 | c->decl_table.put(record_decl, struct_type); |
src/parser.cpp+20-39| ... | @@ -216,6 +216,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, | ... | @@ -216,6 +216,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, |
| 216 | static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod); | 216 | static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod); |
| 217 | static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index); | 217 | static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index); |
| 218 | static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory); | 218 | static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory); |
| 219 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory); | ||
| 219 | 220 | ||
| 220 | static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { | 221 | static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { |
| 221 | if (token->id == token_id) { | 222 | if (token->id == token_id) { |
| ... | @@ -618,7 +619,7 @@ static AstNode *ast_parse_goto_expr(ParseContext *pc, size_t *token_index, bool | ... | @@ -618,7 +619,7 @@ static AstNode *ast_parse_goto_expr(ParseContext *pc, size_t *token_index, bool |
| 618 | return node; | 619 | return node; |
| 619 | } | 620 | } |
| 620 | /* | 621 | /* |
| 621 | PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol") | 622 | PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl |
| 622 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" | 623 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" |
| 623 | */ | 624 | */ |
| 624 | static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 625 | static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| ... | @@ -737,6 +738,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo | ... | @@ -737,6 +738,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo |
| 737 | return asm_expr; | 738 | return asm_expr; |
| 738 | } | 739 | } |
| 739 | 740 | ||
| 741 | AstNode *container_decl = ast_parse_container_decl(pc, token_index, false); | ||
| 742 | if (container_decl) | ||
| 743 | return container_decl; | ||
| 744 | |||
| 740 | if (!mandatory) | 745 | if (!mandatory) |
| 741 | return nullptr; | 746 | return nullptr; |
| 742 | 747 | ||
| ... | @@ -2219,43 +2224,31 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi | ... | @@ -2219,43 +2224,31 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi |
| 2219 | } | 2224 | } |
| 2220 | 2225 | ||
| 2221 | /* | 2226 | /* |
| 2222 | ContainerDecl = ("struct" | "enum" | "union") Symbol option(ParamDeclList) "{" many(StructMember) "}" | 2227 | ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}" |
| 2223 | StructMember = (StructField | FnDef | GlobalVarDecl | ContainerDecl) | 2228 | StructMember = (StructField | FnDef | GlobalVarDecl) |
| 2224 | StructField = Symbol option(":" Expression) ",") | 2229 | StructField = Symbol option(":" Expression) ",") |
| 2225 | */ | 2230 | */ |
| 2226 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) { | 2231 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2227 | Token *first_token = &pc->tokens->at(*token_index); | 2232 | Token *first_token = &pc->tokens->at(*token_index); |
| 2228 | 2233 | ||
| 2229 | ContainerKind kind; | 2234 | ContainerKind kind; |
| 2230 | |||
| 2231 | if (first_token->id == TokenIdKeywordStruct) { | 2235 | if (first_token->id == TokenIdKeywordStruct) { |
| 2232 | kind = ContainerKindStruct; | 2236 | kind = ContainerKindStruct; |
| 2233 | } else if (first_token->id == TokenIdKeywordEnum) { | 2237 | } else if (first_token->id == TokenIdKeywordEnum) { |
| 2234 | kind = ContainerKindEnum; | 2238 | kind = ContainerKindEnum; |
| 2235 | } else if (first_token->id == TokenIdKeywordUnion) { | 2239 | } else if (first_token->id == TokenIdKeywordUnion) { |
| 2236 | kind = ContainerKindUnion; | 2240 | kind = ContainerKindUnion; |
| 2241 | } else if (mandatory) { | ||
| 2242 | ast_invalid_token_error(pc, first_token); | ||
| 2237 | } else { | 2243 | } else { |
| 2238 | return nullptr; | 2244 | return nullptr; |
| 2239 | } | 2245 | } |
| 2240 | *token_index += 1; | 2246 | *token_index += 1; |
| 2241 | 2247 | ||
| 2242 | Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol); | ||
| 2243 | |||
| 2244 | AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token); | 2248 | AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token); |
| 2245 | node->data.struct_decl.kind = kind; | 2249 | node->data.container_decl.kind = kind; |
| 2246 | node->data.struct_decl.name = token_buf(struct_name); | 2250 | |
| 2247 | node->data.struct_decl.visib_mod = visib_mod; | 2251 | ast_eat_token(pc, token_index, TokenIdLBrace); |
| 2248 | |||
| 2249 | Token *paren_or_brace = &pc->tokens->at(*token_index); | ||
| 2250 | if (paren_or_brace->id == TokenIdLParen) { | ||
| 2251 | ast_parse_param_decl_list(pc, token_index, &node->data.struct_decl.generic_params, | ||
| 2252 | &node->data.struct_decl.generic_params_is_var_args); | ||
| 2253 | ast_eat_token(pc, token_index, TokenIdLBrace); | ||
| 2254 | } else if (paren_or_brace->id == TokenIdLBrace) { | ||
| 2255 | *token_index += 1; | ||
| 2256 | } else { | ||
| 2257 | ast_invalid_token_error(pc, paren_or_brace); | ||
| 2258 | } | ||
| 2259 | 2252 | ||
| 2260 | for (;;) { | 2253 | for (;;) { |
| 2261 | Token *visib_tok = &pc->tokens->at(*token_index); | 2254 | Token *visib_tok = &pc->tokens->at(*token_index); |
| ... | @@ -2272,20 +2265,14 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, | ... | @@ -2272,20 +2265,14 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, |
| 2272 | 2265 | ||
| 2273 | AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, visib_mod); | 2266 | AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, visib_mod); |
| 2274 | if (fn_def_node) { | 2267 | if (fn_def_node) { |
| 2275 | node->data.struct_decl.decls.append(fn_def_node); | 2268 | node->data.container_decl.decls.append(fn_def_node); |
| 2276 | continue; | 2269 | continue; |
| 2277 | } | 2270 | } |
| 2278 | 2271 | ||
| 2279 | AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod); | 2272 | AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod); |
| 2280 | if (var_decl_node) { | 2273 | if (var_decl_node) { |
| 2281 | ast_eat_token(pc, token_index, TokenIdSemicolon); | 2274 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 2282 | node->data.struct_decl.decls.append(var_decl_node); | 2275 | node->data.container_decl.decls.append(var_decl_node); |
| 2283 | continue; | ||
| 2284 | } | ||
| 2285 | |||
| 2286 | AstNode *container_decl_node = ast_parse_container_decl(pc, token_index, visib_mod); | ||
| 2287 | if (container_decl_node) { | ||
| 2288 | node->data.struct_decl.decls.append(container_decl_node); | ||
| 2289 | continue; | 2276 | continue; |
| 2290 | } | 2277 | } |
| 2291 | 2278 | ||
| ... | @@ -2311,7 +2298,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, | ... | @@ -2311,7 +2298,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, |
| 2311 | ast_eat_token(pc, token_index, TokenIdComma); | 2298 | ast_eat_token(pc, token_index, TokenIdComma); |
| 2312 | } | 2299 | } |
| 2313 | 2300 | ||
| 2314 | node->data.struct_decl.fields.append(field_node); | 2301 | node->data.container_decl.fields.append(field_node); |
| 2315 | } else { | 2302 | } else { |
| 2316 | ast_invalid_token_error(pc, token); | 2303 | ast_invalid_token_error(pc, token); |
| 2317 | } | 2304 | } |
| ... | @@ -2368,7 +2355,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib | ... | @@ -2368,7 +2355,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib |
| 2368 | 2355 | ||
| 2369 | /* | 2356 | /* |
| 2370 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | 2357 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl |
| 2371 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | ContainerDecl | GlobalVarDecl | TypeDecl | UseDecl) | 2358 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl) |
| 2372 | */ | 2359 | */ |
| 2373 | static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) { | 2360 | static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) { |
| 2374 | for (;;) { | 2361 | for (;;) { |
| ... | @@ -2402,12 +2389,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig | ... | @@ -2402,12 +2389,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig |
| 2402 | continue; | 2389 | continue; |
| 2403 | } | 2390 | } |
| 2404 | 2391 | ||
| 2405 | AstNode *struct_node = ast_parse_container_decl(pc, token_index, visib_mod); | ||
| 2406 | if (struct_node) { | ||
| 2407 | top_level_decls->append(struct_node); | ||
| 2408 | continue; | ||
| 2409 | } | ||
| 2410 | |||
| 2411 | AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod); | 2392 | AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod); |
| 2412 | if (var_decl_node) { | 2393 | if (var_decl_node) { |
| 2413 | ast_eat_token(pc, token_index, TokenIdSemicolon); | 2394 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| ... | @@ -2630,8 +2611,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont | ... | @@ -2630,8 +2611,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2630 | } | 2611 | } |
| 2631 | break; | 2612 | break; |
| 2632 | case NodeTypeContainerDecl: | 2613 | case NodeTypeContainerDecl: |
| 2633 | visit_node_list(&node->data.struct_decl.fields, visit, context); | 2614 | visit_node_list(&node->data.container_decl.fields, visit, context); |
| 2634 | visit_node_list(&node->data.struct_decl.decls, visit, context); | 2615 | visit_node_list(&node->data.container_decl.decls, visit, context); |
| 2635 | break; | 2616 | break; |
| 2636 | case NodeTypeStructField: | 2617 | case NodeTypeStructField: |
| 2637 | visit_field(&node->data.struct_field.type, visit, context); | 2618 | visit_field(&node->data.struct_field.type, visit, context); |
test/self_hosted2.zig+2-2| ... | @@ -87,9 +87,9 @@ var goto_counter: i32 = 0; | ... | @@ -87,9 +87,9 @@ var goto_counter: i32 = 0; |
| 87 | 87 | ||
| 88 | 88 | ||
| 89 | 89 | ||
| 90 | struct FooA { | 90 | const FooA = struct { |
| 91 | fn add(a: i32, b: i32) -> i32 { a + b } | 91 | fn add(a: i32, b: i32) -> i32 { a + b } |
| 92 | } | 92 | }; |
| 93 | const foo_a = FooA {}; | 93 | const foo_a = FooA {}; |
| 94 | 94 | ||
| 95 | fn testStructStatic() { | 95 | fn testStructStatic() { |