| ... | @@ -272,7 +272,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -272,7 +272,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 272 | const proto_node = switch (ZigClangType_getTypeClass(fn_type)) { | 272 | const proto_node = switch (ZigClangType_getTypeClass(fn_type)) { |
| 273 | .FunctionProto => blk: { | 273 | .FunctionProto => blk: { |
| 274 | const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type); | 274 | const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type); |
| 275 | break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { | 275 | break :blk transFnProto(rp, fn_decl, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { |
| 276 | error.UnsupportedType => { | 276 | error.UnsupportedType => { |
| 277 | return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function", .{}); | 277 | return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function", .{}); |
| 278 | }, | 278 | }, |
| ... | @@ -1178,11 +1178,11 @@ fn transCreateNodePtrType( | ... | @@ -1178,11 +1178,11 @@ fn transCreateNodePtrType( |
| 1178 | break :blk lbracket; | 1178 | break :blk lbracket; |
| 1179 | }, | 1179 | }, |
| 1180 | .Identifier => blk: { | 1180 | .Identifier => blk: { |
| 1181 | _ = try appendToken(c, .LBracket, "["); | 1181 | const lbracket = try appendToken(c, .LBracket, "["); // Rendering checks if this token + 2 == .Identifier, so needs to return this token |
| 1182 | _ = try appendToken(c, .Asterisk, "*"); | 1182 | _ = try appendToken(c, .Asterisk, "*"); |
| 1183 | const c_ident = try appendToken(c, .Identifier, "c"); | 1183 | _ = try appendToken(c, .Identifier, "c"); |
| 1184 | _ = try appendToken(c, .RBracket, "]"); | 1184 | _ = try appendToken(c, .RBracket, "]"); |
| 1185 | break :blk c_ident; | 1185 | break :blk lbracket; |
| 1186 | }, | 1186 | }, |
| 1187 | .Asterisk => try appendToken(c, .Asterisk, "*"), | 1187 | .Asterisk => try appendToken(c, .Asterisk, "*"), |
| 1188 | else => unreachable, | 1188 | else => unreachable, |
| ... | @@ -1281,7 +1281,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -1281,7 +1281,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1281 | }, | 1281 | }, |
| 1282 | .FunctionProto => { | 1282 | .FunctionProto => { |
| 1283 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); | 1283 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| 1284 | const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null, false); | 1284 | const fn_proto = try transFnProto(rp, null, fn_proto_ty, source_loc, null, false); |
| 1285 | return &fn_proto.base; | 1285 | return &fn_proto.base; |
| 1286 | }, | 1286 | }, |
| 1287 | .Paren => { | 1287 | .Paren => { |
| ... | @@ -1352,6 +1352,7 @@ fn transCC( | ... | @@ -1352,6 +1352,7 @@ fn transCC( |
| 1352 | | 1352 | |
| 1353 | fn transFnProto( | 1353 | fn transFnProto( |
| 1354 | rp: RestorePoint, | 1354 | rp: RestorePoint, |
| | 1355 | fn_decl: ?*const ZigClangFunctionDecl, |
| 1355 | fn_proto_ty: *const ZigClangFunctionProtoType, | 1356 | fn_proto_ty: *const ZigClangFunctionProtoType, |
| 1356 | source_loc: ZigClangSourceLocation, | 1357 | source_loc: ZigClangSourceLocation, |
| 1357 | fn_decl_context: ?FnDeclContext, | 1358 | fn_decl_context: ?FnDeclContext, |
| ... | @@ -1360,19 +1361,7 @@ fn transFnProto( | ... | @@ -1360,19 +1361,7 @@ fn transFnProto( |
| 1360 | const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty); | 1361 | const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty); |
| 1361 | const cc = try transCC(rp, fn_ty, source_loc); | 1362 | const cc = try transCC(rp, fn_ty, source_loc); |
| 1362 | const is_var_args = ZigClangFunctionProtoType_isVariadic(fn_proto_ty); | 1363 | const is_var_args = ZigClangFunctionProtoType_isVariadic(fn_proto_ty); |
| 1363 | const param_count: usize = ZigClangFunctionProtoType_getNumParams(fn_proto_ty); | 1364 | return finishTransFnProto(rp, fn_decl, fn_proto_ty, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); |
| 1364 | var i: usize = 0; | | |
| 1365 | while (i < param_count) : (i += 1) { | | |
| 1366 | return revertAndWarn( | | |
| 1367 | rp, | | |
| 1368 | error.UnsupportedType, | | |
| 1369 | source_loc, | | |
| 1370 | "TODO: implement parameters for FunctionProto in transType", | | |
| 1371 | .{}, | | |
| 1372 | ); | | |
| 1373 | } | | |
| 1374 | | | |
| 1375 | return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); | | |
| 1376 | } | 1365 | } |
| 1377 | | 1366 | |
| 1378 | fn transFnNoProto( | 1367 | fn transFnNoProto( |
| ... | @@ -1384,11 +1373,13 @@ fn transFnNoProto( | ... | @@ -1384,11 +1373,13 @@ fn transFnNoProto( |
| 1384 | ) !*ast.Node.FnProto { | 1373 | ) !*ast.Node.FnProto { |
| 1385 | const cc = try transCC(rp, fn_ty, source_loc); | 1374 | const cc = try transCC(rp, fn_ty, source_loc); |
| 1386 | const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true; | 1375 | const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true; |
| 1387 | return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); | 1376 | return finishTransFnProto(rp, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); |
| 1388 | } | 1377 | } |
| 1389 | | 1378 | |
| 1390 | fn finishTransFnProto( | 1379 | fn finishTransFnProto( |
| 1391 | rp: RestorePoint, | 1380 | rp: RestorePoint, |
| | 1381 | fn_decl: ?*const ZigClangFunctionDecl, |
| | 1382 | fn_proto_ty: ?*const ZigClangFunctionProtoType, |
| 1392 | fn_ty: *const ZigClangFunctionType, | 1383 | fn_ty: *const ZigClangFunctionType, |
| 1393 | source_loc: ZigClangSourceLocation, | 1384 | source_loc: ZigClangSourceLocation, |
| 1394 | fn_decl_context: ?FnDeclContext, | 1385 | fn_decl_context: ?FnDeclContext, |
| ... | @@ -1414,7 +1405,67 @@ fn finishTransFnProto( | ... | @@ -1414,7 +1405,67 @@ fn finishTransFnProto( |
| 1414 | const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn"); | 1405 | const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn"); |
| 1415 | const name_tok = if (fn_decl_context) |ctx| try appendToken(rp.c, .Identifier, ctx.fn_name) else null; | 1406 | const name_tok = if (fn_decl_context) |ctx| try appendToken(rp.c, .Identifier, ctx.fn_name) else null; |
| 1416 | const lparen_tok = try appendToken(rp.c, .LParen, "("); | 1407 | const lparen_tok = try appendToken(rp.c, .LParen, "("); |
| 1417 | const var_args_tok = if (is_var_args) try appendToken(rp.c, .Ellipsis3, "...") else null; | 1408 | |
| | 1409 | var fn_params = ast.Node.FnProto.ParamList.init(rp.c.a()); |
| | 1410 | const param_count: usize = if (fn_proto_ty != null) ZigClangFunctionProtoType_getNumParams(fn_proto_ty.?) else 0; |
| | 1411 | |
| | 1412 | var i: usize = 0; |
| | 1413 | while (i < param_count) : (i += 1) { |
| | 1414 | const param_qt = ZigClangFunctionProtoType_getParamType(fn_proto_ty.?, @intCast(c_uint, i)); |
| | 1415 | |
| | 1416 | const noalias_tok = if (ZigClangQualType_isRestrictQualified(param_qt)) try appendToken(rp.c, .Keyword_noalias, "noalias") else null; |
| | 1417 | |
| | 1418 | const param_name_tok: ?ast.TokenIndex = blk: { |
| | 1419 | if (fn_decl != null) { |
| | 1420 | const param = ZigClangFunctionDecl_getParamDecl(fn_decl.?, @intCast(c_uint, i)); |
| | 1421 | const param_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param))); |
| | 1422 | if (param_name.len > 0) { |
| | 1423 | // TODO: If len == 0, auto-generate arg1, arg2, etc? Or leave the name blank? |
| | 1424 | const result = try appendToken(rp.c, .Identifier, param_name); |
| | 1425 | _ = try appendToken(rp.c, .Colon, ":"); |
| | 1426 | break :blk result; |
| | 1427 | } |
| | 1428 | } |
| | 1429 | break :blk null; |
| | 1430 | }; |
| | 1431 | |
| | 1432 | const type_node = try transQualType(rp, param_qt, source_loc); |
| | 1433 | |
| | 1434 | const param_node = try rp.c.a().create(ast.Node.ParamDecl); |
| | 1435 | param_node.* = ast.Node.ParamDecl{ |
| | 1436 | .base = ast.Node{ .id = ast.Node.Id.ParamDecl }, |
| | 1437 | .doc_comments = null, |
| | 1438 | .comptime_token = null, |
| | 1439 | .noalias_token = noalias_tok, |
| | 1440 | .name_token = param_name_tok, |
| | 1441 | .type_node = type_node, |
| | 1442 | .var_args_token = null, |
| | 1443 | }; |
| | 1444 | try fn_params.push(&param_node.base); |
| | 1445 | |
| | 1446 | if (i + 1 < param_count) { |
| | 1447 | _ = try appendToken(rp.c, .Comma, ","); |
| | 1448 | } |
| | 1449 | } |
| | 1450 | |
| | 1451 | if (is_var_args) { |
| | 1452 | if (param_count > 0) { |
| | 1453 | _ = try appendToken(rp.c, .Comma, ","); |
| | 1454 | } |
| | 1455 | |
| | 1456 | const var_arg_node = try rp.c.a().create(ast.Node.ParamDecl); |
| | 1457 | var_arg_node.* = ast.Node.ParamDecl{ |
| | 1458 | .base = ast.Node{ .id = ast.Node.Id.ParamDecl }, |
| | 1459 | .doc_comments = null, |
| | 1460 | .comptime_token = null, |
| | 1461 | .noalias_token = null, |
| | 1462 | .name_token = null, |
| | 1463 | .type_node = undefined, // Note: Accessing this causes an access violation. Need to check .var_args_token first before trying this field |
| | 1464 | .var_args_token = try appendToken(rp.c, .Ellipsis3, "..."), |
| | 1465 | }; |
| | 1466 | try fn_params.push(&var_arg_node.base); |
| | 1467 | } |
| | 1468 | |
| 1418 | const rparen_tok = try appendToken(rp.c, .RParen, ")"); | 1469 | const rparen_tok = try appendToken(rp.c, .RParen, ")"); |
| 1419 | | 1470 | |
| 1420 | const return_type_node = blk: { | 1471 | const return_type_node = blk: { |
| ... | @@ -1443,7 +1494,7 @@ fn finishTransFnProto( | ... | @@ -1443,7 +1494,7 @@ fn finishTransFnProto( |
| 1443 | .visib_token = pub_tok, | 1494 | .visib_token = pub_tok, |
| 1444 | .fn_token = fn_tok, | 1495 | .fn_token = fn_tok, |
| 1445 | .name_token = name_tok, | 1496 | .name_token = name_tok, |
| 1446 | .params = ast.Node.FnProto.ParamList.init(rp.c.a()), | 1497 | .params = fn_params, |
| 1447 | .return_type = ast.Node.FnProto.ReturnType{ .Explicit = return_type_node }, | 1498 | .return_type = ast.Node.FnProto.ReturnType{ .Explicit = return_type_node }, |
| 1448 | .var_args_token = null, // TODO this field is broken in the AST data model | 1499 | .var_args_token = null, // TODO this field is broken in the AST data model |
| 1449 | .extern_export_inline_token = extern_export_inline_tok, | 1500 | .extern_export_inline_token = extern_export_inline_tok, |
| ... | @@ -1453,19 +1504,6 @@ fn finishTransFnProto( | ... | @@ -1453,19 +1504,6 @@ fn finishTransFnProto( |
| 1453 | .align_expr = null, | 1504 | .align_expr = null, |
| 1454 | .section_expr = null, | 1505 | .section_expr = null, |
| 1455 | }; | 1506 | }; |
| 1456 | if (is_var_args) { | | |
| 1457 | const var_arg_node = try rp.c.a().create(ast.Node.ParamDecl); | | |
| 1458 | var_arg_node.* = ast.Node.ParamDecl{ | | |
| 1459 | .base = ast.Node{ .id = ast.Node.Id.ParamDecl }, | | |
| 1460 | .doc_comments = null, | | |
| 1461 | .comptime_token = null, | | |
| 1462 | .noalias_token = null, | | |
| 1463 | .name_token = null, | | |
| 1464 | .type_node = undefined, | | |
| 1465 | .var_args_token = var_args_tok, | | |
| 1466 | }; | | |
| 1467 | try fn_proto.params.push(&var_arg_node.base); | | |
| 1468 | } | | |
| 1469 | return fn_proto; | 1507 | return fn_proto; |
| 1470 | } | 1508 | } |
| 1471 | | 1509 | |