diff options
| author | Vexu <git@vexu.eu> | 2019-12-13 14:55:36 +0200 |
|---|---|---|
| committer | Vexu <git@vexu.eu> | 2019-12-13 15:07:10 +0200 |
| commit | eb057ef41c8a5482586fc39bab11c280e261ea94 (patch) | |
| tree | 2d2b3564a10210644bee16a6647b8961017e0db7 /src-self-hosted | |
| parent | 0795f17db23fff5aada41008348a63cbc9e0321b (diff) | |
| download | zig-eb057ef41c8a5482586fc39bab11c280e261ea94.tar.gz zig-eb057ef41c8a5482586fc39bab11c280e261ea94.zip | |
translate-c-2 dont eval init expr
Diffstat (limited to 'src-self-hosted')
| -rw-r--r-- | src-self-hosted/clang.zig | 11 | ||||
| -rw-r--r-- | src-self-hosted/translate_c.zig | 299 |
2 files changed, 145 insertions, 165 deletions
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index eea6d757dc..2ed011cc1e 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -74,6 +74,7 @@ pub const struct_ZigClangVarDecl = @OpaqueType(); pub const struct_ZigClangWhileStmt = @OpaqueType(); pub const struct_ZigClangFunctionType = @OpaqueType(); pub const struct_ZigClangPredefinedExpr = @OpaqueType(); +pub const struct_ZigClangInitListExpr = @OpaqueType(); pub const ZigClangBO = extern enum { PtrMemD, @@ -755,11 +756,12 @@ 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 ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr; +pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr; +pub extern fn ZigClangInitListExpr_getNumInits(self: ?*const struct_ZigClangInitListExpr) c_uint; 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; -pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) *const struct_ZigClangAPValue; -pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) *const struct_ZigClangAPValue; pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint; pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase; pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool; @@ -867,6 +869,7 @@ pub const ZigClangVarDecl = struct_ZigClangVarDecl; pub const ZigClangWhileStmt = struct_ZigClangWhileStmt; pub const ZigClangFunctionType = struct_ZigClangFunctionType; pub const ZigClangPredefinedExpr = struct_ZigClangPredefinedExpr; +pub const ZigClangInitListExpr = struct_ZigClangInitListExpr; pub const struct_ZigClangSourceLocation = extern struct { ID: c_uint, @@ -921,9 +924,8 @@ pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClan 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_getStorageClass(self: *const ZigClangVarDecl) ZigClangStorageClass; 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; @@ -964,7 +966,6 @@ 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 80d0e21989..a4874d92e3 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -305,54 +305,83 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { 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); + const visib_tok = try appendToken(c, .Keyword_pub, "pub"); + + const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None) + null + else + try appendToken(c, .Keyword_threadlocal, "threadlocal"); + 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 qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); + const storage_class = ZigClangVarDecl_getStorageClass(var_decl); const is_const = ZigClangQualType_isConstQualified(qual_type); - var var_node = try transCreateNodeVarDecl(c, true, is_extern, is_const, var_name); + const extern_tok = if (storage_class == .Extern) + try appendToken(c, .Keyword_extern, "extern") + else if (storage_class != .Static) + try appendToken(c, .Keyword_export, "export") + else + null; + + const mut_tok = if (is_const) + try appendToken(c, .Keyword_const, "const") + else + try appendToken(c, .Keyword_var, "var"); - _ = try appendToken(rp.c, .Colon, ":"); - var_node.type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) { + const name_tok = try appendToken(c, .Identifier, var_name); + + _ = try appendToken(c, .Colon, ":"); + 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) { + var eq_tok: ast.TokenIndex = undefined; + var init_node: ?*ast.Node = null; + + if (ZigClangVarDecl_hasInit(var_decl)) { + eq_tok = try appendToken(c, .Equal, "="); + init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| blk: { + var res = transExpr(rp, &c.global_scope.base, expr, .used, .r_value) catch |err| switch (err) { error.UnsupportedTranslation, error.UnsupportedType, => { - return failDecl(c, var_decl_loc, var_name, "unable to evaluate initializer", .{}); + return failDecl(c, var_decl_loc, var_name, "unable to translate initializer", .{}); }, error.OutOfMemory => |e| return e, }; + break :blk res.node; } else try transCreateNodeUndefinedLiteral(c); - var_node.eq_token = eq_tok; - var_node.init_node = init_node; - } else if (!is_extern) { - return failDecl(c, var_decl_loc, var_name, "non-extern, non-static variable not supported", .{}); + } else if (storage_class != .Extern) { + return failDecl(c, var_decl_loc, var_name, "non-extern variable has no initializer", .{}); } - var_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); - return addTopLevelDecl(c, var_name, &var_node.base); + const node = try c.a().create(ast.Node.VarDecl); + node.* = ast.Node.VarDecl{ + .base = ast.Node{ .id = .VarDecl }, + .doc_comments = null, + .visib_token = visib_tok, + .thread_local_token = thread_local_token, + .name_token = name_tok, + .eq_token = eq_tok, + .mut_token = mut_tok, + .comptime_token = null, + .extern_export_token = extern_tok, + .lib_name = null, + .type_node = type_node, + .align_node = null, + .section_node = null, + .init_node = init_node, + .semicolon_token = try appendToken(c, .Semicolon, ";"), + }; + return addTopLevelDecl(c, var_name, &node.base); } const ResultUsed = enum { @@ -384,6 +413,7 @@ fn transStmt( .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)), .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used), .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue), + .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used), else => { return revertAndWarn( rp, @@ -635,7 +665,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| (try transExpr(rp, scope, expr, .used, .r_value)).node else - try transCreateNodeUndefinedLiteral(rp.c); + try transCreateNodeUndefinedLiteral(c); const semicolon_token = try appendToken(c, .Semicolon, ";"); const node = try c.a().create(ast.Node.VarDecl); @@ -725,7 +755,7 @@ fn transImplicitCastExpr( .FunctionToPointerDecay, .ArrayToPointerDecay => { return maybeSuppressResult(rp, scope, result_used, sub_expr_node); }, - .LValueToRValue => { + .LValueToRValue, .NoOp => { return transExpr(rp, scope, sub_expr, .used, .r_value); }, else => |kind| return revertAndWarn( @@ -906,6 +936,88 @@ fn transExpr( return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue); } +fn transInitListExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangInitListExpr, + used: ResultUsed, +) TransError!TransResult { + // TODO use anon literals once they work properly + const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr)); + const qual_type = ZigClangQualType_getTypePtr(qt); + const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr)); + const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type); + const child_qt = ZigClangArrayType_getElementType(arr_type); + const init_count = ZigClangInitListExpr_getNumInits(expr); + const all_count = 200; //ZigClangArrayType_getSize(arr_type); + const leftover_count = all_count - init_count; + + var init_node: *ast.Node.SuffixOp = undefined; + var cat_tok: ast.TokenIndex = undefined; + if (init_count != 0) { + var type_node = try transQualType(rp, qt, source_loc); + init_node = try transCreateNodeArrayInitializer(rp.c, type_node); + var i: c_uint = 0; + while (i < init_count) : (i += 1) { + const elem_expr = ZigClangInitListExpr_getInit(expr, i); + try init_node.op.ArrayInitializer.push((try transExpr(rp, scope, elem_expr, .used, .r_value)).node); + _ = try appendToken(rp.c, .Comma, ","); + } + init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); + if (leftover_count == 0) { + return TransResult{ + .node = &init_node.base, + .child_scope = scope, + .node_scope = scope, + }; + } + cat_tok = try appendToken(rp.c, .PlusPlus, "++"); + } + + var filler_type_node = try transQualType(rp, qt, source_loc); + var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node); + const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr); + try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node); + filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); + + const rhs_node = if (leftover_count == 1) + &filler_init_node.base + else blk: { + const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**"); + const mul_node = try rp.c.a().create(ast.Node.InfixOp); + mul_node.* = .{ + .base = .{ .id = .InfixOp }, + .op_token = mul_tok, + .lhs = &filler_init_node.base, + .op = .ArrayMult, + .rhs = try transCreateNodeInt(rp.c, leftover_count), + }; + break :blk &mul_node.base; + }; + + if (init_count == 0) { + return TransResult{ + .node = rhs_node, + .child_scope = scope, + .node_scope = scope, + }; + } + + const cat_node = try rp.c.a().create(ast.Node.InfixOp); + cat_node.* = .{ + .base = .{ .id = .InfixOp }, + .op_token = cat_tok, + .lhs = &init_node.base, + .op = .ArrayCat, + .rhs = rhs_node, + }; + return TransResult{ + .node = &cat_node.base, + .child_scope = scope, + .node_scope = scope, + }; +} + fn findBlockScope(inner: *Scope) *Scope.Block { var scope = inner; while (true) : (scope = scope.parent orelse unreachable) { @@ -1295,51 +1407,6 @@ fn transCreateNodeArrayInitializer(c: *Context, type_node: *ast.Node) !*ast.Node return node; } -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; -} - fn transCreateNodeInt(c: *Context, int: var) !*ast.Node { const token = try appendToken(c, .IntegerLiteral, try std.fmt.allocPrint(c.a(), "{}", .{int})); const node = try c.a().create(ast.Node.IntegerLiteral); @@ -1474,94 +1541,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour } } -fn transApValue(rp: RestorePoint, ap_value: *const ZigClangAPValue, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { - switch (ZigClangAPValue_getKind(ap_value)) { - .None => return transCreateNodeUndefinedLiteral(rp.c), - .Int => return transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(ap_value)), - .Array => { - // TODO evaluateValue is null for Array init for some reason - // TODO use anon literals once they work properly - const init_count = ZigClangAPValue_getArrayInitializedElts(ap_value); - const all_count = ZigClangAPValue_getArraySize(ap_value); - const leftover_count = all_count - init_count; - const qt_type = ZigClangQualType_getTypePtr(qt); - const child_qt = ZigClangArrayType_getElementType(ZigClangType_getAsArrayTypeUnsafe(qt_type)); - - var init_node: *ast.Node.SuffixOp = undefined; - var cat_tok: ast.TokenIndex = undefined; - if (init_count != 0) { - var type_node = try transQualType(rp, qt, source_loc); - init_node = try transCreateNodeArrayInitializer(rp.c, type_node); - var i: c_uint = 0; - while (i < init_count) : (i += 1) { - const elem_ap_val = ZigClangAPValue_getArrayInitializedElt(ap_value, i); - try init_node.op.ArrayInitializer.push(try transApValue(rp, elem_ap_val, child_qt, source_loc)); - _ = try appendToken(rp.c, .Comma, ","); - } - init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); - if (leftover_count == 0) { - return &init_node.base; - } - cat_tok = try appendToken(rp.c, .PlusPlus, "++"); - } - - var filler_type_node = try transQualType(rp, qt, source_loc); - var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node); - const filler_ap_val = ZigClangAPValue_getArrayFiller(ap_value); - try filler_init_node.op.ArrayInitializer.push(try transApValue(rp, filler_ap_val, child_qt, source_loc)); - filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); - - const rhs_node = if (leftover_count == 1) - &filler_init_node.base - else blk: { - const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**"); - const mul_node = try rp.c.a().create(ast.Node.InfixOp); - mul_node.* = .{ - .base = .{ .id = .InfixOp }, - .op_token = mul_tok, - .lhs = &filler_init_node.base, - .op = .ArrayMult, - .rhs = try transCreateNodeInt(rp.c, leftover_count), - }; - break :blk &mul_node.base; - }; - - if (init_count == 0) { - return rhs_node; - } - - const cat_node = try rp.c.a().create(ast.Node.InfixOp); - cat_node.* = .{ - .base = .{ .id = .InfixOp }, - .op_token = cat_tok, - .lhs = &init_node.base, - .op = .ArrayCat, - .rhs = rhs_node, - }; - return &cat_node.base; - }, - .LValue => { - const lval_base = ZigClangAPValue_getLValueBase(ap_value); - const expr = ZigClangAPValueLValueBase_dyn_cast_Expr(lval_base); - if (expr) |e| { - return (try transExpr(rp, &rp.c.global_scope.base, e, .used, .r_value)).node; - } - try emitWarning(rp.c, source_loc, "TODO handle initializer LValue ValueDecl", .{}); - }, - .Float => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Float", .{}), - .ComplexInt => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: ComplexInt", .{}), - .ComplexFloat => try emitWarning(rp.c, source_loc, "Tunsupported initializer value kind: ComplexFloat", .{}), - .Vector => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Vector", .{}), - .Struct => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Struct", .{}), - .Union => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Union", .{}), - .MemberPointer => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: MemberPointer", .{}), - .AddrLabelDiff => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: AddrLabelDiff", .{}), - .Indeterminate => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: Indeterminate", .{}), - .FixedPoint => try emitWarning(rp.c, source_loc, "unsupported initializer value kind: FixedPoint", .{}), - } - return error.UnsupportedTranslation; -} - const FnDeclContext = struct { fn_name: []const u8, has_body: bool, |
