translate-c-2 add var decl

This commit is contained in:
Vexu 2019-12-12 16:12:19 +02:00
parent 69dee57d95
commit ef361161e2
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
2 changed files with 124 additions and 1 deletions

View File

@ -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,

View File

@ -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,