| ... | @@ -793,6 +793,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -793,6 +793,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 793 | while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) { | 793 | while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) { |
| 794 | const field_decl = ZigClangRecordDecl_field_iterator_deref(it); | 794 | const field_decl = ZigClangRecordDecl_field_iterator_deref(it); |
| 795 | const field_loc = ZigClangFieldDecl_getLocation(field_decl); | 795 | const field_loc = ZigClangFieldDecl_getLocation(field_decl); |
| | 796 | const field_qt = ZigClangFieldDecl_getType(field_decl); |
| 796 | | 797 | |
| 797 | if (ZigClangFieldDecl_isBitField(field_decl)) { | 798 | if (ZigClangFieldDecl_isBitField(field_decl)) { |
| 798 | const opaque = try transCreateNodeOpaqueType(c); | 799 | const opaque = try transCreateNodeOpaqueType(c); |
| ... | @@ -801,6 +802,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -801,6 +802,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 801 | break :blk opaque; | 802 | break :blk opaque; |
| 802 | } | 803 | } |
| 803 | | 804 | |
| | 805 | if (ZigClangType_isIncompleteOrZeroLengthArrayType(qualTypeCanon(field_qt), c.clang_context)) { |
| | 806 | const opaque = try transCreateNodeOpaqueType(c); |
| | 807 | semicolon = try appendToken(c, .Semicolon, ";"); |
| | 808 | try emitWarning(c, field_loc, "{} demoted to opaque type - has variable length array", .{container_kind_name}); |
| | 809 | break :blk opaque; |
| | 810 | } |
| | 811 | |
| 804 | var is_anon = false; | 812 | var is_anon = false; |
| 805 | var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl))); | 813 | var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl))); |
| 806 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) { | 814 | if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) { |
| ... | @@ -809,7 +817,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -809,7 +817,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 809 | } | 817 | } |
| 810 | const field_name = try appendIdentifier(c, raw_name); | 818 | const field_name = try appendIdentifier(c, raw_name); |
| 811 | _ = try appendToken(c, .Colon, ":"); | 819 | _ = try appendToken(c, .Colon, ":"); |
| 812 | const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) { | 820 | const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) { |
| 813 | error.UnsupportedType => { | 821 | error.UnsupportedType => { |
| 814 | const opaque = try transCreateNodeOpaqueType(c); | 822 | const opaque = try transCreateNodeOpaqueType(c); |
| 815 | semicolon = try appendToken(c, .Semicolon, ";"); | 823 | semicolon = try appendToken(c, .Semicolon, ";"); |
| ... | @@ -2237,6 +2245,7 @@ fn transWhileLoop( | ... | @@ -2237,6 +2245,7 @@ fn transWhileLoop( |
| 2237 | .id = .Loop, | 2245 | .id = .Loop, |
| 2238 | }; | 2246 | }; |
| 2239 | while_node.body = try transStmt(rp, &loop_scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value); | 2247 | while_node.body = try transStmt(rp, &loop_scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value); |
| | 2248 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2240 | return &while_node.base; | 2249 | return &while_node.base; |
| 2241 | } | 2250 | } |
| 2242 | | 2251 | |
| ... | @@ -2346,8 +2355,10 @@ fn transForLoop( | ... | @@ -2346,8 +2355,10 @@ fn transForLoop( |
| 2346 | try block_scope.?.block_node.statements.push(&while_node.base); | 2355 | try block_scope.?.block_node.statements.push(&while_node.base); |
| 2347 | block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 2356 | block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 2348 | return &block_scope.?.block_node.base; | 2357 | return &block_scope.?.block_node.base; |
| 2349 | } else | 2358 | } else { |
| | 2359 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2350 | return &while_node.base; | 2360 | return &while_node.base; |
| | 2361 | } |
| 2351 | } | 2362 | } |
| 2352 | | 2363 | |
| 2353 | fn transSwitch( | 2364 | fn transSwitch( |
| ... | @@ -5431,6 +5442,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5431,6 +5442,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5431 | //else | 5442 | //else |
| 5432 | // @as(dest, x) | 5443 | // @as(dest, x) |
| 5433 | | 5444 | |
| | 5445 | const lparen = try appendToken(c, .LParen, "("); |
| | 5446 | |
| 5434 | const if_1 = try transCreateNodeIf(c); | 5447 | const if_1 = try transCreateNodeIf(c); |
| 5435 | const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); | 5448 | const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); |
| 5436 | const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); | 5449 | const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); |
| ... | @@ -5492,7 +5505,13 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5492,7 +5505,13 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5492 | as.rparen_token = try appendToken(c, .RParen, ")"); | 5505 | as.rparen_token = try appendToken(c, .RParen, ")"); |
| 5493 | else_2.body = &as.base; | 5506 | else_2.body = &as.base; |
| 5494 | | 5507 | |
| 5495 | return &if_1.base; | 5508 | const group_node = try c.a().create(ast.Node.GroupedExpression); |
| | 5509 | group_node.* = .{ |
| | 5510 | .lparen = lparen, |
| | 5511 | .expr = &if_1.base, |
| | 5512 | .rparen = try appendToken(c, .RParen, ")"), |
| | 5513 | }; |
| | 5514 | return &group_node.base; |
| 5496 | }, | 5515 | }, |
| 5497 | else => { | 5516 | else => { |
| 5498 | const first_tok = it.list.at(0); | 5517 | const first_tok = it.list.at(0); |
| ... | @@ -5545,14 +5564,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5545,14 +5564,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5545 | ); | 5564 | ); |
| 5546 | return error.ParseError; | 5565 | return error.ParseError; |
| 5547 | } | 5566 | } |
| 5548 | // deref is often used together with casts so we group the lhs expression | 5567 | const deref = try transCreateNodePtrDeref(c, node); |
| 5549 | const group = try c.a().create(ast.Node.GroupedExpression); | | |
| 5550 | group.* = .{ | | |
| 5551 | .lparen = try appendToken(c, .LParen, "("), | | |
| 5552 | .expr = node, | | |
| 5553 | .rparen = try appendToken(c, .RParen, ")"), | | |
| 5554 | }; | | |
| 5555 | const deref = try transCreateNodePtrDeref(c, &group.base); | | |
| 5556 | node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]); | 5568 | node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]); |
| 5557 | continue; | 5569 | continue; |
| 5558 | }, | 5570 | }, |
| ... | @@ -5596,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5596,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5596 | }, | 5608 | }, |
| 5597 | .Ampersand => { | 5609 | .Ampersand => { |
| 5598 | op_token = try appendToken(c, .Ampersand, "&"); | 5610 | op_token = try appendToken(c, .Ampersand, "&"); |
| 5599 | op_id .BitAnd; | 5611 | op_id = .BitAnd; |
| 5600 | }, | 5612 | }, |
| 5601 | .Plus => { | 5613 | .Plus => { |
| 5602 | op_token = try appendToken(c, .Plus, "+"); | 5614 | op_token = try appendToken(c, .Plus, "+"); |
| ... | @@ -5604,7 +5616,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5604,7 +5616,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5604 | }, | 5616 | }, |
| 5605 | .Minus => { | 5617 | .Minus => { |
| 5606 | op_token = try appendToken(c, .Minus, "-"); | 5618 | op_token = try appendToken(c, .Minus, "-"); |
| 5607 | op_id .Sub; | 5619 | op_id = .Sub; |
| 5608 | }, | 5620 | }, |
| 5609 | .AmpersandAmpersand => { | 5621 | .AmpersandAmpersand => { |
| 5610 | op_token = try appendToken(c, .Keyword_and, "and"); | 5622 | op_token = try appendToken(c, .Keyword_and, "and"); |
| ... | @@ -5676,19 +5688,17 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5676,19 +5688,17 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5676 | }, | 5688 | }, |
| 5677 | .BangEqual => { | 5689 | .BangEqual => { |
| 5678 | op_token = try appendToken(c, .BangEqual, "!="); | 5690 | op_token = try appendToken(c, .BangEqual, "!="); |
| 5679 | op_id = .BangEqual; | 5691 | op_id = .BangEqual; |
| 5680 | }, | 5692 | }, |
| 5681 | .EqualEqual => { | 5693 | .EqualEqual => { |
| 5682 | op_token = try appendToken(c, .EqualEqual, "=="); | 5694 | op_token = try appendToken(c, .EqualEqual, "=="); |
| 5683 | op_id = .EqualEqual; | 5695 | op_id = .EqualEqual; |
| 5684 | }, | 5696 | }, |
| 5685 | .Slash => { | 5697 | .Slash => { |
| 5686 | // unsigned/float division uses the operator | | |
| 5687 | op_id = .Div; | 5698 | op_id = .Div; |
| 5688 | op_token = try appendToken(c, .Slash, "/"); | 5699 | op_token = try appendToken(c, .Slash, "/"); |
| 5689 | }, | 5700 | }, |
| 5690 | .Percent => { | 5701 | .Percent => { |
| 5691 | // unsigned/float division uses the operator | | |
| 5692 | op_id = .Mod; | 5702 | op_id = .Mod; |
| 5693 | op_token = try appendToken(c, .Percent, "%"); | 5703 | op_token = try appendToken(c, .Percent, "%"); |
| 5694 | }, | 5704 | }, |
| ... | @@ -5729,25 +5739,12 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5729,25 +5739,12 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5729 | return &node.base; | 5739 | return &node.base; |
| 5730 | }, | 5740 | }, |
| 5731 | .Asterisk => { | 5741 | .Asterisk => { |
| 5732 | // deref is often used together with casts so we group the lhs expression | 5742 | const node = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5733 | const group = try c.a().create(ast.Node.GroupedExpression); | 5743 | return try transCreateNodePtrDeref(c, node); |
| 5734 | group.* = .{ | | |
| 5735 | .lparen = try appendToken(c, .LParen, "("), | | |
| 5736 | .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope), | | |
| 5737 | .rparen = try appendToken(c, .RParen, ")"), | | |
| 5738 | }; | | |
| 5739 | return try transCreateNodePtrDeref(c, &group.base); | | |
| 5740 | }, | 5744 | }, |
| 5741 | .Ampersand => { | 5745 | .Ampersand => { |
| 5742 | // address of is often used together with casts so we group the rhs expression | | |
| 5743 | const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&"); | 5746 | const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&"); |
| 5744 | const group = try c.a().create(ast.Node.GroupedExpression); | 5747 | node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5745 | group.* = .{ | | |
| 5746 | .lparen = try appendToken(c, .LParen, "("), | | |
| 5747 | .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope), | | |
| 5748 | .rparen = try appendToken(c, .RParen, ")"), | | |
| 5749 | }; | | |
| 5750 | node.rhs = &group.base; | | |
| 5751 | return &node.base; | 5748 | return &node.base; |
| 5752 | }, | 5749 | }, |
| 5753 | else => { | 5750 | else => { |