| ... | @@ -182,7 +182,7 @@ const Scope = struct { | ... | @@ -182,7 +182,7 @@ const Scope = struct { |
| 182 | } | 182 | } |
| 183 | }; | 183 | }; |
| 184 | | 184 | |
| 185 | const Context = struct { | 185 | pub const Context = struct { |
| 186 | tree: *ast.Tree, | 186 | tree: *ast.Tree, |
| 187 | source_buffer: *std.Buffer, | 187 | source_buffer: *std.Buffer, |
| 188 | err: Error, | 188 | err: Error, |
| ... | @@ -3921,7 +3921,7 @@ fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []cons | ... | @@ -3921,7 +3921,7 @@ fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []cons |
| 3921 | _ = try appendTokenFmt(c, .LineComment, "// {}: warning: " ++ format, args_prefix ++ args); | 3921 | _ = try appendTokenFmt(c, .LineComment, "// {}: warning: " ++ format, args_prefix ++ args); |
| 3922 | } | 3922 | } |
| 3923 | | 3923 | |
| 3924 | fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: var) !void { | 3924 | pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: var) !void { |
| 3925 | // const name = @compileError(msg); | 3925 | // const name = @compileError(msg); |
| 3926 | const const_tok = try appendToken(c, .Keyword_const, "const"); | 3926 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 3927 | const name_tok = try appendIdentifier(c, name); | 3927 | const name_tok = try appendIdentifier(c, name); |
| ... | @@ -4091,10 +4091,9 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4091,10 +4091,9 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4091 | continue; | 4091 | continue; |
| 4092 | } | 4092 | } |
| 4093 | const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc); | 4093 | const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc); |
| 4094 | ctok.tokenizeCMacro(&tok_list, begin_c) catch |err| switch (err) { | 4094 | ctok.tokenizeCMacro(c, begin_loc, checked_name, &tok_list, begin_c) catch |err| switch (err) { |
| 4095 | error.OutOfMemory => |e| return e, | 4095 | error.OutOfMemory => |e| return e, |
| 4096 | else => { | 4096 | else => { |
| 4097 | try failDecl(c, begin_loc, checked_name, "unable to tokenize macro definition", .{}); | | |
| 4098 | continue; | 4097 | continue; |
| 4099 | }, | 4098 | }, |
| 4100 | }; | 4099 | }; |
| ... | @@ -4127,9 +4126,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4127,9 +4126,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4127 | transMacroFnDefine(c, &tok_it, checked_name, begin_loc) | 4126 | transMacroFnDefine(c, &tok_it, checked_name, begin_loc) |
| 4128 | else | 4127 | else |
| 4129 | transMacroDefine(c, &tok_it, checked_name, begin_loc)) catch |err| switch (err) { | 4128 | transMacroDefine(c, &tok_it, checked_name, begin_loc)) catch |err| switch (err) { |
| 4130 | error.UnsupportedTranslation, | 4129 | error.ParseError => continue, |
| 4131 | error.ParseError, | | |
| 4132 | => try failDecl(c, begin_loc, checked_name, "unable to translate macro", .{}), | | |
| 4133 | error.OutOfMemory => |e| return e, | 4130 | error.OutOfMemory => |e| return e, |
| 4134 | }; | 4131 | }; |
| 4135 | }, | 4132 | }, |
| ... | @@ -4139,20 +4136,19 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { | ... | @@ -4139,20 +4136,19 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 4139 | } | 4136 | } |
| 4140 | | 4137 | |
| 4141 | fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { | 4138 | fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 4142 | const rp = makeRestorePoint(c); | | |
| 4143 | const scope = &c.global_scope.base; | 4139 | const scope = &c.global_scope.base; |
| 4144 | | 4140 | |
| 4145 | const node = try transCreateNodeVarDecl(c, true, true, name); | 4141 | const node = try transCreateNodeVarDecl(c, true, true, name); |
| 4146 | node.eq_token = try appendToken(c, .Equal, "="); | 4142 | node.eq_token = try appendToken(c, .Equal, "="); |
| 4147 | | 4143 | |
| 4148 | node.init_node = try parseCExpr(rp, it, source_loc, scope); | 4144 | node.init_node = try parseCExpr(c, it, source_loc, scope); |
| 4149 | const last = it.next().?; | 4145 | const last = it.next().?; |
| 4150 | if (last.id != .Eof) | 4146 | if (last.id != .Eof) |
| 4151 | return revertAndWarn( | 4147 | return failDecl( |
| 4152 | rp, | 4148 | c, |
| 4153 | error.UnsupportedTranslation, | | |
| 4154 | source_loc, | 4149 | source_loc, |
| 4155 | "unable to translate C expr, unexpected token: {}", | 4150 | name, |
| | 4151 | "unable to translate C expr: unexpected token {}", |
| 4156 | .{last.id}, | 4152 | .{last.id}, |
| 4157 | ); | 4153 | ); |
| 4158 | | 4154 | |
| ... | @@ -4161,7 +4157,6 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, | ... | @@ -4161,7 +4157,6 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, |
| 4161 | } | 4157 | } |
| 4162 | | 4158 | |
| 4163 | fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { | 4159 | fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 4164 | const rp = makeRestorePoint(c); | | |
| 4165 | const block_scope = try Scope.Block.init(c, &c.global_scope.base, null); | 4160 | const block_scope = try Scope.Block.init(c, &c.global_scope.base, null); |
| 4166 | const scope = &block_scope.base; | 4161 | const scope = &block_scope.base; |
| 4167 | | 4162 | |
| ... | @@ -4172,13 +4167,26 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -4172,13 +4167,26 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4172 | _ = try appendToken(c, .LParen, "("); | 4167 | _ = try appendToken(c, .LParen, "("); |
| 4173 | | 4168 | |
| 4174 | if (it.next().?.id != .LParen) { | 4169 | if (it.next().?.id != .LParen) { |
| 4175 | return error.ParseError; | 4170 | return failDecl( |
| | 4171 | c, |
| | 4172 | source_loc, |
| | 4173 | name, |
| | 4174 | "unable to translate C expr: expected '('", |
| | 4175 | .{}, |
| | 4176 | ); |
| 4176 | } | 4177 | } |
| 4177 | var fn_params = ast.Node.FnProto.ParamList.init(c.a()); | 4178 | var fn_params = ast.Node.FnProto.ParamList.init(c.a()); |
| 4178 | while (true) { | 4179 | while (true) { |
| 4179 | const param_tok = it.next().?; | 4180 | const param_tok = it.next().?; |
| 4180 | if (param_tok.id != .Identifier) | 4181 | if (param_tok.id != .Identifier) { |
| 4181 | return error.ParseError; | 4182 | return failDecl( |
| | 4183 | c, |
| | 4184 | source_loc, |
| | 4185 | name, |
| | 4186 | "unable to translate C expr: expected identifier", |
| | 4187 | .{}, |
| | 4188 | ); |
| | 4189 | } |
| 4182 | | 4190 | |
| 4183 | const checked_name = if (try scope.createAlias(c, param_tok.bytes)) |alias| blk: { | 4191 | const checked_name = if (try scope.createAlias(c, param_tok.bytes)) |alias| blk: { |
| 4184 | try block_scope.variables.push(.{ .name = param_tok.bytes, .alias = alias }); | 4192 | try block_scope.variables.push(.{ .name = param_tok.bytes, .alias = alias }); |
| ... | @@ -4213,7 +4221,13 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -4213,7 +4221,13 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4213 | } | 4221 | } |
| 4214 | | 4222 | |
| 4215 | if (it.next().?.id != .RParen) { | 4223 | if (it.next().?.id != .RParen) { |
| 4216 | return error.ParseError; | 4224 | return failDecl( |
| | 4225 | c, |
| | 4226 | source_loc, |
| | 4227 | name, |
| | 4228 | "unable to translate C expr: expected ')'", |
| | 4229 | .{}, |
| | 4230 | ); |
| 4217 | } | 4231 | } |
| 4218 | | 4232 | |
| 4219 | _ = try appendToken(c, .RParen, ")"); | 4233 | _ = try appendToken(c, .RParen, ")"); |
| ... | @@ -4241,14 +4255,14 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -4241,14 +4255,14 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4241 | const block = try transCreateNodeBlock(c, null); | 4255 | const block = try transCreateNodeBlock(c, null); |
| 4242 | | 4256 | |
| 4243 | const return_expr = try transCreateNodeReturnExpr(c); | 4257 | const return_expr = try transCreateNodeReturnExpr(c); |
| 4244 | const expr = try parseCExpr(rp, it, source_loc, scope); | 4258 | const expr = try parseCExpr(c, it, source_loc, scope); |
| 4245 | const last = it.next().?; | 4259 | const last = it.next().?; |
| 4246 | if (last.id != .Eof) | 4260 | if (last.id != .Eof) |
| 4247 | return revertAndWarn( | 4261 | return failDecl( |
| 4248 | rp, | 4262 | c, |
| 4249 | error.UnsupportedTranslation, | | |
| 4250 | source_loc, | 4263 | source_loc, |
| 4251 | "unable to translate C expr, unexpected token: {}", | 4264 | name, |
| | 4265 | "unable to translate C expr: unexpected token {}", |
| 4252 | .{last.id}, | 4266 | .{last.id}, |
| 4253 | ); | 4267 | ); |
| 4254 | _ = try appendToken(c, .Semicolon, ";"); | 4268 | _ = try appendToken(c, .Semicolon, ";"); |
| ... | @@ -4261,31 +4275,28 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u | ... | @@ -4261,31 +4275,28 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4261 | _ = try c.global_scope.macro_table.put(name, &fn_proto.base); | 4275 | _ = try c.global_scope.macro_table.put(name, &fn_proto.base); |
| 4262 | } | 4276 | } |
| 4263 | | 4277 | |
| 4264 | const ParseError = Error || error{ | 4278 | const ParseError = Error || error{ParseError}; |
| 4265 | ParseError, | | |
| 4266 | UnsupportedTranslation, | | |
| 4267 | }; | | |
| 4268 | | 4279 | |
| 4269 | fn parseCExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 4280 | fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 4270 | return parseCPrefixOpExpr(rp, it, source_loc, scope); | 4281 | return parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4271 | } | 4282 | } |
| 4272 | | 4283 | |
| 4273 | fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { | 4284 | fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 4274 | if (tok.id == .NumLitInt) { | 4285 | if (tok.id == .NumLitInt) { |
| 4275 | if (tok.num_lit_suffix == .None) { | 4286 | if (tok.num_lit_suffix == .None) { |
| 4276 | if (tok.bytes.len > 2 and tok.bytes[0] == '0') { | 4287 | if (tok.bytes.len > 2 and tok.bytes[0] == '0') { |
| 4277 | switch (tok.bytes[1]) { | 4288 | switch (tok.bytes[1]) { |
| 4278 | '0'...'7' => { | 4289 | '0'...'7' => { |
| 4279 | // octal | 4290 | // octal |
| 4280 | return transCreateNodeInt(rp.c, try std.fmt.allocPrint(rp.c.a(), "0o{}", .{tok.bytes})); | 4291 | return transCreateNodeInt(c, try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes})); |
| 4281 | }, | 4292 | }, |
| 4282 | else => {}, | 4293 | else => {}, |
| 4283 | } | 4294 | } |
| 4284 | } | 4295 | } |
| 4285 | return transCreateNodeInt(rp.c, tok.bytes); | 4296 | return transCreateNodeInt(c, tok.bytes); |
| 4286 | } | 4297 | } |
| 4287 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 4298 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 4288 | try cast_node.params.push(try transCreateNodeIdentifier(rp.c, switch (tok.num_lit_suffix) { | 4299 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) { |
| 4289 | .U => "c_uint", | 4300 | .U => "c_uint", |
| 4290 | .L => "c_long", | 4301 | .L => "c_long", |
| 4291 | .LU => "c_ulong", | 4302 | .LU => "c_ulong", |
| ... | @@ -4293,62 +4304,55 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati | ... | @@ -4293,62 +4304,55 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati |
| 4293 | .LLU => "c_ulonglong", | 4304 | .LLU => "c_ulonglong", |
| 4294 | else => unreachable, | 4305 | else => unreachable, |
| 4295 | })); | 4306 | })); |
| 4296 | _ = try appendToken(rp.c, .Comma, ","); | 4307 | _ = try appendToken(c, .Comma, ","); |
| 4297 | try cast_node.params.push(try transCreateNodeInt(rp.c, tok.bytes)); | 4308 | try cast_node.params.push(try transCreateNodeInt(c, tok.bytes)); |
| 4298 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 4309 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 4299 | return &cast_node.base; | 4310 | return &cast_node.base; |
| 4300 | } else if (tok.id == .NumLitFloat) { | 4311 | } else if (tok.id == .NumLitFloat) { |
| 4301 | if (tok.num_lit_suffix == .None) { | 4312 | if (tok.num_lit_suffix == .None) { |
| 4302 | return transCreateNodeFloat(rp.c, tok.bytes); | 4313 | return transCreateNodeFloat(c, tok.bytes); |
| 4303 | } | 4314 | } |
| 4304 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 4315 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 4305 | try cast_node.params.push(try transCreateNodeIdentifier(rp.c, switch (tok.num_lit_suffix) { | 4316 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) { |
| 4306 | .F => "f32", | 4317 | .F => "f32", |
| 4307 | .L => "f64", | 4318 | .L => "f64", |
| 4308 | else => unreachable, | 4319 | else => unreachable, |
| 4309 | })); | 4320 | })); |
| 4310 | _ = try appendToken(rp.c, .Comma, ","); | 4321 | _ = try appendToken(c, .Comma, ","); |
| 4311 | try cast_node.params.push(try transCreateNodeFloat(rp.c, tok.bytes)); | 4322 | try cast_node.params.push(try transCreateNodeFloat(c, tok.bytes)); |
| 4312 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 4323 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 4313 | return &cast_node.base; | 4324 | return &cast_node.base; |
| 4314 | } else | 4325 | } else unreachable; |
| 4315 | return revertAndWarn( | | |
| 4316 | rp, | | |
| 4317 | error.ParseError, | | |
| 4318 | source_loc, | | |
| 4319 | "expected number literal", | | |
| 4320 | .{}, | | |
| 4321 | ); | | |
| 4322 | } | 4326 | } |
| 4323 | | 4327 | |
| 4324 | fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 4328 | fn parseCPrimaryExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 4325 | const tok = it.next().?; | 4329 | const tok = it.next().?; |
| 4326 | switch (tok.id) { | 4330 | switch (tok.id) { |
| 4327 | .CharLit => { | 4331 | .CharLit => { |
| 4328 | const token = try appendToken(rp.c, .CharLiteral, tok.bytes); | 4332 | const token = try appendToken(c, .CharLiteral, tok.bytes); |
| 4329 | const node = try rp.c.a().create(ast.Node.CharLiteral); | 4333 | const node = try c.a().create(ast.Node.CharLiteral); |
| 4330 | node.* = ast.Node.CharLiteral{ | 4334 | node.* = ast.Node.CharLiteral{ |
| 4331 | .token = token, | 4335 | .token = token, |
| 4332 | }; | 4336 | }; |
| 4333 | return &node.base; | 4337 | return &node.base; |
| 4334 | }, | 4338 | }, |
| 4335 | .StrLit => { | 4339 | .StrLit => { |
| 4336 | const token = try appendToken(rp.c, .StringLiteral, tok.bytes); | 4340 | const token = try appendToken(c, .StringLiteral, tok.bytes); |
| 4337 | const node = try rp.c.a().create(ast.Node.StringLiteral); | 4341 | const node = try c.a().create(ast.Node.StringLiteral); |
| 4338 | node.* = ast.Node.StringLiteral{ | 4342 | node.* = ast.Node.StringLiteral{ |
| 4339 | .token = token, | 4343 | .token = token, |
| 4340 | }; | 4344 | }; |
| 4341 | return &node.base; | 4345 | return &node.base; |
| 4342 | }, | 4346 | }, |
| 4343 | .NumLitInt, .NumLitFloat => { | 4347 | .NumLitInt, .NumLitFloat => { |
| 4344 | return parseCNumLit(rp, tok, source_loc); | 4348 | return parseCNumLit(c, tok, source_loc); |
| 4345 | }, | 4349 | }, |
| 4346 | .Identifier => { | 4350 | .Identifier => { |
| 4347 | const name = if (scope.getAlias(tok.bytes)) |a| a else tok.bytes; | 4351 | const name = if (scope.getAlias(tok.bytes)) |a| a else tok.bytes; |
| 4348 | return transCreateNodeIdentifier(rp.c, name); | 4352 | return transCreateNodeIdentifier(c, name); |
| 4349 | }, | 4353 | }, |
| 4350 | .LParen => { | 4354 | .LParen => { |
| 4351 | const inner_node = try parseCExpr(rp, it, source_loc, scope); | 4355 | const inner_node = try parseCExpr(c, it, source_loc, scope); |
| 4352 | | 4356 | |
| 4353 | if (it.peek().?.id == .RParen) { | 4357 | if (it.peek().?.id == .RParen) { |
| 4354 | _ = it.next(); | 4358 | _ = it.next(); |
| ... | @@ -4359,18 +4363,19 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: | ... | @@ -4359,18 +4363,19 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: |
| 4359 | } | 4363 | } |
| 4360 | | 4364 | |
| 4361 | // hack to get zig fmt to render a comma in builtin calls | 4365 | // hack to get zig fmt to render a comma in builtin calls |
| 4362 | _ = try appendToken(rp.c, .Comma, ","); | 4366 | _ = try appendToken(c, .Comma, ","); |
| 4363 | | 4367 | |
| 4364 | const node_to_cast = try parseCExpr(rp, it, source_loc, scope); | 4368 | const node_to_cast = try parseCExpr(c, it, source_loc, scope); |
| 4365 | | 4369 | |
| 4366 | if (it.next().?.id != .RParen) { | 4370 | if (it.next().?.id != .RParen) { |
| 4367 | return revertAndWarn( | 4371 | try failDecl( |
| 4368 | rp, | 4372 | c, |
| 4369 | error.ParseError, | | |
| 4370 | source_loc, | 4373 | source_loc, |
| 4371 | "unable to translate C expr", | 4374 | it.list.at(0).*.bytes, |
| | 4375 | "unable to translate C expr: expected ')''", |
| 4372 | .{}, | 4376 | .{}, |
| 4373 | ); | 4377 | ); |
| | 4378 | return error.ParseError; |
| 4374 | } | 4379 | } |
| 4375 | | 4380 | |
| 4376 | //if (@typeId(@TypeOf(x)) == .Pointer) | 4381 | //if (@typeId(@TypeOf(x)) == .Pointer) |
| ... | @@ -4380,114 +4385,133 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: | ... | @@ -4380,114 +4385,133 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: |
| 4380 | //else | 4385 | //else |
| 4381 | // @as(dest, x) | 4386 | // @as(dest, x) |
| 4382 | | 4387 | |
| 4383 | const if_1 = try transCreateNodeIf(rp.c); | 4388 | const if_1 = try transCreateNodeIf(c); |
| 4384 | const type_id_1 = try transCreateNodeBuiltinFnCall(rp.c, "@typeId"); | 4389 | const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeId"); |
| 4385 | const type_of_1 = try transCreateNodeBuiltinFnCall(rp.c, "@TypeOf"); | 4390 | const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); |
| 4386 | try type_id_1.params.push(&type_of_1.base); | 4391 | try type_id_1.params.push(&type_of_1.base); |
| 4387 | try type_of_1.params.push(node_to_cast); | 4392 | try type_of_1.params.push(node_to_cast); |
| 4388 | type_of_1.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4393 | type_of_1.rparen_token = try appendToken(c, .LParen, ")"); |
| 4389 | type_id_1.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4394 | type_id_1.rparen_token = try appendToken(c, .LParen, ")"); |
| 4390 | | 4395 | |
| 4391 | const cmp_1 = try rp.c.a().create(ast.Node.InfixOp); | 4396 | const cmp_1 = try c.a().create(ast.Node.InfixOp); |
| 4392 | cmp_1.* = .{ | 4397 | cmp_1.* = .{ |
| 4393 | .op_token = try appendToken(rp.c, .EqualEqual, "=="), | 4398 | .op_token = try appendToken(c, .EqualEqual, "=="), |
| 4394 | .lhs = &type_id_1.base, | 4399 | .lhs = &type_id_1.base, |
| 4395 | .op = .EqualEqual, | 4400 | .op = .EqualEqual, |
| 4396 | .rhs = try transCreateNodeEnumLiteral(rp.c, "Pointer"), | 4401 | .rhs = try transCreateNodeEnumLiteral(c, "Pointer"), |
| 4397 | }; | 4402 | }; |
| 4398 | if_1.condition = &cmp_1.base; | 4403 | if_1.condition = &cmp_1.base; |
| 4399 | _ = try appendToken(rp.c, .LParen, ")"); | 4404 | _ = try appendToken(c, .LParen, ")"); |
| 4400 | | 4405 | |
| 4401 | const ptr_cast = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast"); | 4406 | const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast"); |
| 4402 | try ptr_cast.params.push(inner_node); | 4407 | try ptr_cast.params.push(inner_node); |
| 4403 | try ptr_cast.params.push(node_to_cast); | 4408 | try ptr_cast.params.push(node_to_cast); |
| 4404 | ptr_cast.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4409 | ptr_cast.rparen_token = try appendToken(c, .LParen, ")"); |
| 4405 | if_1.body = &ptr_cast.base; | 4410 | if_1.body = &ptr_cast.base; |
| 4406 | | 4411 | |
| 4407 | const else_1 = try transCreateNodeElse(rp.c); | 4412 | const else_1 = try transCreateNodeElse(c); |
| 4408 | if_1.@"else" = else_1; | 4413 | if_1.@"else" = else_1; |
| 4409 | | 4414 | |
| 4410 | const if_2 = try transCreateNodeIf(rp.c); | 4415 | const if_2 = try transCreateNodeIf(c); |
| 4411 | const type_id_2 = try transCreateNodeBuiltinFnCall(rp.c, "@typeId"); | 4416 | const type_id_2 = try transCreateNodeBuiltinFnCall(c, "@typeId"); |
| 4412 | const type_of_2 = try transCreateNodeBuiltinFnCall(rp.c, "@TypeOf"); | 4417 | const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); |
| 4413 | try type_id_2.params.push(&type_of_2.base); | 4418 | try type_id_2.params.push(&type_of_2.base); |
| 4414 | try type_of_2.params.push(node_to_cast); | 4419 | try type_of_2.params.push(node_to_cast); |
| 4415 | type_of_2.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4420 | type_of_2.rparen_token = try appendToken(c, .LParen, ")"); |
| 4416 | type_id_2.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4421 | type_id_2.rparen_token = try appendToken(c, .LParen, ")"); |
| 4417 | | 4422 | |
| 4418 | const cmp_2 = try rp.c.a().create(ast.Node.InfixOp); | 4423 | const cmp_2 = try c.a().create(ast.Node.InfixOp); |
| 4419 | cmp_2.* = .{ | 4424 | cmp_2.* = .{ |
| 4420 | .op_token = try appendToken(rp.c, .EqualEqual, "=="), | 4425 | .op_token = try appendToken(c, .EqualEqual, "=="), |
| 4421 | .lhs = &type_id_2.base, | 4426 | .lhs = &type_id_2.base, |
| 4422 | .op = .EqualEqual, | 4427 | .op = .EqualEqual, |
| 4423 | .rhs = try transCreateNodeEnumLiteral(rp.c, "Int"), | 4428 | .rhs = try transCreateNodeEnumLiteral(c, "Int"), |
| 4424 | }; | 4429 | }; |
| 4425 | if_2.condition = &cmp_2.base; | 4430 | if_2.condition = &cmp_2.base; |
| 4426 | else_1.body = &if_2.base; | 4431 | else_1.body = &if_2.base; |
| 4427 | _ = try appendToken(rp.c, .LParen, ")"); | 4432 | _ = try appendToken(c, .LParen, ")"); |
| 4428 | | 4433 | |
| 4429 | const int_to_ptr = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); | 4434 | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); |
| 4430 | try int_to_ptr.params.push(inner_node); | 4435 | try int_to_ptr.params.push(inner_node); |
| 4431 | try int_to_ptr.params.push(node_to_cast); | 4436 | try int_to_ptr.params.push(node_to_cast); |
| 4432 | int_to_ptr.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4437 | int_to_ptr.rparen_token = try appendToken(c, .LParen, ")"); |
| 4433 | if_2.body = &int_to_ptr.base; | 4438 | if_2.body = &int_to_ptr.base; |
| 4434 | | 4439 | |
| 4435 | const else_2 = try transCreateNodeElse(rp.c); | 4440 | const else_2 = try transCreateNodeElse(c); |
| 4436 | if_2.@"else" = else_2; | 4441 | if_2.@"else" = else_2; |
| 4437 | | 4442 | |
| 4438 | const as = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 4443 | const as = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 4439 | try as.params.push(inner_node); | 4444 | try as.params.push(inner_node); |
| 4440 | try as.params.push(node_to_cast); | 4445 | try as.params.push(node_to_cast); |
| 4441 | as.rparen_token = try appendToken(rp.c, .LParen, ")"); | 4446 | as.rparen_token = try appendToken(c, .LParen, ")"); |
| 4442 | else_2.body = &as.base; | 4447 | else_2.body = &as.base; |
| 4443 | | 4448 | |
| 4444 | return &if_1.base; | 4449 | return &if_1.base; |
| 4445 | }, | 4450 | }, |
| 4446 | else => return revertAndWarn( | 4451 | else => { |
| 4447 | rp, | 4452 | try failDecl( |
| 4448 | error.UnsupportedTranslation, | 4453 | c, |
| 4449 | source_loc, | 4454 | source_loc, |
| 4450 | "unable to translate C expr, unexpected token: {}", | 4455 | it.list.at(0).*.bytes, |
| 4451 | .{tok.id}, | 4456 | "unable to translate C expr: unexpected token {}", |
| 4452 | ), | 4457 | .{tok.id}, |
| | 4458 | ); |
| | 4459 | return error.ParseError; |
| | 4460 | }, |
| 4453 | } | 4461 | } |
| 4454 | } | 4462 | } |
| 4455 | | 4463 | |
| 4456 | fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 4464 | fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 4457 | var node = try parseCPrimaryExpr(rp, it, source_loc, scope); | 4465 | var node = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 4458 | while (true) { | 4466 | while (true) { |
| 4459 | const tok = it.next().?; | 4467 | const tok = it.next().?; |
| 4460 | switch (tok.id) { | 4468 | switch (tok.id) { |
| 4461 | .Dot => { | 4469 | .Dot => { |
| 4462 | const name_tok = it.next().?; | 4470 | const name_tok = it.next().?; |
| 4463 | if (name_tok.id != .Identifier) | 4471 | if (name_tok.id != .Identifier) { |
| | 4472 | try failDecl( |
| | 4473 | c, |
| | 4474 | source_loc, |
| | 4475 | it.list.at(0).*.bytes, |
| | 4476 | "unable to translate C expr: expected identifier", |
| | 4477 | .{}, |
| | 4478 | ); |
| 4464 | return error.ParseError; | 4479 | return error.ParseError; |
| | 4480 | } |
| 4465 | | 4481 | |
| 4466 | node = try transCreateNodeFieldAccess(rp.c, node, name_tok.bytes); | 4482 | node = try transCreateNodeFieldAccess(c, node, name_tok.bytes); |
| 4467 | }, | 4483 | }, |
| 4468 | .Arrow => { | 4484 | .Arrow => { |
| 4469 | const name_tok = it.next().?; | 4485 | const name_tok = it.next().?; |
| 4470 | if (name_tok.id != .Identifier) | 4486 | if (name_tok.id != .Identifier) { |
| | 4487 | try failDecl( |
| | 4488 | c, |
| | 4489 | source_loc, |
| | 4490 | it.list.at(0).*.bytes, |
| | 4491 | "unable to translate C expr: expected identifier", |
| | 4492 | .{}, |
| | 4493 | ); |
| 4471 | return error.ParseError; | 4494 | return error.ParseError; |
| | 4495 | } |
| 4472 | | 4496 | |
| 4473 | const deref = try transCreateNodePtrDeref(rp.c, node); | 4497 | const deref = try transCreateNodePtrDeref(c, node); |
| 4474 | node = try transCreateNodeFieldAccess(rp.c, deref, name_tok.bytes); | 4498 | node = try transCreateNodeFieldAccess(c, deref, name_tok.bytes); |
| 4475 | }, | 4499 | }, |
| 4476 | .Asterisk => { | 4500 | .Asterisk => { |
| 4477 | if (it.peek().?.id == .RParen) { | 4501 | if (it.peek().?.id == .RParen) { |
| 4478 | // type *) | 4502 | // type *) |
| 4479 | | 4503 | |
| 4480 | // hack to get zig fmt to render a comma in builtin calls | 4504 | // hack to get zig fmt to render a comma in builtin calls |
| 4481 | _ = try appendToken(rp.c, .Comma, ","); | 4505 | _ = try appendToken(c, .Comma, ","); |
| 4482 | | 4506 | |
| 4483 | const ptr = try transCreateNodePtrType(rp.c, false, false, .Identifier); | 4507 | const ptr = try transCreateNodePtrType(c, false, false, .Identifier); |
| 4484 | ptr.rhs = node; | 4508 | ptr.rhs = node; |
| 4485 | return &ptr.base; | 4509 | return &ptr.base; |
| 4486 | } else { | 4510 | } else { |
| 4487 | // expr * expr | 4511 | // expr * expr |
| 4488 | const op_token = try appendToken(rp.c, .Asterisk, "*"); | 4512 | const op_token = try appendToken(c, .Asterisk, "*"); |
| 4489 | const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope); | 4513 | const rhs = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 4490 | const mul_node = try rp.c.a().create(ast.Node.InfixOp); | 4514 | const mul_node = try c.a().create(ast.Node.InfixOp); |
| 4491 | mul_node.* = .{ | 4515 | mul_node.* = .{ |
| 4492 | .op_token = op_token, | 4516 | .op_token = op_token, |
| 4493 | .lhs = node, | 4517 | .lhs = node, |
| ... | @@ -4498,9 +4522,9 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -4498,9 +4522,9 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 4498 | } | 4522 | } |
| 4499 | }, | 4523 | }, |
| 4500 | .Shl => { | 4524 | .Shl => { |
| 4501 | const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<"); | 4525 | const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<"); |
| 4502 | const rhs = try parseCExpr(rp, it, source_loc, scope); | 4526 | const rhs = try parseCExpr(c, it, source_loc, scope); |
| 4503 | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); | 4527 | const bitshift_node = try c.a().create(ast.Node.InfixOp); |
| 4504 | bitshift_node.* = .{ | 4528 | bitshift_node.* = .{ |
| 4505 | .op_token = op_token, | 4529 | .op_token = op_token, |
| 4506 | .lhs = node, | 4530 | .lhs = node, |
| ... | @@ -4510,9 +4534,9 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -4510,9 +4534,9 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 4510 | node = &bitshift_node.base; | 4534 | node = &bitshift_node.base; |
| 4511 | }, | 4535 | }, |
| 4512 | .Pipe => { | 4536 | .Pipe => { |
| 4513 | const op_token = try appendToken(rp.c, .Pipe, "|"); | 4537 | const op_token = try appendToken(c, .Pipe, "|"); |
| 4514 | const rhs = try parseCExpr(rp, it, source_loc, scope); | 4538 | const rhs = try parseCExpr(c, it, source_loc, scope); |
| 4515 | const or_node = try rp.c.a().create(ast.Node.InfixOp); | 4539 | const or_node = try c.a().create(ast.Node.InfixOp); |
| 4516 | or_node.* = .{ | 4540 | or_node.* = .{ |
| 4517 | .op_token = op_token, | 4541 | .op_token = op_token, |
| 4518 | .lhs = node, | 4542 | .lhs = node, |
| ... | @@ -4522,29 +4546,65 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -4522,29 +4546,65 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 4522 | node = &or_node.base; | 4546 | node = &or_node.base; |
| 4523 | }, | 4547 | }, |
| 4524 | .LBrace => { | 4548 | .LBrace => { |
| 4525 | const arr_node = try transCreateNodeArrayAccess(rp.c, node); | 4549 | const arr_node = try transCreateNodeArrayAccess(c, node); |
| 4526 | arr_node.op.ArrayAccess = try parseCExpr(rp, it, source_loc, scope); | 4550 | arr_node.op.ArrayAccess = try parseCExpr(c, it, source_loc, scope); |
| 4527 | arr_node.rtoken = try appendToken(rp.c, .RBrace, "]"); | 4551 | arr_node.rtoken = try appendToken(c, .RBrace, "]"); |
| 4528 | node = &arr_node.base; | 4552 | node = &arr_node.base; |
| 4529 | if (it.next().?.id != .RBrace) | 4553 | if (it.next().?.id != .RBrace) { |
| | 4554 | try failDecl( |
| | 4555 | c, |
| | 4556 | source_loc, |
| | 4557 | it.list.at(0).*.bytes, |
| | 4558 | "unable to translate C expr: expected ']'", |
| | 4559 | .{}, |
| | 4560 | ); |
| 4530 | return error.ParseError; | 4561 | return error.ParseError; |
| | 4562 | } |
| 4531 | }, | 4563 | }, |
| 4532 | .LParen => { | 4564 | .LParen => { |
| 4533 | const call_node = try transCreateNodeFnCall(rp.c, node); | 4565 | const call_node = try transCreateNodeFnCall(c, node); |
| 4534 | while (true) { | 4566 | while (true) { |
| 4535 | const arg = try parseCExpr(rp, it, source_loc, scope); | 4567 | const arg = try parseCExpr(c, it, source_loc, scope); |
| 4536 | try call_node.op.Call.params.push(arg); | 4568 | try call_node.op.Call.params.push(arg); |
| 4537 | const next = it.next().?; | 4569 | const next = it.next().?; |
| 4538 | if (next.id == .Comma) | 4570 | if (next.id == .Comma) |
| 4539 | _ = try appendToken(rp.c, .Comma, ",") | 4571 | _ = try appendToken(c, .Comma, ",") |
| 4540 | else if (next.id == .RParen) | 4572 | else if (next.id == .RParen) |
| 4541 | break | 4573 | break |
| 4542 | else | 4574 | else { |
| | 4575 | try failDecl( |
| | 4576 | c, |
| | 4577 | source_loc, |
| | 4578 | it.list.at(0).*.bytes, |
| | 4579 | "unable to translate C expr: expected ',' or ')'", |
| | 4580 | .{}, |
| | 4581 | ); |
| 4543 | return error.ParseError; | 4582 | return error.ParseError; |
| | 4583 | } |
| 4544 | } | 4584 | } |
| 4545 | call_node.rtoken = try appendToken(rp.c, .RParen, ")"); | 4585 | call_node.rtoken = try appendToken(c, .RParen, ")"); |
| 4546 | node = &call_node.base; | 4586 | node = &call_node.base; |
| 4547 | }, | 4587 | }, |
| | 4588 | .QuestionMark => { |
| | 4589 | // must come immediately after expr |
| | 4590 | _ = try appendToken(c, .RParen, ")"); |
| | 4591 | const if_node = try transCreateNodeIf(c); |
| | 4592 | if_node.condition = node; |
| | 4593 | if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| | 4594 | if (it.next().?.id != .Colon) { |
| | 4595 | try failDecl( |
| | 4596 | c, |
| | 4597 | source_loc, |
| | 4598 | it.list.at(0).*.bytes, |
| | 4599 | "unable to translate C expr: expected ':'", |
| | 4600 | .{}, |
| | 4601 | ); |
| | 4602 | return error.ParseError; |
| | 4603 | } |
| | 4604 | if_node.@"else" = try transCreateNodeElse(c); |
| | 4605 | if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| | 4606 | node = &if_node.base; |
| | 4607 | }, |
| 4548 | else => { | 4608 | else => { |
| 4549 | _ = it.prev(); | 4609 | _ = it.prev(); |
| 4550 | return node; | 4610 | return node; |
| ... | @@ -4553,32 +4613,32 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -4553,32 +4613,32 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 4553 | } | 4613 | } |
| 4554 | } | 4614 | } |
| 4555 | | 4615 | |
| 4556 | fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { | 4616 | fn parseCPrefixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 4557 | const op_tok = it.next().?; | 4617 | const op_tok = it.next().?; |
| 4558 | | 4618 | |
| 4559 | switch (op_tok.id) { | 4619 | switch (op_tok.id) { |
| 4560 | .Bang => { | 4620 | .Bang => { |
| 4561 | const node = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!"); | 4621 | const node = try transCreateNodePrefixOp(c, .BoolNot, .Bang, "!"); |
| 4562 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc, scope); | 4622 | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4563 | return &node.base; | 4623 | return &node.base; |
| 4564 | }, | 4624 | }, |
| 4565 | .Minus => { | 4625 | .Minus => { |
| 4566 | const node = try transCreateNodePrefixOp(rp.c, .Negation, .Minus, "-"); | 4626 | const node = try transCreateNodePrefixOp(c, .Negation, .Minus, "-"); |
| 4567 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc, scope); | 4627 | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4568 | return &node.base; | 4628 | return &node.base; |
| 4569 | }, | 4629 | }, |
| 4570 | .Tilde => { | 4630 | .Tilde => { |
| 4571 | const node = try transCreateNodePrefixOp(rp.c, .BitNot, .Tilde, "~"); | 4631 | const node = try transCreateNodePrefixOp(c, .BitNot, .Tilde, "~"); |
| 4572 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc, scope); | 4632 | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4573 | return &node.base; | 4633 | return &node.base; |
| 4574 | }, | 4634 | }, |
| 4575 | .Asterisk => { | 4635 | .Asterisk => { |
| 4576 | const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope); | 4636 | const prefix_op_expr = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4577 | return try transCreateNodePtrDeref(rp.c, prefix_op_expr); | 4637 | return try transCreateNodePtrDeref(c, prefix_op_expr); |
| 4578 | }, | 4638 | }, |
| 4579 | else => { | 4639 | else => { |
| 4580 | _ = it.prev(); | 4640 | _ = it.prev(); |
| 4581 | return try parseCSuffixOpExpr(rp, it, source_loc, scope); | 4641 | return try parseCSuffixOpExpr(c, it, source_loc, scope); |
| 4582 | }, | 4642 | }, |
| 4583 | } | 4643 | } |
| 4584 | } | 4644 | } |