| ... | ... | @@ -42,6 +42,7 @@ struct Context { |
| 42 | 42 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; |
| 43 | 43 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_decl_table; |
| 44 | 44 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; |
| 45 | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; |
| 45 | 46 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; |
| 46 | 47 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 47 | 48 | SourceManager *source_manager; |
| ... | ... | @@ -58,6 +59,7 @@ static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, con |
| 58 | 59 | |
| 59 | 60 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl); |
| 60 | 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 | 65 | __attribute__ ((format (printf, 3, 4))) |
| ... | ... | @@ -292,6 +294,7 @@ static const char *decl_name(const Decl *decl) { |
| 292 | 294 | |
| 293 | 295 | static AstNode *add_typedef_node(Context *c, TypeTableEntry *type_decl) { |
| 294 | 296 | assert(type_decl); |
| 297 | assert(type_decl->id == TypeTableEntryIdTypeDecl); |
| 295 | 298 | |
| 296 | 299 | AstNode *node = create_type_decl_node(c, buf_ptr(&type_decl->name), |
| 297 | 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 | 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 | 336 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { |
| 314 | 337 | while (type_entry->id == TypeTableEntryIdTypeDecl) { |
| 315 | 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 | 609 | case Type::Enum: |
| 587 | 610 | { |
| 588 | 611 | const EnumType *enum_ty = static_cast<const EnumType*>(ty); |
| 589 | | Buf *record_name = buf_create_from_str(decl_name(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; |
| 612 | return resolve_enum_decl(c, enum_ty->getDecl()); |
| 601 | 613 | } |
| 602 | 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 | 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 | 790 | const char *raw_name = decl_name(enum_decl); |
| 764 | | // we have no interest in top level anonymous enums since they're |
| 765 | | // not exposing anything. |
| 791 | |
| 792 | Buf *bare_name; |
| 766 | 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 | 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 | 801 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 779 | | |
| 780 | 802 | if (!enum_def) { |
| 781 | | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(full_type_name), |
| 782 | | c->codegen->builtin_types.entry_u8); |
| 783 | | c->enum_type_table.put(bare_name, typedecl_type); |
| 803 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, |
| 804 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name)); |
| 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;`. |
| 786 | | add_typedef_node(c, typedecl_type); |
| 787 | | add_alias(c, buf_ptr(bare_name), buf_ptr(full_type_name)); |
| 788 | | return; |
| 809 | return enum_type; |
| 789 | 810 | } |
| 790 | 811 | |
| 791 | | // count and validate |
| 812 | bool pure_enum = true; |
| 792 | 813 | uint32_t field_count = 0; |
| 793 | 814 | for (auto it = enum_def->enumerator_begin(), |
| 794 | 815 | it_end = enum_def->enumerator_end(); |
| ... | ... | @@ -796,120 +817,156 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 796 | 817 | { |
| 797 | 818 | const EnumConstantDecl *enum_const = *it; |
| 798 | 819 | if (enum_const->getInitExpr()) { |
| 799 | | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); |
| 800 | | return; |
| 820 | pure_enum = false; |
| 801 | 821 | } |
| 802 | 822 | } |
| 803 | 823 | |
| 804 | | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import, |
| 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; |
| 824 | TypeTableEntry *tag_type_entry = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl); |
| 809 | 825 | |
| 810 | | TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(c->codegen, field_count); |
| 811 | | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 826 | if (pure_enum) { |
| 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); |
| 814 | | // make an alias without the "enum_" prefix. this will get emitted at the |
| 815 | | // end if it doesn't conflict with anything else |
| 816 | | add_alias(c, buf_ptr(bare_name), buf_ptr(full_type_name)); |
| 832 | enum_type->data.enumeration.gen_field_count = 0; |
| 833 | enum_type->data.enumeration.complete = true; |
| 834 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 817 | 835 | |
| 818 | | enum_type->data.enumeration.field_count = field_count; |
| 819 | | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 820 | | LLVMZigDIEnumerator **di_enumerators = allocate<LLVMZigDIEnumerator*>(field_count); |
| 836 | enum_type->data.enumeration.field_count = field_count; |
| 837 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 838 | LLVMZigDIEnumerator **di_enumerators = allocate<LLVMZigDIEnumerator*>(field_count); |
| 821 | 839 | |
| 822 | | ZigList<AstNode *> var_decls = {0}; |
| 823 | | uint32_t i = 0; |
| 824 | | for (auto it = enum_def->enumerator_begin(), |
| 825 | | it_end = enum_def->enumerator_end(); |
| 826 | | it != it_end; ++it, i += 1) |
| 827 | | { |
| 828 | | const EnumConstantDecl *enum_const = *it; |
| 840 | uint32_t i = 0; |
| 841 | for (auto it = enum_def->enumerator_begin(), |
| 842 | it_end = enum_def->enumerator_end(); |
| 843 | it != it_end; ++it, i += 1) |
| 844 | { |
| 845 | const EnumConstantDecl *enum_const = *it; |
| 829 | 846 | |
| 830 | | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 831 | | Buf *field_name; |
| 832 | | 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)); |
| 834 | | if (valid_symbol_starter(buf_ptr(slice)[0])) { |
| 835 | | field_name = slice; |
| 847 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 848 | Buf *field_name; |
| 849 | if (buf_starts_with_buf(enum_val_name, bare_name)) { |
| 850 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 836 | 851 | } else { |
| 837 | | field_name = buf_sprintf("_%s", buf_ptr(slice)); |
| 852 | field_name = enum_val_name; |
| 838 | 853 | } |
| 839 | | } else { |
| 840 | | field_name = enum_val_name; |
| 854 | |
| 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]; |
| 844 | | type_enum_field->name = field_name; |
| 845 | | type_enum_field->type_entry = c->codegen->builtin_types.entry_void; |
| 846 | | type_enum_field->value = i; |
| 872 | // create llvm type for root struct |
| 873 | enum_type->type_ref = tag_type_entry->type_ref; |
| 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. |
| 852 | | // at this point we can rely on the enum emitting successfully |
| 853 | | AstNode *field_access_node = create_field_access_node(c, buf_ptr(full_type_name), buf_ptr(field_name)); |
| 854 | | AstNode *var_node = create_var_decl_node(c, buf_ptr(enum_val_name), field_access_node); |
| 855 | | var_decls.append(var_node); |
| 856 | | c->global_value_table.put(enum_val_name, {enum_type, true}); |
| 857 | | } |
| 889 | return enum_type; |
| 890 | } else { |
| 891 | TypeTableEntry *enum_type = get_typedecl_type(c->codegen, buf_ptr(full_type_name), tag_type_entry); |
| 892 | c->enum_type_table.put(bare_name, enum_type); |
| 893 | c->decl_table.put(enum_decl, enum_type); |
| 858 | 894 | |
| 859 | | // create llvm type for root struct |
| 860 | | enum_type->type_ref = tag_type_entry->type_ref; |
| 895 | // add variables for all the values with enum_type |
| 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 |
| 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, ""); |
| 906 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 872 | 907 | |
| 873 | | LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type); |
| 874 | | enum_type->di_type = tag_di_type; |
| 908 | AstNode *type_node = make_type_node(c, enum_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 |
| 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; |
| 915 | } |
| 884 | 916 | |
| 885 | | for (uint32_t i = 0; i < field_count; i += 1) { |
| 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); |
| 917 | return enum_type; |
| 890 | 918 | } |
| 919 | } |
| 891 | 920 | |
| 892 | | normalize_parent_ptrs(enum_node); |
| 893 | | c->root->data.root.top_level_decls.append(enum_node); |
| 921 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 922 | TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl); |
| 894 | 923 | |
| 895 | | for (int i = 0; i < var_decls.length; i += 1) { |
| 896 | | AstNode *var_node = var_decls.at(i); |
| 897 | | c->root->data.root.top_level_decls.append(var_node); |
| 924 | if (enum_type->id == TypeTableEntryIdInvalid) { |
| 925 | return; |
| 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) { |
| 903 | | unsigned line = c->source_node ? c->source_node->line : 0; |
| 904 | | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugForwardDeclType(c->codegen->dbuilder, |
| 905 | | LLVMZigTag_DW_structure_type(), buf_ptr(full_type_name), |
| 906 | | LLVMZigFileToScope(c->import->di_file), c->import->di_file, line); |
| 934 | if (enum_type->id == TypeTableEntryIdEnum) { |
| 935 | if (enum_type->data.enumeration.complete) { |
| 936 | // now create top level decl for the type |
| 937 | AstNode *enum_node = create_node(c, NodeTypeStructDecl); |
| 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); |
| 909 | | struct_type->di_type = replacement_di_type; |
| 950 | normalize_parent_ptrs(enum_node); |
| 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 | 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 | 970 | const char *raw_name = decl_name(record_decl); |
| 914 | 971 | |
| 915 | 972 | if (!record_decl->isStruct()) { |
| ... | ... | @@ -922,11 +979,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 922 | 979 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c)); |
| 923 | 980 | } else { |
| 924 | 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 | 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 | 988 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name)); |
| 937 | 989 | |
| 938 | 990 | c->struct_type_table.put(bare_name, struct_type); |
| 991 | c->decl_table.put(record_decl, struct_type); |
| 939 | 992 | |
| 940 | 993 | RecordDecl *record_def = record_decl->getDefinition(); |
| 941 | 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 | 1178 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); |
| 1126 | 1179 | return; |
| 1127 | 1180 | } |
| 1128 | | llvm::APSInt aps_int = ap_value->getInt(); |
| 1129 | | if (aps_int.isSigned()) { |
| 1130 | | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { |
| 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 | | } |
| 1181 | init_node = create_ap_num_lit_node(c, var_decl, ap_value->getInt()); |
| 1182 | if (!init_node) { |
| 1183 | return; |
| 1145 | 1184 | } |
| 1146 | 1185 | break; |
| 1147 | 1186 | } |
| ... | ... | @@ -1360,7 +1399,7 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 1360 | 1399 | case PreprocessedEntity::MacroDefinitionKind: |
| 1361 | 1400 | { |
| 1362 | 1401 | MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity); |
| 1363 | | const char *name = macro->getName()->getNameStart(); |
| 1402 | const char *raw_name = macro->getName()->getNameStart(); |
| 1364 | 1403 | SourceRange range = macro->getSourceRange(); |
| 1365 | 1404 | SourceLocation begin_loc = range.getBegin(); |
| 1366 | 1405 | SourceLocation end_loc = range.getEnd(); |
| ... | ... | @@ -1370,9 +1409,13 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 1370 | 1409 | // we don't care about such things |
| 1371 | 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 | 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 | 1451 | c->enum_type_table.init(8); |
| 1409 | 1452 | c->struct_type_table.init(8); |
| 1410 | 1453 | c->struct_decl_table.init(8); |
| 1454 | c->decl_table.init(8); |
| 1411 | 1455 | c->fn_table.init(8); |
| 1412 | 1456 | c->macro_table.init(8); |
| 1413 | 1457 | c->codegen = codegen; |