mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
parent
dbb5da14f4
commit
5f4c3e6557
@ -12,7 +12,7 @@ pub const struct_ZigClangCStyleCastExpr = @OpaqueType();
|
||||
pub const struct_ZigClangCallExpr = @OpaqueType();
|
||||
pub const struct_ZigClangCaseStmt = @OpaqueType();
|
||||
pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
|
||||
pub const struct_ZigClangCompoundStmt = @OpaqueType();
|
||||
pub const ZigClangCompoundStmt = @OpaqueType();
|
||||
pub const struct_ZigClangConditionalOperator = @OpaqueType();
|
||||
pub const struct_ZigClangConstantArrayType = @OpaqueType();
|
||||
pub const struct_ZigClangContinueStmt = @OpaqueType();
|
||||
@ -33,7 +33,7 @@ pub const struct_ZigClangFieldDecl = @OpaqueType();
|
||||
pub const struct_ZigClangFileID = @OpaqueType();
|
||||
pub const struct_ZigClangForStmt = @OpaqueType();
|
||||
pub const struct_ZigClangFullSourceLoc = @OpaqueType();
|
||||
pub const struct_ZigClangFunctionDecl = @OpaqueType();
|
||||
pub const ZigClangFunctionDecl = @OpaqueType();
|
||||
pub const struct_ZigClangFunctionProtoType = @OpaqueType();
|
||||
pub const struct_ZigClangIfStmt = @OpaqueType();
|
||||
pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
|
||||
@ -488,12 +488,12 @@ pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType
|
||||
pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
|
||||
pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
|
||||
pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;
|
||||
pub extern fn ZigClangStmt_getBeginLoc(self: ?*const struct_ZigClangStmt) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
|
||||
pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
|
||||
pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
|
||||
pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangExpr_getBeginLoc(self: ?*const struct_ZigClangExpr) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;
|
||||
pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
|
||||
pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
|
||||
@ -510,11 +510,12 @@ pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_
|
||||
pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
|
||||
pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void;
|
||||
|
||||
pub extern fn ZigClangFunctionDecl_getType(self: *const struct_ZigClangFunctionDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangFunctionDecl_getLocation(self: *const struct_ZigClangFunctionDecl) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangFunctionDecl_hasBody(self: *const struct_ZigClangFunctionDecl) bool;
|
||||
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const struct_ZigClangFunctionDecl) ZigClangStorageClass;
|
||||
pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const struct_ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
|
||||
pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
|
||||
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
|
||||
pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
|
||||
pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
|
||||
|
||||
pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
|
||||
|
||||
@ -543,7 +544,6 @@ pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr;
|
||||
pub const ZigClangCallExpr = struct_ZigClangCallExpr;
|
||||
pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
|
||||
pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
|
||||
pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt;
|
||||
pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
|
||||
pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
|
||||
pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
|
||||
@ -564,7 +564,6 @@ pub const ZigClangFieldDecl = struct_ZigClangFieldDecl;
|
||||
pub const ZigClangFileID = struct_ZigClangFileID;
|
||||
pub const ZigClangForStmt = struct_ZigClangForStmt;
|
||||
pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc;
|
||||
pub const ZigClangFunctionDecl = struct_ZigClangFunctionDecl;
|
||||
pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType;
|
||||
pub const ZigClangIfStmt = struct_ZigClangIfStmt;
|
||||
pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
|
||||
@ -860,3 +859,8 @@ pub const ZigClangStorageClass = extern enum {
|
||||
Auto,
|
||||
Register,
|
||||
};
|
||||
|
||||
pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangStmt;
|
||||
|
||||
pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
|
||||
pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const ast = std.zig.ast;
|
||||
const Token = std.zig.Token;
|
||||
use @import("clang.zig");
|
||||
@ -21,6 +22,10 @@ pub const Error = error{
|
||||
OutOfMemory,
|
||||
UnsupportedType,
|
||||
};
|
||||
pub const TransError = error{
|
||||
OutOfMemory,
|
||||
UnsupportedTranslation,
|
||||
};
|
||||
|
||||
const DeclTable = std.HashMap(usize, void, addrHash, addrEql);
|
||||
|
||||
@ -61,6 +66,27 @@ const Scope = struct {
|
||||
|
||||
const Block = struct {
|
||||
base: Scope,
|
||||
block_node: *ast.Node.Block,
|
||||
|
||||
/// Don't forget to set rbrace token later
|
||||
fn create(c: *Context, parent: *Scope, lbrace_tok: ast.TokenIndex) !*Block {
|
||||
const block = try c.a().create(Block);
|
||||
block.* = Block{
|
||||
.base = Scope{
|
||||
.id = Id.Block,
|
||||
.parent = parent,
|
||||
},
|
||||
.block_node = try c.a().create(ast.Node.Block),
|
||||
};
|
||||
block.block_node.* = ast.Node.Block{
|
||||
.base = ast.Node{ .id = ast.Node.Id.Block },
|
||||
.label = null,
|
||||
.lbrace = lbrace_tok,
|
||||
.statements = ast.Node.Block.StatementList.init(c.a()),
|
||||
.rbrace = undefined,
|
||||
};
|
||||
return block;
|
||||
}
|
||||
};
|
||||
|
||||
const Root = struct {
|
||||
@ -72,6 +98,12 @@ const Scope = struct {
|
||||
};
|
||||
};
|
||||
|
||||
const TransResult = struct {
|
||||
node: *ast.Node,
|
||||
node_scope: *Scope,
|
||||
child_scope: *Scope,
|
||||
};
|
||||
|
||||
const Context = struct {
|
||||
tree: *ast.Tree,
|
||||
source_buffer: *std.Buffer,
|
||||
@ -170,6 +202,14 @@ pub fn translate(
|
||||
|
||||
_ = try appendToken(&context, .Eof, "");
|
||||
tree.source = source_buffer.toOwnedSlice();
|
||||
if (false) {
|
||||
std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", tree.source);
|
||||
var i: usize = 0;
|
||||
while (i < tree.tokens.len) : (i += 1) {
|
||||
const token = tree.tokens.at(i);
|
||||
std.debug.warn("{}\n", token);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
@ -213,29 +253,107 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl);
|
||||
const fn_qt = ZigClangFunctionDecl_getType(fn_decl);
|
||||
const fn_type = ZigClangQualType_getTypePtr(fn_qt);
|
||||
var scope = &c.global_scope.base;
|
||||
const decl_ctx = FnDeclContext{
|
||||
.fn_name = fn_name,
|
||||
.has_body = ZigClangFunctionDecl_hasBody(fn_decl),
|
||||
.storage_class = ZigClangFunctionDecl_getStorageClass(fn_decl),
|
||||
.scope = &scope,
|
||||
};
|
||||
const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {
|
||||
.FunctionProto => transFnProto(
|
||||
rp,
|
||||
@ptrCast(*const ZigClangFunctionProtoType, fn_type),
|
||||
fn_decl_loc,
|
||||
fn_decl,
|
||||
fn_name,
|
||||
) catch |err| switch (err) {
|
||||
error.UnsupportedType => {
|
||||
return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
|
||||
},
|
||||
else => return err,
|
||||
.FunctionProto => blk: {
|
||||
const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type);
|
||||
break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) {
|
||||
error.UnsupportedType => {
|
||||
return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
|
||||
},
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
};
|
||||
},
|
||||
.FunctionNoProto => return failDecl(c, fn_decl_loc, fn_name, "TODO support functions with no prototype"),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
if (!ZigClangFunctionDecl_hasBody(fn_decl)) {
|
||||
if (!decl_ctx.has_body) {
|
||||
const semi_tok = try appendToken(c, .Semicolon, ";");
|
||||
return addTopLevelDecl(c, fn_name, &proto_node.base);
|
||||
}
|
||||
|
||||
try emitWarning(c, fn_decl_loc, "TODO implement function body translation");
|
||||
// actual function definition with body
|
||||
const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
|
||||
const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.UnsupportedTranslation => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function"),
|
||||
};
|
||||
assert(result.node.id == ast.Node.Id.Block);
|
||||
proto_node.body_node = result.node;
|
||||
|
||||
return addTopLevelDecl(c, fn_name, &proto_node.base);
|
||||
}
|
||||
|
||||
const ResultUsed = enum {
|
||||
used,
|
||||
unused,
|
||||
};
|
||||
|
||||
const LRValue = enum {
|
||||
l_value,
|
||||
r_value,
|
||||
};
|
||||
|
||||
fn transStmt(
|
||||
rp: RestorePoint,
|
||||
scope: *Scope,
|
||||
stmt: *const ZigClangStmt,
|
||||
result_used: ResultUsed,
|
||||
lrvalue: LRValue,
|
||||
) !TransResult {
|
||||
const sc = ZigClangStmt_getStmtClass(stmt);
|
||||
switch (sc) {
|
||||
.CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)),
|
||||
else => {
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
error.UnsupportedTranslation,
|
||||
ZigClangStmt_getBeginLoc(stmt),
|
||||
"TODO implement translation of stmt class {}",
|
||||
@tagName(sc),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn transCompoundStmtInline(
|
||||
rp: RestorePoint,
|
||||
parent_scope: *Scope,
|
||||
stmt: *const ZigClangCompoundStmt,
|
||||
block_node: *ast.Node.Block,
|
||||
) TransError!TransResult {
|
||||
var it = ZigClangCompoundStmt_body_begin(stmt);
|
||||
const end_it = ZigClangCompoundStmt_body_end(stmt);
|
||||
var scope = parent_scope;
|
||||
while (it != end_it) : (it += 1) {
|
||||
const result = try transStmt(rp, scope, it.*, .unused, .r_value);
|
||||
scope = result.child_scope;
|
||||
try block_node.statements.push(result.node);
|
||||
}
|
||||
return TransResult{
|
||||
.node = &block_node.base,
|
||||
.child_scope = scope,
|
||||
.node_scope = scope,
|
||||
};
|
||||
}
|
||||
|
||||
fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) !TransResult {
|
||||
const lbrace_tok = try appendToken(rp.c, .LBrace, "{");
|
||||
const block_scope = try Scope.Block.create(rp.c, scope, lbrace_tok);
|
||||
const inline_result = try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
|
||||
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
|
||||
return TransResult{
|
||||
.node = &block_scope.block_node.base,
|
||||
.node_scope = inline_result.node_scope,
|
||||
.child_scope = inline_result.child_scope,
|
||||
};
|
||||
}
|
||||
|
||||
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
|
||||
@ -299,7 +417,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
|
||||
},
|
||||
.FunctionProto => {
|
||||
const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
|
||||
const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null, null);
|
||||
const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null);
|
||||
return &fn_proto.base;
|
||||
},
|
||||
else => {
|
||||
@ -309,12 +427,18 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
|
||||
}
|
||||
}
|
||||
|
||||
const FnDeclContext = struct {
|
||||
fn_name: []const u8,
|
||||
has_body: bool,
|
||||
storage_class: ZigClangStorageClass,
|
||||
scope: **Scope,
|
||||
};
|
||||
|
||||
fn transFnProto(
|
||||
rp: RestorePoint,
|
||||
fn_proto_ty: *const ZigClangFunctionProtoType,
|
||||
source_loc: ZigClangSourceLocation,
|
||||
opt_fn_decl: ?*const ZigClangFunctionDecl,
|
||||
fn_name: ?[]const u8,
|
||||
fn_decl_context: ?FnDeclContext,
|
||||
) !*ast.Node.FnProto {
|
||||
const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty);
|
||||
const cc = switch (ZigClangFunctionType_getCallConv(fn_ty)) {
|
||||
@ -351,13 +475,11 @@ fn transFnProto(
|
||||
const pub_tok = try appendToken(rp.c, .Keyword_pub, "pub");
|
||||
const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;
|
||||
const is_export = exp: {
|
||||
const fn_decl = opt_fn_decl orelse break :exp false;
|
||||
const has_body = ZigClangFunctionDecl_hasBody(fn_decl);
|
||||
const storage_class = ZigClangFunctionDecl_getStorageClass(fn_decl);
|
||||
break :exp switch (storage_class) {
|
||||
const decl_ctx = fn_decl_context orelse break :exp false;
|
||||
break :exp switch (decl_ctx.storage_class) {
|
||||
.None => switch (rp.c.mode) {
|
||||
.import => false,
|
||||
.translate => has_body,
|
||||
.translate => decl_ctx.has_body,
|
||||
},
|
||||
.Extern, .Static => false,
|
||||
.PrivateExtern => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported storage class: private extern"),
|
||||
@ -372,7 +494,7 @@ fn transFnProto(
|
||||
else
|
||||
null;
|
||||
const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn");
|
||||
const name_tok = if (fn_name) |n| try appendToken(rp.c, .Identifier, "{}", n) else null;
|
||||
const name_tok = if (fn_decl_context) |ctx| try appendToken(rp.c, .Identifier, ctx.fn_name) else null;
|
||||
const lparen_tok = try appendToken(rp.c, .LParen, "(");
|
||||
const var_args_tok = if (is_var_args) try appendToken(rp.c, .Ellipsis3, "...") else null;
|
||||
const rparen_tok = try appendToken(rp.c, .RParen, ")");
|
||||
@ -390,7 +512,7 @@ fn transFnProto(
|
||||
try emitWarning(rp.c, source_loc, "unsupported function proto return type");
|
||||
return err;
|
||||
},
|
||||
else => return err,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -430,17 +552,17 @@ fn revertAndWarn(
|
||||
}
|
||||
|
||||
fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []const u8, args: ...) !void {
|
||||
_ = try appendToken(c, .LineComment, "// {}: warning: " ++ format, c.locStr(loc), args);
|
||||
_ = try appendTokenFmt(c, .LineComment, "// {}: warning: " ++ format, c.locStr(loc), args);
|
||||
}
|
||||
|
||||
fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: ...) !void {
|
||||
// const name = @compileError(msg);
|
||||
const const_tok = try appendToken(c, .Keyword_const, "const");
|
||||
const name_tok = try appendToken(c, .Identifier, "{}", name);
|
||||
const name_tok = try appendToken(c, .Identifier, name);
|
||||
const eq_tok = try appendToken(c, .Equal, "=");
|
||||
const builtin_tok = try appendToken(c, .Builtin, "@compileError");
|
||||
const lparen_tok = try appendToken(c, .LParen, "(");
|
||||
const msg_tok = try appendToken(c, .StringLiteral, "\"" ++ format ++ "\"", args);
|
||||
const msg_tok = try appendTokenFmt(c, .StringLiteral, "\"" ++ format ++ "\"", args);
|
||||
const rparen_tok = try appendToken(c, .RParen, ")");
|
||||
const semi_tok = try appendToken(c, .Semicolon, ";");
|
||||
|
||||
@ -480,16 +602,20 @@ fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime
|
||||
try c.tree.root_node.decls.push(&var_decl_node.base);
|
||||
}
|
||||
|
||||
fn appendToken(c: *Context, token_id: Token.Id, comptime format: []const u8, args: ...) !ast.TokenIndex {
|
||||
fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenIndex {
|
||||
return appendTokenFmt(c, token_id, "{}", bytes);
|
||||
}
|
||||
|
||||
fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: ...) !ast.TokenIndex {
|
||||
const S = struct {
|
||||
fn callback(context: *Context, bytes: []const u8) Error!void {
|
||||
fn callback(context: *Context, bytes: []const u8) error{OutOfMemory}!void {
|
||||
return context.source_buffer.append(bytes);
|
||||
}
|
||||
};
|
||||
const start_index = c.source_buffer.len();
|
||||
errdefer c.source_buffer.shrink(start_index);
|
||||
|
||||
try std.fmt.format(c, Error, S.callback, format, args);
|
||||
try std.fmt.format(c, error{OutOfMemory}, S.callback, format, args);
|
||||
const end_index = c.source_buffer.len();
|
||||
const token_index = c.tree.tokens.len;
|
||||
const new_token = try c.tree.tokens.addOne();
|
||||
@ -506,7 +632,7 @@ fn appendToken(c: *Context, token_id: Token.Id, comptime format: []const u8, arg
|
||||
}
|
||||
|
||||
fn appendIdentifier(c: *Context, name: []const u8) !*ast.Node {
|
||||
const token_index = try appendToken(c, .Identifier, "{}", name);
|
||||
const token_index = try appendToken(c, .Identifier, name);
|
||||
const identifier = try c.a().create(ast.Node.Identifier);
|
||||
identifier.* = ast.Node.Identifier{
|
||||
.base = ast.Node{ .id = ast.Node.Id.Identifier },
|
||||
|
||||
@ -1277,15 +1277,15 @@ static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceL
|
||||
return trans_type(c, ZigClangQualType_getTypePtr(qt), source_loc);
|
||||
}
|
||||
|
||||
static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang::CompoundStmt *stmt,
|
||||
static int trans_compound_stmt_inline(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
|
||||
AstNode *block_node, TransScope **out_node_scope)
|
||||
{
|
||||
assert(block_node->type == NodeTypeBlock);
|
||||
for (clang::CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end();
|
||||
it != end_it; ++it)
|
||||
for (ZigClangCompoundStmt_const_body_iterator it = ZigClangCompoundStmt_body_begin(stmt),
|
||||
end_it = ZigClangCompoundStmt_body_end(stmt); it != end_it; ++it)
|
||||
{
|
||||
AstNode *child_node;
|
||||
scope = trans_stmt(c, scope, bitcast(*it), &child_node);
|
||||
scope = trans_stmt(c, scope, *it, &child_node);
|
||||
if (scope == nullptr)
|
||||
return ErrorUnexpected;
|
||||
if (child_node != nullptr)
|
||||
@ -1297,7 +1297,7 @@ static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::CompoundStmt *stmt,
|
||||
static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
|
||||
TransScope **out_node_scope)
|
||||
{
|
||||
TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
|
||||
@ -1309,7 +1309,7 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::
|
||||
static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *scope,
|
||||
const clang::StmtExpr *stmt, TransScope **out_node_scope)
|
||||
{
|
||||
AstNode *block = trans_compound_stmt(c, scope, stmt->getSubStmt(), out_node_scope);
|
||||
AstNode *block = trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt->getSubStmt(), out_node_scope);
|
||||
if (block == nullptr)
|
||||
return block;
|
||||
assert(block->type == NodeTypeBlock);
|
||||
@ -3220,7 +3220,7 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl
|
||||
AstNode *body_node;
|
||||
const ZigClangStmt *body_stmt = bitcast(stmt->getBody());
|
||||
if (ZigClangStmt_getStmtClass(body_stmt) == ZigClangStmt_CompoundStmtClass) {
|
||||
if (trans_compound_stmt_inline(c, &switch_scope->base, (const clang::CompoundStmt *)body_stmt,
|
||||
if (trans_compound_stmt_inline(c, &switch_scope->base, (const ZigClangCompoundStmt *)body_stmt,
|
||||
block_scope->node, nullptr))
|
||||
{
|
||||
return nullptr;
|
||||
@ -3399,7 +3399,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *s
|
||||
trans_return_stmt(c, scope, (const clang::ReturnStmt *)stmt));
|
||||
case ZigClangStmt_CompoundStmtClass:
|
||||
return wrap_stmt(out_node, out_child_scope, scope,
|
||||
trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope));
|
||||
trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt, out_node_scope));
|
||||
case ZigClangStmt_IntegerLiteralClass:
|
||||
return wrap_stmt(out_node, out_child_scope, scope,
|
||||
trans_integer_literal(c, result_used, (const clang::IntegerLiteral *)stmt));
|
||||
|
||||
@ -1292,6 +1292,14 @@ static clang::APValue::LValueBase bitcast(ZigClangAPValueLValueBase src) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
static_assert(sizeof(ZigClangCompoundStmt_const_body_iterator) == sizeof(clang::CompoundStmt::const_body_iterator), "");
|
||||
static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::const_body_iterator src) {
|
||||
ZigClangCompoundStmt_const_body_iterator dest;
|
||||
memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangCompoundStmt_const_body_iterator));
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self,
|
||||
ZigClangSourceLocation Loc)
|
||||
{
|
||||
@ -1811,3 +1819,13 @@ struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigC
|
||||
auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self);
|
||||
return bitcast(casted->getParamType(index));
|
||||
}
|
||||
|
||||
ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self) {
|
||||
auto casted = reinterpret_cast<const clang::CompoundStmt *>(self);
|
||||
return bitcast(casted->body_begin());
|
||||
}
|
||||
|
||||
ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self) {
|
||||
auto casted = reinterpret_cast<const clang::CompoundStmt *>(self);
|
||||
return bitcast(casted->body_end());
|
||||
}
|
||||
|
||||
@ -102,6 +102,8 @@ struct ZigClangVarDecl;
|
||||
struct ZigClangWhileStmt;
|
||||
struct ZigClangFunctionType;
|
||||
|
||||
typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;
|
||||
|
||||
enum ZigClangBO {
|
||||
ZigClangBO_PtrMemD,
|
||||
ZigClangBO_PtrMemI,
|
||||
@ -820,4 +822,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionType_getReturnType(const st
|
||||
ZIG_EXTERN_C bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self);
|
||||
ZIG_EXTERN_C unsigned ZigClangFunctionProtoType_getNumParams(const struct ZigClangFunctionProtoType *self);
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigClangFunctionProtoType *self, unsigned i);
|
||||
|
||||
|
||||
ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self);
|
||||
ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self);
|
||||
|
||||
#endif
|
||||
|
||||
@ -11,6 +11,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub extern fn bar() c_int;
|
||||
);
|
||||
|
||||
cases.add_both("simple function definition",
|
||||
\\void foo(void) {};
|
||||
,
|
||||
\\pub export fn foo() void {}
|
||||
);
|
||||
|
||||
/////////////// Cases that pass for only stage2 ////////////////
|
||||
// (none)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user