diff options
| author | Vexu <git@vexu.eu> | 2019-12-12 16:12:19 +0200 |
|---|---|---|
| committer | Vexu <git@vexu.eu> | 2019-12-12 16:12:19 +0200 |
| commit | ef361161e2d6e5d23ee7e8d0fc924e16cf691173 (patch) | |
| tree | 18de59d65bb8657559c15ffacea30eaca9eaeee5 | |
| parent | 69dee57d95271169898f8382f7e4846bf77a0040 (diff) | |
| download | zig-ef361161e2d6e5d23ee7e8d0fc924e16cf691173.tar.gz zig-ef361161e2d6e5d23ee7e8d0fc924e16cf691173.zip | |
translate-c-2 add var decl
| -rw-r--r-- | src-self-hosted/clang.zig | 5 | ||||
| -rw-r--r-- | src-self-hosted/translate_c.zig | 120 |
2 files changed, 124 insertions, 1 deletions
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 1c8c0928b3..3b498ffdab 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -916,6 +916,10 @@ pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl; pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator; pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator; +pub extern fn ZigClangVarDecl_getLocation(self: *const struct_ZigClangVarDecl) ZigClangSourceLocation; +pub extern fn ZigClangVarDecl_hasExternalStorage(self: *const struct_ZigClangVarDecl) bool; +pub extern fn ZigClangVarDecl_isFileVarDecl(self: *const struct_ZigClangVarDecl) bool; +pub extern fn ZigClangVarDecl_hasInit(self: *const struct_ZigClangVarDecl) bool; pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType; pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr; pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind; @@ -953,6 +957,7 @@ pub const struct_ZigClangExprEvalResult = extern struct { Val: ZigClangAPValue, }; +pub extern fn ZigClangVarDecl_evaluateValue(self: *const struct_ZigClangVarDecl) ?*const ZigClangAPValue; pub const struct_ZigClangAPValue = extern struct { Kind: ZigClangAPValueKind, Data: if (builtin.os == .windows and builtin.abi == .msvc) [52]u8 else [68]u8, diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index d4a783634c..e370678dac 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -229,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{}); }, .Var => { - try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for variables", .{}); + return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl)); }, else => { const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl)); @@ -302,6 +302,59 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { return addTopLevelDecl(c, fn_name, &proto_node.base); } +fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { + if (try c.decl_table.put(@ptrToInt(var_decl), {})) |_| return; // Avoid processing this decl twice + const rp = makeRestorePoint(c); + var scope = &c.global_scope.base; + const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl))); + const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); + + switch (ZigClangVarDecl_getTLSKind(var_decl)) { + .None => {}, + .Static => return failDecl(c, var_decl_loc, var_name, "static thread local storage not supported", .{}), + .Dynamic => return failDecl(c, var_decl_loc, var_name, "dynamic thread local storag not supported", .{}), + } + + const qual_type = ZigClangVarDecl_getType(var_decl); + const is_extern = ZigClangVarDecl_hasExternalStorage(var_decl); + const is_static = ZigClangVarDecl_isFileVarDecl(var_decl); + const is_const = ZigClangQualType_isConstQualified(qual_type); + + var var_node = try transCreateNodeVarDecl(c, true, is_extern, is_const, var_name); + + const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) { + error.UnsupportedType => { + return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{}); + }, + error.OutOfMemory => |e| return e, + }; + + if (is_static and !is_extern) { + const eq_tok = try appendToken(c, .Equal, "="); + const init_node = if (ZigClangVarDecl_hasInit(var_decl)) blk: { + const ap_value = ZigClangVarDecl_evaluateValue(var_decl) orelse + return failDecl(c, var_decl_loc, var_name, "unable to evaluate initializer", .{}); + break :blk transApValue(rp, ap_value, qual_type, var_decl_loc) catch |err| switch (err) { + error.UnsupportedTranslation, + error.UnsupportedType, => { + return failDecl(c, var_decl_loc, var_name, "unable to evaluate initializer", .{}); + }, + error.OutOfMemory => |e| return e, + }; + } else + try transCreateNodeUndefinedLiteral(c); + var_node.eq_token = eq_tok; + var_node.init_node = init_node; + } + + if (!is_extern) { + return failDecl(c, var_decl_loc, var_name, "non-extern, non-static variable not supported", .{}); + } + + var_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); + return addTopLevelDecl(c, var_name, &var_node.base); +} + const ResultUsed = enum { used, unused, @@ -1225,6 +1278,61 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { return &node.base; } +fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node { + const token = try appendToken(c, .Keyword_undefined, "undefined"); + const node = try c.a().create(ast.Node.UndefinedLiteral); + node.* = ast.Node.UndefinedLiteral{ + .base = ast.Node{ .id = .UndefinedLiteral }, + .token = token, + }; + return &node.base; +} + +fn transCreateNodeVarDecl( + c: *Context, + is_pub: bool, + is_extern: bool, + is_const: bool, + var_name: []const u8, +) !*ast.Node.VarDecl { + const visb_tok = if (is_pub) + try appendToken(c, .Keyword_pub, "pub") + else + null; + + const extern_tok = if (is_extern) + try appendToken(c, .Keyword_extern, "extern") + else + null; + + const mut_tok = if (is_const) + try appendToken(c, .Keyword_const, "const") + else + try appendToken(c, .Keyword_var, "var"); + + const name_tok = try appendToken(c, .Identifier, var_name); + + const node = try c.a().create(ast.Node.VarDecl); + node.* = ast.Node.VarDecl{ + .base = ast.Node{ .id = .VarDecl }, + .doc_comments = null, + .visib_token = visb_tok, + .thread_local_token = null, + .name_token = name_tok, + .eq_token = undefined, // set by caller + .mut_token = mut_tok, + .comptime_token = null, + .extern_export_token = extern_tok, + .lib_name = null, + .type_node = null, + .align_node = null, + .section_node = null, + .init_node = null, + .semicolon_token = undefined, // set by caller + }; + return node; +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, @@ -1315,6 +1423,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour } } +fn transApValue(rp: RestorePoint, ap_value: *const ZigClangAPValue, qual_type: ZigClangQualType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { + return revertAndWarn( + rp, + error.UnsupportedTranslation, + source_loc, + "TODO implement translation of ap value", + .{}, + ); +} + const FnDeclContext = struct { fn_name: []const u8, has_body: bool, |
