| ... | ... | @@ -322,7 +322,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 322 | 322 | |
| 323 | 323 | var var_node = try transCreateNodeVarDecl(c, true, is_extern, is_const, var_name); |
| 324 | 324 | |
| 325 | | _= try appendToken(rp.c, .Colon, ":"); |
| 325 | _ = try appendToken(rp.c, .Colon, ":"); |
| 326 | 326 | var_node.type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) { |
| 327 | 327 | error.UnsupportedType => { |
| 328 | 328 | return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{}); |
| ... | ... | @@ -634,15 +634,8 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe |
| 634 | 634 | const eq_token = try appendToken(c, .Equal, "="); |
| 635 | 635 | const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| |
| 636 | 636 | (try transExpr(rp, scope, expr, .used, .r_value)).node |
| 637 | | else blk: { |
| 638 | | const undefined_token = try appendToken(c, .Keyword_undefined, "undefined"); |
| 639 | | const undefined_node = try rp.c.a().create(ast.Node.UndefinedLiteral); |
| 640 | | undefined_node.* = ast.Node.UndefinedLiteral{ |
| 641 | | .base = ast.Node{ .id = .UndefinedLiteral }, |
| 642 | | .token = undefined_token, |
| 643 | | }; |
| 644 | | break :blk &undefined_node.base; |
| 645 | | }; |
| 637 | else |
| 638 | try transCreateNodeUndefinedLiteral(rp.c); |
| 646 | 639 | const semicolon_token = try appendToken(c, .Semicolon, ";"); |
| 647 | 640 | |
| 648 | 641 | const node = try c.a().create(ast.Node.VarDecl); |
| ... | ... | @@ -1288,6 +1281,20 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node { |
| 1288 | 1281 | return &node.base; |
| 1289 | 1282 | } |
| 1290 | 1283 | |
| 1284 | fn transCreateNodeArrayInitializer(c: *Context, type_node: *ast.Node) !*ast.Node.SuffixOp { |
| 1285 | _ = try appendToken(c, .LBrace, "{"); |
| 1286 | const node = try c.a().create(ast.Node.SuffixOp); |
| 1287 | node.* = ast.Node.SuffixOp{ |
| 1288 | .base = ast.Node{ .id = .SuffixOp }, |
| 1289 | .lhs = .{ .node = type_node }, |
| 1290 | .op = .{ |
| 1291 | .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()), |
| 1292 | }, |
| 1293 | .rtoken = undefined, // set after appending values |
| 1294 | }; |
| 1295 | return node; |
| 1296 | } |
| 1297 | |
| 1291 | 1298 | fn transCreateNodeVarDecl( |
| 1292 | 1299 | c: *Context, |
| 1293 | 1300 | is_pub: bool, |
| ... | ... | @@ -1333,6 +1340,16 @@ fn transCreateNodeVarDecl( |
| 1333 | 1340 | return node; |
| 1334 | 1341 | } |
| 1335 | 1342 | |
| 1343 | fn transCreateNodeInt(c: *Context, int: var) !*ast.Node { |
| 1344 | const token = try appendToken(c, .IntegerLiteral, try std.fmt.allocPrint(c.a(), "{}", .{int})); |
| 1345 | const node = try c.a().create(ast.Node.IntegerLiteral); |
| 1346 | node.* = ast.Node.IntegerLiteral{ |
| 1347 | .base = ast.Node{ .id = .IntegerLiteral }, |
| 1348 | .token = token, |
| 1349 | }; |
| 1350 | return &node.base; |
| 1351 | } |
| 1352 | |
| 1336 | 1353 | const RestorePoint = struct { |
| 1337 | 1354 | c: *Context, |
| 1338 | 1355 | token_index: ast.TokenIndex, |
| ... | ... | @@ -1416,6 +1433,27 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1416 | 1433 | pointer_node.rhs = try transQualType(rp, child_qt, source_loc); |
| 1417 | 1434 | return &pointer_node.base; |
| 1418 | 1435 | }, |
| 1436 | .ConstantArray => { |
| 1437 | const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty); |
| 1438 | |
| 1439 | const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty); |
| 1440 | const size = ZigClangAPInt_getLimitedValue(size_ap_int, std.math.maxInt(usize)); |
| 1441 | var node = try transCreateNodePrefixOp( |
| 1442 | rp.c, |
| 1443 | .{ |
| 1444 | .ArrayType = .{ |
| 1445 | .len_expr = undefined, |
| 1446 | .sentinel = null, |
| 1447 | }, |
| 1448 | }, |
| 1449 | .LBracket, |
| 1450 | "[", |
| 1451 | ); |
| 1452 | node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, size); |
| 1453 | _ = try appendToken(rp.c, .RBracket, "]"); |
| 1454 | node.rhs = try transQualType(rp, ZigClangConstantArrayType_getElementType(const_arr_ty), source_loc); |
| 1455 | return &node.base; |
| 1456 | }, |
| 1419 | 1457 | else => { |
| 1420 | 1458 | const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); |
| 1421 | 1459 | return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name}); |
| ... | ... | @@ -1423,14 +1461,92 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1423 | 1461 | } |
| 1424 | 1462 | } |
| 1425 | 1463 | |
| 1426 | | fn transApValue(rp: RestorePoint, ap_value: *const ZigClangAPValue, qual_type: ZigClangQualType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { |
| 1427 | | return revertAndWarn( |
| 1428 | | rp, |
| 1429 | | error.UnsupportedTranslation, |
| 1430 | | source_loc, |
| 1431 | | "TODO implement translation of ap value", |
| 1432 | | .{}, |
| 1433 | | ); |
| 1464 | fn transApValue(rp: RestorePoint, ap_value: *const ZigClangAPValue, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { |
| 1465 | switch (ZigClangAPValue_getKind(ap_value)) { |
| 1466 | .None => return transCreateNodeUndefinedLiteral(rp.c), |
| 1467 | .Int => return transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(ap_value)), |
| 1468 | .Array => { |
| 1469 | // TODO evaluateValue is null for Array init for some reason |
| 1470 | // TODO use anon literals once they work properly |
| 1471 | const init_count = ZigClangAPValue_getArrayInitializedElts(ap_value); |
| 1472 | const all_count = ZigClangAPValue_getArraySize(ap_value); |
| 1473 | const leftover_count = all_count - init_count; |
| 1474 | const qt_type = ZigClangQualType_getTypePtr(qt); |
| 1475 | const child_qt = ZigClangArrayType_getElementType(ZigClangType_getAsArrayTypeUnsafe(qt_type)); |
| 1476 | |
| 1477 | var init_node: *ast.Node.SuffixOp = undefined; |
| 1478 | var cat_tok: ast.TokenIndex = undefined; |
| 1479 | if (init_count != 0) { |
| 1480 | var type_node = try transQualType(rp, qt, source_loc); |
| 1481 | init_node = try transCreateNodeArrayInitializer(rp.c, type_node); |
| 1482 | var i: c_uint = 0; |
| 1483 | while (i < init_count) : (i += 1) { |
| 1484 | const elem_ap_val = ZigClangAPValue_getArrayInitializedElt(ap_value, i); |
| 1485 | try init_node.op.ArrayInitializer.push(try transApValue(rp, elem_ap_val, child_qt, source_loc)); |
| 1486 | _ = try appendToken(rp.c, .Comma, ","); |
| 1487 | } |
| 1488 | init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); |
| 1489 | if (leftover_count == 0) { |
| 1490 | return &init_node.base; |
| 1491 | } |
| 1492 | cat_tok = try appendToken(rp.c, .PlusPlus, "++"); |
| 1493 | } |
| 1494 | |
| 1495 | var filler_type_node = try transQualType(rp, qt, source_loc); |
| 1496 | var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node); |
| 1497 | const filler_ap_val = ZigClangAPValue_getArrayFiller(ap_value); |
| 1498 | try filler_init_node.op.ArrayInitializer.push(try transApValue(rp, filler_ap_val, child_qt, source_loc)); |
| 1499 | filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); |
| 1500 | |
| 1501 | const rhs_node = if (leftover_count == 1) |
| 1502 | &filler_init_node.base |
| 1503 | else blk: { |
| 1504 | const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**"); |
| 1505 | const mul_node = try rp.c.a().create(ast.Node.InfixOp); |
| 1506 | mul_node.* = .{ |
| 1507 | .base = .{ .id = .InfixOp }, |
| 1508 | .op_token = mul_tok, |
| 1509 | .lhs = &filler_init_node.base, |
| 1510 | .op = .ArrayMult, |
| 1511 | .rhs = try transCreateNodeInt(rp.c, leftover_count), |
| 1512 | }; |
| 1513 | break :blk &mul_node.base; |
| 1514 | }; |
| 1515 | |
| 1516 | if (init_count == 0) { |
| 1517 | return rhs_node; |
| 1518 | } |
| 1519 | |
| 1520 | const cat_node = try rp.c.a().create(ast.Node.InfixOp); |
| 1521 | cat_node.* = .{ |
| 1522 | .base = .{ .id = .InfixOp }, |
| 1523 | .op_token = cat_tok, |
| 1524 | .lhs = &init_node.base, |
| 1525 | .op = .ArrayCat, |
| 1526 | .rhs = rhs_node, |
| 1527 | }; |
| 1528 | return &cat_node.base; |
| 1529 | }, |
| 1530 | .LValue => { |
| 1531 | const lval_base = ZigClangAPValue_getLValueBase(ap_value); |
| 1532 | const expr = ZigClangAPValueLValueBase_dyn_cast_Expr(lval_base); |
| 1533 | if (expr) |e| { |
| 1534 | return (try transExpr(rp, &rp.c.global_scope.base, e, .used, .r_value)).node; |
| 1535 | } |
| 1536 | try emitWarning(rp.c, source_loc, "TODO handle initializer LValue ValueDecl", .{}); |
| 1537 | }, |
| 1538 | .Float => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Float", .{}), |
| 1539 | .ComplexInt => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: ComplexInt", .{}), |
| 1540 | .ComplexFloat => try emitWarning(rp.c, source_loc, "Tunsupported initializer value kind: ComplexFloat", .{}), |
| 1541 | .Vector => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Vector", .{}), |
| 1542 | .Struct => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Struct", .{}), |
| 1543 | .Union => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Union", .{}), |
| 1544 | .MemberPointer => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: MemberPointer", .{}), |
| 1545 | .AddrLabelDiff => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: AddrLabelDiff", .{}), |
| 1546 | .Indeterminate => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Indeterminate", .{}), |
| 1547 | .FixedPoint => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: FixedPoint", .{}), |
| 1548 | } |
| 1549 | return error.UnsupportedTranslation; |
| 1434 | 1550 | } |
| 1435 | 1551 | |
| 1436 | 1552 | const FnDeclContext = struct { |