| ... | ... | @@ -30,8 +30,8 @@ struct MacroSymbol { |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | 32 | struct Alias { |
| 33 | | Buf *name; |
| 34 | | AstNode *node; |
| 33 | Buf *new_name; |
| 34 | Buf *canon_name; |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | 37 | struct Context { |
| ... | ... | @@ -85,10 +85,10 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma |
| 85 | 85 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | | static void add_global_weak_alias(Context *c, Buf *name, AstNode *node) { |
| 88 | static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) { |
| 89 | 89 | Alias *alias = c->aliases.add_one(); |
| 90 | | alias->name = name; |
| 91 | | alias->node = node; |
| 90 | alias->new_name = new_name; |
| 91 | alias->canon_name = canon_name; |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | static AstNode * trans_create_node(Context *c, NodeType id) { |
| ... | ... | @@ -128,7 +128,7 @@ static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *na |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | 130 | static AstNode *trans_create_node_opaque(Context *c) { |
| 131 | | return trans_create_node_builtin_fn_call_str(c, "opaque"); |
| 131 | return trans_create_node_builtin_fn_call_str(c, "OpaqueType"); |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) { |
| ... | ... | @@ -209,7 +209,7 @@ static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_n |
| 209 | 209 | static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) { |
| 210 | 210 | AstNode *fn_def = trans_create_node(c, NodeTypeFnDef); |
| 211 | 211 | AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto); |
| 212 | | fn_proto->data.fn_proto.visib_mod = c->visib_mod;; |
| 212 | fn_proto->data.fn_proto.visib_mod = c->visib_mod; |
| 213 | 213 | fn_proto->data.fn_proto.name = fn_name; |
| 214 | 214 | fn_proto->data.fn_proto.is_inline = true; |
| 215 | 215 | fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias? |
| ... | ... | @@ -559,6 +559,7 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo |
| 559 | 559 | switch (fn_proto_ty->getCallConv()) { |
| 560 | 560 | case CC_C: // __attribute__((cdecl)) |
| 561 | 561 | proto_node->data.fn_proto.cc = CallingConventionC; |
| 562 | proto_node->data.fn_proto.is_extern = true; |
| 562 | 563 | break; |
| 563 | 564 | case CC_X86StdCall: // __attribute__((stdcall)) |
| 564 | 565 | proto_node->data.fn_proto.cc = CallingConventionStdcall; |
| ... | ... | @@ -646,9 +647,7 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo |
| 646 | 647 | AstNode *param_node = trans_create_node(c, NodeTypeParamDecl); |
| 647 | 648 | //emit_warning(c, source_loc, "TODO figure out fn prototype param name"); |
| 648 | 649 | const char *param_name = nullptr; |
| 649 | | if (param_name == nullptr) { |
| 650 | | param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i); |
| 651 | | } else { |
| 650 | if (param_name != nullptr) { |
| 652 | 651 | param_node->data.param_decl.name = buf_create_from_str(param_name); |
| 653 | 652 | } |
| 654 | 653 | param_node->data.param_decl.is_noalias = qt.isRestrictQualified(); |
| ... | ... | @@ -1662,7 +1661,14 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 1662 | 1661 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 1663 | 1662 | const ParmVarDecl *param = fn_decl->getParamDecl(i); |
| 1664 | 1663 | const char *name = decl_name(param); |
| 1665 | | if (strlen(name) != 0) { |
| 1664 | if (strlen(name) == 0) { |
| 1665 | Buf *proto_param_name = param_node->data.param_decl.name; |
| 1666 | if (proto_param_name == nullptr) { |
| 1667 | param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i); |
| 1668 | } else { |
| 1669 | param_node->data.param_decl.name = proto_param_name; |
| 1670 | } |
| 1671 | } else { |
| 1666 | 1672 | param_node->data.param_decl.name = buf_create_from_str(name); |
| 1667 | 1673 | } |
| 1668 | 1674 | } |
| ... | ... | @@ -1714,6 +1720,22 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) |
| 1714 | 1720 | c->global_type_table.put(type_name, type_node); |
| 1715 | 1721 | } |
| 1716 | 1722 | |
| 1723 | struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl, |
| 1724 | Buf *full_type_name, Buf *bare_name) |
| 1725 | { |
| 1726 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1727 | if (full_type_name == nullptr) { |
| 1728 | c->decl_table.put(enum_decl, opaque_node); |
| 1729 | return opaque_node; |
| 1730 | } |
| 1731 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 1732 | c->enum_type_table.put(bare_name, symbol_node); |
| 1733 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1734 | add_global_var(c, full_type_name, opaque_node); |
| 1735 | c->decl_table.put(enum_decl, symbol_node); |
| 1736 | return symbol_node; |
| 1737 | } |
| 1738 | |
| 1717 | 1739 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 1718 | 1740 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl); |
| 1719 | 1741 | if (existing_entry) { |
| ... | ... | @@ -1727,14 +1749,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 1727 | 1749 | |
| 1728 | 1750 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 1729 | 1751 | if (!enum_def) { |
| 1730 | | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1731 | | if (!is_anonymous) { |
| 1732 | | c->enum_type_table.put(bare_name, opaque_node); |
| 1733 | | add_global_weak_alias(c, bare_name, opaque_node); |
| 1734 | | add_global_var(c, full_type_name, opaque_node); |
| 1735 | | } |
| 1736 | | c->decl_table.put(enum_decl, opaque_node); |
| 1737 | | return opaque_node; |
| 1752 | return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); |
| 1738 | 1753 | } |
| 1739 | 1754 | |
| 1740 | 1755 | bool pure_enum = true; |
| ... | ... | @@ -1786,14 +1801,17 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 1786 | 1801 | add_global_var(c, enum_val_name, field_access_node); |
| 1787 | 1802 | } |
| 1788 | 1803 | |
| 1789 | | if (!is_anonymous) { |
| 1790 | | c->enum_type_table.put(bare_name, enum_node); |
| 1791 | | add_global_weak_alias(c, bare_name, enum_node); |
| 1804 | if (is_anonymous) { |
| 1805 | c->decl_table.put(enum_decl, enum_node); |
| 1806 | return enum_node; |
| 1807 | } else { |
| 1808 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 1809 | c->enum_type_table.put(bare_name, symbol_node); |
| 1810 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1792 | 1811 | add_global_var(c, full_type_name, enum_node); |
| 1812 | c->decl_table.put(enum_decl, symbol_node); |
| 1813 | return enum_node; |
| 1793 | 1814 | } |
| 1794 | | c->decl_table.put(enum_decl, enum_node); |
| 1795 | | |
| 1796 | | return enum_node; |
| 1797 | 1815 | } |
| 1798 | 1816 | |
| 1799 | 1817 | // TODO after issue #305 is solved, make this be an enum with tag_int_type |
| ... | ... | @@ -1814,14 +1832,32 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 1814 | 1832 | var_node->data.variable_declaration.type = tag_int_type; |
| 1815 | 1833 | } |
| 1816 | 1834 | |
| 1817 | | if (!is_anonymous) { |
| 1818 | | c->enum_type_table.put(bare_name, enum_node); |
| 1819 | | add_global_weak_alias(c, bare_name, enum_node); |
| 1835 | if (is_anonymous) { |
| 1836 | c->decl_table.put(enum_decl, enum_node); |
| 1837 | return enum_node; |
| 1838 | } else { |
| 1839 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 1840 | c->enum_type_table.put(bare_name, symbol_node); |
| 1841 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1820 | 1842 | add_global_var(c, full_type_name, enum_node); |
| 1843 | return symbol_node; |
| 1821 | 1844 | } |
| 1822 | | c->decl_table.put(enum_decl, enum_node); |
| 1845 | } |
| 1823 | 1846 | |
| 1824 | | return enum_node; |
| 1847 | static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl, |
| 1848 | Buf *full_type_name, Buf *bare_name) |
| 1849 | { |
| 1850 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1851 | if (full_type_name == nullptr) { |
| 1852 | c->decl_table.put(record_decl, opaque_node); |
| 1853 | return opaque_node; |
| 1854 | } |
| 1855 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 1856 | c->struct_type_table.put(bare_name, symbol_node); |
| 1857 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1858 | add_global_var(c, full_type_name, opaque_node); |
| 1859 | c->decl_table.put(record_decl, symbol_node); |
| 1860 | return symbol_node; |
| 1825 | 1861 | } |
| 1826 | 1862 | |
| 1827 | 1863 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| ... | ... | @@ -1834,7 +1870,6 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1834 | 1870 | |
| 1835 | 1871 | if (!record_decl->isStruct()) { |
| 1836 | 1872 | emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name); |
| 1837 | | c->decl_table.put(record_decl, nullptr); |
| 1838 | 1873 | return nullptr; |
| 1839 | 1874 | } |
| 1840 | 1875 | |
| ... | ... | @@ -1844,14 +1879,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1844 | 1879 | |
| 1845 | 1880 | RecordDecl *record_def = record_decl->getDefinition(); |
| 1846 | 1881 | if (record_def == nullptr) { |
| 1847 | | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1848 | | if (!is_anonymous) { |
| 1849 | | c->struct_type_table.put(bare_name, opaque_node); |
| 1850 | | add_global_weak_alias(c, bare_name, opaque_node); |
| 1851 | | add_global_var(c, full_type_name, opaque_node); |
| 1852 | | } |
| 1853 | | c->decl_table.put(record_decl, opaque_node); |
| 1854 | | return opaque_node; |
| 1882 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 1855 | 1883 | } |
| 1856 | 1884 | |
| 1857 | 1885 | // count fields and validate |
| ... | ... | @@ -1865,16 +1893,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1865 | 1893 | if (field_decl->isBitField()) { |
| 1866 | 1894 | emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield", |
| 1867 | 1895 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 1868 | | |
| 1869 | | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1870 | | |
| 1871 | | if (!is_anonymous) { |
| 1872 | | c->struct_type_table.put(bare_name, opaque_node); |
| 1873 | | add_global_weak_alias(c, bare_name, opaque_node); |
| 1874 | | add_global_var(c, full_type_name, opaque_node); |
| 1875 | | } |
| 1876 | | c->decl_table.put(record_decl, opaque_node); |
| 1877 | | return opaque_node;; |
| 1896 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 1878 | 1897 | } |
| 1879 | 1898 | } |
| 1880 | 1899 | |
| ... | ... | @@ -1887,12 +1906,14 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1887 | 1906 | struct_node->data.container_decl.fields.resize(field_count); |
| 1888 | 1907 | |
| 1889 | 1908 | // must be before fields in case a circular reference happens |
| 1890 | | if (!is_anonymous) { |
| 1909 | if (is_anonymous) { |
| 1910 | c->decl_table.put(record_decl, struct_node); |
| 1911 | } else { |
| 1891 | 1912 | c->struct_type_table.put(bare_name, struct_node); |
| 1892 | | add_global_weak_alias(c, bare_name, struct_node); |
| 1913 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1893 | 1914 | add_global_var(c, full_type_name, struct_node); |
| 1915 | c->decl_table.put(record_decl, trans_create_node_symbol(c, full_type_name)); |
| 1894 | 1916 | } |
| 1895 | | c->decl_table.put(record_decl, struct_node); |
| 1896 | 1917 | |
| 1897 | 1918 | uint32_t i = 0; |
| 1898 | 1919 | for (auto it = record_def->field_begin(), |
| ... | ... | @@ -1910,22 +1931,17 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1910 | 1931 | "struct %s demoted to opaque type - unresolved type", |
| 1911 | 1932 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 1912 | 1933 | |
| 1913 | | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1914 | | if (!is_anonymous) { |
| 1915 | | c->struct_type_table.put(bare_name, opaque_node); |
| 1916 | | add_global_weak_alias(c, bare_name, opaque_node); |
| 1917 | | add_global_var(c, full_type_name, opaque_node); |
| 1918 | | } |
| 1919 | | c->decl_table.put(record_decl, opaque_node); |
| 1920 | | |
| 1921 | | return opaque_node; |
| 1934 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 1922 | 1935 | } |
| 1923 | 1936 | |
| 1924 | 1937 | struct_node->data.container_decl.fields.items[i] = field_node; |
| 1925 | 1938 | } |
| 1926 | 1939 | |
| 1927 | | |
| 1928 | | return struct_node; |
| 1940 | if (is_anonymous) { |
| 1941 | return struct_node; |
| 1942 | } else { |
| 1943 | return trans_create_node_symbol(c, full_type_name); |
| 1944 | } |
| 1929 | 1945 | } |
| 1930 | 1946 | |
| 1931 | 1947 | static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| ... | ... | @@ -2045,10 +2061,10 @@ static bool name_exists(Context *c, Buf *name) { |
| 2045 | 2061 | static void render_aliases(Context *c) { |
| 2046 | 2062 | for (size_t i = 0; i < c->aliases.length; i += 1) { |
| 2047 | 2063 | Alias *alias = &c->aliases.at(i); |
| 2048 | | if (name_exists(c, alias->name)) |
| 2064 | if (name_exists(c, alias->new_name)) |
| 2049 | 2065 | continue; |
| 2050 | 2066 | |
| 2051 | | add_global_var(c, alias->name, alias->node); |
| 2067 | add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name)); |
| 2052 | 2068 | } |
| 2053 | 2069 | } |
| 2054 | 2070 | |
| ... | ... | @@ -2174,7 +2190,7 @@ static void process_symbol_macros(Context *c) { |
| 2174 | 2190 | } |
| 2175 | 2191 | } |
| 2176 | 2192 | |
| 2177 | | add_global_var(c, ms.name, existing_node); |
| 2193 | add_global_var(c, ms.name, trans_create_node_symbol(c, ms.value)); |
| 2178 | 2194 | } |
| 2179 | 2195 | } |
| 2180 | 2196 | |