| ... | ... | @@ -20,6 +20,11 @@ |
| 20 | 20 | |
| 21 | 21 | using namespace clang; |
| 22 | 22 | |
| 23 | struct MacroSymbol { |
| 24 | Buf *name; |
| 25 | Buf *value; |
| 26 | }; |
| 27 | |
| 23 | 28 | struct Context { |
| 24 | 29 | ImportTableEntry *import; |
| 25 | 30 | ZigList<ErrorMsg *> *errors; |
| ... | ... | @@ -27,13 +32,14 @@ struct Context { |
| 27 | 32 | VisibMod visib_mod; |
| 28 | 33 | bool have_c_void_decl_node; |
| 29 | 34 | AstNode *root; |
| 30 | | HashMap<Buf *, bool, buf_hash, buf_eql_buf> root_type_table; |
| 35 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> root_name_table; |
| 31 | 36 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> struct_type_table; |
| 32 | 37 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> enum_type_table; |
| 33 | 38 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; |
| 34 | 39 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 35 | 40 | SourceManager *source_manager; |
| 36 | 41 | ZigList<AstNode *> aliases; |
| 42 | ZigList<MacroSymbol> macro_symbols; |
| 37 | 43 | }; |
| 38 | 44 | |
| 39 | 45 | static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl); |
| ... | ... | @@ -169,7 +175,7 @@ static AstNode *add_typedef_node(Context *c, Buf *new_name, AstNode *target_node |
| 169 | 175 | } |
| 170 | 176 | AstNode *node = create_var_decl_node(c, buf_ptr(new_name), target_node); |
| 171 | 177 | |
| 172 | | c->root_type_table.put(new_name, true); |
| 178 | c->root_name_table.put(new_name, true); |
| 173 | 179 | c->root->data.root.top_level_decls.append(node); |
| 174 | 180 | return node; |
| 175 | 181 | } |
| ... | ... | @@ -453,7 +459,7 @@ static AstNode *make_qual_type_node_with_table(Context *c, QualType qt, const De |
| 453 | 459 | } |
| 454 | 460 | |
| 455 | 461 | static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl) { |
| 456 | | return make_qual_type_node_with_table(c, qt, decl, &c->root_type_table); |
| 462 | return make_qual_type_node_with_table(c, qt, decl, &c->root_name_table); |
| 457 | 463 | } |
| 458 | 464 | |
| 459 | 465 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| ... | ... | @@ -576,13 +582,12 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 576 | 582 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); |
| 577 | 583 | return; |
| 578 | 584 | } |
| 579 | | Buf enum_val_name = BUF_INIT; |
| 580 | | buf_init_from_str(&enum_val_name, decl_name(enum_const)); |
| 585 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 581 | 586 | |
| 582 | 587 | Buf field_name = BUF_INIT; |
| 583 | 588 | |
| 584 | | if (buf_starts_with_buf(&enum_val_name, bare_name)) { |
| 585 | | Buf *slice = buf_slice(&enum_val_name, buf_len(bare_name), buf_len(&enum_val_name)); |
| 589 | if (buf_starts_with_buf(enum_val_name, bare_name)) { |
| 590 | Buf *slice = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 586 | 591 | if (valid_symbol_starter(buf_ptr(slice)[0])) { |
| 587 | 592 | buf_init_from_buf(&field_name, slice); |
| 588 | 593 | } else { |
| ... | ... | @@ -590,7 +595,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 590 | 595 | buf_appendf(&field_name, "_%s", buf_ptr(slice)); |
| 591 | 596 | } |
| 592 | 597 | } else { |
| 593 | | buf_init_from_buf(&field_name, &enum_val_name); |
| 598 | buf_init_from_buf(&field_name, enum_val_name); |
| 594 | 599 | } |
| 595 | 600 | |
| 596 | 601 | AstNode *field_node = create_struct_field_node(c, buf_ptr(&field_name), create_symbol_node(c, "void")); |
| ... | ... | @@ -598,8 +603,9 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 598 | 603 | |
| 599 | 604 | // in C each enum value is in the global namespace. so we put them there too. |
| 600 | 605 | AstNode *field_access_node = create_field_access_node(c, buf_ptr(full_type_name), buf_ptr(&field_name)); |
| 601 | | AstNode *var_node = create_var_decl_node(c, buf_ptr(&enum_val_name), field_access_node); |
| 606 | AstNode *var_node = create_var_decl_node(c, buf_ptr(enum_val_name), field_access_node); |
| 602 | 607 | var_decls.append(var_node); |
| 608 | c->root_name_table.put(enum_val_name, true); |
| 603 | 609 | } |
| 604 | 610 | |
| 605 | 611 | normalize_parent_ptrs(node); |
| ... | ... | @@ -704,18 +710,25 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 704 | 710 | return true; |
| 705 | 711 | } |
| 706 | 712 | |
| 713 | static bool name_exists(Context *c, Buf *name) { |
| 714 | if (c->root_name_table.maybe_get(name)) { |
| 715 | return true; |
| 716 | } |
| 717 | if (c->fn_table.maybe_get(name)) { |
| 718 | return true; |
| 719 | } |
| 720 | if (c->macro_table.maybe_get(name)) { |
| 721 | return true; |
| 722 | } |
| 723 | return false; |
| 724 | } |
| 725 | |
| 707 | 726 | static void render_aliases(Context *c) { |
| 708 | 727 | for (int i = 0; i < c->aliases.length; i += 1) { |
| 709 | 728 | AstNode *alias_node = c->aliases.at(i); |
| 710 | 729 | assert(alias_node->type == NodeTypeVariableDeclaration); |
| 711 | 730 | Buf *name = &alias_node->data.variable_declaration.symbol; |
| 712 | | if (c->root_type_table.maybe_get(name)) { |
| 713 | | continue; |
| 714 | | } |
| 715 | | if (c->fn_table.maybe_get(name)) { |
| 716 | | continue; |
| 717 | | } |
| 718 | | if (c->macro_table.maybe_get(name)) { |
| 731 | if (name_exists(c, name)) { |
| 719 | 732 | continue; |
| 720 | 733 | } |
| 721 | 734 | c->root->data.root.top_level_decls.append(alias_node); |
| ... | ... | @@ -791,7 +804,30 @@ static int parse_c_num_lit_unsigned(Buf *buf, uint64_t *out_val) { |
| 791 | 804 | return 0; |
| 792 | 805 | } |
| 793 | 806 | |
| 807 | static bool is_simple_symbol(Buf *buf) { |
| 808 | bool first = true; |
| 809 | for (int i = 0; i < buf_len(buf); i += 1) { |
| 810 | uint8_t c = buf_ptr(buf)[i]; |
| 811 | bool valid_alpha = (c >= 'a' && c <= 'z') || |
| 812 | (c >= 'A' && c <= 'Z') || c == '_'; |
| 813 | bool valid_digit = (c >= '0' && c <= '9'); |
| 814 | |
| 815 | bool ok = (valid_alpha || (!first && valid_digit)); |
| 816 | first = false; |
| 817 | |
| 818 | if (!ok) { |
| 819 | return false; |
| 820 | } |
| 821 | } |
| 822 | return true; |
| 823 | } |
| 824 | |
| 794 | 825 | static void process_macro(Context *c, Buf *name, Buf *value) { |
| 826 | //fprintf(stderr, "macro '%s' = '%s'\n", buf_ptr(name), buf_ptr(value)); |
| 827 | if (is_zig_keyword(name)) { |
| 828 | return; |
| 829 | } |
| 830 | |
| 795 | 831 | // maybe it's a character literal |
| 796 | 832 | uint8_t ch; |
| 797 | 833 | if (!parse_c_char_lit(value, &ch)) { |
| ... | ... | @@ -811,7 +847,20 @@ static void process_macro(Context *c, Buf *name, Buf *value) { |
| 811 | 847 | } |
| 812 | 848 | |
| 813 | 849 | // maybe it's a symbol |
| 814 | | // TODO |
| 850 | if (is_simple_symbol(value)) { |
| 851 | c->macro_symbols.append({name, value}); |
| 852 | } |
| 853 | } |
| 854 | |
| 855 | static void process_symbol_macros(Context *c) { |
| 856 | for (int i = 0; i < c->macro_symbols.length; i += 1) { |
| 857 | MacroSymbol ms = c->macro_symbols.at(i); |
| 858 | if (name_exists(c, ms.value)) { |
| 859 | AstNode *var_node = create_var_decl_node(c, buf_ptr(ms.name), |
| 860 | create_symbol_node(c, buf_ptr(ms.value))); |
| 861 | c->macro_table.put(ms.name, var_node); |
| 862 | } |
| 863 | } |
| 815 | 864 | } |
| 816 | 865 | |
| 817 | 866 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| ... | ... | @@ -885,7 +934,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, |
| 885 | 934 | c->import = import; |
| 886 | 935 | c->errors = errors; |
| 887 | 936 | c->visib_mod = VisibModPub; |
| 888 | | c->root_type_table.init(8); |
| 937 | c->root_name_table.init(8); |
| 889 | 938 | c->enum_type_table.init(8); |
| 890 | 939 | c->struct_type_table.init(8); |
| 891 | 940 | c->fn_table.init(8); |
| ... | ... | @@ -991,6 +1040,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, |
| 991 | 1040 | |
| 992 | 1041 | process_preprocessor_entities(c, *ast_unit); |
| 993 | 1042 | |
| 1043 | process_symbol_macros(c); |
| 1044 | |
| 994 | 1045 | render_macros(c); |
| 995 | 1046 | render_aliases(c); |
| 996 | 1047 | |