| ... | @@ -3744,6 +3744,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -3744,6 +3744,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 3744 | return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); | 3744 | return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); |
| 3745 | } | 3745 | } |
| 3746 | | 3746 | |
| | 3747 | |
| 3747 | bool pure_enum = true; | 3748 | bool pure_enum = true; |
| 3748 | uint32_t field_count = 0; | 3749 | uint32_t field_count = 0; |
| 3749 | for (auto it = enum_def->enumerator_begin(), | 3750 | for (auto it = enum_def->enumerator_begin(), |
| ... | @@ -3755,84 +3756,53 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -3755,84 +3756,53 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 3755 | pure_enum = false; | 3756 | pure_enum = false; |
| 3756 | } | 3757 | } |
| 3757 | } | 3758 | } |
| 3758 | | | |
| 3759 | AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); | 3759 | AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); |
| 3760 | assert(tag_int_type); | 3760 | assert(tag_int_type); |
| 3761 | | 3761 | |
| 3762 | if (pure_enum) { | 3762 | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); |
| 3763 | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); | 3763 | enum_node->data.container_decl.kind = ContainerKindEnum; |
| 3764 | enum_node->data.container_decl.kind = ContainerKindEnum; | 3764 | enum_node->data.container_decl.layout = ContainerLayoutExtern; |
| 3765 | enum_node->data.container_decl.layout = ContainerLayoutExtern; | 3765 | // TODO only emit this tag type if the enum tag type is not the default. |
| 3766 | // TODO only emit this tag type if the enum tag type is not the default. | 3766 | // I don't know what the default is, need to figure out how clang is deciding. |
| 3767 | // I don't know what the default is, need to figure out how clang is deciding. | 3767 | // it appears to at least be different across gcc/msvc |
| 3768 | // it appears to at least be different across gcc/msvc | 3768 | if (!c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::UInt) && |
| 3769 | if (!c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::UInt) && | 3769 | !c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::Int)) |
| 3770 | !c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::Int)) | 3770 | { |
| 3771 | { | 3771 | enum_node->data.container_decl.init_arg_expr = tag_int_type; |
| 3772 | enum_node->data.container_decl.init_arg_expr = tag_int_type; | | |
| 3773 | } | | |
| 3774 | | | |
| 3775 | enum_node->data.container_decl.fields.resize(field_count); | | |
| 3776 | uint32_t i = 0; | | |
| 3777 | for (auto it = enum_def->enumerator_begin(), | | |
| 3778 | it_end = enum_def->enumerator_end(); | | |
| 3779 | it != it_end; ++it, i += 1) | | |
| 3780 | { | | |
| 3781 | const EnumConstantDecl *enum_const = *it; | | |
| 3782 | | | |
| 3783 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | | |
| 3784 | Buf *field_name; | | |
| 3785 | if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) { | | |
| 3786 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); | | |
| 3787 | } else { | | |
| 3788 | field_name = enum_val_name; | | |
| 3789 | } | | |
| 3790 | | | |
| 3791 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); | | |
| 3792 | field_node->data.struct_field.name = field_name; | | |
| 3793 | field_node->data.struct_field.type = nullptr; | | |
| 3794 | enum_node->data.container_decl.fields.items[i] = field_node; | | |
| 3795 | | | |
| 3796 | // in C each enum value is in the global namespace. so we put them there too. | | |
| 3797 | // at this point we can rely on the enum emitting successfully | | |
| 3798 | if (is_anonymous) { | | |
| 3799 | AstNode *lit_node = trans_create_node_unsigned(c, i); | | |
| 3800 | add_global_var(c, enum_val_name, lit_node); | | |
| 3801 | } else { | | |
| 3802 | AstNode *field_access_node = trans_create_node_field_access(c, | | |
| 3803 | trans_create_node_symbol(c, full_type_name), field_name); | | |
| 3804 | add_global_var(c, enum_val_name, field_access_node); | | |
| 3805 | } | | |
| 3806 | } | | |
| 3807 | | | |
| 3808 | if (is_anonymous) { | | |
| 3809 | c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node); | | |
| 3810 | return enum_node; | | |
| 3811 | } else { | | |
| 3812 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); | | |
| 3813 | add_global_weak_alias(c, bare_name, full_type_name); | | |
| 3814 | add_global_var(c, full_type_name, enum_node); | | |
| 3815 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); | | |
| 3816 | return enum_node; | | |
| 3817 | } | | |
| 3818 | } | 3772 | } |
| 3819 | | 3773 | enum_node->data.container_decl.fields.resize(field_count); |
| 3820 | // TODO after issue #305 is solved, make this be an enum with tag_int_type | 3774 | uint32_t i = 0; |
| 3821 | // as the integer type and set the custom enum values | | |
| 3822 | AstNode *enum_node = tag_int_type; | | |
| 3823 | | | |
| 3824 | | | |
| 3825 | // add variables for all the values with enum_node | | |
| 3826 | for (auto it = enum_def->enumerator_begin(), | 3775 | for (auto it = enum_def->enumerator_begin(), |
| 3827 | it_end = enum_def->enumerator_end(); | 3776 | it_end = enum_def->enumerator_end(); |
| 3828 | it != it_end; ++it) | 3777 | it != it_end; ++it, i += 1) |
| 3829 | { | 3778 | { |
| 3830 | const EnumConstantDecl *enum_const = *it; | 3779 | const EnumConstantDecl *enum_const = *it; |
| 3831 | | 3780 | |
| 3832 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | 3781 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 3833 | AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal()); | 3782 | Buf *field_name; |
| 3834 | AstNode *var_node = add_global_var(c, enum_val_name, int_node); | 3783 | if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) { |
| 3835 | var_node->data.variable_declaration.type = tag_int_type; | 3784 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| | 3785 | } else { |
| | 3786 | field_name = enum_val_name; |
| | 3787 | } |
| | 3788 | |
| | 3789 | AstNode *int_node = pure_enum && !is_anonymous ? nullptr : trans_create_node_apint(c, enum_const->getInitVal()); |
| | 3790 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| | 3791 | field_node->data.struct_field.name = field_name; |
| | 3792 | field_node->data.struct_field.type = nullptr; |
| | 3793 | field_node->data.struct_field.value = int_node; |
| | 3794 | enum_node->data.container_decl.fields.items[i] = field_node; |
| | 3795 | |
| | 3796 | // in C each enum value is in the global namespace. so we put them there too. |
| | 3797 | // at this point we can rely on the enum emitting successfully |
| | 3798 | if (is_anonymous) { |
| | 3799 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| | 3800 | add_global_var(c, enum_val_name, int_node); |
| | 3801 | } else { |
| | 3802 | AstNode *field_access_node = trans_create_node_field_access(c, |
| | 3803 | trans_create_node_symbol(c, full_type_name), field_name); |
| | 3804 | add_global_var(c, enum_val_name, field_access_node); |
| | 3805 | } |
| 3836 | } | 3806 | } |
| 3837 | | 3807 | |
| 3838 | if (is_anonymous) { | 3808 | if (is_anonymous) { |
| ... | @@ -3843,7 +3813,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -3843,7 +3813,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 3843 | add_global_weak_alias(c, bare_name, full_type_name); | 3813 | add_global_weak_alias(c, bare_name, full_type_name); |
| 3844 | add_global_var(c, full_type_name, enum_node); | 3814 | add_global_var(c, full_type_name, enum_node); |
| 3845 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); | 3815 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); |
| 3846 | return symbol_node; | 3816 | return enum_node; |
| 3847 | } | 3817 | } |
| 3848 | } | 3818 | } |
| 3849 | | 3819 | |