| ... | @@ -15,7 +15,7 @@ pub const Error = error{OutOfMemory}; | ... | @@ -15,7 +15,7 @@ pub const Error = error{OutOfMemory}; |
| 15 | const TypeError = Error || error{UnsupportedType}; | 15 | const TypeError = Error || error{UnsupportedType}; |
| 16 | const TransError = TypeError || error{UnsupportedTranslation}; | 16 | const TransError = TypeError || error{UnsupportedTranslation}; |
| 17 | | 17 | |
| 18 | const DeclTable = std.HashMap(usize, void, addrHash, addrEql); | 18 | const DeclTable = std.HashMap(usize, []const u8, addrHash, addrEql); |
| 19 | | 19 | |
| 20 | fn addrHash(x: usize) u32 { | 20 | fn addrHash(x: usize) u32 { |
| 21 | switch (@typeInfo(usize).Int.bits) { | 21 | switch (@typeInfo(usize).Int.bits) { |
| ... | @@ -109,6 +109,12 @@ const Context = struct { | ... | @@ -109,6 +109,12 @@ const Context = struct { |
| 109 | global_scope: *Scope.Root, | 109 | global_scope: *Scope.Root, |
| 110 | ptr_params: std.BufSet, | 110 | ptr_params: std.BufSet, |
| 111 | clang_context: *ZigClangASTContext, | 111 | clang_context: *ZigClangASTContext, |
| | 112 | mangle_count: u64 = 0, |
| | 113 | |
| | 114 | fn getMangle(c: *Context) u64 { |
| | 115 | c.mangle_count += 1; |
| | 116 | return c.mangle_count; |
| | 117 | } |
| 112 | | 118 | |
| 113 | fn a(c: *Context) *std.mem.Allocator { | 119 | fn a(c: *Context) *std.mem.Allocator { |
| 114 | return &c.tree.arena_allocator.allocator; | 120 | return &c.tree.arena_allocator.allocator; |
| ... | @@ -239,7 +245,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { | ... | @@ -239,7 +245,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { |
| 239 | return resolveTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl)); | 245 | return resolveTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl)); |
| 240 | }, | 246 | }, |
| 241 | .Enum => { | 247 | .Enum => { |
| 242 | try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for enums", .{}); | 248 | _ = try transEnumDecl(c, @ptrCast(*const ZigClangEnumDecl, decl)); |
| 243 | }, | 249 | }, |
| 244 | .Record => { | 250 | .Record => { |
| 245 | return resolveRecordDecl(c, @ptrCast(*const ZigClangRecordDecl, decl)); | 251 | return resolveRecordDecl(c, @ptrCast(*const ZigClangRecordDecl, decl)); |
| ... | @@ -255,9 +261,10 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { | ... | @@ -255,9 +261,10 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { |
| 255 | } | 261 | } |
| 256 | | 262 | |
| 257 | fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | 263 | fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 258 | if (try c.decl_table.put(@ptrToInt(fn_decl), {})) |_| return; // Avoid processing this decl twice | 264 | if (c.decl_table.contains(@ptrToInt(fn_decl))) return; // Avoid processing this decl twice |
| 259 | const rp = makeRestorePoint(c); | 265 | const rp = makeRestorePoint(c); |
| 260 | const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl))); | 266 | const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl))); |
| | 267 | _ = try c.decl_table.put(@ptrToInt(fn_decl), fn_name); |
| 261 | const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl); | 268 | const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl); |
| 262 | const fn_qt = ZigClangFunctionDecl_getType(fn_decl); | 269 | const fn_qt = ZigClangFunctionDecl_getType(fn_decl); |
| 263 | const fn_type = ZigClangQualType_getTypePtr(fn_qt); | 270 | const fn_type = ZigClangQualType_getTypePtr(fn_qt); |
| ... | @@ -319,7 +326,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -319,7 +326,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 319 | } | 326 | } |
| 320 | | 327 | |
| 321 | fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { | 328 | fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 322 | if (try c.decl_table.put(@ptrToInt(var_decl), {})) |_| return; // Avoid processing this decl twice | 329 | if (c.decl_table.contains(@ptrToInt(var_decl))) return; // Avoid processing this decl twice |
| 323 | const rp = makeRestorePoint(c); | 330 | const rp = makeRestorePoint(c); |
| 324 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); | 331 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 325 | | 332 | |
| ... | @@ -330,6 +337,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { | ... | @@ -330,6 +337,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 330 | | 337 | |
| 331 | var scope = &c.global_scope.base; | 338 | var scope = &c.global_scope.base; |
| 332 | const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl))); | 339 | const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl))); |
| | 340 | _ = try c.decl_table.put(@ptrToInt(var_decl), var_name); |
| 333 | const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); | 341 | const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); |
| 334 | | 342 | |
| 335 | const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); | 343 | const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); |
| ... | @@ -400,12 +408,15 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { | ... | @@ -400,12 +408,15 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 400 | } | 408 | } |
| 401 | | 409 | |
| 402 | fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void { | 410 | fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void { |
| 403 | if (try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), {})) |_| return; // Avoid processing this decl twice | 411 | if (c.decl_table.contains( |
| | 412 | @ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), |
| | 413 | )) return; // Avoid processing this decl twice |
| 404 | const rp = makeRestorePoint(c); | 414 | const rp = makeRestorePoint(c); |
| 405 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); | 415 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 406 | const const_tok = try appendToken(c, .Keyword_const, "const"); | 416 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 407 | | 417 | |
| 408 | const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl))); | 418 | const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl))); |
| | 419 | _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name); |
| 409 | const name_tok = try appendIdentifier(c, typedef_name); | 420 | const name_tok = try appendIdentifier(c, typedef_name); |
| 410 | const eq_tok = try appendToken(c, .Equal, "="); | 421 | const eq_tok = try appendToken(c, .Equal, "="); |
| 411 | | 422 | |
| ... | @@ -439,7 +450,7 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err | ... | @@ -439,7 +450,7 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err |
| 439 | } | 450 | } |
| 440 | | 451 | |
| 441 | fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!void { | 452 | fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!void { |
| 442 | if (try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), {})) |_| return; // Avoid processing this decl twice | 453 | if (c.decl_table.contains(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)))) return; // Avoid processing this decl twice |
| 443 | const rp = makeRestorePoint(c); | 454 | const rp = makeRestorePoint(c); |
| 444 | | 455 | |
| 445 | const bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, record_decl))); | 456 | const bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, record_decl))); |
| ... | @@ -449,7 +460,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! | ... | @@ -449,7 +460,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! |
| 449 | else if (ZigClangRecordDecl_isStruct(record_decl)) | 460 | else if (ZigClangRecordDecl_isStruct(record_decl)) |
| 450 | "struct" | 461 | "struct" |
| 451 | else | 462 | else |
| 452 | return failDecl(c, ZigClangRecordDecl_getLocation(record_decl), bare_name, "record {} is not a struct or union", .{bare_name}); | 463 | return emitWarning(c, ZigClangRecordDecl_getLocation(record_decl), "record {} is not a struct or union", .{bare_name}); |
| 453 | | 464 | |
| 454 | if (ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) or bare_name.len == 0) | 465 | if (ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) or bare_name.len == 0) |
| 455 | return; | 466 | return; |
| ... | @@ -458,6 +469,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! | ... | @@ -458,6 +469,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! |
| 458 | const const_tok = try appendToken(c, .Keyword_const, "const"); | 469 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 459 | | 470 | |
| 460 | const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name }); | 471 | const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name }); |
| | 472 | _ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name); |
| 461 | const name_tok = try appendIdentifier(c, name); | 473 | const name_tok = try appendIdentifier(c, name); |
| 462 | | 474 | |
| 463 | const eq_tok = try appendToken(c, .Equal, "="); | 475 | const eq_tok = try appendToken(c, .Equal, "="); |
| ... | @@ -1386,6 +1398,195 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro | ... | @@ -1386,6 +1398,195 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro |
| 1386 | return &container_node.base; | 1398 | return &container_node.base; |
| 1387 | } | 1399 | } |
| 1388 | | 1400 | |
| | 1401 | fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.Node { |
| | 1402 | if (c.decl_table.get(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)))) |name| |
| | 1403 | return try transCreateNodeIdentifier(c, name.value); // Avoid processing this decl twice |
| | 1404 | const rp = makeRestorePoint(c); |
| | 1405 | const enum_loc = ZigClangEnumDecl_getLocation(enum_decl); |
| | 1406 | |
| | 1407 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| | 1408 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| | 1409 | |
| | 1410 | var bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_decl))); |
| | 1411 | var is_unnamed = false; |
| | 1412 | if (bare_name.len == 0) { |
| | 1413 | bare_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()}); |
| | 1414 | is_unnamed = true; |
| | 1415 | } |
| | 1416 | |
| | 1417 | const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name}); |
| | 1418 | _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name); |
| | 1419 | const name_tok = try appendIdentifier(c, name); |
| | 1420 | const eq_tok = try appendToken(c, .Equal, "="); |
| | 1421 | |
| | 1422 | const init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: { |
| | 1423 | var pure_enum = true; |
| | 1424 | var it = ZigClangEnumDecl_enumerator_begin(enum_def); |
| | 1425 | var end_it = ZigClangEnumDecl_enumerator_end(enum_def); |
| | 1426 | while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) { |
| | 1427 | const enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it); |
| | 1428 | if (ZigClangEnumConstantDecl_getInitExpr(enum_const)) |_| { |
| | 1429 | pure_enum = false; |
| | 1430 | break; |
| | 1431 | } |
| | 1432 | } |
| | 1433 | |
| | 1434 | const extern_tok = try appendToken(c, .Keyword_extern, "extern"); |
| | 1435 | const container_tok = try appendToken(c, .Keyword_enum, "enum"); |
| | 1436 | |
| | 1437 | const container_node = try c.a().create(ast.Node.ContainerDecl); |
| | 1438 | container_node.* = .{ |
| | 1439 | .layout_token = extern_tok, |
| | 1440 | .kind_token = container_tok, |
| | 1441 | .init_arg_expr = .None, |
| | 1442 | .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(c.a()), |
| | 1443 | .lbrace_token = undefined, |
| | 1444 | .rbrace_token = undefined, |
| | 1445 | }; |
| | 1446 | |
| | 1447 | const int_type = ZigClangEnumDecl_getIntegerType(enum_decl); |
| | 1448 | |
| | 1449 | // TODO only emit this tag type if the enum tag type is not the default. |
| | 1450 | // I don't know what the default is, need to figure out how clang is deciding. |
| | 1451 | // it appears to at least be different across gcc/msvc |
| | 1452 | if (!isCBuiltinType(int_type, .UInt) and |
| | 1453 | !isCBuiltinType(int_type, .Int)) |
| | 1454 | { |
| | 1455 | _ = try appendToken(c, .LParen, "("); |
| | 1456 | container_node.init_arg_expr = .{ |
| | 1457 | .Type = transQualType(rp, int_type, enum_loc) catch |err| switch (err) { |
| | 1458 | error.UnsupportedType => { |
| | 1459 | if (is_unnamed) { |
| | 1460 | try emitWarning(c, enum_loc, "unable to translate enum tag type", .{}); |
| | 1461 | } else { |
| | 1462 | try failDecl(c, enum_loc, name, "unable to translate enum tag type", .{}); |
| | 1463 | } |
| | 1464 | return null; |
| | 1465 | }, |
| | 1466 | else => |e| return e, |
| | 1467 | }, |
| | 1468 | }; |
| | 1469 | _ = try appendToken(c, .RParen, ")"); |
| | 1470 | } |
| | 1471 | |
| | 1472 | container_node.lbrace_token = try appendToken(c, .LBrace, "{"); |
| | 1473 | |
| | 1474 | it = ZigClangEnumDecl_enumerator_begin(enum_def); |
| | 1475 | end_it = ZigClangEnumDecl_enumerator_end(enum_def); |
| | 1476 | while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) { |
| | 1477 | const enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it); |
| | 1478 | |
| | 1479 | const enum_val_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_const))); |
| | 1480 | |
| | 1481 | const field_name = if (!is_unnamed and std.mem.startsWith(u8, enum_val_name, bare_name)) |
| | 1482 | enum_val_name[bare_name.len..] |
| | 1483 | else |
| | 1484 | enum_val_name; |
| | 1485 | |
| | 1486 | const field_name_tok = try appendIdentifier(c, field_name); |
| | 1487 | |
| | 1488 | const int_node = if (!pure_enum) blk: { |
| | 1489 | _ = try appendToken(c, .Colon, "="); |
| | 1490 | break :blk try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const)); |
| | 1491 | } else |
| | 1492 | null; |
| | 1493 | |
| | 1494 | const field_node = try c.a().create(ast.Node.ContainerField); |
| | 1495 | field_node.* = .{ |
| | 1496 | .doc_comments = null, |
| | 1497 | .comptime_token = null, |
| | 1498 | .name_token = field_name_tok, |
| | 1499 | .type_expr = null, |
| | 1500 | .value_expr = int_node, |
| | 1501 | .align_expr = null, |
| | 1502 | }; |
| | 1503 | |
| | 1504 | try container_node.fields_and_decls.push(&field_node.base); |
| | 1505 | _ = try appendToken(c, .Comma, ","); |
| | 1506 | // In C each enum value is in the global namespace. So we put them there too. |
| | 1507 | // At this point we can rely on the enum emitting successfully. |
| | 1508 | try addEnumTopLevel(c, name, field_name, enum_val_name); |
| | 1509 | } |
| | 1510 | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); |
| | 1511 | |
| | 1512 | break :blk &container_node.base; |
| | 1513 | } else |
| | 1514 | try transCreateNodeOpaqueType(c); |
| | 1515 | |
| | 1516 | const semicolon_token = try appendToken(c, .Semicolon, ";"); |
| | 1517 | |
| | 1518 | const node = try c.a().create(ast.Node.VarDecl); |
| | 1519 | node.* = ast.Node.VarDecl{ |
| | 1520 | .visib_token = visib_tok, |
| | 1521 | .mut_token = const_tok, |
| | 1522 | .name_token = name_tok, |
| | 1523 | .eq_token = eq_tok, |
| | 1524 | .init_node = init_node, |
| | 1525 | .semicolon_token = semicolon_token, |
| | 1526 | .doc_comments = null, |
| | 1527 | .comptime_token = null, |
| | 1528 | .extern_export_token = null, |
| | 1529 | .thread_local_token = null, |
| | 1530 | .lib_name = null, |
| | 1531 | .type_node = null, |
| | 1532 | .align_node = null, |
| | 1533 | .section_node = null, |
| | 1534 | }; |
| | 1535 | |
| | 1536 | try addTopLevelDecl(c, name, &node.base); |
| | 1537 | if (!is_unnamed) |
| | 1538 | try c.alias_list.push(.{ .alias = bare_name, .name = name }); |
| | 1539 | return transCreateNodeIdentifier(c, name); |
| | 1540 | } |
| | 1541 | |
| | 1542 | fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, enum_val_name: []const u8) !void { |
| | 1543 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| | 1544 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| | 1545 | const name_tok = try appendIdentifier(c, enum_val_name); |
| | 1546 | const eq_tok = try appendToken(c, .Equal, "="); |
| | 1547 | |
| | 1548 | const enum_ident = try transCreateNodeIdentifier(c, enum_name); |
| | 1549 | const period_tok = try appendToken(c, .Period, "."); |
| | 1550 | const field_ident = try transCreateNodeIdentifier(c, field_name); |
| | 1551 | |
| | 1552 | const field_access_node = try c.a().create(ast.Node.InfixOp); |
| | 1553 | field_access_node.* = .{ |
| | 1554 | .op_token = period_tok, |
| | 1555 | .lhs = enum_ident, |
| | 1556 | .op = .Period, |
| | 1557 | .rhs = field_ident, |
| | 1558 | }; |
| | 1559 | const semicolon_token = try appendToken(c, .Semicolon, ";"); |
| | 1560 | |
| | 1561 | const node = try c.a().create(ast.Node.VarDecl); |
| | 1562 | node.* = ast.Node.VarDecl{ |
| | 1563 | .visib_token = visib_tok, |
| | 1564 | .mut_token = const_tok, |
| | 1565 | .name_token = name_tok, |
| | 1566 | .eq_token = eq_tok, |
| | 1567 | .init_node = &field_access_node.base, |
| | 1568 | .semicolon_token = semicolon_token, |
| | 1569 | .thread_local_token = null, |
| | 1570 | .doc_comments = null, |
| | 1571 | .comptime_token = null, |
| | 1572 | .extern_export_token = null, |
| | 1573 | .lib_name = null, |
| | 1574 | .type_node = null, |
| | 1575 | .align_node = null, |
| | 1576 | .section_node = null, |
| | 1577 | }; |
| | 1578 | |
| | 1579 | try addTopLevelDecl(c, field_name, &node.base); |
| | 1580 | } |
| | 1581 | |
| | 1582 | fn isCBuiltinType(qt: ZigClangQualType, kind: ZigClangBuiltinTypeKind) bool { |
| | 1583 | const c_type = qualTypeCanon(qt); |
| | 1584 | if (ZigClangType_getTypeClass(c_type) != .Builtin) |
| | 1585 | return false; |
| | 1586 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, c_type); |
| | 1587 | return ZigClangBuiltinType_getKind(builtin_ty) == kind; |
| | 1588 | } |
| | 1589 | |
| 1389 | fn qualTypeIsPtr(qt: ZigClangQualType) bool { | 1590 | fn qualTypeIsPtr(qt: ZigClangQualType) bool { |
| 1390 | return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer; | 1591 | return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer; |
| 1391 | } | 1592 | } |
| ... | @@ -1878,10 +2079,25 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -1878,10 +2079,25 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1878 | else | 2079 | else |
| 1879 | return transRecordDecl(rp.c, record_decl); | 2080 | return transRecordDecl(rp.c, record_decl); |
| 1880 | }, | 2081 | }, |
| | 2082 | .Enum => { |
| | 2083 | const enum_ty = @ptrCast(*const ZigClangEnumType, ty); |
| | 2084 | |
| | 2085 | const enum_decl = ZigClangEnumType_getDecl(enum_ty); |
| | 2086 | return (try transEnumDecl(rp.c, enum_decl)) orelse |
| | 2087 | revertAndWarn(rp, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{}); |
| | 2088 | }, |
| 1881 | .Elaborated => { | 2089 | .Elaborated => { |
| 1882 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); | 2090 | const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); |
| 1883 | return transQualType(rp, ZigClangElaboratedType_getNamedType(elaborated_ty), source_loc); | 2091 | return transQualType(rp, ZigClangElaboratedType_getNamedType(elaborated_ty), source_loc); |
| 1884 | }, | 2092 | }, |
| | 2093 | .Decayed => { |
| | 2094 | const decayed_ty = @ptrCast(*const ZigClangDecayedType, ty); |
| | 2095 | return transQualType(rp, ZigClangDecayedType_getDecayedType(decayed_ty), source_loc); |
| | 2096 | }, |
| | 2097 | .Attributed => { |
| | 2098 | const attributed_ty = @ptrCast(*const ZigClangAttributedType, ty); |
| | 2099 | return transQualType(rp, ZigClangAttributedType_getEquivalentType(attributed_ty), source_loc); |
| | 2100 | }, |
| 1885 | else => { | 2101 | else => { |
| 1886 | const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); | 2102 | const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); |
| 1887 | return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name}); | 2103 | return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name}); |
| ... | @@ -2193,8 +2409,19 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, | ... | @@ -2193,8 +2409,19 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, |
| 2193 | return token_index; | 2409 | return token_index; |
| 2194 | } | 2410 | } |
| 2195 | | 2411 | |
| | 2412 | fn isValidZigIdentifier(name: []const u8) bool { |
| | 2413 | for (name) |c, i| { |
| | 2414 | switch (c) { |
| | 2415 | '_', 'a'...'z', 'A'...'Z' => {}, |
| | 2416 | '0'...'9' => if (i == 0) return false, |
| | 2417 | else => return false, |
| | 2418 | } |
| | 2419 | } |
| | 2420 | return true; |
| | 2421 | } |
| | 2422 | |
| 2196 | fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex { | 2423 | fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex { |
| 2197 | if (std.zig.Token.getKeyword(name)) |_| { | 2424 | if (!isValidZigIdentifier(name) or std.zig.Token.getKeyword(name) != null) { |
| 2198 | return appendTokenFmt(c, .Identifier, "@\"{}\"", .{name}); | 2425 | return appendTokenFmt(c, .Identifier, "@\"{}\"", .{name}); |
| 2199 | } else { | 2426 | } else { |
| 2200 | return appendTokenFmt(c, .Identifier, "{}", .{name}); | 2427 | return appendTokenFmt(c, .Identifier, "{}", .{name}); |