| ... | @@ -33,8 +33,7 @@ fn addrEql(a: usize, b: usize) bool { | ... | @@ -33,8 +33,7 @@ fn addrEql(a: usize, b: usize) bool { |
| 33 | return a == b; | 33 | return a == b; |
| 34 | } | 34 | } |
| 35 | | 35 | |
| 36 | const MacroTable = std.StringHashMap(*ast.Node); | 36 | const SymbolTable = std.StringHashMap(*ast.Node); |
| 37 | const SymbolTable = std.StringHashMap(void); | | |
| 38 | const AliasList = std.SegmentedList(struct { | 37 | const AliasList = std.SegmentedList(struct { |
| 39 | alias: []const u8, | 38 | alias: []const u8, |
| 40 | name: []const u8, | 39 | name: []const u8, |
| ... | @@ -109,7 +108,7 @@ const Context = struct { | ... | @@ -109,7 +108,7 @@ const Context = struct { |
| 109 | decl_table: DeclTable, | 108 | decl_table: DeclTable, |
| 110 | alias_list: AliasList, | 109 | alias_list: AliasList, |
| 111 | sym_table: SymbolTable, | 110 | sym_table: SymbolTable, |
| 112 | macro_table: MacroTable, | 111 | macro_table: SymbolTable, |
| 113 | global_scope: *Scope.Root, | 112 | global_scope: *Scope.Root, |
| 114 | ptr_params: std.BufSet, | 113 | ptr_params: std.BufSet, |
| 115 | clang_context: *ZigClangASTContext, | 114 | clang_context: *ZigClangASTContext, |
| ... | @@ -197,7 +196,7 @@ pub fn translate( | ... | @@ -197,7 +196,7 @@ pub fn translate( |
| 197 | .decl_table = DeclTable.init(arena), | 196 | .decl_table = DeclTable.init(arena), |
| 198 | .alias_list = AliasList.init(arena), | 197 | .alias_list = AliasList.init(arena), |
| 199 | .sym_table = SymbolTable.init(arena), | 198 | .sym_table = SymbolTable.init(arena), |
| 200 | .macro_table = MacroTable.init(arena), | 199 | .macro_table = SymbolTable.init(arena), |
| 201 | .global_scope = try arena.create(Scope.Root), | 200 | .global_scope = try arena.create(Scope.Root), |
| 202 | .ptr_params = std.BufSet.init(arena), | 201 | .ptr_params = std.BufSet.init(arena), |
| 203 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, | 202 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, |
| ... | @@ -215,11 +214,7 @@ pub fn translate( | ... | @@ -215,11 +214,7 @@ pub fn translate( |
| 215 | | 214 | |
| 216 | try transPreprocessorEntities(&context, ast_unit); | 215 | try transPreprocessorEntities(&context, ast_unit); |
| 217 | | 216 | |
| 218 | var macro_it = context.macro_table.iterator(); | 217 | try addMacros(&context); |
| 219 | while (macro_it.next()) |kv| { | | |
| 220 | try addTopLevelDecl(&context, kv.key, kv.value); | | |
| 221 | } | | |
| 222 | | | |
| 223 | var it = context.alias_list.iterator(0); | 218 | var it = context.alias_list.iterator(0); |
| 224 | while (it.next()) |alias| { | 219 | while (it.next()) |alias| { |
| 225 | if (!context.sym_table.contains(alias.alias)) { | 220 | if (!context.sym_table.contains(alias.alias)) { |
| ... | @@ -962,12 +957,11 @@ fn transReturnStmt( | ... | @@ -962,12 +957,11 @@ fn transReturnStmt( |
| 962 | ) !TransResult { | 957 | ) !TransResult { |
| 963 | const node = try transCreateNodeReturnExpr(rp.c); | 958 | const node = try transCreateNodeReturnExpr(rp.c); |
| 964 | if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| { | 959 | if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| { |
| 965 | const ret_node = node.cast(ast.Node.ControlFlowExpression).?; | 960 | node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node; |
| 966 | ret_node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node; | | |
| 967 | } | 961 | } |
| 968 | _ = try appendToken(rp.c, .Semicolon, ";"); | 962 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 969 | return TransResult{ | 963 | return TransResult{ |
| 970 | .node = node, | 964 | .node = &node.base, |
| 971 | .child_scope = scope, | 965 | .child_scope = scope, |
| 972 | .node_scope = scope, | 966 | .node_scope = scope, |
| 973 | }; | 967 | }; |
| ... | @@ -1327,7 +1321,7 @@ fn maybeSuppressResult( | ... | @@ -1327,7 +1321,7 @@ fn maybeSuppressResult( |
| 1327 | | 1321 | |
| 1328 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { | 1322 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { |
| 1329 | try c.tree.root_node.decls.push(decl_node); | 1323 | try c.tree.root_node.decls.push(decl_node); |
| 1330 | _ = try c.sym_table.put(name, {}); | 1324 | _ = try c.sym_table.put(name, decl_node); |
| 1331 | } | 1325 | } |
| 1332 | | 1326 | |
| 1333 | fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TypeError!*ast.Node { | 1327 | fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TypeError!*ast.Node { |
| ... | @@ -1767,7 +1761,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { | ... | @@ -1767,7 +1761,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { |
| 1767 | _ = try appendToken(c, .LParen, "("); | 1761 | _ = try appendToken(c, .LParen, "("); |
| 1768 | const node = try c.a().create(ast.Node.SuffixOp); | 1762 | const node = try c.a().create(ast.Node.SuffixOp); |
| 1769 | node.* = ast.Node.SuffixOp{ | 1763 | node.* = ast.Node.SuffixOp{ |
| 1770 | .lhs = fn_expr, | 1764 | .lhs = .{ .node = fn_expr }, |
| 1771 | .op = ast.Node.SuffixOp.Op{ | 1765 | .op = ast.Node.SuffixOp.Op{ |
| 1772 | .Call = ast.Node.SuffixOp.Op.Call{ | 1766 | .Call = ast.Node.SuffixOp.Op.Call{ |
| 1773 | .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()), | 1767 | .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()), |
| ... | @@ -1881,7 +1875,7 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { | ... | @@ -1881,7 +1875,7 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { |
| 1881 | return &node.base; | 1875 | return &node.base; |
| 1882 | } | 1876 | } |
| 1883 | | 1877 | |
| 1884 | fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { | 1878 | fn transCreateNodeReturnExpr(c: *Context) !*ast.Node.ControlFlowExpression { |
| 1885 | const ltoken = try appendToken(c, .Keyword_return, "return"); | 1879 | const ltoken = try appendToken(c, .Keyword_return, "return"); |
| 1886 | const node = try c.a().create(ast.Node.ControlFlowExpression); | 1880 | const node = try c.a().create(ast.Node.ControlFlowExpression); |
| 1887 | node.* = ast.Node.ControlFlowExpression{ | 1881 | node.* = ast.Node.ControlFlowExpression{ |
| ... | @@ -1889,7 +1883,7 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { | ... | @@ -1889,7 +1883,7 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { |
| 1889 | .kind = .Return, | 1883 | .kind = .Return, |
| 1890 | .rhs = null, | 1884 | .rhs = null, |
| 1891 | }; | 1885 | }; |
| 1892 | return &node.base; | 1886 | return node; |
| 1893 | } | 1887 | } |
| 1894 | | 1888 | |
| 1895 | fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node { | 1889 | fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node { |
| ... | @@ -1959,6 +1953,100 @@ fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { | ... | @@ -1959,6 +1953,100 @@ fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { |
| 1959 | return &call_node.base; | 1953 | return &call_node.base; |
| 1960 | } | 1954 | } |
| 1961 | | 1955 | |
| | 1956 | fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias_node: *ast.Node) !*ast.Node { |
| | 1957 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| | 1958 | const inline_tok = try appendToken(c, .Keyword_inline, "inline"); |
| | 1959 | const fn_tok = try appendToken(c, .Keyword_fn, "fn"); |
| | 1960 | const name_tok = try appendIdentifier(c, name); |
| | 1961 | _ = try appendToken(c, .LParen, "("); |
| | 1962 | |
| | 1963 | const proto_alias = proto_alias_node.cast(ast.Node.FnProto).?; |
| | 1964 | |
| | 1965 | var fn_params = ast.Node.FnProto.ParamList.init(c.a()); |
| | 1966 | var it = proto_alias.params.iterator(0); |
| | 1967 | while (it.next()) |pn| { |
| | 1968 | if (it.index != 0) { |
| | 1969 | _ = try appendToken(c, .Comma, ","); |
| | 1970 | } |
| | 1971 | const param = pn.*.cast(ast.Node.ParamDecl).?; |
| | 1972 | |
| | 1973 | const param_name_tok = param.name_token orelse |
| | 1974 | try appendTokenFmt(c, .Identifier, "arg_{}", .{c.getMangle()}); |
| | 1975 | |
| | 1976 | _ = try appendToken(c, .Colon, ":"); |
| | 1977 | |
| | 1978 | const param_node = try c.a().create(ast.Node.ParamDecl); |
| | 1979 | param_node.* = .{ |
| | 1980 | .doc_comments = null, |
| | 1981 | .comptime_token = null, |
| | 1982 | .noalias_token = param.noalias_token, |
| | 1983 | .name_token = param_name_tok, |
| | 1984 | .type_node = param.type_node, |
| | 1985 | .var_args_token = null, |
| | 1986 | }; |
| | 1987 | try fn_params.push(&param_node.base); |
| | 1988 | } |
| | 1989 | |
| | 1990 | _ = try appendToken(c, .RParen, ")"); |
| | 1991 | |
| | 1992 | const fn_proto = try c.a().create(ast.Node.FnProto); |
| | 1993 | fn_proto.* = .{ |
| | 1994 | .doc_comments = null, |
| | 1995 | .visib_token = pub_tok, |
| | 1996 | .fn_token = fn_tok, |
| | 1997 | .name_token = name_tok, |
| | 1998 | .params = fn_params, |
| | 1999 | .return_type = proto_alias.return_type, |
| | 2000 | .var_args_token = null, |
| | 2001 | .extern_export_inline_token = inline_tok, |
| | 2002 | .cc_token = null, |
| | 2003 | .body_node = null, |
| | 2004 | .lib_name = null, |
| | 2005 | .align_expr = null, |
| | 2006 | .section_expr = null, |
| | 2007 | }; |
| | 2008 | |
| | 2009 | const block = try c.a().create(ast.Node.Block); |
| | 2010 | block.* = .{ |
| | 2011 | .label = null, |
| | 2012 | .lbrace = try appendToken(c, .LBrace, "{"), |
| | 2013 | .statements = ast.Node.Block.StatementList.init(c.a()), |
| | 2014 | .rbrace = undefined, |
| | 2015 | }; |
| | 2016 | |
| | 2017 | const return_expr = try transCreateNodeReturnExpr(c); |
| | 2018 | const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?); |
| | 2019 | const call_expr = try transCreateNodeFnCall(c, unwrap_expr); |
| | 2020 | it = fn_params.iterator(0); |
| | 2021 | while (it.next()) |pn| { |
| | 2022 | if (it.index != 0) { |
| | 2023 | _ = try appendToken(c, .Comma, ","); |
| | 2024 | } |
| | 2025 | const param = pn.*.cast(ast.Node.ParamDecl).?; |
| | 2026 | try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?))); |
| | 2027 | } |
| | 2028 | call_expr.rtoken = try appendToken(c, .RParen, ")"); |
| | 2029 | return_expr.rhs = &call_expr.base; |
| | 2030 | _ = try appendToken(c, .Semicolon, ";"); |
| | 2031 | |
| | 2032 | block.rbrace = try appendToken(c, .RBrace, "}"); |
| | 2033 | try block.statements.push(&return_expr.base); |
| | 2034 | fn_proto.body_node = &block.base; |
| | 2035 | return &fn_proto.base; |
| | 2036 | } |
| | 2037 | |
| | 2038 | fn transCreateNodeUnwrapNull(c: *Context, wrapped: *ast.Node) !*ast.Node { |
| | 2039 | _ = try appendToken(c, .Period, "."); |
| | 2040 | const qm = try appendToken(c, .QuestionMark, "?"); |
| | 2041 | const node = try c.a().create(ast.Node.SuffixOp); |
| | 2042 | node.* = ast.Node.SuffixOp{ |
| | 2043 | .op = .UnwrapOptional, |
| | 2044 | .lhs = .{ .node = wrapped }, |
| | 2045 | .rtoken = qm, |
| | 2046 | }; |
| | 2047 | return &node.base; |
| | 2048 | } |
| | 2049 | |
| 1962 | const RestorePoint = struct { | 2050 | const RestorePoint = struct { |
| 1963 | c: *Context, | 2051 | c: *Context, |
| 1964 | token_index: ast.TokenIndex, | 2052 | token_index: ast.TokenIndex, |
| ... | @@ -1982,28 +2070,28 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -1982,28 +2070,28 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1982 | switch (ZigClangType_getTypeClass(ty)) { | 2070 | switch (ZigClangType_getTypeClass(ty)) { |
| 1983 | .Builtin => { | 2071 | .Builtin => { |
| 1984 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); | 2072 | const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); |
| 1985 | switch (ZigClangBuiltinType_getKind(builtin_ty)) { | 2073 | return transCreateNodeIdentifier(rp.c, switch (ZigClangBuiltinType_getKind(builtin_ty)) { |
| 1986 | .Void => return transCreateNodeIdentifier(rp.c, "c_void"), | 2074 | .Void => "c_void", |
| 1987 | .Bool => return transCreateNodeIdentifier(rp.c, "bool"), | 2075 | .Bool => "bool", |
| 1988 | .Char_U, .UChar, .Char_S, .Char8 => return transCreateNodeIdentifier(rp.c, "u8"), | 2076 | .Char_U, .UChar, .Char_S, .Char8 => "u8", |
| 1989 | .SChar => return transCreateNodeIdentifier(rp.c, "i8"), | 2077 | .SChar => "i8", |
| 1990 | .UShort => return transCreateNodeIdentifier(rp.c, "c_ushort"), | 2078 | .UShort => "c_ushort", |
| 1991 | .UInt => return transCreateNodeIdentifier(rp.c, "c_uint"), | 2079 | .UInt => "c_uint", |
| 1992 | .ULong => return transCreateNodeIdentifier(rp.c, "c_ulong"), | 2080 | .ULong => "c_ulong", |
| 1993 | .ULongLong => return transCreateNodeIdentifier(rp.c, "c_ulonglong"), | 2081 | .ULongLong => "c_ulonglong", |
| 1994 | .Short => return transCreateNodeIdentifier(rp.c, "c_short"), | 2082 | .Short => "c_short", |
| 1995 | .Int => return transCreateNodeIdentifier(rp.c, "c_int"), | 2083 | .Int => "c_int", |
| 1996 | .Long => return transCreateNodeIdentifier(rp.c, "c_long"), | 2084 | .Long => "c_long", |
| 1997 | .LongLong => return transCreateNodeIdentifier(rp.c, "c_longlong"), | 2085 | .LongLong => "c_longlong", |
| 1998 | .UInt128 => return transCreateNodeIdentifier(rp.c, "u128"), | 2086 | .UInt128 => "u128", |
| 1999 | .Int128 => return transCreateNodeIdentifier(rp.c, "i128"), | 2087 | .Int128 => "i128", |
| 2000 | .Float => return transCreateNodeIdentifier(rp.c, "f32"), | 2088 | .Float => "f32", |
| 2001 | .Double => return transCreateNodeIdentifier(rp.c, "f64"), | 2089 | .Double => "f64", |
| 2002 | .Float128 => return transCreateNodeIdentifier(rp.c, "f128"), | 2090 | .Float128 => "f128", |
| 2003 | .Float16 => return transCreateNodeIdentifier(rp.c, "f16"), | 2091 | .Float16 => "f16", |
| 2004 | .LongDouble => return transCreateNodeIdentifier(rp.c, "c_longdouble"), | 2092 | .LongDouble => "c_longdouble", |
| 2005 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), | 2093 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 2006 | } | 2094 | }); |
| 2007 | }, | 2095 | }, |
| 2008 | .FunctionProto => { | 2096 | .FunctionProto => { |
| 2009 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); | 2097 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| ... | @@ -2693,8 +2781,6 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -2693,8 +2781,6 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 2693 | node = &access_node.base; | 2781 | node = &access_node.base; |
| 2694 | }, | 2782 | }, |
| 2695 | .Shl => { | 2783 | .Shl => { |
| 2696 | const rhs_node = try parseCPrimaryExpr(rp, it, source_loc); | | |
| 2697 | | | |
| 2698 | const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<"); | 2784 | const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<"); |
| 2699 | const rhs = try parseCPrimaryExpr(rp, it, source_loc); | 2785 | const rhs = try parseCPrimaryExpr(rp, it, source_loc); |
| 2700 | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); | 2786 | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); |
| ... | @@ -2718,9 +2804,64 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -2718,9 +2804,64 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 2718 | const op_tok = it.next().?; | 2804 | const op_tok = it.next().?; |
| 2719 | | 2805 | |
| 2720 | switch (op_tok.id) { | 2806 | switch (op_tok.id) { |
| | 2807 | .Bang => { |
| | 2808 | const node = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!"); |
| | 2809 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc); |
| | 2810 | return &node.base; |
| | 2811 | }, |
| | 2812 | .Minus => { |
| | 2813 | const node = try transCreateNodePrefixOp(rp.c, .Negation, .Minus, "-"); |
| | 2814 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc); |
| | 2815 | return &node.base; |
| | 2816 | }, |
| | 2817 | .Tilde => { |
| | 2818 | const node = try transCreateNodePrefixOp(rp.c, .BitNot, .Tilde, "~"); |
| | 2819 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc); |
| | 2820 | return &node.base; |
| | 2821 | }, |
| 2721 | else => { | 2822 | else => { |
| 2722 | _ = it.prev(); | 2823 | _ = it.prev(); |
| 2723 | return try parseCSuffixOpExpr(rp, it, source_loc); | 2824 | return try parseCSuffixOpExpr(rp, it, source_loc); |
| 2724 | }, | 2825 | }, |
| 2725 | } | 2826 | } |
| 2726 | } | 2827 | } |
| | 2828 | |
| | 2829 | fn tokenSlice(c: *Context, token: ast.TokenIndex) []const u8 { |
| | 2830 | const tok = c.tree.tokens.at(token); |
| | 2831 | return c.source_buffer.toSliceConst()[tok.start..tok.end]; |
| | 2832 | } |
| | 2833 | |
| | 2834 | fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node { |
| | 2835 | const init = ref.cast(ast.Node.VarDecl).?.init_node.?; |
| | 2836 | const name = if (init.cast(ast.Node.Identifier)) |id| |
| | 2837 | tokenSlice(c, id.token) |
| | 2838 | else |
| | 2839 | return null; |
| | 2840 | // TODO a.b.c |
| | 2841 | if (c.sym_table.get(name)) |kv| { |
| | 2842 | if (kv.value.cast(ast.Node.VarDecl)) |val| { |
| | 2843 | if (val.type_node) |type_node| { |
| | 2844 | if (type_node.cast(ast.Node.PrefixOp)) |casted| { |
| | 2845 | if (casted.rhs.id == .FnProto) { |
| | 2846 | return casted.rhs; |
| | 2847 | } |
| | 2848 | } |
| | 2849 | } |
| | 2850 | } |
| | 2851 | } |
| | 2852 | return null; |
| | 2853 | } |
| | 2854 | |
| | 2855 | fn addMacros(c: *Context) !void { |
| | 2856 | var macro_it = c.macro_table.iterator(); |
| | 2857 | while (macro_it.next()) |kv| { |
| | 2858 | if (getFnDecl(c, kv.value)) |proto_node| { |
| | 2859 | // If a macro aliases a global variable which is a function pointer, we conclude that |
| | 2860 | // the macro is intended to represent a function that assumes the function pointer |
| | 2861 | // variable is non-null and calls it. |
| | 2862 | try addTopLevelDecl(c, kv.key, try transCreateNodeMacroFn(c, kv.key, kv.value, proto_node)); |
| | 2863 | } else { |
| | 2864 | try addTopLevelDecl(c, kv.key, kv.value); |
| | 2865 | } |
| | 2866 | } |
| | 2867 | } |