| author | |
| committer | |
| log | 71d335e5ccc5c7c37ac40debf78ad3aa096b22d3 |
| tree | b64024a77a76bf26ed77596125c046321edfb4ff |
| parent | cd7713b1788aeeadf6c46def38d4ef4fa313fe75 |
closes #18312 files changed, 161 insertions(+), 118 deletions(-)
doc/langref.md+3-3| ... | @@ -17,9 +17,9 @@ GlobalVarDecl = VariableDeclaration ";" | ... | @@ -17,9 +17,9 @@ GlobalVarDecl = VariableDeclaration ";" |
| 17 | 17 | ||
| 18 | VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression | 18 | VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression |
| 19 | 19 | ||
| 20 | StructMember = (StructField | FnDef | GlobalVarDecl) | 20 | ContainerMember = (ContainerField | FnDef | GlobalVarDecl) |
| 21 | 21 | ||
| 22 | StructField = Symbol option(":" Expression) ",") | 22 | ContainerField = Symbol option(":" Expression) ",") |
| 23 | 23 | ||
| 24 | UseDecl = "use" Expression ";" | 24 | UseDecl = "use" Expression ";" |
| 25 | 25 | ||
| ... | @@ -155,7 +155,7 @@ GroupedExpression = "(" Expression ")" | ... | @@ -155,7 +155,7 @@ GroupedExpression = "(" Expression ")" |
| 155 | 155 | ||
| 156 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" | 156 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" |
| 157 | 157 | ||
| 158 | ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}" | 158 | ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" many(ContainerMember) "}" |
| 159 | 159 | ||
| 160 | ``` | 160 | ``` |
| 161 | 161 |
doc/vim/syntax/zig.vim+3-3| ... | @@ -8,15 +8,15 @@ if exists("b:current_syntax") | ... | @@ -8,15 +8,15 @@ if exists("b:current_syntax") |
| 8 | endif | 8 | endif |
| 9 | let b:current_syntax = "zig" | 9 | let b:current_syntax = "zig" |
| 10 | 10 | ||
| 11 | syn keyword zigStorage const var extern export pub noalias inline comptime nakedcc coldcc | 11 | syn keyword zigStorage const var extern packed export pub noalias inline comptime nakedcc coldcc volatile |
| 12 | syn keyword zigStructure struct enum union | 12 | syn keyword zigStructure struct enum union |
| 13 | syn keyword zigStatement goto break return continue asm defer | 13 | syn keyword zigStatement goto break return continue asm defer unreachable |
| 14 | syn keyword zigConditional if else switch try | 14 | syn keyword zigConditional if else switch try |
| 15 | syn keyword zigRepeat while for | 15 | syn keyword zigRepeat while for |
| 16 | 16 | ||
| 17 | syn keyword zigConstant null undefined zeroes this | 17 | syn keyword zigConstant null undefined zeroes this |
| 18 | syn keyword zigKeyword fn use | 18 | syn keyword zigKeyword fn use |
| 19 | syn keyword zigType bool f32 f64 void unreachable type error | 19 | syn keyword zigType bool f32 f64 void Unreachable type error |
| 20 | syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize | 20 | syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize |
| 21 | syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_long_double | 21 | syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_long_double |
| 22 | 22 |
src/all_types.hpp+10-4| ... | @@ -621,11 +621,17 @@ enum ContainerKind { | ... | @@ -621,11 +621,17 @@ enum ContainerKind { |
| 621 | ContainerKindUnion, | 621 | ContainerKindUnion, |
| 622 | }; | 622 | }; |
| 623 | 623 | ||
| 624 | enum ContainerLayout { | ||
| 625 | ContainerLayoutAuto, | ||
| 626 | ContainerLayoutExtern, | ||
| 627 | ContainerLayoutPacked, | ||
| 628 | }; | ||
| 629 | |||
| 624 | struct AstNodeContainerDecl { | 630 | struct AstNodeContainerDecl { |
| 625 | ContainerKind kind; | 631 | ContainerKind kind; |
| 626 | ZigList<AstNode *> fields; | 632 | ZigList<AstNode *> fields; |
| 627 | ZigList<AstNode *> decls; | 633 | ZigList<AstNode *> decls; |
| 628 | bool is_extern; | 634 | ContainerLayout layout; |
| 629 | }; | 635 | }; |
| 630 | 636 | ||
| 631 | struct AstNodeStructField { | 637 | struct AstNodeStructField { |
| ... | @@ -820,7 +826,7 @@ struct TypeStructField { | ... | @@ -820,7 +826,7 @@ struct TypeStructField { |
| 820 | }; | 826 | }; |
| 821 | struct TypeTableEntryStruct { | 827 | struct TypeTableEntryStruct { |
| 822 | AstNode *decl_node; | 828 | AstNode *decl_node; |
| 823 | bool is_extern; | 829 | ContainerLayout layout; |
| 824 | bool is_packed; | 830 | bool is_packed; |
| 825 | uint32_t src_field_count; | 831 | uint32_t src_field_count; |
| 826 | uint32_t gen_field_count; | 832 | uint32_t gen_field_count; |
| ... | @@ -850,7 +856,7 @@ struct TypeTableEntryError { | ... | @@ -850,7 +856,7 @@ struct TypeTableEntryError { |
| 850 | 856 | ||
| 851 | struct TypeTableEntryEnum { | 857 | struct TypeTableEntryEnum { |
| 852 | AstNode *decl_node; | 858 | AstNode *decl_node; |
| 853 | bool is_extern; | 859 | ContainerLayout layout; |
| 854 | uint32_t src_field_count; | 860 | uint32_t src_field_count; |
| 855 | uint32_t gen_field_count; | 861 | uint32_t gen_field_count; |
| 856 | TypeEnumField *fields; | 862 | TypeEnumField *fields; |
| ... | @@ -877,7 +883,7 @@ struct TypeTableEntryEnumTag { | ... | @@ -877,7 +883,7 @@ struct TypeTableEntryEnumTag { |
| 877 | 883 | ||
| 878 | struct TypeTableEntryUnion { | 884 | struct TypeTableEntryUnion { |
| 879 | AstNode *decl_node; | 885 | AstNode *decl_node; |
| 880 | bool is_extern; | 886 | ContainerLayout layout; |
| 881 | uint32_t src_field_count; | 887 | uint32_t src_field_count; |
| 882 | uint32_t gen_field_count; | 888 | uint32_t gen_field_count; |
| 883 | TypeStructField *fields; | 889 | TypeStructField *fields; |
src/analyze.cpp+8-5| ... | @@ -823,22 +823,24 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { | ... | @@ -823,22 +823,24 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { |
| 823 | zig_unreachable(); | 823 | zig_unreachable(); |
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name, bool is_extern) { | 826 | TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, |
| 827 | AstNode *decl_node, const char *name, ContainerLayout layout) | ||
| 828 | { | ||
| 827 | TypeTableEntryId type_id = container_to_type(kind); | 829 | TypeTableEntryId type_id = container_to_type(kind); |
| 828 | TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); | 830 | TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); |
| 829 | 831 | ||
| 830 | switch (kind) { | 832 | switch (kind) { |
| 831 | case ContainerKindStruct: | 833 | case ContainerKindStruct: |
| 832 | entry->data.structure.decl_node = decl_node; | 834 | entry->data.structure.decl_node = decl_node; |
| 833 | entry->data.structure.is_extern = is_extern; | 835 | entry->data.structure.layout = layout; |
| 834 | break; | 836 | break; |
| 835 | case ContainerKindEnum: | 837 | case ContainerKindEnum: |
| 836 | entry->data.enumeration.decl_node = decl_node; | 838 | entry->data.enumeration.decl_node = decl_node; |
| 837 | entry->data.enumeration.is_extern = is_extern; | 839 | entry->data.enumeration.layout = layout; |
| 838 | break; | 840 | break; |
| 839 | case ContainerKindUnion: | 841 | case ContainerKindUnion: |
| 840 | entry->data.unionation.decl_node = decl_node; | 842 | entry->data.unionation.decl_node = decl_node; |
| 841 | entry->data.unionation.is_extern = is_extern; | 843 | entry->data.unionation.layout = layout; |
| 842 | break; | 844 | break; |
| 843 | } | 845 | } |
| 844 | 846 | ||
| ... | @@ -1328,7 +1330,8 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1328,7 +1330,8 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1328 | } | 1330 | } |
| 1329 | assert(struct_type->di_type); | 1331 | assert(struct_type->di_type); |
| 1330 | 1332 | ||
| 1331 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, false); | 1333 | bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| 1334 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, packed); | ||
| 1332 | assert(LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref) > 0); | 1335 | assert(LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref) > 0); |
| 1333 | 1336 | ||
| 1334 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); | 1337 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); |
src/analyze.hpp+2-1| ... | @@ -26,7 +26,8 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); | ... | @@ -26,7 +26,8 @@ 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, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name, bool is_extern); | 29 | TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, |
| 30 | AstNode *decl_node, const char *name, ContainerLayout layout); | ||
| 30 | TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); | 31 | TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); |
| 31 | TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); | 32 | TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); |
| 32 | TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry); | 33 | TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry); |
src/ast_render.cpp+13-4| ... | @@ -104,6 +104,15 @@ static const char *defer_string(ReturnKind kind) { | ... | @@ -104,6 +104,15 @@ static const char *defer_string(ReturnKind kind) { |
| 104 | zig_unreachable(); | 104 | zig_unreachable(); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | static const char *layout_string(ContainerLayout layout) { | ||
| 108 | switch (layout) { | ||
| 109 | case ContainerLayoutAuto: return ""; | ||
| 110 | case ContainerLayoutExtern: return "extern "; | ||
| 111 | case ContainerLayoutPacked: return "packed "; | ||
| 112 | } | ||
| 113 | zig_unreachable(); | ||
| 114 | } | ||
| 115 | |||
| 107 | static const char *extern_string(bool is_extern) { | 116 | static const char *extern_string(bool is_extern) { |
| 108 | return is_extern ? "extern " : ""; | 117 | return is_extern ? "extern " : ""; |
| 109 | } | 118 | } |
| ... | @@ -970,8 +979,8 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { | ... | @@ -970,8 +979,8 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { |
| 970 | { | 979 | { |
| 971 | TypeTableEntry *type_entry = var->value.data.x_type; | 980 | TypeTableEntry *type_entry = var->value.data.x_type; |
| 972 | if (type_entry->id == TypeTableEntryIdStruct) { | 981 | if (type_entry->id == TypeTableEntryIdStruct) { |
| 973 | const char *extern_str = extern_string(type_entry->data.structure.is_extern); | 982 | const char *layout_str = layout_string(type_entry->data.structure.layout); |
| 974 | fprintf(ar->f, "%sstruct {\n", extern_str); | 983 | fprintf(ar->f, "%sstruct {\n", layout_str); |
| 975 | if (type_entry->data.structure.complete) { | 984 | if (type_entry->data.structure.complete) { |
| 976 | for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { | 985 | for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { |
| 977 | TypeStructField *field = &type_entry->data.structure.fields[i]; | 986 | TypeStructField *field = &type_entry->data.structure.fields[i]; |
| ... | @@ -982,8 +991,8 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { | ... | @@ -982,8 +991,8 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { |
| 982 | } | 991 | } |
| 983 | fprintf(ar->f, "}"); | 992 | fprintf(ar->f, "}"); |
| 984 | } else if (type_entry->id == TypeTableEntryIdEnum) { | 993 | } else if (type_entry->id == TypeTableEntryIdEnum) { |
| 985 | const char *extern_str = extern_string(type_entry->data.enumeration.is_extern); | 994 | const char *layout_str = layout_string(type_entry->data.enumeration.layout); |
| 986 | fprintf(ar->f, "%senum {\n", extern_str); | 995 | fprintf(ar->f, "%senum {\n", layout_str); |
| 987 | if (type_entry->data.enumeration.complete) { | 996 | if (type_entry->data.enumeration.complete) { |
| 988 | for (size_t i = 0; i < type_entry->data.enumeration.src_field_count; i += 1) { | 997 | for (size_t i = 0; i < type_entry->data.enumeration.src_field_count; i += 1) { |
| 989 | TypeEnumField *field = &type_entry->data.enumeration.fields[i]; | 998 | TypeEnumField *field = &type_entry->data.enumeration.fields[i]; |
src/ir.cpp+3-2| ... | @@ -5283,8 +5283,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, | ... | @@ -5283,8 +5283,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, |
| 5283 | TldContainer *tld_container = allocate<TldContainer>(1); | 5283 | TldContainer *tld_container = allocate<TldContainer>(1); |
| 5284 | init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, parent_scope); | 5284 | init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, parent_scope); |
| 5285 | 5285 | ||
| 5286 | TypeTableEntry *container_type = get_partial_container_type(irb->codegen, parent_scope, kind, node, buf_ptr(name), | 5286 | ContainerLayout layout = node->data.container_decl.layout; |
| 5287 | node->data.container_decl.is_extern); | 5287 | TypeTableEntry *container_type = get_partial_container_type(irb->codegen, parent_scope, |
| 5288 | kind, node, buf_ptr(name), layout); | ||
| 5288 | ScopeDecls *child_scope = get_container_scope(container_type); | 5289 | ScopeDecls *child_scope = get_container_scope(container_type); |
| 5289 | 5290 | ||
| 5290 | tld_container->type_entry = container_type; | 5291 | tld_container->type_entry = container_type; |
src/parseh.cpp+3-3| ... | @@ -720,7 +720,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -720,7 +720,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 720 | const EnumDecl *enum_def = enum_decl->getDefinition(); | 720 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 721 | if (!enum_def) { | 721 | if (!enum_def) { |
| 722 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 722 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 723 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), true); | 723 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); |
| 724 | enum_type->data.enumeration.zero_bits_known = true; | 724 | enum_type->data.enumeration.zero_bits_known = true; |
| 725 | c->enum_type_table.put(bare_name, enum_type); | 725 | c->enum_type_table.put(bare_name, enum_type); |
| 726 | c->decl_table.put(enum_decl, enum_type); | 726 | c->decl_table.put(enum_decl, enum_type); |
| ... | @@ -745,7 +745,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -745,7 +745,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 745 | 745 | ||
| 746 | if (pure_enum) { | 746 | if (pure_enum) { |
| 747 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 747 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 748 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), true); | 748 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); |
| 749 | c->enum_type_table.put(bare_name, enum_type); | 749 | c->enum_type_table.put(bare_name, enum_type); |
| 750 | c->decl_table.put(enum_decl, enum_type); | 750 | c->decl_table.put(enum_decl, enum_type); |
| 751 | 751 | ||
| ... | @@ -885,7 +885,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -885,7 +885,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 885 | 885 | ||
| 886 | 886 | ||
| 887 | TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 887 | TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 888 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name), true); | 888 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); |
| 889 | struct_type->data.structure.zero_bits_known = true; | 889 | struct_type->data.structure.zero_bits_known = true; |
| 890 | 890 | ||
| 891 | c->struct_type_table.put(bare_name, struct_type); | 891 | c->struct_type_table.put(bare_name, struct_type); |
src/parser.cpp+11-8| ... | @@ -2275,21 +2275,24 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi | ... | @@ -2275,21 +2275,24 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi |
| 2275 | } | 2275 | } |
| 2276 | 2276 | ||
| 2277 | /* | 2277 | /* |
| 2278 | ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}" | 2278 | ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" many(ContainerMember) "}" |
| 2279 | StructMember = (StructField | FnDef | GlobalVarDecl) | 2279 | ContainerMember = (ContainerField | FnDef | GlobalVarDecl) |
| 2280 | StructField = Symbol option(":" Expression) ",") | 2280 | ContainerField = Symbol option(":" Expression) ",") |
| 2281 | */ | 2281 | */ |
| 2282 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) { | 2282 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2283 | Token *first_token = &pc->tokens->at(*token_index); | 2283 | Token *first_token = &pc->tokens->at(*token_index); |
| 2284 | Token *container_kind_token; | 2284 | Token *container_kind_token; |
| 2285 | 2285 | ||
| 2286 | bool is_extern; | 2286 | ContainerLayout layout; |
| 2287 | if (first_token->id == TokenIdKeywordExtern) { | 2287 | if (first_token->id == TokenIdKeywordExtern) { |
| 2288 | container_kind_token = &pc->tokens->at(*token_index + 1); | 2288 | container_kind_token = &pc->tokens->at(*token_index + 1); |
| 2289 | is_extern = true; | 2289 | layout = ContainerLayoutExtern; |
| 2290 | } else if (first_token->id == TokenIdKeywordPacked) { | ||
| 2291 | container_kind_token = &pc->tokens->at(*token_index + 1); | ||
| 2292 | layout = ContainerLayoutPacked; | ||
| 2290 | } else { | 2293 | } else { |
| 2291 | container_kind_token = first_token; | 2294 | container_kind_token = first_token; |
| 2292 | is_extern = false; | 2295 | layout = ContainerLayoutAuto; |
| 2293 | } | 2296 | } |
| 2294 | 2297 | ||
| 2295 | ContainerKind kind; | 2298 | ContainerKind kind; |
| ... | @@ -2304,10 +2307,10 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, | ... | @@ -2304,10 +2307,10 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, |
| 2304 | } else { | 2307 | } else { |
| 2305 | return nullptr; | 2308 | return nullptr; |
| 2306 | } | 2309 | } |
| 2307 | *token_index += is_extern ? 2 : 1; | 2310 | *token_index += (layout == ContainerLayoutAuto) ? 1 : 2; |
| 2308 | 2311 | ||
| 2309 | AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token); | 2312 | AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token); |
| 2310 | node->data.container_decl.is_extern = is_extern; | 2313 | node->data.container_decl.layout = layout; |
| 2311 | node->data.container_decl.kind = kind; | 2314 | node->data.container_decl.kind = kind; |
| 2312 | 2315 | ||
| 2313 | ast_eat_token(pc, token_index, TokenIdLBrace); | 2316 | ast_eat_token(pc, token_index, TokenIdLBrace); |
src/tokenizer.cpp+2| ... | @@ -128,6 +128,7 @@ static const struct ZigKeyword zig_keywords[] = { | ... | @@ -128,6 +128,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 128 | {"nakedcc", TokenIdKeywordNakedCC}, | 128 | {"nakedcc", TokenIdKeywordNakedCC}, |
| 129 | {"noalias", TokenIdKeywordNoAlias}, | 129 | {"noalias", TokenIdKeywordNoAlias}, |
| 130 | {"null", TokenIdKeywordNull}, | 130 | {"null", TokenIdKeywordNull}, |
| 131 | {"packed", TokenIdKeywordPacked}, | ||
| 131 | {"pub", TokenIdKeywordPub}, | 132 | {"pub", TokenIdKeywordPub}, |
| 132 | {"return", TokenIdKeywordReturn}, | 133 | {"return", TokenIdKeywordReturn}, |
| 133 | {"struct", TokenIdKeywordStruct}, | 134 | {"struct", TokenIdKeywordStruct}, |
| ... | @@ -1502,6 +1503,7 @@ const char * token_name(TokenId id) { | ... | @@ -1502,6 +1503,7 @@ const char * token_name(TokenId id) { |
| 1502 | case TokenIdKeywordNakedCC: return "nakedcc"; | 1503 | case TokenIdKeywordNakedCC: return "nakedcc"; |
| 1503 | case TokenIdKeywordNoAlias: return "noalias"; | 1504 | case TokenIdKeywordNoAlias: return "noalias"; |
| 1504 | case TokenIdKeywordNull: return "null"; | 1505 | case TokenIdKeywordNull: return "null"; |
| 1506 | case TokenIdKeywordPacked: return "packed"; | ||
| 1505 | case TokenIdKeywordPub: return "pub"; | 1507 | case TokenIdKeywordPub: return "pub"; |
| 1506 | case TokenIdKeywordReturn: return "return"; | 1508 | case TokenIdKeywordReturn: return "return"; |
| 1507 | case TokenIdKeywordStruct: return "struct"; | 1509 | case TokenIdKeywordStruct: return "struct"; |
src/tokenizer.hpp+86-85| ... | @@ -12,109 +12,110 @@ | ... | @@ -12,109 +12,110 @@ |
| 12 | #include "bignum.hpp" | 12 | #include "bignum.hpp" |
| 13 | 13 | ||
| 14 | enum TokenId { | 14 | enum TokenId { |
| 15 | TokenIdEof, | 15 | TokenIdAmpersand, |
| 16 | TokenIdSymbol, | ||
| 17 | TokenIdKeywordFn, | ||
| 18 | TokenIdKeywordReturn, | ||
| 19 | TokenIdKeywordVar, | ||
| 20 | TokenIdKeywordConst, | ||
| 21 | TokenIdKeywordExtern, | ||
| 22 | TokenIdKeywordPub, | ||
| 23 | TokenIdKeywordUse, | ||
| 24 | TokenIdKeywordExport, | ||
| 25 | TokenIdKeywordTrue, | ||
| 26 | TokenIdKeywordFalse, | ||
| 27 | TokenIdKeywordIf, | ||
| 28 | TokenIdKeywordTry, | ||
| 29 | TokenIdKeywordElse, | ||
| 30 | TokenIdKeywordGoto, | ||
| 31 | TokenIdKeywordAsm, | ||
| 32 | TokenIdKeywordVolatile, | ||
| 33 | TokenIdKeywordStruct, | ||
| 34 | TokenIdKeywordEnum, | ||
| 35 | TokenIdKeywordUnion, | ||
| 36 | TokenIdKeywordWhile, | ||
| 37 | TokenIdKeywordFor, | ||
| 38 | TokenIdKeywordContinue, | ||
| 39 | TokenIdKeywordBreak, | ||
| 40 | TokenIdKeywordNull, | ||
| 41 | TokenIdKeywordNoAlias, | ||
| 42 | TokenIdKeywordSwitch, | ||
| 43 | TokenIdKeywordUndefined, | ||
| 44 | TokenIdKeywordError, | ||
| 45 | TokenIdKeywordType, | ||
| 46 | TokenIdKeywordInline, | ||
| 47 | TokenIdKeywordCompTime, | ||
| 48 | TokenIdKeywordDefer, | ||
| 49 | TokenIdKeywordThis, | ||
| 50 | TokenIdKeywordColdCC, | ||
| 51 | TokenIdKeywordNakedCC, | ||
| 52 | TokenIdLParen, | ||
| 53 | TokenIdRParen, | ||
| 54 | TokenIdComma, | ||
| 55 | TokenIdStar, | ||
| 56 | TokenIdStarStar, | ||
| 57 | TokenIdLBrace, | ||
| 58 | TokenIdRBrace, | ||
| 59 | TokenIdLBracket, | ||
| 60 | TokenIdRBracket, | ||
| 61 | TokenIdStringLiteral, | ||
| 62 | TokenIdCharLiteral, | ||
| 63 | TokenIdSemicolon, | ||
| 64 | TokenIdNumberLiteral, | ||
| 65 | TokenIdPlus, | ||
| 66 | TokenIdPlusPlus, | ||
| 67 | TokenIdColon, | ||
| 68 | TokenIdArrow, | 16 | TokenIdArrow, |
| 69 | TokenIdFatArrow, | 17 | TokenIdAtSign, |
| 70 | TokenIdDash, | 18 | TokenIdBang, |
| 71 | TokenIdNumberSign, | ||
| 72 | TokenIdBoolOr, | ||
| 73 | TokenIdBoolAnd, | ||
| 74 | TokenIdBinOr, | 19 | TokenIdBinOr, |
| 75 | TokenIdAmpersand, | ||
| 76 | TokenIdBinXor, | 20 | TokenIdBinXor, |
| 77 | TokenIdEq, | 21 | TokenIdBitAndEq, |
| 78 | TokenIdTimesEq, | 22 | TokenIdBitOrEq, |
| 79 | TokenIdTimesPercent, | 23 | TokenIdBitShiftLeft, |
| 80 | TokenIdTimesPercentEq, | ||
| 81 | TokenIdDivEq, | ||
| 82 | TokenIdModEq, | ||
| 83 | TokenIdPlusEq, | ||
| 84 | TokenIdPlusPercent, | ||
| 85 | TokenIdPlusPercentEq, | ||
| 86 | TokenIdMinusEq, | ||
| 87 | TokenIdMinusPercent, | ||
| 88 | TokenIdMinusPercentEq, | ||
| 89 | TokenIdBitShiftLeftEq, | 24 | TokenIdBitShiftLeftEq, |
| 90 | TokenIdBitShiftLeftPercent, | 25 | TokenIdBitShiftLeftPercent, |
| 91 | TokenIdBitShiftLeftPercentEq, | 26 | TokenIdBitShiftLeftPercentEq, |
| 27 | TokenIdBitShiftRight, | ||
| 92 | TokenIdBitShiftRightEq, | 28 | TokenIdBitShiftRightEq, |
| 93 | TokenIdBitAndEq, | ||
| 94 | TokenIdBitXorEq, | 29 | TokenIdBitXorEq, |
| 95 | TokenIdBitOrEq, | 30 | TokenIdBoolAnd, |
| 96 | TokenIdBoolAndEq, | 31 | TokenIdBoolAndEq, |
| 32 | TokenIdBoolOr, | ||
| 97 | TokenIdBoolOrEq, | 33 | TokenIdBoolOrEq, |
| 34 | TokenIdCharLiteral, | ||
| 98 | TokenIdCmpEq, | 35 | TokenIdCmpEq, |
| 99 | TokenIdBang, | 36 | TokenIdCmpGreaterOrEq, |
| 100 | TokenIdTilde, | ||
| 101 | TokenIdCmpNotEq, | ||
| 102 | TokenIdCmpLessThan, | ||
| 103 | TokenIdCmpGreaterThan, | 37 | TokenIdCmpGreaterThan, |
| 104 | TokenIdCmpLessOrEq, | 38 | TokenIdCmpLessOrEq, |
| 105 | TokenIdCmpGreaterOrEq, | 39 | TokenIdCmpLessThan, |
| 106 | TokenIdBitShiftLeft, | 40 | TokenIdCmpNotEq, |
| 107 | TokenIdBitShiftRight, | 41 | TokenIdColon, |
| 108 | TokenIdSlash, | 42 | TokenIdComma, |
| 109 | TokenIdPercent, | 43 | TokenIdDash, |
| 110 | TokenIdPercentPercent, | 44 | TokenIdDivEq, |
| 111 | TokenIdDot, | 45 | TokenIdDot, |
| 46 | TokenIdDoubleQuestion, | ||
| 112 | TokenIdEllipsis, | 47 | TokenIdEllipsis, |
| 48 | TokenIdEof, | ||
| 49 | TokenIdEq, | ||
| 50 | TokenIdFatArrow, | ||
| 51 | TokenIdKeywordAsm, | ||
| 52 | TokenIdKeywordBreak, | ||
| 53 | TokenIdKeywordColdCC, | ||
| 54 | TokenIdKeywordCompTime, | ||
| 55 | TokenIdKeywordConst, | ||
| 56 | TokenIdKeywordContinue, | ||
| 57 | TokenIdKeywordDefer, | ||
| 58 | TokenIdKeywordElse, | ||
| 59 | TokenIdKeywordEnum, | ||
| 60 | TokenIdKeywordError, | ||
| 61 | TokenIdKeywordExport, | ||
| 62 | TokenIdKeywordExtern, | ||
| 63 | TokenIdKeywordFalse, | ||
| 64 | TokenIdKeywordFn, | ||
| 65 | TokenIdKeywordFor, | ||
| 66 | TokenIdKeywordGoto, | ||
| 67 | TokenIdKeywordIf, | ||
| 68 | TokenIdKeywordInline, | ||
| 69 | TokenIdKeywordNakedCC, | ||
| 70 | TokenIdKeywordNoAlias, | ||
| 71 | TokenIdKeywordNull, | ||
| 72 | TokenIdKeywordPacked, | ||
| 73 | TokenIdKeywordPub, | ||
| 74 | TokenIdKeywordReturn, | ||
| 75 | TokenIdKeywordStruct, | ||
| 76 | TokenIdKeywordSwitch, | ||
| 77 | TokenIdKeywordThis, | ||
| 78 | TokenIdKeywordTrue, | ||
| 79 | TokenIdKeywordTry, | ||
| 80 | TokenIdKeywordType, | ||
| 81 | TokenIdKeywordUndefined, | ||
| 82 | TokenIdKeywordUnion, | ||
| 83 | TokenIdKeywordUse, | ||
| 84 | TokenIdKeywordVar, | ||
| 85 | TokenIdKeywordVolatile, | ||
| 86 | TokenIdKeywordWhile, | ||
| 87 | TokenIdLBrace, | ||
| 88 | TokenIdLBracket, | ||
| 89 | TokenIdLParen, | ||
| 113 | TokenIdMaybe, | 90 | TokenIdMaybe, |
| 114 | TokenIdDoubleQuestion, | ||
| 115 | TokenIdMaybeAssign, | 91 | TokenIdMaybeAssign, |
| 116 | TokenIdAtSign, | 92 | TokenIdMinusEq, |
| 93 | TokenIdMinusPercent, | ||
| 94 | TokenIdMinusPercentEq, | ||
| 95 | TokenIdModEq, | ||
| 96 | TokenIdNumberLiteral, | ||
| 97 | TokenIdNumberSign, | ||
| 98 | TokenIdPercent, | ||
| 117 | TokenIdPercentDot, | 99 | TokenIdPercentDot, |
| 100 | TokenIdPercentPercent, | ||
| 101 | TokenIdPlus, | ||
| 102 | TokenIdPlusEq, | ||
| 103 | TokenIdPlusPercent, | ||
| 104 | TokenIdPlusPercentEq, | ||
| 105 | TokenIdPlusPlus, | ||
| 106 | TokenIdRBrace, | ||
| 107 | TokenIdRBracket, | ||
| 108 | TokenIdRParen, | ||
| 109 | TokenIdSemicolon, | ||
| 110 | TokenIdSlash, | ||
| 111 | TokenIdStar, | ||
| 112 | TokenIdStarStar, | ||
| 113 | TokenIdStringLiteral, | ||
| 114 | TokenIdSymbol, | ||
| 115 | TokenIdTilde, | ||
| 116 | TokenIdTimesEq, | ||
| 117 | TokenIdTimesPercent, | ||
| 118 | TokenIdTimesPercentEq, | ||
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 120 | struct TokenNumLit { | 121 | struct TokenNumLit { |
test/cases/struct.zig+17| ... | @@ -208,3 +208,20 @@ fn passSliceOfEmptyStructToFn() { | ... | @@ -208,3 +208,20 @@ fn passSliceOfEmptyStructToFn() { |
| 208 | fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize { | 208 | fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize { |
| 209 | slice.len | 209 | slice.len |
| 210 | } | 210 | } |
| 211 | |||
| 212 | const APackedStruct = packed struct { | ||
| 213 | x: u8, | ||
| 214 | y: u8, | ||
| 215 | }; | ||
| 216 | |||
| 217 | fn packedStruct() { | ||
| 218 | @setFnTest(this); | ||
| 219 | |||
| 220 | var foo = APackedStruct { | ||
| 221 | .x = 1, | ||
| 222 | .y = 2, | ||
| 223 | }; | ||
| 224 | foo.y += 1; | ||
| 225 | const four = foo.x + foo.y; | ||
| 226 | assert(four == 4); | ||
| 227 | } |