| ... | @@ -20,6 +20,11 @@ | ... | @@ -20,6 +20,11 @@ |
| 20 | | 20 | |
| 21 | using namespace clang; | 21 | using namespace clang; |
| 22 | | 22 | |
| | 23 | struct MacroSymbol { |
| | 24 | Buf *name; |
| | 25 | Buf *value; |
| | 26 | }; |
| | 27 | |
| 23 | struct Context { | 28 | struct Context { |
| 24 | ImportTableEntry *import; | 29 | ImportTableEntry *import; |
| 25 | ZigList<ErrorMsg *> *errors; | 30 | ZigList<ErrorMsg *> *errors; |
| ... | @@ -27,13 +32,14 @@ struct Context { | ... | @@ -27,13 +32,14 @@ struct Context { |
| 27 | VisibMod visib_mod; | 32 | VisibMod visib_mod; |
| 28 | bool have_c_void_decl_node; | 33 | bool have_c_void_decl_node; |
| 29 | AstNode *root; | 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 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> struct_type_table; | 36 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> struct_type_table; |
| 32 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> enum_type_table; | 37 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> enum_type_table; |
| 33 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; | 38 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; |
| 34 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; | 39 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 35 | SourceManager *source_manager; | 40 | SourceManager *source_manager; |
| 36 | ZigList<AstNode *> aliases; | 41 | ZigList<AstNode *> aliases; |
| | 42 | ZigList<MacroSymbol> macro_symbols; |
| 37 | }; | 43 | }; |
| 38 | | 44 | |
| 39 | static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl); | 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,7 +175,7 @@ static AstNode *add_typedef_node(Context *c, Buf *new_name, AstNode *target_node |
| 169 | } | 175 | } |
| 170 | AstNode *node = create_var_decl_node(c, buf_ptr(new_name), target_node); | 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 | c->root->data.root.top_level_decls.append(node); | 179 | c->root->data.root.top_level_decls.append(node); |
| 174 | return node; | 180 | return node; |
| 175 | } | 181 | } |
| ... | @@ -453,7 +459,7 @@ static AstNode *make_qual_type_node_with_table(Context *c, QualType qt, const De | ... | @@ -453,7 +459,7 @@ static AstNode *make_qual_type_node_with_table(Context *c, QualType qt, const De |
| 453 | } | 459 | } |
| 454 | | 460 | |
| 455 | static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl) { | 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 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | 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,13 +582,12 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 576 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); | 582 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); |
| 577 | return; | 583 | return; |
| 578 | } | 584 | } |
| 579 | Buf enum_val_name = BUF_INIT; | 585 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 580 | buf_init_from_str(&enum_val_name, decl_name(enum_const)); | | |
| 581 | | 586 | |
| 582 | Buf field_name = BUF_INIT; | 587 | Buf field_name = BUF_INIT; |
| 583 | | 588 | |
| 584 | if (buf_starts_with_buf(&enum_val_name, bare_name)) { | 589 | 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)); | 590 | Buf *slice = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 586 | if (valid_symbol_starter(buf_ptr(slice)[0])) { | 591 | if (valid_symbol_starter(buf_ptr(slice)[0])) { |
| 587 | buf_init_from_buf(&field_name, slice); | 592 | buf_init_from_buf(&field_name, slice); |
| 588 | } else { | 593 | } else { |
| ... | @@ -590,7 +595,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -590,7 +595,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 590 | buf_appendf(&field_name, "_%s", buf_ptr(slice)); | 595 | buf_appendf(&field_name, "_%s", buf_ptr(slice)); |
| 591 | } | 596 | } |
| 592 | } else { | 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 | AstNode *field_node = create_struct_field_node(c, buf_ptr(&field_name), create_symbol_node(c, "void")); | 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,8 +603,9 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 598 | | 603 | |
| 599 | // in C each enum value is in the global namespace. so we put them there too. | 604 | // in C each enum value is in the global namespace. so we put them there too. |
| 600 | AstNode *field_access_node = create_field_access_node(c, buf_ptr(full_type_name), buf_ptr(&field_name)); | 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 | var_decls.append(var_node); | 607 | var_decls.append(var_node); |
| | 608 | c->root_name_table.put(enum_val_name, true); |
| 603 | } | 609 | } |
| 604 | | 610 | |
| 605 | normalize_parent_ptrs(node); | 611 | normalize_parent_ptrs(node); |
| ... | @@ -704,18 +710,25 @@ static bool decl_visitor(void *context, const Decl *decl) { | ... | @@ -704,18 +710,25 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 704 | return true; | 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 | static void render_aliases(Context *c) { | 726 | static void render_aliases(Context *c) { |
| 708 | for (int i = 0; i < c->aliases.length; i += 1) { | 727 | for (int i = 0; i < c->aliases.length; i += 1) { |
| 709 | AstNode *alias_node = c->aliases.at(i); | 728 | AstNode *alias_node = c->aliases.at(i); |
| 710 | assert(alias_node->type == NodeTypeVariableDeclaration); | 729 | assert(alias_node->type == NodeTypeVariableDeclaration); |
| 711 | Buf *name = &alias_node->data.variable_declaration.symbol; | 730 | Buf *name = &alias_node->data.variable_declaration.symbol; |
| 712 | if (c->root_type_table.maybe_get(name)) { | 731 | if (name_exists(c, name)) { |
| 713 | continue; | | |
| 714 | } | | |
| 715 | if (c->fn_table.maybe_get(name)) { | | |
| 716 | continue; | | |
| 717 | } | | |
| 718 | if (c->macro_table.maybe_get(name)) { | | |
| 719 | continue; | 732 | continue; |
| 720 | } | 733 | } |
| 721 | c->root->data.root.top_level_decls.append(alias_node); | 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,7 +804,30 @@ static int parse_c_num_lit_unsigned(Buf *buf, uint64_t *out_val) { |
| 791 | return 0; | 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 | static void process_macro(Context *c, Buf *name, Buf *value) { | 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 | // maybe it's a character literal | 831 | // maybe it's a character literal |
| 796 | uint8_t ch; | 832 | uint8_t ch; |
| 797 | if (!parse_c_char_lit(value, &ch)) { | 833 | if (!parse_c_char_lit(value, &ch)) { |
| ... | @@ -811,7 +847,20 @@ static void process_macro(Context *c, Buf *name, Buf *value) { | ... | @@ -811,7 +847,20 @@ static void process_macro(Context *c, Buf *name, Buf *value) { |
| 811 | } | 847 | } |
| 812 | | 848 | |
| 813 | // maybe it's a symbol | 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 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | 866 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| ... | @@ -885,7 +934,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, | ... | @@ -885,7 +934,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, |
| 885 | c->import = import; | 934 | c->import = import; |
| 886 | c->errors = errors; | 935 | c->errors = errors; |
| 887 | c->visib_mod = VisibModPub; | 936 | c->visib_mod = VisibModPub; |
| 888 | c->root_type_table.init(8); | 937 | c->root_name_table.init(8); |
| 889 | c->enum_type_table.init(8); | 938 | c->enum_type_table.init(8); |
| 890 | c->struct_type_table.init(8); | 939 | c->struct_type_table.init(8); |
| 891 | c->fn_table.init(8); | 940 | c->fn_table.init(8); |
| ... | @@ -991,6 +1040,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, | ... | @@ -991,6 +1040,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, |
| 991 | | 1040 | |
| 992 | process_preprocessor_entities(c, *ast_unit); | 1041 | process_preprocessor_entities(c, *ast_unit); |
| 993 | | 1042 | |
| | 1043 | process_symbol_macros(c); |
| | 1044 | |
| 994 | render_macros(c); | 1045 | render_macros(c); |
| 995 | render_aliases(c); | 1046 | render_aliases(c); |
| 996 | | 1047 | |