diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index e640e3eadc..de3c538c4b 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -958,3 +958,5 @@ pub const ZigClangAPValue_ValueKind = extern enum { pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool; pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation; + +pub extern fn ZigClangReturnStmt_getRetValue(*const ZigClangReturnStmt) ?*const ZigClangExpr; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 7e05df4f56..7de834b4f0 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -334,6 +334,7 @@ fn transStmt( .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue), .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used), .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used), + .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)), else => { return revertAndWarn( rp, @@ -555,6 +556,24 @@ fn transIntegerLiteral( return maybeSuppressResult(rp, scope, result_used, res); } +fn transReturnStmt( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangReturnStmt, +) !TransResult { + const node = try transCreateNodeReturnExpr(rp.c); + if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| { + const ret_node = node.cast(ast.Node.ControlFlowExpression).?; + ret_node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node; + } + _ = try appendToken(rp.c, .Semicolon, ";"); + return TransResult{ + .node = node, + .child_scope = scope, + .node_scope = scope, + }; +} + fn transCCast( rp: RestorePoint, scope: *Scope, @@ -848,6 +867,18 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { return &node.base; } +fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { + const ltoken = try appendToken(c, .Keyword_return, "return"); + const node = try c.a().create(ast.Node.ControlFlowExpression); + node.* = ast.Node.ControlFlowExpression{ + .base = ast.Node{ .id = .ControlFlowExpression }, + .ltoken = ltoken, + .kind = .Return, + .rhs = null, + }; + return &node.base; +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 99b55dc59e..0d6361bac1 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -2017,3 +2017,8 @@ struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct Zi auto casted = reinterpret_cast(self); return bitcast(casted->getBeginLoc()); } + +const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getRetValue()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 6efdca89d8..6f691371b7 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -919,4 +919,6 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZIG_EXTERN_C bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *, struct ZigClangExprEvalResult *, const struct ZigClangASTContext *); ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *); + #endif