From 430e33b869b004ca24faee2dfa9e51aa4e94093f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 10 Jan 2017 15:39:52 -0500 Subject: [PATCH] partially fix parseh command --- src/analyze.cpp | 14 ++++---- src/analyze.hpp | 2 +- src/ast_render.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/ast_render.hpp | 2 ++ src/codegen.cpp | 6 +--- src/ir.cpp | 3 +- src/main.cpp | 9 +++--- src/parseh.cpp | 6 ++-- 8 files changed, 102 insertions(+), 21 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 97e30f50d0..8bd83826d9 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -870,26 +870,26 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { zig_unreachable(); } -TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name) { +TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name, bool is_extern) { TypeTableEntryId type_id = container_to_type(kind); TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); switch (kind) { case ContainerKindStruct: entry->data.structure.decl_node = decl_node; - entry->data.structure.is_extern = decl_node->data.container_decl.is_extern; + entry->data.structure.is_extern = is_extern; break; case ContainerKindEnum: entry->data.enumeration.decl_node = decl_node; - entry->data.enumeration.is_extern = decl_node->data.container_decl.is_extern; + entry->data.enumeration.is_extern = is_extern; break; case ContainerKindUnion: entry->data.unionation.decl_node = decl_node; - entry->data.unionation.is_extern = decl_node->data.container_decl.is_extern; + entry->data.unionation.is_extern = is_extern; break; } - unsigned line = decl_node->line; + unsigned line = decl_node ? decl_node->line : 0; ImportTableEntry *import = get_scope_import(scope); entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name); @@ -1688,7 +1688,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source tld->name = name; tld->visib_mod = visib_mod; tld->source_node = source_node; - tld->import = source_node->owner; + tld->import = source_node ? source_node->owner : nullptr; tld->parent_scope = parent_scope; } @@ -1895,7 +1895,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent } Scope *child_scope; - if (source_node->type == NodeTypeParamDecl) { + if (source_node && source_node->type == NodeTypeParamDecl) { child_scope = create_var_scope(source_node, parent_scope, variable_entry); } else { // it's already in the decls table diff --git a/src/analyze.hpp b/src/analyze.hpp index cce39e9fe6..4132f463f0 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -26,7 +26,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type); TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size); TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const); -TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name); +TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, AstNode *decl_node, const char *name, bool is_extern); TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry); diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 2c541b1600..0ade4005bc 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -6,6 +6,7 @@ */ #include "ast_render.hpp" +#include "analyze.hpp" #include @@ -891,3 +892,83 @@ void ast_render(FILE *f, AstNode *node, int indent_size) { render_node_grouped(&ar, node); } +static void ast_render_tld_fn(AstRender *ar, TldFn *tld_fn) { + FnTableEntry *fn_entry = tld_fn->fn_entry; + FnTypeId *fn_type_id = &fn_entry->type_entry->data.fn.fn_type_id; + const char *visib_mod_str = visib_mod_string(tld_fn->base.visib_mod); + const char *extern_str = extern_string(fn_type_id->is_extern); + const char *coldcc_str = fn_type_id->is_cold ? "coldcc " : ""; + const char *nakedcc_str = fn_type_id->is_naked ? "nakedcc " : ""; + fprintf(ar->f, "%s%s%s%sfn %s(", visib_mod_str, extern_str, coldcc_str, nakedcc_str, buf_ptr(&fn_entry->symbol_name)); + for (size_t i = 0; i < fn_type_id->param_count; i += 1) { + FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; + if (param_info->is_noalias) { + fprintf(ar->f, "noalias "); + } + fprintf(ar->f, "arg_%zu: %s", i, buf_ptr(¶m_info->type->name)); + } + if (fn_type_id->return_type->id == TypeTableEntryIdVoid) { + fprintf(ar->f, ");\n"); + } else { + fprintf(ar->f, ") -> %s;\n", buf_ptr(&fn_type_id->return_type->name)); + } +} + +static void ast_render_tld_var(AstRender *ar, TldVar *tld_var) { + VariableTableEntry *var = tld_var->var; + const char *visib_mod_str = visib_mod_string(tld_var->base.visib_mod); + const char *const_or_var = const_or_var_string(var->src_is_const); + const char *extern_str = extern_string(var->is_extern); + fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(&var->name)); + + if (var->value.type->id == TypeTableEntryIdNumLitFloat || + var->value.type->id == TypeTableEntryIdNumLitInt) + { + // skip type + } else { + fprintf(ar->f, ": %s", buf_ptr(&var->value.type->name)); + } + + if (var->value.special == ConstValSpecialRuntime) { + fprintf(ar->f, ";\n"); + return; + } + + Buf buf = BUF_INIT; + buf_resize(&buf, 0); + render_const_value(&buf, &var->value); + + fprintf(ar->f, " = %s;\n", buf_ptr(&buf)); +} + +void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) { + AstRender ar = {0}; + ar.f = f; + ar.indent_size = indent_size; + ar.indent = 0; + + auto it = import->decls_scope->decl_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + Tld *tld = entry->value; + switch (tld->id) { + case TldIdVar: + ast_render_tld_var(&ar, (TldVar *)tld); + break; + case TldIdFn: + ast_render_tld_fn(&ar, (TldFn *)tld); + break; + case TldIdContainer: + fprintf(stdout, "container\n"); + break; + case TldIdTypeDef: + fprintf(stdout, "typedef\n"); + break; + } + } +} + + diff --git a/src/ast_render.hpp b/src/ast_render.hpp index 9ff7b4845f..168aba1bab 100644 --- a/src/ast_render.hpp +++ b/src/ast_render.hpp @@ -19,5 +19,7 @@ void ast_render(FILE *f, AstNode *node, int indent_size); const char *container_string(ContainerKind kind); +void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import); + #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index ff5c0bdb8b..5a9066e120 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3713,6 +3713,7 @@ void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source import->source_code = source_code; import->path = full_path; g->root_import = import; + import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import); init(g, full_path); @@ -3734,11 +3735,6 @@ void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source } } -void codegen_render_ast(CodeGen *g, FILE *f, int indent_size) { - ast_render(stdout, g->root_import->root, 4); -} - - static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package, const char *basename) { Buf *std_dir = g->zig_std_dir; Buf *code_basename = buf_create_from_str(basename); diff --git a/src/ir.cpp b/src/ir.cpp index b4475499d3..ad589b8294 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5031,7 +5031,8 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, TldContainer *tld_container = allocate(1); init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, parent_scope); - TypeTableEntry *container_type = get_partial_container_type(irb->codegen, parent_scope, kind, node, buf_ptr(name)); + TypeTableEntry *container_type = get_partial_container_type(irb->codegen, parent_scope, kind, node, buf_ptr(name), + node->data.container_decl.is_extern); ScopeDecls *child_scope = get_container_scope(container_type); tld_container->type_entry = container_type; diff --git a/src/main.cpp b/src/main.cpp index ca283df97f..1f8fb5132f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,13 +5,14 @@ * See http://opensource.org/licenses/MIT */ -#include "config.h" +#include "ast_render.hpp" #include "buffer.hpp" #include "codegen.hpp" -#include "os.hpp" +#include "config.h" #include "error.hpp" -#include "target.hpp" #include "link.hpp" +#include "os.hpp" +#include "target.hpp" #include @@ -410,7 +411,7 @@ int main(int argc, char **argv) { return EXIT_SUCCESS; } else if (cmd == CmdParseH) { codegen_parseh(g, &root_source_dir, &root_source_name, &root_source_code); - codegen_render_ast(g, stdout, 4); + ast_render_decls(stdout, 4, g->root_import); return EXIT_SUCCESS; } else if (cmd == CmdTest) { codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); diff --git a/src/parseh.cpp b/src/parseh.cpp index aeadf2ae75..dcd34d342d 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -687,7 +687,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) const EnumDecl *enum_def = enum_decl->getDefinition(); if (!enum_def) { TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, - ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); + ContainerKindEnum, c->source_node, buf_ptr(full_type_name), true); enum_type->data.enumeration.zero_bits_known = true; c->enum_type_table.put(bare_name, enum_type); c->decl_table.put(enum_decl, enum_type); @@ -712,7 +712,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) if (pure_enum) { TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, - ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); + ContainerKindEnum, c->source_node, buf_ptr(full_type_name), true); c->enum_type_table.put(bare_name, enum_type); c->decl_table.put(enum_decl, enum_type); @@ -852,7 +852,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, - ContainerKindStruct, c->source_node, buf_ptr(full_type_name)); + ContainerKindStruct, c->source_node, buf_ptr(full_type_name), true); struct_type->data.structure.zero_bits_known = true; c->struct_type_table.put(bare_name, struct_type);