diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-02-01 02:00:25 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-02-01 02:00:25 -0700 |
| commit | b3459f64e795118c4c12890ed0fec75638b74a2c (patch) | |
| tree | d5730790d1b61f71a606e30023d68cc36071cce4 /src | |
| parent | 6b2e29c6ac58d5f4370828bfa0f54b83d1931a97 (diff) | |
| download | zig-b3459f64e795118c4c12890ed0fec75638b74a2c.tar.gz zig-b3459f64e795118c4c12890ed0fec75638b74a2c.zip | |
parseh understands macros which alias global fn ptr vars
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 2 | ||||
| -rw-r--r-- | src/ast_render.cpp | 60 | ||||
| -rw-r--r-- | src/codegen.cpp | 3 | ||||
| -rw-r--r-- | src/parseh.cpp | 93 |
4 files changed, 151 insertions, 7 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 8942746e2d..e71c762669 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -29,6 +29,7 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node); static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn); static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node); +static void analyze_top_level_decls_root(CodeGen *g, ImportTableEntry *import, AstNode *node); static AstNode *first_executing_node(AstNode *node) { switch (node->type) { @@ -1251,6 +1252,7 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A child_import->importers.append({parent_import, node}); detect_top_level_decl_deps(g, child_import, child_import->root); + analyze_top_level_decls_root(g, child_import, child_import->root); } static void satisfy_dep(CodeGen *g, AstNode *node) { diff --git a/src/ast_render.cpp b/src/ast_render.cpp index cebacaa0f7..a09b4c52be 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -582,15 +582,34 @@ static void render_node(AstRender *ar, AstNode *node) { break; } case NodeTypeFnDef: - zig_panic("TODO"); + for (int i = 0; i < node->data.fn_def.fn_proto->data.fn_proto.directives->length; i += 1) { + render_node(ar, node->data.fn_def.fn_proto->data.fn_proto.directives->at(i)); + } + render_node(ar, node->data.fn_def.fn_proto); + fprintf(ar->f, " "); + render_node(ar, node->data.fn_def.body); + break; case NodeTypeFnDecl: zig_panic("TODO"); case NodeTypeParamDecl: zig_panic("TODO"); case NodeTypeBlock: - zig_panic("TODO"); + fprintf(ar->f, "{\n"); + ar->indent += ar->indent_size; + for (int i = 0; i < node->data.block.statements.length; i += 1) { + AstNode *statement = node->data.block.statements.at(i); + print_indent(ar); + render_node(ar, statement); + } + ar->indent -= ar->indent_size; + fprintf(ar->f, "\n"); + print_indent(ar); + fprintf(ar->f, "}"); + break; case NodeTypeDirective: - zig_panic("TODO"); + fprintf(ar->f, "#%s(\"%s\")\n", buf_ptr(&node->data.directive.name), + buf_ptr(&node->data.directive.param)); + break; case NodeTypeReturnExpr: zig_panic("TODO"); case NodeTypeVariableDeclaration: @@ -621,7 +640,12 @@ static void render_node(AstRender *ar, AstNode *node) { case NodeTypeErrorValueDecl: zig_panic("TODO"); case NodeTypeBinOpExpr: - zig_panic("TODO"); + fprintf(ar->f, "("); + render_node(ar, node->data.bin_op_expr.op1); + fprintf(ar->f, " %s ", bin_op_str(node->data.bin_op_expr.bin_op)); + render_node(ar, node->data.bin_op_expr.op2); + fprintf(ar->f, ")"); + break; case NodeTypeUnwrapErrorExpr: zig_panic("TODO"); case NodeTypeNumberLiteral: @@ -635,7 +659,11 @@ static void render_node(AstRender *ar, AstNode *node) { } break; case NodeTypeStringLiteral: - zig_panic("TODO"); + if (node->data.string_literal.c) { + fprintf(ar->f, "c"); + } + fprintf(ar->f, "\"%s\"", buf_ptr(&node->data.string_literal.buf)); + break; case NodeTypeCharLiteral: { uint8_t c = node->data.char_literal.value; @@ -665,7 +693,20 @@ static void render_node(AstRender *ar, AstNode *node) { break; } case NodeTypeFnCallExpr: - zig_panic("TODO"); + if (node->data.fn_call_expr.is_builtin) { + fprintf(ar->f, "@"); + } + render_node(ar, node->data.fn_call_expr.fn_ref_expr); + fprintf(ar->f, "("); + for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { + AstNode *param = node->data.fn_call_expr.params.at(i); + if (i != 0) { + fprintf(ar->f, ", "); + } + render_node(ar, param); + } + fprintf(ar->f, ")"); + break; case NodeTypeArrayAccessExpr: zig_panic("TODO"); case NodeTypeSliceExpr: @@ -739,7 +780,12 @@ static void render_node(AstRender *ar, AstNode *node) { case NodeTypeStructField: zig_panic("TODO"); case NodeTypeContainerInitExpr: - zig_panic("TODO"); + fprintf(ar->f, "("); + render_node(ar, node->data.container_init_expr.type); + fprintf(ar->f, "){"); + assert(node->data.container_init_expr.entries.length == 0); + fprintf(ar->f, "}"); + break; case NodeTypeStructValueField: zig_panic("TODO"); case NodeTypeArrayType: diff --git a/src/codegen.cpp b/src/codegen.cpp index a5374eb2de..ef910bbba7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -612,6 +612,8 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { return LLVMBuildUnreachable(g->builder); } else if (first_arg_ret) { return node->data.fn_call_expr.tmp_ptr; + } else if (src_return_type->size_in_bits == 0) { + return nullptr; } else { return result; } @@ -2767,6 +2769,7 @@ static void do_code_gen(CodeGen *g) { } VariableTableEntry *variable = param_decl->data.param_decl.variable; + assert(variable); LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(param_decl->line + 1, param_decl->column + 1, fn_def_node->data.fn_def.block_context->di_scope); diff --git a/src/parseh.cpp b/src/parseh.cpp index b8945c3741..271fb318dc 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -51,6 +51,7 @@ struct Context { AstNode *source_node; CodeGen *codegen; + bool transform_extern_fn_ptr; }; static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, @@ -196,6 +197,13 @@ static AstNode *create_num_lit_signed(Context *c, int64_t x) { return create_prefix_node(c, PrefixOpNegation, num_lit_node); } +static AstNode *create_directive_node(Context *c, const char *name, const char *value) { + AstNode *node = create_node(c, NodeTypeDirective); + buf_init_from_str(&node->data.directive.name, name); + buf_init_from_str(&node->data.directive.param, value); + return node; +} + static AstNode *create_type_decl_node(Context *c, const char *name, AstNode *child_type_node) { AstNode *node = create_node(c, NodeTypeTypeDecl); buf_init_from_str(&node->data.type_decl.symbol, name); @@ -213,6 +221,80 @@ static AstNode *make_type_node(Context *c, TypeTableEntry *type_entry) { return node; } +static AstNode *create_fn_proto_node(Context *c, Buf *name, TypeTableEntry *fn_type) { + assert(fn_type->id == TypeTableEntryIdFn); + AstNode *node = create_node(c, NodeTypeFnProto); + node->data.fn_proto.directives = create_empty_directives(c); + node->data.fn_proto.directives->append(create_directive_node(c, "attribute", "inline")); + node->data.fn_proto.visib_mod = c->visib_mod; + buf_init_from_buf(&node->data.fn_proto.name, name); + node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type); + + for (int i = 0; i < fn_type->data.fn.fn_type_id.param_count; i += 1) { + FnTypeParamInfo *info = &fn_type->data.fn.fn_type_id.param_info[i]; + Buf *name = buf_sprintf("arg_%d", i); + node->data.fn_proto.params.append(create_param_decl_node(c, buf_ptr(name), + make_type_node(c, info->type), info->is_noalias)); + } + + normalize_parent_ptrs(node); + return node; +} + +static AstNode *create_one_statement_block(Context *c, AstNode *statement) { + AstNode *node = create_node(c, NodeTypeBlock); + node->data.block.statements.append(statement); + + normalize_parent_ptrs(node); + return node; +} + +static AstNode *create_container_init_node(Context *c, AstNode *type_node) { + AstNode *node = create_node(c, NodeTypeContainerInitExpr); + node->data.container_init_expr.kind = ContainerInitKindArray; + node->data.container_init_expr.type = type_node; + + normalize_parent_ptrs(node); + return node; +} + +static AstNode *create_bin_op_node(Context *c, AstNode *lhs, BinOpType op, AstNode *rhs) { + AstNode *node = create_node(c, NodeTypeBinOpExpr); + node->data.bin_op_expr.op1 = lhs; + node->data.bin_op_expr.bin_op = op; + node->data.bin_op_expr.op2 = rhs; + + normalize_parent_ptrs(node); + return node; +} + +static AstNode *create_inline_fn_node(Context *c, Buf *fn_name, Buf *var_name, TypeTableEntry *fn_type) { + AstNode *node = create_node(c, NodeTypeFnDef); + node->data.fn_def.fn_proto = create_fn_proto_node(c, fn_name, fn_type); + + AstNode *unreach_type_node = make_type_node(c, c->codegen->builtin_types.entry_unreachable); + AstNode *unreach_node = create_container_init_node(c, unreach_type_node); + AstNode *unwrap_node = create_bin_op_node(c, create_symbol_node(c, buf_ptr(var_name)), + BinOpTypeUnwrapMaybe, unreach_node); + + AstNode *fn_call_node = create_node(c, NodeTypeFnCallExpr); + fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node; + for (int i = 0; i < fn_type->data.fn.fn_type_id.param_count; i += 1) { + AstNode *decl_node = node->data.fn_def.fn_proto->data.fn_proto.params.at(i); + Buf *param_name = &decl_node->data.param_decl.name; + fn_call_node->data.fn_call_expr.params.append(create_symbol_node(c, buf_ptr(param_name))); + } + + normalize_parent_ptrs(fn_call_node); + + node->data.fn_def.body = create_one_statement_block(c, fn_call_node); + + normalize_parent_ptrs(node); + return node; +} + + + static const char *decl_name(const Decl *decl) { const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); return (const char *)named_decl->getName().bytes_begin(); @@ -1257,6 +1339,17 @@ static void process_symbol_macros(Context *c) { AstNode *var_node = create_var_decl_node(c, buf_ptr(ms.name), create_symbol_node(c, buf_ptr(ms.value))); c->macro_table.put(ms.name, var_node); + } else if (c->transform_extern_fn_ptr || true) { // TODO take off the || true + if (auto entry = c->global_value_table.maybe_get(ms.value)) { + TypeTableEntry *maybe_type = entry->value.type; + if (maybe_type->id == TypeTableEntryIdMaybe) { + TypeTableEntry *fn_type = maybe_type->data.maybe.child_type; + if (fn_type->id == TypeTableEntryIdFn) { + AstNode *fn_node = create_inline_fn_node(c, ms.name, ms.value, fn_type); + c->macro_table.put(ms.name, fn_node); + } + } + } } } } |
