aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/translate_c.zig54
1 files changed, 50 insertions, 4 deletions
diff --git a/src/translate_c.zig b/src/translate_c.zig
index e57a1952af..1a398ffe13 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -328,6 +328,47 @@ pub const Context = struct {
}
};
+fn addCBuiltinsNamespace(c: *Context) Error!void {
+ // pub usingnamespace @import("std").c.builtins;
+ const pub_tok = try appendToken(c, .Keyword_pub, "pub");
+ const use_tok = try appendToken(c, .Keyword_usingnamespace, "usingnamespace");
+ const import_tok = try appendToken(c, .Builtin, "@import");
+ const lparen_tok = try appendToken(c, .LParen, "(");
+ const std_tok = try appendToken(c, .StringLiteral, "\"std\"");
+ const rparen_tok = try appendToken(c, .RParen, ")");
+
+ const std_node = try c.arena.create(ast.Node.OneToken);
+ std_node.* = .{
+ .base = .{ .tag = .StringLiteral },
+ .token = std_tok,
+ };
+
+ const call_node = try ast.Node.BuiltinCall.alloc(c.arena, 1);
+ call_node.* = .{
+ .builtin_token = import_tok,
+ .params_len = 1,
+ .rparen_token = rparen_tok,
+ };
+ call_node.params()[0] = &std_node.base;
+
+ var access_chain = &call_node.base;
+ access_chain = try transCreateNodeFieldAccess(c, access_chain, "c");
+ access_chain = try transCreateNodeFieldAccess(c, access_chain, "builtins");
+
+ const semi_tok = try appendToken(c, .Semicolon, ";");
+
+ const bytes = try c.gpa.alignedAlloc(u8, @alignOf(ast.Node.Use), @sizeOf(ast.Node.Use));
+ const using_node = @ptrCast(*ast.Node.Use, bytes.ptr);
+ using_node.* = .{
+ .doc_comments = null,
+ .visib_token = pub_tok,
+ .use_token = use_tok,
+ .expr = access_chain,
+ .semicolon_token = semi_tok,
+ };
+ try c.root_decls.append(c.gpa, &using_node.base);
+}
+
pub fn translate(
gpa: *mem.Allocator,
args_begin: [*]?[*]const u8,
@@ -377,6 +418,8 @@ pub fn translate(
context.opaque_demotes.deinit(gpa);
}
+ try addCBuiltinsNamespace(&context);
+
try prepopulateGlobalNameTable(ast_unit, &context);
if (!ast_unit.visitLocalTopLevelDecls(&context, declVisitorC)) {
@@ -1726,6 +1769,9 @@ fn transImplicitCastExpr(
const rhs_node = try transCreateNodeInt(rp.c, 0);
return transCreateNodeInfixOp(rp, scope, sub_expr_node, .BangEqual, op_token, rhs_node, result_used, false);
},
+ .BuiltinFnToFnPtr => {
+ return transExpr(rp, scope, sub_expr, .used, .r_value);
+ },
else => |kind| return revertAndWarn(
rp,
error.UnsupportedTranslation,
@@ -2028,7 +2074,6 @@ fn transCCast(
// 1. If src_type is an enum, determine the underlying signed int type
// 2. Extend or truncate without changing signed-ness.
// 3. Bit-cast to correct signed-ness
-
const src_type_is_signed = cIsSignedInteger(src_type) or cIsEnum(src_type);
const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type);
const src_int_expr = if (cIsInteger(src_type)) expr else try transEnumToInt(rp.c, expr);
@@ -3048,8 +3093,9 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const clang.CallExpr, r
const fn_expr = if (is_ptr and fn_ty != null) blk: {
if (callee.getStmtClass() == .ImplicitCastExprClass) {
const implicit_cast = @ptrCast(*const clang.ImplicitCastExpr, callee);
-
- if (implicit_cast.getCastKind() == .FunctionToPointerDecay) {
+ const cast_kind = implicit_cast.getCastKind();
+ if (cast_kind == .BuiltinFnToFnPtr) break :blk raw_fn_expr;
+ if (cast_kind == .FunctionToPointerDecay) {
const subexpr = implicit_cast.getSubExpr();
if (subexpr.getStmtClass() == .DeclRefExprClass) {
const decl_ref = @ptrCast(*const clang.DeclRefExpr, subexpr);
@@ -5881,7 +5927,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*
return error.ParseError;
}
- const ident_token = try appendTokenFmt(c, .Identifier, "{}_{}", .{slice, m.slice()});
+ const ident_token = try appendTokenFmt(c, .Identifier, "{}_{}", .{ slice, m.slice() });
const identifier = try c.arena.create(ast.Node.OneToken);
identifier.* = .{
.base = .{ .tag = .Identifier },