authorgravatar for tetralux@teknik.ioTetralux <tetralux@teknik.io> 2019-08-22 20:41:33+00:00
committergravatar for tetralux@teknik.ioTetralux <tetralux@teknik.io> 2019-08-22 22:58:02+00:00
log3ec10ea174d5738098e9bd1ef709b552603cc3b4
tree54718d6ad8bfa40ef8bf8450b816cffe3abeab38
parentec7d7a5b14540ea3b2bab9f11318630338467965
signaturelock-open Commit is signed but in an unrecognized format.

parsing of align(N) on struct fields


5 files changed, 31 insertions(+), 11 deletions(-)

src/all_types.hpp+2
...@@ -849,6 +849,8 @@ struct AstNodeStructField {...@@ -849,6 +849,8 @@ struct AstNodeStructField {
849 Buf *name;849 Buf *name;
850 AstNode *type;850 AstNode *type;
851 AstNode *value;851 AstNode *value;
852 // populated if the "align(A)" is present
853 AstNode *align_expr;
852};854};
853855
854struct AstNodeStringLiteral {856struct AstNodeStringLiteral {
src/analyze.cpp+14-2
...@@ -2255,9 +2255,21 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2255,9 +2255,21 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2255 if (field->gen_index == SIZE_MAX)2255 if (field->gen_index == SIZE_MAX)
2256 continue;2256 continue;
22572257
2258 size_t this_field_align;2258 uint32_t this_field_align;
2259 if (packed) {2259
2260 // TODO: Sets the field alignment in the type, but doesn't do anything
2261 // to actually make that happen yet.
2262 AstNode *align_expr = field->decl_node->data.struct_field.align_expr;
2263 if (align_expr != nullptr) {
2264 if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr, &this_field_align)) {
2265 field->type_entry = g->builtin_types.entry_invalid;
2266 } else {
2267 field->align = this_field_align;
2268 }
2269 } else if (packed) {
2260 // TODO: https://github.com/ziglang/zig/issues/15122270 // TODO: https://github.com/ziglang/zig/issues/1512
2271 // TODO: Validate requested alignment is possible, given packed,
2272 // and given other field alignments.
2261 this_field_align = 1;2273 this_field_align = 1;
2262 // TODO If we have no type_entry for the field, we've already failed to2274 // TODO If we have no type_entry for the field, we've already failed to
2263 // compile the program correctly. This stage1 compiler needs a deeper2275 // compile the program correctly. This stage1 compiler needs a deeper
src/parser.cpp+5-3
...@@ -782,24 +782,26 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {...@@ -782,24 +782,26 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
782 return res;782 return res;
783}783}
784784
785// ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?785// ContainerField <- IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
786static AstNode *ast_parse_container_field(ParseContext *pc) {786static AstNode *ast_parse_container_field(ParseContext *pc) {
787 Token *identifier = eat_token_if(pc, TokenIdSymbol);787 Token *identifier = eat_token_if(pc, TokenIdSymbol);
788 if (identifier == nullptr)788 if (identifier == nullptr)
789 return nullptr;789 return nullptr;
790790
791 AstNode *type_expr = nullptr;791 AstNode *type_expr = nullptr;
792 if (eat_token_if(pc, TokenIdColon) != nullptr)792 if (eat_token_if(pc, TokenIdColon) != nullptr) {
793 type_expr = ast_expect(pc, ast_parse_type_expr);793 type_expr = ast_expect(pc, ast_parse_type_expr);
794 }
795 AstNode *align_expr = ast_parse_byte_align(pc);
794 AstNode *expr = nullptr;796 AstNode *expr = nullptr;
795 if (eat_token_if(pc, TokenIdEq) != nullptr)797 if (eat_token_if(pc, TokenIdEq) != nullptr)
796 expr = ast_expect(pc, ast_parse_expr);798 expr = ast_expect(pc, ast_parse_expr);
797799
798
799 AstNode *res = ast_create_node(pc, NodeTypeStructField, identifier);800 AstNode *res = ast_create_node(pc, NodeTypeStructField, identifier);
800 res->data.struct_field.name = token_buf(identifier);801 res->data.struct_field.name = token_buf(identifier);
801 res->data.struct_field.type = type_expr;802 res->data.struct_field.type = type_expr;
802 res->data.struct_field.value = expr;803 res->data.struct_field.value = expr;
804 res->data.struct_field.align_expr = align_expr;
803 return res;805 return res;
804}806}
805807
std/zig/ast.zig+1
...@@ -761,6 +761,7 @@ pub const Node = struct {...@@ -761,6 +761,7 @@ pub const Node = struct {
761 name_token: TokenIndex,761 name_token: TokenIndex,
762 type_expr: ?*Node,762 type_expr: ?*Node,
763 value_expr: ?*Node,763 value_expr: ?*Node,
764 align_expr: ?*Node,
764765
765 pub fn iterate(self: *ContainerField, index: usize) ?*Node {766 pub fn iterate(self: *ContainerField, index: usize) ?*Node {
766 var i = index;767 var i = index;
std/zig/parse.zig+9-6
...@@ -380,16 +380,18 @@ fn parseVarDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -380,16 +380,18 @@ fn parseVarDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
380 return &node.base;380 return &node.base;
381}381}
382382
383/// ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?383/// ContainerField <- IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
384fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {384fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
385 const name_token = eatToken(it, .Identifier) orelse return null;385 const name_token = eatToken(it, .Identifier) orelse return null;
386386
387 const type_expr = if (eatToken(it, .Colon)) |_|387 var align_expr: ?*Node = null;
388 try expectNode(arena, it, tree, parseTypeExpr, AstError{388 var type_expr: ?*Node = null;
389 if (eatToken(it, .Colon)) |_| {
390 type_expr = try expectNode(arena, it, tree, parseTypeExpr, AstError{
389 .ExpectedTypeExpr = AstError.ExpectedTypeExpr{ .token = it.index },391 .ExpectedTypeExpr = AstError.ExpectedTypeExpr{ .token = it.index },
390 })392 });
391 else393 align_expr = try parseByteAlign(arena, it, tree);
392 null;394 }
393395
394 const value_expr = if (eatToken(it, .Equal)) |_|396 const value_expr = if (eatToken(it, .Equal)) |_|
395 try expectNode(arena, it, tree, parseExpr, AstError{397 try expectNode(arena, it, tree, parseExpr, AstError{
...@@ -406,6 +408,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -406,6 +408,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
406 .name_token = name_token,408 .name_token = name_token,
407 .type_expr = type_expr,409 .type_expr = type_expr,
408 .value_expr = value_expr,410 .value_expr = value_expr,
411 .align_expr = align_expr,
409 };412 };
410 return &node.base;413 return &node.base;
411}414}