| ... | ... | @@ -3744,6 +3744,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 3744 | 3744 | return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); |
| 3745 | 3745 | } |
| 3746 | 3746 | |
| 3747 | |
| 3747 | 3748 | bool pure_enum = true; |
| 3748 | 3749 | uint32_t field_count = 0; |
| 3749 | 3750 | for (auto it = enum_def->enumerator_begin(), |
| ... | ... | @@ -3755,84 +3756,53 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 3755 | 3756 | pure_enum = false; |
| 3756 | 3757 | } |
| 3757 | 3758 | } |
| 3758 | | |
| 3759 | 3759 | AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); |
| 3760 | 3760 | assert(tag_int_type); |
| 3761 | 3761 | |
| 3762 | | if (pure_enum) { |
| 3763 | | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); |
| 3764 | | enum_node->data.container_decl.kind = ContainerKindEnum; |
| 3765 | | enum_node->data.container_decl.layout = ContainerLayoutExtern; |
| 3766 | | // TODO only emit this tag type if the enum tag type is not the default. |
| 3767 | | // I don't know what the default is, need to figure out how clang is deciding. |
| 3768 | | // it appears to at least be different across gcc/msvc |
| 3769 | | if (!c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::UInt) && |
| 3770 | | !c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::Int)) |
| 3771 | | { |
| 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 | | } |
| 3762 | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); |
| 3763 | enum_node->data.container_decl.kind = ContainerKindEnum; |
| 3764 | enum_node->data.container_decl.layout = ContainerLayoutExtern; |
| 3765 | // 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 | // it appears to at least be different across gcc/msvc |
| 3768 | if (!c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::UInt) && |
| 3769 | !c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::Int)) |
| 3770 | { |
| 3771 | enum_node->data.container_decl.init_arg_expr = tag_int_type; |
| 3818 | 3772 | } |
| 3819 | | |
| 3820 | | // TODO after issue #305 is solved, make this be an enum with tag_int_type |
| 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 |
| 3773 | enum_node->data.container_decl.fields.resize(field_count); |
| 3774 | uint32_t i = 0; |
| 3826 | 3775 | for (auto it = enum_def->enumerator_begin(), |
| 3827 | 3776 | it_end = enum_def->enumerator_end(); |
| 3828 | | it != it_end; ++it) |
| 3777 | it != it_end; ++it, i += 1) |
| 3829 | 3778 | { |
| 3830 | 3779 | const EnumConstantDecl *enum_const = *it; |
| 3831 | 3780 | |
| 3832 | 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()); |
| 3834 | | AstNode *var_node = add_global_var(c, enum_val_name, int_node); |
| 3835 | | var_node->data.variable_declaration.type = tag_int_type; |
| 3782 | Buf *field_name; |
| 3783 | if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) { |
| 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 | 3808 | if (is_anonymous) { |
| ... | ... | @@ -3843,7 +3813,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 3843 | 3813 | add_global_weak_alias(c, bare_name, full_type_name); |
| 3844 | 3814 | add_global_var(c, full_type_name, enum_node); |
| 3845 | 3815 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); |
| 3846 | | return symbol_node; |
| 3816 | return enum_node; |
| 3847 | 3817 | } |
| 3848 | 3818 | } |
| 3849 | 3819 | |