| ... | @@ -6,8 +6,9 @@ const assert = std.debug.assert; | ... | @@ -6,8 +6,9 @@ const assert = std.debug.assert; |
| 6 | const ast = std.zig.ast; | 6 | const ast = std.zig.ast; |
| 7 | const Token = std.zig.Token; | 7 | const Token = std.zig.Token; |
| 8 | usingnamespace @import("clang.zig"); | 8 | usingnamespace @import("clang.zig"); |
| 9 | const ctok = @import("c_tokenizer.zig"); | 9 | const ctok = std.c.tokenizer; |
| 10 | const CToken = ctok.CToken; | 10 | const CToken = std.c.Token; |
| | 11 | const CTokenList = std.c.tokenizer.Source.TokenList; |
| 11 | const mem = std.mem; | 12 | const mem = std.mem; |
| 12 | const math = std.math; | 13 | const math = std.math; |
| 13 | | 14 | |
| ... | @@ -4818,7 +4819,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4818,7 +4819,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4818 | // TODO if we see #undef, delete it from the table | 4819 | // TODO if we see #undef, delete it from the table |
| 4819 | var it = ZigClangASTUnit_getLocalPreprocessingEntities_begin(unit); | 4820 | var it = ZigClangASTUnit_getLocalPreprocessingEntities_begin(unit); |
| 4820 | const it_end = ZigClangASTUnit_getLocalPreprocessingEntities_end(unit); | 4821 | const it_end = ZigClangASTUnit_getLocalPreprocessingEntities_end(unit); |
| 4821 | var tok_list = ctok.TokenList.init(c.a()); | 4822 | var tok_list = CTokenList.init(c.a()); |
| 4822 | const scope = c.global_scope; | 4823 | const scope = c.global_scope; |
| 4823 | | 4824 | |
| 4824 | while (it.I != it_end.I) : (it.I += 1) { | 4825 | while (it.I != it_end.I) : (it.I += 1) { |
| ... | @@ -4829,6 +4830,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4829,6 +4830,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4829 | const macro = @ptrCast(*ZigClangMacroDefinitionRecord, entity); | 4830 | const macro = @ptrCast(*ZigClangMacroDefinitionRecord, entity); |
| 4830 | const raw_name = ZigClangMacroDefinitionRecord_getName_getNameStart(macro); | 4831 | const raw_name = ZigClangMacroDefinitionRecord_getName_getNameStart(macro); |
| 4831 | const begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro); | 4832 | const begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro); |
| | 4833 | // const end_loc = ZigClangMacroDefinitionRecord_getSourceRange_getEnd(macro); |
| 4832 | | 4834 | |
| 4833 | const name = try c.str(raw_name); | 4835 | const name = try c.str(raw_name); |
| 4834 | // TODO https://github.com/ziglang/zig/issues/3756 | 4836 | // TODO https://github.com/ziglang/zig/issues/3756 |
| ... | @@ -4839,42 +4841,61 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4839,42 +4841,61 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4839 | } | 4841 | } |
| 4840 | | 4842 | |
| 4841 | const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc); | 4843 | const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc); |
| 4842 | ctok.tokenizeCMacro(c, begin_loc, mangled_name, &tok_list, begin_c) catch |err| switch (err) { | 4844 | // const end_c = ZigClangSourceManager_getCharacterData(c.source_manager, end_loc); |
| 4843 | error.OutOfMemory => |e| return e, | 4845 | // const slice = begin_c[0 .. @ptrToInt(end_c) - @ptrToInt(begin_c)]; |
| 4844 | else => { | 4846 | const slice = begin_c[0..mem.len(u8, begin_c)]; |
| 4845 | continue; | 4847 | |
| | 4848 | tok_list.shrink(0); |
| | 4849 | var tokenizer = std.c.Tokenizer{ |
| | 4850 | .source = &std.c.tokenizer.Source{ |
| | 4851 | .buffer = slice, |
| | 4852 | .file_name = undefined, |
| | 4853 | .tokens = undefined, |
| 4846 | }, | 4854 | }, |
| 4847 | }; | 4855 | }; |
| | 4856 | while (true) { |
| | 4857 | const tok = tokenizer.next(); |
| | 4858 | switch (tok.id) { |
| | 4859 | .Nl, .Eof => { |
| | 4860 | try tok_list.push(tok); |
| | 4861 | break; |
| | 4862 | }, |
| | 4863 | .LineComment, .MultiLineComment => continue, |
| | 4864 | else => {}, |
| | 4865 | } |
| | 4866 | try tok_list.push(tok); |
| | 4867 | } |
| 4848 | | 4868 | |
| 4849 | var tok_it = tok_list.iterator(0); | 4869 | var tok_it = tok_list.iterator(0); |
| 4850 | const first_tok = tok_it.next().?; | 4870 | const first_tok = tok_it.next().?; |
| 4851 | assert(first_tok.id == .Identifier and mem.eql(u8, first_tok.bytes, name)); | 4871 | assert(first_tok.id == .Identifier and mem.eql(u8, slice[first_tok.start..first_tok.end], name)); |
| | 4872 | |
| | 4873 | var macro_fn = false; |
| 4852 | const next = tok_it.peek().?; | 4874 | const next = tok_it.peek().?; |
| 4853 | switch (next.id) { | 4875 | switch (next.id) { |
| 4854 | .Identifier => { | 4876 | .Identifier => { |
| 4855 | // if it equals itself, ignore. for example, from stdio.h: | 4877 | // if it equals itself, ignore. for example, from stdio.h: |
| 4856 | // #define stdin stdin | 4878 | // #define stdin stdin |
| 4857 | if (mem.eql(u8, name, next.bytes)) { | 4879 | if (mem.eql(u8, name, slice[next.start..next.end])) { |
| 4858 | continue; | 4880 | continue; |
| 4859 | } | 4881 | } |
| 4860 | }, | 4882 | }, |
| 4861 | .Eof => { | 4883 | .Nl, .Eof => { |
| 4862 | // this means it is a macro without a value | 4884 | // this means it is a macro without a value |
| 4863 | // we don't care about such things | 4885 | // we don't care about such things |
| 4864 | continue; | 4886 | continue; |
| 4865 | }, | 4887 | }, |
| | 4888 | .LParen => { |
| | 4889 | // if the name is immediately followed by a '(' then it is a function |
| | 4890 | macro_fn = first_tok.end == next.start; |
| | 4891 | }, |
| 4866 | else => {}, | 4892 | else => {}, |
| 4867 | } | 4893 | } |
| 4868 | | 4894 | |
| 4869 | const macro_fn = if (tok_it.peek().?.id == .Fn) blk: { | | |
| 4870 | _ = tok_it.next(); | | |
| 4871 | break :blk true; | | |
| 4872 | } else false; | | |
| 4873 | | | |
| 4874 | (if (macro_fn) | 4895 | (if (macro_fn) |
| 4875 | transMacroFnDefine(c, &tok_it, mangled_name, begin_loc) | 4896 | transMacroFnDefine(c, &tok_it, slice, mangled_name, begin_loc) |
| 4876 | else | 4897 | else |
| 4877 | transMacroDefine(c, &tok_it, mangled_name, begin_loc)) catch |err| switch (err) { | 4898 | transMacroDefine(c, &tok_it, slice, mangled_name, begin_loc)) catch |err| switch (err) { |
| 4878 | error.ParseError => continue, | 4899 | error.ParseError => continue, |
| 4879 | error.OutOfMemory => |e| return e, | 4900 | error.OutOfMemory => |e| return e, |
| 4880 | }; | 4901 | }; |
| ... | @@ -4884,15 +4905,15 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4884,15 +4905,15 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4884 | } | 4905 | } |
| 4885 | } | 4906 | } |
| 4886 | | 4907 | |
| 4887 | fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { | 4908 | fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 4888 | const scope = &c.global_scope.base; | 4909 | const scope = &c.global_scope.base; |
| 4889 | | 4910 | |
| 4890 | const node = try transCreateNodeVarDecl(c, true, true, name); | 4911 | const node = try transCreateNodeVarDecl(c, true, true, name); |
| 4891 | node.eq_token = try appendToken(c, .Equal, "="); | 4912 | node.eq_token = try appendToken(c, .Equal, "="); |
| 4892 | | 4913 | |
| 4893 | node.init_node = try parseCExpr(c, it, source_loc, scope); | 4914 | node.init_node = try parseCExpr(c, it, source, source_loc, scope); |
| 4894 | const last = it.next().?; | 4915 | const last = it.next().?; |
| 4895 | if (last.id != .Eof) | 4916 | if (last.id != .Eof and last.id != .Nl) |
| 4896 | return failDecl( | 4917 | return failDecl( |
| 4897 | c, | 4918 | c, |
| 4898 | source_loc, | 4919 | source_loc, |
| ... | @@ -4905,7 +4926,7 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, | ... | @@ -4905,7 +4926,7 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, |
| 4905 | _ = try c.global_scope.macro_table.put(name, &node.base); | 4926 | _ = try c.global_scope.macro_table.put(name, &node.base); |
| 4906 | } | 4927 | } |
| 4907 | | 4928 | |
| 4908 | fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { | 4929 | fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 4909 | const block_scope = try Scope.Block.init(c, &c.global_scope.base, null); | 4930 | const block_scope = try Scope.Block.init(c, &c.global_scope.base, null); |
| 4910 | const scope = &block_scope.base; | 4931 | const scope = &block_scope.base; |
| 4911 | | 4932 | |
| ... | @@ -4937,7 +4958,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -4937,7 +4958,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4937 | ); | 4958 | ); |
| 4938 | } | 4959 | } |
| 4939 | | 4960 | |
| 4940 | const mangled_name = try block_scope.makeMangledName(c, param_tok.bytes); | 4961 | const mangled_name = try block_scope.makeMangledName(c, source[param_tok.start..param_tok.end]); |
| 4941 | const param_name_tok = try appendIdentifier(c, mangled_name); | 4962 | const param_name_tok = try appendIdentifier(c, mangled_name); |
| 4942 | _ = try appendToken(c, .Colon, ":"); | 4963 | _ = try appendToken(c, .Colon, ":"); |
| 4943 | | 4964 | |
| ... | @@ -5000,7 +5021,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -5000,7 +5021,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 5000 | const block = try transCreateNodeBlock(c, null); | 5021 | const block = try transCreateNodeBlock(c, null); |
| 5001 | | 5022 | |
| 5002 | const return_expr = try transCreateNodeReturnExpr(c); | 5023 | const return_expr = try transCreateNodeReturnExpr(c); |
| 5003 | const expr = try parseCExpr(c, it, source_loc, scope); | 5024 | const expr = try parseCExpr(c, it, source, source_loc, scope); |
| 5004 | const last = it.next().?; | 5025 | const last = it.next().?; |
| 5005 | if (last.id != .Eof) | 5026 | if (last.id != .Eof) |
| 5006 | return failDecl( | 5027 | return failDecl( |
| ... | @@ -5022,27 +5043,28 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -5022,27 +5043,28 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 5022 | | 5043 | |
| 5023 | const ParseError = Error || error{ParseError}; | 5044 | const ParseError = Error || error{ParseError}; |
| 5024 | | 5045 | |
| 5025 | fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 5046 | fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 5026 | const node = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5047 | const node = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5027 | switch (it.next().?.id) { | 5048 | switch (it.next().?.id) { |
| 5028 | .QuestionMark => { | 5049 | .QuestionMark => { |
| 5029 | // must come immediately after expr | 5050 | // must come immediately after expr |
| 5030 | _ = try appendToken(c, .RParen, ")"); | 5051 | _ = try appendToken(c, .RParen, ")"); |
| 5031 | const if_node = try transCreateNodeIf(c); | 5052 | const if_node = try transCreateNodeIf(c); |
| 5032 | if_node.condition = node; | 5053 | if_node.condition = node; |
| 5033 | if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope); | 5054 | if_node.body = try parseCPrimaryExpr(c, it, source, source_loc, scope); |
| 5034 | if (it.next().?.id != .Colon) { | 5055 | if (it.next().?.id != .Colon) { |
| | 5056 | const first_tok = it.list.at(0); |
| 5035 | try failDecl( | 5057 | try failDecl( |
| 5036 | c, | 5058 | c, |
| 5037 | source_loc, | 5059 | source_loc, |
| 5038 | it.list.at(0).*.bytes, | 5060 | source[first_tok.start..first_tok.end], |
| 5039 | "unable to translate C expr: expected ':'", | 5061 | "unable to translate C expr: expected ':'", |
| 5040 | .{}, | 5062 | .{}, |
| 5041 | ); | 5063 | ); |
| 5042 | return error.ParseError; | 5064 | return error.ParseError; |
| 5043 | } | 5065 | } |
| 5044 | if_node.@"else" = try transCreateNodeElse(c); | 5066 | if_node.@"else" = try transCreateNodeElse(c); |
| 5045 | if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope); | 5067 | if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source, source_loc, scope); |
| 5046 | return &if_node.base; | 5068 | return &if_node.base; |
| 5047 | }, | 5069 | }, |
| 5048 | else => { | 5070 | else => { |
| ... | @@ -5052,30 +5074,30 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou | ... | @@ -5052,30 +5074,30 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou |
| 5052 | } | 5074 | } |
| 5053 | } | 5075 | } |
| 5054 | | 5076 | |
| 5055 | fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { | 5077 | fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 5056 | if (tok.id == .NumLitInt) { | 5078 | var lit_bytes = source[tok.start..tok.end]; |
| 5057 | var lit_bytes = tok.bytes; | | |
| 5058 | | 5079 | |
| 5059 | if (tok.bytes.len > 2 and tok.bytes[0] == '0') { | 5080 | if (tok.id == .IntegerLiteral) { |
| 5060 | switch (tok.bytes[1]) { | 5081 | if (lit_bytes.len > 2 and lit_bytes[0] == '0') { |
| | 5082 | switch (lit_bytes[1]) { |
| 5061 | '0'...'7' => { | 5083 | '0'...'7' => { |
| 5062 | // Octal | 5084 | // Octal |
| 5063 | lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes}); | 5085 | lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{lit_bytes}); |
| 5064 | }, | 5086 | }, |
| 5065 | 'X' => { | 5087 | 'X' => { |
| 5066 | // Hexadecimal with capital X, valid in C but not in Zig | 5088 | // Hexadecimal with capital X, valid in C but not in Zig |
| 5067 | lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{tok.bytes[2..]}); | 5089 | lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{lit_bytes[2..]}); |
| 5068 | }, | 5090 | }, |
| 5069 | else => {}, | 5091 | else => {}, |
| 5070 | } | 5092 | } |
| 5071 | } | 5093 | } |
| 5072 | | 5094 | |
| 5073 | if (tok.num_lit_suffix == .None) { | 5095 | if (tok.id.IntegerLiteral == .None) { |
| 5074 | return transCreateNodeInt(c, lit_bytes); | 5096 | return transCreateNodeInt(c, lit_bytes); |
| 5075 | } | 5097 | } |
| 5076 | | 5098 | |
| 5077 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); | 5099 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 5078 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) { | 5100 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) { |
| 5079 | .U => "c_uint", | 5101 | .U => "c_uint", |
| 5080 | .L => "c_long", | 5102 | .L => "c_long", |
| 5081 | .LU => "c_ulong", | 5103 | .LU => "c_ulong", |
| ... | @@ -5083,55 +5105,216 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P | ... | @@ -5083,55 +5105,216 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P |
| 5083 | .LLU => "c_ulonglong", | 5105 | .LLU => "c_ulonglong", |
| 5084 | else => unreachable, | 5106 | else => unreachable, |
| 5085 | })); | 5107 | })); |
| | 5108 | lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) { |
| | 5109 | .U, .L => @as(u8, 1), |
| | 5110 | .LU, .LL => 2, |
| | 5111 | .LLU => 3, |
| | 5112 | else => unreachable, |
| | 5113 | }]; |
| 5086 | _ = try appendToken(c, .Comma, ","); | 5114 | _ = try appendToken(c, .Comma, ","); |
| 5087 | try cast_node.params.push(try transCreateNodeInt(c, lit_bytes)); | 5115 | try cast_node.params.push(try transCreateNodeInt(c, lit_bytes)); |
| 5088 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); | 5116 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5089 | return &cast_node.base; | 5117 | return &cast_node.base; |
| 5090 | } else if (tok.id == .NumLitFloat) { | 5118 | } else if (tok.id == .FloatLiteral) { |
| 5091 | if (tok.num_lit_suffix == .None) { | 5119 | if (tok.id.FloatLiteral == .None) { |
| 5092 | return transCreateNodeFloat(c, tok.bytes); | 5120 | return transCreateNodeFloat(c, lit_bytes); |
| 5093 | } | 5121 | } |
| 5094 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); | 5122 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 5095 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) { | 5123 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) { |
| 5096 | .F => "f32", | 5124 | .F => "f32", |
| 5097 | .L => "f64", | 5125 | .L => "f64", |
| 5098 | else => unreachable, | 5126 | else => unreachable, |
| 5099 | })); | 5127 | })); |
| 5100 | _ = try appendToken(c, .Comma, ","); | 5128 | _ = try appendToken(c, .Comma, ","); |
| 5101 | try cast_node.params.push(try transCreateNodeFloat(c, tok.bytes)); | 5129 | try cast_node.params.push(try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1])); |
| 5102 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); | 5130 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5103 | return &cast_node.base; | 5131 | return &cast_node.base; |
| 5104 | } else unreachable; | 5132 | } else unreachable; |
| 5105 | } | 5133 | } |
| 5106 | | 5134 | |
| 5107 | fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 5135 | fn zigifyEscapeSequences(ctx: *Context, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ![]const u8 { |
| | 5136 | for (source) |c| { |
| | 5137 | if (c == '\\') { |
| | 5138 | break; |
| | 5139 | } |
| | 5140 | } else return source; |
| | 5141 | var bytes = try ctx.a().alloc(u8, source.len * 2); |
| | 5142 | var state: enum { |
| | 5143 | Start, |
| | 5144 | Escape, |
| | 5145 | Hex, |
| | 5146 | Octal, |
| | 5147 | } = .Start; |
| | 5148 | var i: usize = 0; |
| | 5149 | var count: u8 = 0; |
| | 5150 | var num: u8 = 0; |
| | 5151 | for (source) |c| { |
| | 5152 | switch (state) { |
| | 5153 | .Escape => { |
| | 5154 | switch (c) { |
| | 5155 | 'n', 'r', 't', '\\', '\'', '\"' => { |
| | 5156 | bytes[i] = c; |
| | 5157 | }, |
| | 5158 | '0'...'7' => { |
| | 5159 | count += 1; |
| | 5160 | num += c - '0'; |
| | 5161 | state = .Octal; |
| | 5162 | bytes[i] = 'x'; |
| | 5163 | }, |
| | 5164 | 'x' => { |
| | 5165 | state = .Hex; |
| | 5166 | bytes[i] = 'x'; |
| | 5167 | }, |
| | 5168 | 'a' => { |
| | 5169 | bytes[i] = 'x'; |
| | 5170 | i += 1; |
| | 5171 | bytes[i] = '0'; |
| | 5172 | i += 1; |
| | 5173 | bytes[i] = '7'; |
| | 5174 | }, |
| | 5175 | 'b' => { |
| | 5176 | bytes[i] = 'x'; |
| | 5177 | i += 1; |
| | 5178 | bytes[i] = '0'; |
| | 5179 | i += 1; |
| | 5180 | bytes[i] = '8'; |
| | 5181 | }, |
| | 5182 | 'f' => { |
| | 5183 | bytes[i] = 'x'; |
| | 5184 | i += 1; |
| | 5185 | bytes[i] = '0'; |
| | 5186 | i += 1; |
| | 5187 | bytes[i] = 'C'; |
| | 5188 | }, |
| | 5189 | 'v' => { |
| | 5190 | bytes[i] = 'x'; |
| | 5191 | i += 1; |
| | 5192 | bytes[i] = '0'; |
| | 5193 | i += 1; |
| | 5194 | bytes[i] = 'B'; |
| | 5195 | }, |
| | 5196 | '?' => { |
| | 5197 | i -= 1; |
| | 5198 | bytes[i] = '?'; |
| | 5199 | }, |
| | 5200 | 'u', 'U' => { |
| | 5201 | try failDecl(ctx, source_loc, name, "macro tokenizing failed: TODO unicode escape sequences", .{}); |
| | 5202 | return error.ParseError; |
| | 5203 | }, |
| | 5204 | else => { |
| | 5205 | try failDecl(ctx, source_loc, name, "macro tokenizing failed: unknown escape sequence", .{}); |
| | 5206 | return error.ParseError; |
| | 5207 | }, |
| | 5208 | } |
| | 5209 | i += 1; |
| | 5210 | if (state == .Escape) |
| | 5211 | state = .Start; |
| | 5212 | }, |
| | 5213 | .Start => { |
| | 5214 | if (c == '\\') { |
| | 5215 | state = .Escape; |
| | 5216 | } |
| | 5217 | bytes[i] = c; |
| | 5218 | i += 1; |
| | 5219 | }, |
| | 5220 | .Hex => { |
| | 5221 | switch (c) { |
| | 5222 | '0'...'9' => { |
| | 5223 | num = std.math.mul(u8, num, 16) catch { |
| | 5224 | try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{}); |
| | 5225 | return error.ParseError; |
| | 5226 | }; |
| | 5227 | num += c - '0'; |
| | 5228 | }, |
| | 5229 | 'a'...'f' => { |
| | 5230 | num = std.math.mul(u8, num, 16) catch { |
| | 5231 | try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{}); |
| | 5232 | return error.ParseError; |
| | 5233 | }; |
| | 5234 | num += c - 'a' + 10; |
| | 5235 | }, |
| | 5236 | 'A'...'F' => { |
| | 5237 | num = std.math.mul(u8, num, 16) catch { |
| | 5238 | try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{}); |
| | 5239 | return error.ParseError; |
| | 5240 | }; |
| | 5241 | num += c - 'A' + 10; |
| | 5242 | }, |
| | 5243 | else => { |
| | 5244 | i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 }); |
| | 5245 | num = 0; |
| | 5246 | if (c == '\\') |
| | 5247 | state = .Escape |
| | 5248 | else |
| | 5249 | state = .Start; |
| | 5250 | bytes[i] = c; |
| | 5251 | i += 1; |
| | 5252 | }, |
| | 5253 | } |
| | 5254 | }, |
| | 5255 | .Octal => { |
| | 5256 | const accept_digit = switch (c) { |
| | 5257 | // The maximum length of a octal literal is 3 digits |
| | 5258 | '0'...'7' => count < 3, |
| | 5259 | else => false, |
| | 5260 | }; |
| | 5261 | |
| | 5262 | if (accept_digit) { |
| | 5263 | count += 1; |
| | 5264 | num = std.math.mul(u8, num, 8) catch { |
| | 5265 | try failDecl(ctx, source_loc, name, "macro tokenizing failed: octal literal overflowed", .{}); |
| | 5266 | return error.ParseError; |
| | 5267 | }; |
| | 5268 | num += c - '0'; |
| | 5269 | } else { |
| | 5270 | i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 }); |
| | 5271 | num = 0; |
| | 5272 | count = 0; |
| | 5273 | if (c == '\\') |
| | 5274 | state = .Escape |
| | 5275 | else |
| | 5276 | state = .Start; |
| | 5277 | bytes[i] = c; |
| | 5278 | i += 1; |
| | 5279 | } |
| | 5280 | }, |
| | 5281 | } |
| | 5282 | } |
| | 5283 | if (state == .Hex or state == .Octal) |
| | 5284 | i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 }); |
| | 5285 | return bytes[0..i]; |
| | 5286 | } |
| | 5287 | |
| | 5288 | fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 5108 | const tok = it.next().?; | 5289 | const tok = it.next().?; |
| 5109 | switch (tok.id) { | 5290 | switch (tok.id) { |
| 5110 | .CharLit => { | 5291 | .CharLiteral => { |
| 5111 | const token = try appendToken(c, .CharLiteral, tok.bytes); | 5292 | const first_tok = it.list.at(0); |
| | 5293 | const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, source[tok.start..tok.end], source[first_tok.start..first_tok.end], source_loc)); |
| 5112 | const node = try c.a().create(ast.Node.CharLiteral); | 5294 | const node = try c.a().create(ast.Node.CharLiteral); |
| 5113 | node.* = ast.Node.CharLiteral{ | 5295 | node.* = ast.Node.CharLiteral{ |
| 5114 | .token = token, | 5296 | .token = token, |
| 5115 | }; | 5297 | }; |
| 5116 | return &node.base; | 5298 | return &node.base; |
| 5117 | }, | 5299 | }, |
| 5118 | .StrLit => { | 5300 | .StringLiteral => { |
| 5119 | const token = try appendToken(c, .StringLiteral, tok.bytes); | 5301 | const first_tok = it.list.at(0); |
| | 5302 | const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, source[tok.start..tok.end], source[first_tok.start..first_tok.end], source_loc)); |
| 5120 | const node = try c.a().create(ast.Node.StringLiteral); | 5303 | const node = try c.a().create(ast.Node.StringLiteral); |
| 5121 | node.* = ast.Node.StringLiteral{ | 5304 | node.* = ast.Node.StringLiteral{ |
| 5122 | .token = token, | 5305 | .token = token, |
| 5123 | }; | 5306 | }; |
| 5124 | return &node.base; | 5307 | return &node.base; |
| 5125 | }, | 5308 | }, |
| 5126 | .NumLitInt, .NumLitFloat => { | 5309 | .IntegerLiteral, .FloatLiteral => { |
| 5127 | return parseCNumLit(c, tok, source_loc); | 5310 | return parseCNumLit(c, tok, source, source_loc); |
| 5128 | }, | 5311 | }, |
| 5129 | .Identifier => { | 5312 | .Identifier => { |
| 5130 | const mangled_name = scope.getAlias(tok.bytes); | 5313 | const mangled_name = scope.getAlias(source[tok.start..tok.end]); |
| 5131 | return transCreateNodeIdentifier(c, mangled_name); | 5314 | return transCreateNodeIdentifier(c, mangled_name); |
| 5132 | }, | 5315 | }, |
| 5133 | .LParen => { | 5316 | .LParen => { |
| 5134 | const inner_node = try parseCExpr(c, it, source_loc, scope); | 5317 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); |
| 5135 | | 5318 | |
| 5136 | if (it.peek().?.id == .RParen) { | 5319 | if (it.peek().?.id == .RParen) { |
| 5137 | _ = it.next(); | 5320 | _ = it.next(); |
| ... | @@ -5144,13 +5327,14 @@ fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigC | ... | @@ -5144,13 +5327,14 @@ fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigC |
| 5144 | // hack to get zig fmt to render a comma in builtin calls | 5327 | // hack to get zig fmt to render a comma in builtin calls |
| 5145 | _ = try appendToken(c, .Comma, ","); | 5328 | _ = try appendToken(c, .Comma, ","); |
| 5146 | | 5329 | |
| 5147 | const node_to_cast = try parseCExpr(c, it, source_loc, scope); | 5330 | const node_to_cast = try parseCExpr(c, it, source, source_loc, scope); |
| 5148 | | 5331 | |
| 5149 | if (it.next().?.id != .RParen) { | 5332 | if (it.next().?.id != .RParen) { |
| | 5333 | const first_tok = it.list.at(0); |
| 5150 | try failDecl( | 5334 | try failDecl( |
| 5151 | c, | 5335 | c, |
| 5152 | source_loc, | 5336 | source_loc, |
| 5153 | it.list.at(0).*.bytes, | 5337 | source[first_tok.start..first_tok.end], |
| 5154 | "unable to translate C expr: expected ')''", | 5338 | "unable to translate C expr: expected ')''", |
| 5155 | .{}, | 5339 | .{}, |
| 5156 | ); | 5340 | ); |
| ... | @@ -5228,10 +5412,11 @@ fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigC | ... | @@ -5228,10 +5412,11 @@ fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigC |
| 5228 | return &if_1.base; | 5412 | return &if_1.base; |
| 5229 | }, | 5413 | }, |
| 5230 | else => { | 5414 | else => { |
| | 5415 | const first_tok = it.list.at(0); |
| 5231 | try failDecl( | 5416 | try failDecl( |
| 5232 | c, | 5417 | c, |
| 5233 | source_loc, | 5418 | source_loc, |
| 5234 | it.list.at(0).*.bytes, | 5419 | source[first_tok.start..first_tok.end], |
| 5235 | "unable to translate C expr: unexpected token {}", | 5420 | "unable to translate C expr: unexpected token {}", |
| 5236 | .{tok.id}, | 5421 | .{tok.id}, |
| 5237 | ); | 5422 | ); |
| ... | @@ -5240,33 +5425,35 @@ fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigC | ... | @@ -5240,33 +5425,35 @@ fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigC |
| 5240 | } | 5425 | } |
| 5241 | } | 5426 | } |
| 5242 | | 5427 | |
| 5243 | fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 5428 | fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 5244 | var node = try parseCPrimaryExpr(c, it, source_loc, scope); | 5429 | var node = try parseCPrimaryExpr(c, it, source, source_loc, scope); |
| 5245 | while (true) { | 5430 | while (true) { |
| 5246 | const tok = it.next().?; | 5431 | const tok = it.next().?; |
| 5247 | switch (tok.id) { | 5432 | switch (tok.id) { |
| 5248 | .Dot => { | 5433 | .Period => { |
| 5249 | const name_tok = it.next().?; | 5434 | const name_tok = it.next().?; |
| 5250 | if (name_tok.id != .Identifier) { | 5435 | if (name_tok.id != .Identifier) { |
| | 5436 | const first_tok = it.list.at(0); |
| 5251 | try failDecl( | 5437 | try failDecl( |
| 5252 | c, | 5438 | c, |
| 5253 | source_loc, | 5439 | source_loc, |
| 5254 | it.list.at(0).*.bytes, | 5440 | source[first_tok.start..first_tok.end], |
| 5255 | "unable to translate C expr: expected identifier", | 5441 | "unable to translate C expr: expected identifier", |
| 5256 | .{}, | 5442 | .{}, |
| 5257 | ); | 5443 | ); |
| 5258 | return error.ParseError; | 5444 | return error.ParseError; |
| 5259 | } | 5445 | } |
| 5260 | | 5446 | |
| 5261 | node = try transCreateNodeFieldAccess(c, node, name_tok.bytes); | 5447 | node = try transCreateNodeFieldAccess(c, node, source[name_tok.start..name_tok.end]); |
| 5262 | }, | 5448 | }, |
| 5263 | .Arrow => { | 5449 | .Arrow => { |
| 5264 | const name_tok = it.next().?; | 5450 | const name_tok = it.next().?; |
| 5265 | if (name_tok.id != .Identifier) { | 5451 | if (name_tok.id != .Identifier) { |
| | 5452 | const first_tok = it.list.at(0); |
| 5266 | try failDecl( | 5453 | try failDecl( |
| 5267 | c, | 5454 | c, |
| 5268 | source_loc, | 5455 | source_loc, |
| 5269 | it.list.at(0).*.bytes, | 5456 | source[first_tok.start..first_tok.end], |
| 5270 | "unable to translate C expr: expected identifier", | 5457 | "unable to translate C expr: expected identifier", |
| 5271 | .{}, | 5458 | .{}, |
| 5272 | ); | 5459 | ); |
| ... | @@ -5274,7 +5461,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5274,7 +5461,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5274 | } | 5461 | } |
| 5275 | | 5462 | |
| 5276 | const deref = try transCreateNodePtrDeref(c, node); | 5463 | const deref = try transCreateNodePtrDeref(c, node); |
| 5277 | node = try transCreateNodeFieldAccess(c, deref, name_tok.bytes); | 5464 | node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]); |
| 5278 | }, | 5465 | }, |
| 5279 | .Asterisk => { | 5466 | .Asterisk => { |
| 5280 | if (it.peek().?.id == .RParen) { | 5467 | if (it.peek().?.id == .RParen) { |
| ... | @@ -5289,7 +5476,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5289,7 +5476,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5289 | } else { | 5476 | } else { |
| 5290 | // expr * expr | 5477 | // expr * expr |
| 5291 | const op_token = try appendToken(c, .Asterisk, "*"); | 5478 | const op_token = try appendToken(c, .Asterisk, "*"); |
| 5292 | const rhs = try parseCPrimaryExpr(c, it, source_loc, scope); | 5479 | const rhs = try parseCPrimaryExpr(c, it, source, source_loc, scope); |
| 5293 | const mul_node = try c.a().create(ast.Node.InfixOp); | 5480 | const mul_node = try c.a().create(ast.Node.InfixOp); |
| 5294 | mul_node.* = .{ | 5481 | mul_node.* = .{ |
| 5295 | .op_token = op_token, | 5482 | .op_token = op_token, |
| ... | @@ -5300,9 +5487,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5300,9 +5487,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5300 | node = &mul_node.base; | 5487 | node = &mul_node.base; |
| 5301 | } | 5488 | } |
| 5302 | }, | 5489 | }, |
| 5303 | .Shl => { | 5490 | .AngleBracketAngleBracketLeft => { |
| 5304 | const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<"); | 5491 | const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<"); |
| 5305 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5492 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5306 | const bitshift_node = try c.a().create(ast.Node.InfixOp); | 5493 | const bitshift_node = try c.a().create(ast.Node.InfixOp); |
| 5307 | bitshift_node.* = .{ | 5494 | bitshift_node.* = .{ |
| 5308 | .op_token = op_token, | 5495 | .op_token = op_token, |
| ... | @@ -5312,9 +5499,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5312,9 +5499,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5312 | }; | 5499 | }; |
| 5313 | node = &bitshift_node.base; | 5500 | node = &bitshift_node.base; |
| 5314 | }, | 5501 | }, |
| 5315 | .Shr => { | 5502 | .AngleBracketAngleBracketRight => { |
| 5316 | const op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>"); | 5503 | const op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>"); |
| 5317 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5504 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5318 | const bitshift_node = try c.a().create(ast.Node.InfixOp); | 5505 | const bitshift_node = try c.a().create(ast.Node.InfixOp); |
| 5319 | bitshift_node.* = .{ | 5506 | bitshift_node.* = .{ |
| 5320 | .op_token = op_token, | 5507 | .op_token = op_token, |
| ... | @@ -5326,7 +5513,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5326,7 +5513,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5326 | }, | 5513 | }, |
| 5327 | .Pipe => { | 5514 | .Pipe => { |
| 5328 | const op_token = try appendToken(c, .Pipe, "|"); | 5515 | const op_token = try appendToken(c, .Pipe, "|"); |
| 5329 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5516 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5330 | const or_node = try c.a().create(ast.Node.InfixOp); | 5517 | const or_node = try c.a().create(ast.Node.InfixOp); |
| 5331 | or_node.* = .{ | 5518 | or_node.* = .{ |
| 5332 | .op_token = op_token, | 5519 | .op_token = op_token, |
| ... | @@ -5338,7 +5525,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5338,7 +5525,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5338 | }, | 5525 | }, |
| 5339 | .Ampersand => { | 5526 | .Ampersand => { |
| 5340 | const op_token = try appendToken(c, .Ampersand, "&"); | 5527 | const op_token = try appendToken(c, .Ampersand, "&"); |
| 5341 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5528 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5342 | const bitand_node = try c.a().create(ast.Node.InfixOp); | 5529 | const bitand_node = try c.a().create(ast.Node.InfixOp); |
| 5343 | bitand_node.* = .{ | 5530 | bitand_node.* = .{ |
| 5344 | .op_token = op_token, | 5531 | .op_token = op_token, |
| ... | @@ -5350,7 +5537,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5350,7 +5537,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5350 | }, | 5537 | }, |
| 5351 | .Plus => { | 5538 | .Plus => { |
| 5352 | const op_token = try appendToken(c, .Plus, "+"); | 5539 | const op_token = try appendToken(c, .Plus, "+"); |
| 5353 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5540 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5354 | const add_node = try c.a().create(ast.Node.InfixOp); | 5541 | const add_node = try c.a().create(ast.Node.InfixOp); |
| 5355 | add_node.* = .{ | 5542 | add_node.* = .{ |
| 5356 | .op_token = op_token, | 5543 | .op_token = op_token, |
| ... | @@ -5362,7 +5549,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5362,7 +5549,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5362 | }, | 5549 | }, |
| 5363 | .Minus => { | 5550 | .Minus => { |
| 5364 | const op_token = try appendToken(c, .Minus, "-"); | 5551 | const op_token = try appendToken(c, .Minus, "-"); |
| 5365 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5552 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5366 | const sub_node = try c.a().create(ast.Node.InfixOp); | 5553 | const sub_node = try c.a().create(ast.Node.InfixOp); |
| 5367 | sub_node.* = .{ | 5554 | sub_node.* = .{ |
| 5368 | .op_token = op_token, | 5555 | .op_token = op_token, |
| ... | @@ -5372,9 +5559,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5372,9 +5559,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5372 | }; | 5559 | }; |
| 5373 | node = &sub_node.base; | 5560 | node = &sub_node.base; |
| 5374 | }, | 5561 | }, |
| 5375 | .And => { | 5562 | .AmpersandAmpersand => { |
| 5376 | const op_token = try appendToken(c, .Keyword_and, "and"); | 5563 | const op_token = try appendToken(c, .Keyword_and, "and"); |
| 5377 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5564 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5378 | const and_node = try c.a().create(ast.Node.InfixOp); | 5565 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 5379 | and_node.* = .{ | 5566 | and_node.* = .{ |
| 5380 | .op_token = op_token, | 5567 | .op_token = op_token, |
| ... | @@ -5384,9 +5571,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5384,9 +5571,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5384 | }; | 5571 | }; |
| 5385 | node = &and_node.base; | 5572 | node = &and_node.base; |
| 5386 | }, | 5573 | }, |
| 5387 | .Or => { | 5574 | .PipePipe => { |
| 5388 | const op_token = try appendToken(c, .Keyword_or, "or"); | 5575 | const op_token = try appendToken(c, .Keyword_or, "or"); |
| 5389 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5576 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5390 | const or_node = try c.a().create(ast.Node.InfixOp); | 5577 | const or_node = try c.a().create(ast.Node.InfixOp); |
| 5391 | or_node.* = .{ | 5578 | or_node.* = .{ |
| 5392 | .op_token = op_token, | 5579 | .op_token = op_token, |
| ... | @@ -5396,9 +5583,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5396,9 +5583,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5396 | }; | 5583 | }; |
| 5397 | node = &or_node.base; | 5584 | node = &or_node.base; |
| 5398 | }, | 5585 | }, |
| 5399 | .Gt => { | 5586 | .AngleBracketRight => { |
| 5400 | const op_token = try appendToken(c, .AngleBracketRight, ">"); | 5587 | const op_token = try appendToken(c, .AngleBracketRight, ">"); |
| 5401 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5588 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5402 | const and_node = try c.a().create(ast.Node.InfixOp); | 5589 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 5403 | and_node.* = .{ | 5590 | and_node.* = .{ |
| 5404 | .op_token = op_token, | 5591 | .op_token = op_token, |
| ... | @@ -5408,9 +5595,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5408,9 +5595,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5408 | }; | 5595 | }; |
| 5409 | node = &and_node.base; | 5596 | node = &and_node.base; |
| 5410 | }, | 5597 | }, |
| 5411 | .Gte => { | 5598 | .AngleBracketRightEqual => { |
| 5412 | const op_token = try appendToken(c, .AngleBracketRightEqual, ">="); | 5599 | const op_token = try appendToken(c, .AngleBracketRightEqual, ">="); |
| 5413 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5600 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5414 | const and_node = try c.a().create(ast.Node.InfixOp); | 5601 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 5415 | and_node.* = .{ | 5602 | and_node.* = .{ |
| 5416 | .op_token = op_token, | 5603 | .op_token = op_token, |
| ... | @@ -5420,9 +5607,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5420,9 +5607,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5420 | }; | 5607 | }; |
| 5421 | node = &and_node.base; | 5608 | node = &and_node.base; |
| 5422 | }, | 5609 | }, |
| 5423 | .Lt => { | 5610 | .AngleBracketLeft => { |
| 5424 | const op_token = try appendToken(c, .AngleBracketLeft, "<"); | 5611 | const op_token = try appendToken(c, .AngleBracketLeft, "<"); |
| 5425 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5612 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5426 | const and_node = try c.a().create(ast.Node.InfixOp); | 5613 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 5427 | and_node.* = .{ | 5614 | and_node.* = .{ |
| 5428 | .op_token = op_token, | 5615 | .op_token = op_token, |
| ... | @@ -5432,9 +5619,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5432,9 +5619,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5432 | }; | 5619 | }; |
| 5433 | node = &and_node.base; | 5620 | node = &and_node.base; |
| 5434 | }, | 5621 | }, |
| 5435 | .Lte => { | 5622 | .AngleBracketLeftEqual => { |
| 5436 | const op_token = try appendToken(c, .AngleBracketLeftEqual, "<="); | 5623 | const op_token = try appendToken(c, .AngleBracketLeftEqual, "<="); |
| 5437 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5624 | const rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5438 | const and_node = try c.a().create(ast.Node.InfixOp); | 5625 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 5439 | and_node.* = .{ | 5626 | and_node.* = .{ |
| 5440 | .op_token = op_token, | 5627 | .op_token = op_token, |
| ... | @@ -5446,14 +5633,15 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5446,14 +5633,15 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5446 | }, | 5633 | }, |
| 5447 | .LBrace => { | 5634 | .LBrace => { |
| 5448 | const arr_node = try transCreateNodeArrayAccess(c, node); | 5635 | const arr_node = try transCreateNodeArrayAccess(c, node); |
| 5449 | arr_node.op.ArrayAccess = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5636 | arr_node.op.ArrayAccess = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5450 | arr_node.rtoken = try appendToken(c, .RBrace, "]"); | 5637 | arr_node.rtoken = try appendToken(c, .RBrace, "]"); |
| 5451 | node = &arr_node.base; | 5638 | node = &arr_node.base; |
| 5452 | if (it.next().?.id != .RBrace) { | 5639 | if (it.next().?.id != .RBrace) { |
| | 5640 | const first_tok = it.list.at(0); |
| 5453 | try failDecl( | 5641 | try failDecl( |
| 5454 | c, | 5642 | c, |
| 5455 | source_loc, | 5643 | source_loc, |
| 5456 | it.list.at(0).*.bytes, | 5644 | source[first_tok.start..first_tok.end], |
| 5457 | "unable to translate C expr: expected ']'", | 5645 | "unable to translate C expr: expected ']'", |
| 5458 | .{}, | 5646 | .{}, |
| 5459 | ); | 5647 | ); |
| ... | @@ -5463,7 +5651,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5463,7 +5651,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5463 | .LParen => { | 5651 | .LParen => { |
| 5464 | const call_node = try transCreateNodeFnCall(c, node); | 5652 | const call_node = try transCreateNodeFnCall(c, node); |
| 5465 | while (true) { | 5653 | while (true) { |
| 5466 | const arg = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5654 | const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5467 | try call_node.op.Call.params.push(arg); | 5655 | try call_node.op.Call.params.push(arg); |
| 5468 | const next = it.next().?; | 5656 | const next = it.next().?; |
| 5469 | if (next.id == .Comma) | 5657 | if (next.id == .Comma) |
| ... | @@ -5471,10 +5659,11 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5471,10 +5659,11 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5471 | else if (next.id == .RParen) | 5659 | else if (next.id == .RParen) |
| 5472 | break | 5660 | break |
| 5473 | else { | 5661 | else { |
| | 5662 | const first_tok = it.list.at(0); |
| 5474 | try failDecl( | 5663 | try failDecl( |
| 5475 | c, | 5664 | c, |
| 5476 | source_loc, | 5665 | source_loc, |
| 5477 | it.list.at(0).*.bytes, | 5666 | source[first_tok.start..first_tok.end], |
| 5478 | "unable to translate C expr: expected ',' or ')'", | 5667 | "unable to translate C expr: expected ',' or ')'", |
| 5479 | .{}, | 5668 | .{}, |
| 5480 | ); | 5669 | ); |
| ... | @@ -5492,32 +5681,32 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig | ... | @@ -5492,32 +5681,32 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 5492 | } | 5681 | } |
| 5493 | } | 5682 | } |
| 5494 | | 5683 | |
| 5495 | fn parseCPrefixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 5684 | fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 5496 | const op_tok = it.next().?; | 5685 | const op_tok = it.next().?; |
| 5497 | | 5686 | |
| 5498 | switch (op_tok.id) { | 5687 | switch (op_tok.id) { |
| 5499 | .Bang => { | 5688 | .Bang => { |
| 5500 | const node = try transCreateNodePrefixOp(c, .BoolNot, .Bang, "!"); | 5689 | const node = try transCreateNodePrefixOp(c, .BoolNot, .Bang, "!"); |
| 5501 | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5690 | node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5502 | return &node.base; | 5691 | return &node.base; |
| 5503 | }, | 5692 | }, |
| 5504 | .Minus => { | 5693 | .Minus => { |
| 5505 | const node = try transCreateNodePrefixOp(c, .Negation, .Minus, "-"); | 5694 | const node = try transCreateNodePrefixOp(c, .Negation, .Minus, "-"); |
| 5506 | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5695 | node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5507 | return &node.base; | 5696 | return &node.base; |
| 5508 | }, | 5697 | }, |
| 5509 | .Tilde => { | 5698 | .Tilde => { |
| 5510 | const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~"); | 5699 | const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~"); |
| 5511 | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5700 | node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5512 | return &node.base; | 5701 | return &node.base; |
| 5513 | }, | 5702 | }, |
| 5514 | .Asterisk => { | 5703 | .Asterisk => { |
| 5515 | const prefix_op_expr = try parseCPrefixOpExpr(c, it, source_loc, scope); | 5704 | const prefix_op_expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5516 | return try transCreateNodePtrDeref(c, prefix_op_expr); | 5705 | return try transCreateNodePtrDeref(c, prefix_op_expr); |
| 5517 | }, | 5706 | }, |
| 5518 | else => { | 5707 | else => { |
| 5519 | _ = it.prev(); | 5708 | _ = it.prev(); |
| 5520 | return try parseCSuffixOpExpr(c, it, source_loc, scope); | 5709 | return try parseCSuffixOpExpr(c, it, source, source_loc, scope); |
| 5521 | }, | 5710 | }, |
| 5522 | } | 5711 | } |
| 5523 | } | 5712 | } |