| ... | @@ -42,6 +42,7 @@ struct Context { | ... | @@ -42,6 +42,7 @@ struct Context { |
| 42 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; | 42 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; |
| 43 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_decl_table; | 43 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_decl_table; |
| 44 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; | 44 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; |
| | 45 | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; |
| 45 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; | 46 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; |
| 46 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; | 47 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 47 | SourceManager *source_manager; | 48 | SourceManager *source_manager; |
| ... | @@ -58,6 +59,7 @@ static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, con | ... | @@ -58,6 +59,7 @@ static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, con |
| 58 | | 59 | |
| 59 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl); | 60 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl); |
| 60 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl); | 61 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl); |
| | 62 | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| 61 | | 63 | |
| 62 | | 64 | |
| 63 | __attribute__ ((format (printf, 3, 4))) | 65 | __attribute__ ((format (printf, 3, 4))) |
| ... | @@ -292,6 +294,7 @@ static const char *decl_name(const Decl *decl) { | ... | @@ -292,6 +294,7 @@ static const char *decl_name(const Decl *decl) { |
| 292 | | 294 | |
| 293 | static AstNode *add_typedef_node(Context *c, TypeTableEntry *type_decl) { | 295 | static AstNode *add_typedef_node(Context *c, TypeTableEntry *type_decl) { |
| 294 | assert(type_decl); | 296 | assert(type_decl); |
| | 297 | assert(type_decl->id == TypeTableEntryIdTypeDecl); |
| 295 | | 298 | |
| 296 | AstNode *node = create_type_decl_node(c, buf_ptr(&type_decl->name), | 299 | AstNode *node = create_type_decl_node(c, buf_ptr(&type_decl->name), |
| 297 | make_type_node(c, type_decl->data.type_decl.child_type)); | 300 | make_type_node(c, type_decl->data.type_decl.child_type)); |
| ... | @@ -310,6 +313,26 @@ static AstNode *add_const_var_node(Context *c, Buf *name, TypeTableEntry *type_e | ... | @@ -310,6 +313,26 @@ static AstNode *add_const_var_node(Context *c, Buf *name, TypeTableEntry *type_e |
| 310 | return node; | 313 | return node; |
| 311 | } | 314 | } |
| 312 | | 315 | |
| | 316 | static AstNode *create_ap_num_lit_node(Context *c, const Decl *source_decl, |
| | 317 | const llvm::APSInt &aps_int) |
| | 318 | { |
| | 319 | if (aps_int.isSigned()) { |
| | 320 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { |
| | 321 | emit_warning(c, source_decl, "integer overflow\n"); |
| | 322 | return nullptr; |
| | 323 | } else { |
| | 324 | return create_num_lit_signed(c, aps_int.getExtValue()); |
| | 325 | } |
| | 326 | } else { |
| | 327 | if (aps_int > INT64_MAX) { |
| | 328 | emit_warning(c, source_decl, "integer overflow\n"); |
| | 329 | return nullptr; |
| | 330 | } else { |
| | 331 | return create_num_lit_unsigned(c, aps_int.getExtValue()); |
| | 332 | } |
| | 333 | } |
| | 334 | } |
| | 335 | |
| 313 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { | 336 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { |
| 314 | while (type_entry->id == TypeTableEntryIdTypeDecl) { | 337 | while (type_entry->id == TypeTableEntryIdTypeDecl) { |
| 315 | if (type_entry == c->codegen->builtin_types.entry_c_void) { | 338 | if (type_entry == c->codegen->builtin_types.entry_c_void) { |
| ... | @@ -586,18 +609,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -586,18 +609,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 586 | case Type::Enum: | 609 | case Type::Enum: |
| 587 | { | 610 | { |
| 588 | const EnumType *enum_ty = static_cast<const EnumType*>(ty); | 611 | const EnumType *enum_ty = static_cast<const EnumType*>(ty); |
| 589 | Buf *record_name = buf_create_from_str(decl_name(enum_ty->getDecl())); | 612 | return resolve_enum_decl(c, enum_ty->getDecl()); |
| 590 | if (buf_len(record_name) == 0) { | | |
| 591 | emit_warning(c, decl, "unhandled anonymous enum"); | | |
| 592 | return c->codegen->builtin_types.entry_invalid; | | |
| 593 | } | | |
| 594 | | | |
| 595 | auto entry = type_table->maybe_get(record_name); | | |
| 596 | if (!entry) { | | |
| 597 | return c->codegen->builtin_types.entry_invalid; | | |
| 598 | } | | |
| 599 | | | |
| 600 | return entry->value; | | |
| 601 | } | 613 | } |
| 602 | case Type::ConstantArray: | 614 | case Type::ConstantArray: |
| 603 | { | 615 | { |
| ... | @@ -759,36 +771,45 @@ static void add_alias(Context *c, const char *new_name, const char *target_name) | ... | @@ -759,36 +771,45 @@ static void add_alias(Context *c, const char *new_name, const char *target_name) |
| 759 | c->aliases.append(alias_node); | 771 | c->aliases.append(alias_node); |
| 760 | } | 772 | } |
| 761 | | 773 | |
| 762 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | 774 | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { |
| | 775 | unsigned line = c->source_node ? c->source_node->line : 0; |
| | 776 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugForwardDeclType(c->codegen->dbuilder, |
| | 777 | LLVMZigTag_DW_structure_type(), buf_ptr(full_type_name), |
| | 778 | LLVMZigFileToScope(c->import->di_file), c->import->di_file, line); |
| | 779 | |
| | 780 | LLVMZigReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); |
| | 781 | struct_type->di_type = replacement_di_type; |
| | 782 | } |
| | 783 | |
| | 784 | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| | 785 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl); |
| | 786 | if (existing_entry) { |
| | 787 | return existing_entry->value; |
| | 788 | } |
| | 789 | |
| 763 | const char *raw_name = decl_name(enum_decl); | 790 | const char *raw_name = decl_name(enum_decl); |
| 764 | // we have no interest in top level anonymous enums since they're | 791 | |
| 765 | // not exposing anything. | 792 | Buf *bare_name; |
| 766 | if (raw_name[0] == 0) { | 793 | if (raw_name[0] == 0) { |
| 767 | return; | 794 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c)); |
| | 795 | } else { |
| | 796 | bare_name = buf_create_from_str(raw_name); |
| 768 | } | 797 | } |
| 769 | | 798 | |
| 770 | Buf *bare_name = buf_create_from_str(raw_name); | | |
| 771 | Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name)); | 799 | Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name)); |
| 772 | | 800 | |
| 773 | if (c->enum_type_table.maybe_get(bare_name)) { | | |
| 774 | // we've already seen it | | |
| 775 | return; | | |
| 776 | } | | |
| 777 | | | |
| 778 | const EnumDecl *enum_def = enum_decl->getDefinition(); | 801 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 779 | | | |
| 780 | if (!enum_def) { | 802 | if (!enum_def) { |
| 781 | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(full_type_name), | 803 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, |
| 782 | c->codegen->builtin_types.entry_u8); | 804 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); |
| 783 | c->enum_type_table.put(bare_name, typedecl_type); | 805 | c->enum_type_table.put(bare_name, enum_type); |
| | 806 | c->decl_table.put(enum_decl, enum_type); |
| | 807 | replace_with_fwd_decl(c, enum_type, full_type_name); |
| 784 | | 808 | |
| 785 | // this is a type that we can point to but that's it, same as `struct Foo;`. | 809 | return enum_type; |
| 786 | add_typedef_node(c, typedecl_type); | | |
| 787 | add_alias(c, buf_ptr(bare_name), buf_ptr(full_type_name)); | | |
| 788 | return; | | |
| 789 | } | 810 | } |
| 790 | | 811 | |
| 791 | // count and validate | 812 | bool pure_enum = true; |
| 792 | uint32_t field_count = 0; | 813 | uint32_t field_count = 0; |
| 793 | for (auto it = enum_def->enumerator_begin(), | 814 | for (auto it = enum_def->enumerator_begin(), |
| 794 | it_end = enum_def->enumerator_end(); | 815 | it_end = enum_def->enumerator_end(); |
| ... | @@ -796,120 +817,156 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -796,120 +817,156 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 796 | { | 817 | { |
| 797 | const EnumConstantDecl *enum_const = *it; | 818 | const EnumConstantDecl *enum_const = *it; |
| 798 | if (enum_const->getInitExpr()) { | 819 | if (enum_const->getInitExpr()) { |
| 799 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); | 820 | pure_enum = false; |
| 800 | return; | | |
| 801 | } | 821 | } |
| 802 | } | 822 | } |
| 803 | | 823 | |
| 804 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, | 824 | TypeTableEntry *tag_type_entry = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl); |
| 805 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); | | |
| 806 | | | |
| 807 | enum_type->data.enumeration.gen_field_count = 0; | | |
| 808 | enum_type->data.enumeration.complete = true; | | |
| 809 | | 825 | |
| 810 | TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(c->codegen, field_count); | 826 | if (pure_enum) { |
| 811 | enum_type->data.enumeration.tag_type = tag_type_entry; | 827 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, |
| | 828 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); |
| | 829 | c->enum_type_table.put(bare_name, enum_type); |
| | 830 | c->decl_table.put(enum_decl, enum_type); |
| 812 | | 831 | |
| 813 | c->enum_type_table.put(bare_name, enum_type); | 832 | enum_type->data.enumeration.gen_field_count = 0; |
| 814 | // make an alias without the "enum_" prefix. this will get emitted at the | 833 | enum_type->data.enumeration.complete = true; |
| 815 | // end if it doesn't conflict with anything else | 834 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 816 | add_alias(c, buf_ptr(bare_name), buf_ptr(full_type_name)); | | |
| 817 | | 835 | |
| 818 | enum_type->data.enumeration.field_count = field_count; | 836 | enum_type->data.enumeration.field_count = field_count; |
| 819 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | 837 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 820 | LLVMZigDIEnumerator **di_enumerators = allocate<LLVMZigDIEnumerator*>(field_count); | 838 | LLVMZigDIEnumerator **di_enumerators = allocate<LLVMZigDIEnumerator*>(field_count); |
| 821 | | 839 | |
| 822 | ZigList<AstNode *> var_decls = {0}; | 840 | uint32_t i = 0; |
| 823 | uint32_t i = 0; | 841 | for (auto it = enum_def->enumerator_begin(), |
| 824 | for (auto it = enum_def->enumerator_begin(), | 842 | it_end = enum_def->enumerator_end(); |
| 825 | it_end = enum_def->enumerator_end(); | 843 | it != it_end; ++it, i += 1) |
| 826 | it != it_end; ++it, i += 1) | 844 | { |
| 827 | { | 845 | const EnumConstantDecl *enum_const = *it; |
| 828 | const EnumConstantDecl *enum_const = *it; | | |
| 829 | | 846 | |
| 830 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | 847 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 831 | Buf *field_name; | 848 | Buf *field_name; |
| 832 | if (buf_starts_with_buf(enum_val_name, bare_name)) { | 849 | if (buf_starts_with_buf(enum_val_name, bare_name)) { |
| 833 | Buf *slice = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); | 850 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 834 | if (valid_symbol_starter(buf_ptr(slice)[0])) { | | |
| 835 | field_name = slice; | | |
| 836 | } else { | 851 | } else { |
| 837 | field_name = buf_sprintf("_%s", buf_ptr(slice)); | 852 | field_name = enum_val_name; |
| 838 | } | 853 | } |
| 839 | } else { | 854 | |
| 840 | field_name = enum_val_name; | 855 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| | 856 | type_enum_field->name = field_name; |
| | 857 | type_enum_field->type_entry = c->codegen->builtin_types.entry_void; |
| | 858 | type_enum_field->value = i; |
| | 859 | |
| | 860 | di_enumerators[i] = LLVMZigCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i); |
| | 861 | |
| | 862 | |
| | 863 | // in C each enum value is in the global namespace. so we put them there too. |
| | 864 | // at this point we can rely on the enum emitting successfully |
| | 865 | AstNode *field_access_node = create_field_access_node(c, buf_ptr(full_type_name), buf_ptr(field_name)); |
| | 866 | AstNode *var_node = create_var_decl_node(c, buf_ptr(enum_val_name), field_access_node); |
| | 867 | c->root->data.root.top_level_decls.append(var_node); |
| | 868 | |
| | 869 | c->global_value_table.put(enum_val_name, {enum_type, true}); |
| 841 | } | 870 | } |
| 842 | | 871 | |
| 843 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 872 | // create llvm type for root struct |
| 844 | type_enum_field->name = field_name; | 873 | enum_type->type_ref = tag_type_entry->type_ref; |
| 845 | type_enum_field->type_entry = c->codegen->builtin_types.entry_void; | | |
| 846 | type_enum_field->value = i; | | |
| 847 | | 874 | |
| 848 | di_enumerators[i] = LLVMZigCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i); | 875 | // create debug type for tag |
| | 876 | unsigned line = c->source_node ? (c->source_node->line + 1) : 0; |
| | 877 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref); |
| | 878 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref); |
| | 879 | LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(c->codegen->dbuilder, |
| | 880 | LLVMZigFileToScope(c->import->di_file), buf_ptr(bare_name), |
| | 881 | c->import->di_file, line, |
| | 882 | debug_size_in_bits, |
| | 883 | debug_align_in_bits, |
| | 884 | di_enumerators, field_count, tag_type_entry->di_type, ""); |
| 849 | | 885 | |
| | 886 | LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type); |
| | 887 | enum_type->di_type = tag_di_type; |
| 850 | | 888 | |
| 851 | // in C each enum value is in the global namespace. so we put them there too. | 889 | return enum_type; |
| 852 | // at this point we can rely on the enum emitting successfully | 890 | } else { |
| 853 | AstNode *field_access_node = create_field_access_node(c, buf_ptr(full_type_name), buf_ptr(field_name)); | 891 | TypeTableEntry *enum_type = get_typedecl_type(c->codegen, buf_ptr(full_type_name), tag_type_entry); |
| 854 | AstNode *var_node = create_var_decl_node(c, buf_ptr(enum_val_name), field_access_node); | 892 | c->enum_type_table.put(bare_name, enum_type); |
| 855 | var_decls.append(var_node); | 893 | c->decl_table.put(enum_decl, enum_type); |
| 856 | c->global_value_table.put(enum_val_name, {enum_type, true}); | | |
| 857 | } | | |
| 858 | | 894 | |
| 859 | // create llvm type for root struct | 895 | // add variables for all the values with enum_type |
| 860 | enum_type->type_ref = tag_type_entry->type_ref; | 896 | for (auto it = enum_def->enumerator_begin(), |
| | 897 | it_end = enum_def->enumerator_end(); |
| | 898 | it != it_end; ++it) |
| | 899 | { |
| | 900 | const EnumConstantDecl *enum_const = *it; |
| | 901 | AstNode *num_lit_node = create_ap_num_lit_node(c, enum_decl, enum_const->getInitVal()); |
| | 902 | if (!num_lit_node) { |
| | 903 | return c->codegen->builtin_types.entry_invalid; |
| | 904 | } |
| 861 | | 905 | |
| 862 | // create debug type for tag | 906 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 863 | unsigned line = c->source_node ? (c->source_node->line + 1) : 0; | | |
| 864 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref); | | |
| 865 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref); | | |
| 866 | LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(c->codegen->dbuilder, | | |
| 867 | LLVMZigFileToScope(c->import->di_file), buf_ptr(bare_name), | | |
| 868 | c->import->di_file, line, | | |
| 869 | debug_size_in_bits, | | |
| 870 | debug_align_in_bits, | | |
| 871 | di_enumerators, field_count, tag_type_entry->di_type, ""); | | |
| 872 | | 907 | |
| 873 | LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type); | 908 | AstNode *type_node = make_type_node(c, enum_type); |
| 874 | enum_type->di_type = tag_di_type; | 909 | AstNode *var_decl_node = create_typed_var_decl_node(c, true, buf_ptr(enum_val_name), |
| | 910 | type_node, num_lit_node); |
| 875 | | 911 | |
| 876 | ////////// | 912 | c->root->data.root.top_level_decls.append(var_decl_node); |
| | 913 | c->global_value_table.put(enum_val_name, {enum_type, true}); |
| 877 | | 914 | |
| 878 | // now create top level decl for the type | 915 | } |
| 879 | AstNode *enum_node = create_node(c, NodeTypeStructDecl); | | |
| 880 | buf_init_from_buf(&enum_node->data.struct_decl.name, full_type_name); | | |
| 881 | enum_node->data.struct_decl.kind = ContainerKindEnum; | | |
| 882 | enum_node->data.struct_decl.top_level_decl.visib_mod = VisibModExport; | | |
| 883 | enum_node->data.struct_decl.type_entry = enum_type; | | |
| 884 | | 916 | |
| 885 | for (uint32_t i = 0; i < field_count; i += 1) { | 917 | return enum_type; |
| 886 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | | |
| 887 | AstNode *type_node = make_type_node(c, type_enum_field->type_entry); | | |
| 888 | AstNode *field_node = create_struct_field_node(c, buf_ptr(type_enum_field->name), type_node); | | |
| 889 | enum_node->data.struct_decl.fields.append(field_node); | | |
| 890 | } | 918 | } |
| | 919 | } |
| 891 | | 920 | |
| 892 | normalize_parent_ptrs(enum_node); | 921 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 893 | c->root->data.root.top_level_decls.append(enum_node); | 922 | TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl); |
| 894 | | 923 | |
| 895 | for (int i = 0; i < var_decls.length; i += 1) { | 924 | if (enum_type->id == TypeTableEntryIdInvalid) { |
| 896 | AstNode *var_node = var_decls.at(i); | 925 | return; |
| 897 | c->root->data.root.top_level_decls.append(var_node); | | |
| 898 | } | 926 | } |
| 899 | | 927 | |
| 900 | } | 928 | // make an alias without the "enum_" prefix. this will get emitted at the |
| | 929 | // end if it doesn't conflict with anything else |
| | 930 | if (decl_name(enum_decl)[0] != 0) { |
| | 931 | add_alias(c, decl_name(enum_decl), buf_ptr(&enum_type->name)); |
| | 932 | } |
| 901 | | 933 | |
| 902 | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { | 934 | if (enum_type->id == TypeTableEntryIdEnum) { |
| 903 | unsigned line = c->source_node ? c->source_node->line : 0; | 935 | if (enum_type->data.enumeration.complete) { |
| 904 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugForwardDeclType(c->codegen->dbuilder, | 936 | // now create top level decl for the type |
| 905 | LLVMZigTag_DW_structure_type(), buf_ptr(full_type_name), | 937 | AstNode *enum_node = create_node(c, NodeTypeStructDecl); |
| 906 | LLVMZigFileToScope(c->import->di_file), c->import->di_file, line); | 938 | buf_init_from_buf(&enum_node->data.struct_decl.name, &enum_type->name); |
| | 939 | enum_node->data.struct_decl.kind = ContainerKindEnum; |
| | 940 | enum_node->data.struct_decl.top_level_decl.visib_mod = VisibModExport; |
| | 941 | enum_node->data.struct_decl.type_entry = enum_type; |
| | 942 | |
| | 943 | for (uint32_t i = 0; i < enum_type->data.enumeration.field_count; i += 1) { |
| | 944 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| | 945 | AstNode *type_node = make_type_node(c, type_enum_field->type_entry); |
| | 946 | AstNode *field_node = create_struct_field_node(c, buf_ptr(type_enum_field->name), type_node); |
| | 947 | enum_node->data.struct_decl.fields.append(field_node); |
| | 948 | } |
| 907 | | 949 | |
| 908 | LLVMZigReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); | 950 | normalize_parent_ptrs(enum_node); |
| 909 | struct_type->di_type = replacement_di_type; | 951 | c->root->data.root.top_level_decls.append(enum_node); |
| | 952 | } else { |
| | 953 | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name), |
| | 954 | c->codegen->builtin_types.entry_u8); |
| | 955 | add_typedef_node(c, typedecl_type); |
| | 956 | } |
| | 957 | } else if (enum_type->id == TypeTableEntryIdTypeDecl) { |
| | 958 | add_typedef_node(c, enum_type); |
| | 959 | } else { |
| | 960 | zig_unreachable(); |
| | 961 | } |
| 910 | } | 962 | } |
| 911 | | 963 | |
| 912 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) { | 964 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| | 965 | auto existing_entry = c->decl_table.maybe_get((void*)record_decl); |
| | 966 | if (existing_entry) { |
| | 967 | return existing_entry->value; |
| | 968 | } |
| | 969 | |
| 913 | const char *raw_name = decl_name(record_decl); | 970 | const char *raw_name = decl_name(record_decl); |
| 914 | | 971 | |
| 915 | if (!record_decl->isStruct()) { | 972 | if (!record_decl->isStruct()) { |
| ... | @@ -922,11 +979,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -922,11 +979,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 922 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c)); | 979 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c)); |
| 923 | } else { | 980 | } else { |
| 924 | bare_name = buf_create_from_str(raw_name); | 981 | bare_name = buf_create_from_str(raw_name); |
| 925 | | | |
| 926 | auto existing_entry = c->struct_type_table.maybe_get(bare_name); | | |
| 927 | if (existing_entry) { | | |
| 928 | return existing_entry->value; | | |
| 929 | } | | |
| 930 | } | 982 | } |
| 931 | | 983 | |
| 932 | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); | 984 | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); |
| ... | @@ -936,6 +988,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -936,6 +988,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 936 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name)); | 988 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name)); |
| 937 | | 989 | |
| 938 | c->struct_type_table.put(bare_name, struct_type); | 990 | c->struct_type_table.put(bare_name, struct_type); |
| | 991 | c->decl_table.put(record_decl, struct_type); |
| 939 | | 992 | |
| 940 | RecordDecl *record_def = record_decl->getDefinition(); | 993 | RecordDecl *record_def = record_decl->getDefinition(); |
| 941 | unsigned line = c->source_node ? c->source_node->line : 0; | 994 | unsigned line = c->source_node ? c->source_node->line : 0; |
| ... | @@ -1125,23 +1178,9 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -1125,23 +1178,9 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 1125 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); | 1178 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); |
| 1126 | return; | 1179 | return; |
| 1127 | } | 1180 | } |
| 1128 | llvm::APSInt aps_int = ap_value->getInt(); | 1181 | init_node = create_ap_num_lit_node(c, var_decl, ap_value->getInt()); |
| 1129 | if (aps_int.isSigned()) { | 1182 | if (!init_node) { |
| 1130 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { | 1183 | return; |
| 1131 | emit_warning(c, var_decl, | | |
| 1132 | "ignoring variable '%s' - initializer overflow\n", buf_ptr(name)); | | |
| 1133 | return; | | |
| 1134 | } else { | | |
| 1135 | init_node = create_num_lit_signed(c, aps_int.getExtValue()); | | |
| 1136 | } | | |
| 1137 | } else { | | |
| 1138 | if (aps_int > UINT64_MAX) { | | |
| 1139 | emit_warning(c, var_decl, | | |
| 1140 | "ignoring variable '%s' - initializer overflow\n", buf_ptr(name)); | | |
| 1141 | return; | | |
| 1142 | } else { | | |
| 1143 | init_node = create_num_lit_unsigned(c, aps_int.getExtValue()); | | |
| 1144 | } | | |
| 1145 | } | 1184 | } |
| 1146 | break; | 1185 | break; |
| 1147 | } | 1186 | } |
| ... | @@ -1360,7 +1399,7 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | ... | @@ -1360,7 +1399,7 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 1360 | case PreprocessedEntity::MacroDefinitionKind: | 1399 | case PreprocessedEntity::MacroDefinitionKind: |
| 1361 | { | 1400 | { |
| 1362 | MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity); | 1401 | MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity); |
| 1363 | const char *name = macro->getName()->getNameStart(); | 1402 | const char *raw_name = macro->getName()->getNameStart(); |
| 1364 | SourceRange range = macro->getSourceRange(); | 1403 | SourceRange range = macro->getSourceRange(); |
| 1365 | SourceLocation begin_loc = range.getBegin(); | 1404 | SourceLocation begin_loc = range.getBegin(); |
| 1366 | SourceLocation end_loc = range.getEnd(); | 1405 | SourceLocation end_loc = range.getEnd(); |
| ... | @@ -1370,9 +1409,13 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | ... | @@ -1370,9 +1409,13 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 1370 | // we don't care about such things | 1409 | // we don't care about such things |
| 1371 | continue; | 1410 | continue; |
| 1372 | } | 1411 | } |
| | 1412 | Buf *name = buf_create_from_str(raw_name); |
| | 1413 | if (name_exists(c, name)) { |
| | 1414 | continue; |
| | 1415 | } |
| 1373 | | 1416 | |
| 1374 | const char *end_c = c->source_manager->getCharacterData(end_loc); | 1417 | const char *end_c = c->source_manager->getCharacterData(end_loc); |
| 1375 | process_macro(c, &ctok, buf_create_from_str(name), end_c); | 1418 | process_macro(c, &ctok, name, end_c); |
| 1376 | } | 1419 | } |
| 1377 | } | 1420 | } |
| 1378 | } | 1421 | } |
| ... | @@ -1408,6 +1451,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1408,6 +1451,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1408 | c->enum_type_table.init(8); | 1451 | c->enum_type_table.init(8); |
| 1409 | c->struct_type_table.init(8); | 1452 | c->struct_type_table.init(8); |
| 1410 | c->struct_decl_table.init(8); | 1453 | c->struct_decl_table.init(8); |
| | 1454 | c->decl_table.init(8); |
| 1411 | c->fn_table.init(8); | 1455 | c->fn_table.init(8); |
| 1412 | c->macro_table.init(8); | 1456 | c->macro_table.init(8); |
| 1413 | c->codegen = codegen; | 1457 | c->codegen = codegen; |