authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-22 21:43:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-22 21:43:48-07:00
log66163692ad35048e0bab5861e371067b63ee0f88
treeca4aba04b5b775d5bb568081e5c4e78b6745f3e1
parent8187396f640d2a56e0d56c7d199074b4590e49eb

parseh: support anonymous enums and enums with initializers


5 files changed, 202 insertions(+), 155 deletions(-)

src/ast_render.cpp+2-1
......@@ -523,7 +523,8 @@ static void render_node(AstRender *ar, AstNode *node) {
523523 AstNode *lhs = node->data.field_access_expr.struct_expr;
524524 Buf *rhs = &node->data.field_access_expr.field_name;
525525 render_node(ar, lhs);
526 fprintf(ar->f, ".%s", buf_ptr(rhs));
526 fprintf(ar->f, ".");
527 print_symbol(ar, rhs);
527528 break;
528529 }
529530 case NodeTypeUse:
src/parseh.cpp+182-138
......@@ -42,6 +42,7 @@ struct Context {
4242 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table;
4343 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_decl_table;
4444 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table;
45 HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table;
4546 HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table;
4647 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
4748 SourceManager *source_manager;
......@@ -58,6 +59,7 @@ static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, con
5859
5960static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl);
6061static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl);
62static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
6163
6264
6365__attribute__ ((format (printf, 3, 4)))
......@@ -292,6 +294,7 @@ static const char *decl_name(const Decl *decl) {
292294
293295static AstNode *add_typedef_node(Context *c, TypeTableEntry *type_decl) {
294296 assert(type_decl);
297 assert(type_decl->id == TypeTableEntryIdTypeDecl);
295298
296299 AstNode *node = create_type_decl_node(c, buf_ptr(&type_decl->name),
297300 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
310313 return node;
311314}
312315
316static 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
313336static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) {
314337 while (type_entry->id == TypeTableEntryIdTypeDecl) {
315338 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
586609 case Type::Enum:
587610 {
588611 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());
601613 }
602614 case Type::ConstantArray:
603615 {
......@@ -759,36 +771,45 @@ static void add_alias(Context *c, const char *new_name, const char *target_name)
759771 c->aliases.append(alias_node);
760772}
761773
762static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
774static 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
784static 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
763790 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;
766793 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);
768797 }
769798
770 Buf *bare_name = buf_create_from_str(raw_name);
771799 Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name));
772800
773 if (c->enum_type_table.maybe_get(bare_name)) {
774 // we've already seen it
775 return;
776 }
777
778801 const EnumDecl *enum_def = enum_decl->getDefinition();
779
780802 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);
784808
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;
789810 }
790811
791 // count and validate
812 bool pure_enum = true;
792813 uint32_t field_count = 0;
793814 for (auto it = enum_def->enumerator_begin(),
794815 it_end = enum_def->enumerator_end();
......@@ -796,120 +817,156 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
796817 {
797818 const EnumConstantDecl *enum_const = *it;
798819 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;
801821 }
802822 }
803823
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);
809825
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);
812831
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;
817835
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);
821839
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;
829846
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));
836851 } else {
837 field_name = buf_sprintf("_%s", buf_ptr(slice));
852 field_name = enum_val_name;
838853 }
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});
841870 }
842871
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;
847874
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, "");
849885
886 LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type);
887 enum_type->di_type = tag_di_type;
850888
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);
858894
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 }
861905
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));
872907
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);
875911
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});
877914
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 }
884916
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;
890918 }
919}
891920
892 normalize_parent_ptrs(enum_node);
893 c->root->data.root.top_level_decls.append(enum_node);
921static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
922 TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl);
894923
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;
898926 }
899927
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 }
901933
902static 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 }
907949
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 }
910962}
911963
912964static 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
913970 const char *raw_name = decl_name(record_decl);
914971
915972 if (!record_decl->isStruct()) {
......@@ -922,11 +979,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
922979 bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c));
923980 } else {
924981 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 }
930982 }
931983
932984 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_
936988 ContainerKindStruct, c->source_node, buf_ptr(full_type_name));
937989
938990 c->struct_type_table.put(bare_name, struct_type);
991 c->decl_table.put(record_decl, struct_type);
939992
940993 RecordDecl *record_def = record_decl->getDefinition();
941994 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) {
11251178 "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name));
11261179 return;
11271180 }
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;
11451184 }
11461185 break;
11471186 }
......@@ -1360,7 +1399,7 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
13601399 case PreprocessedEntity::MacroDefinitionKind:
13611400 {
13621401 MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity);
1363 const char *name = macro->getName()->getNameStart();
1402 const char *raw_name = macro->getName()->getNameStart();
13641403 SourceRange range = macro->getSourceRange();
13651404 SourceLocation begin_loc = range.getBegin();
13661405 SourceLocation end_loc = range.getEnd();
......@@ -1370,9 +1409,13 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
13701409 // we don't care about such things
13711410 continue;
13721411 }
1412 Buf *name = buf_create_from_str(raw_name);
1413 if (name_exists(c, name)) {
1414 continue;
1415 }
13731416
13741417 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);
13761419 }
13771420 }
13781421 }
......@@ -1408,6 +1451,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
14081451 c->enum_type_table.init(8);
14091452 c->struct_type_table.init(8);
14101453 c->struct_decl_table.init(8);
1454 c->decl_table.init(8);
14111455 c->fn_table.init(8);
14121456 c->macro_table.init(8);
14131457 c->codegen = codegen;
src/util.cpp+8
......@@ -34,3 +34,11 @@ uint32_t uint64_hash(uint64_t i) {
3434bool uint64_eq(uint64_t a, uint64_t b) {
3535 return a == b;
3636}
37
38uint32_t ptr_hash(const void *ptr) {
39 return ((uintptr_t)ptr) % UINT32_MAX;
40}
41
42bool ptr_eq(const void *a, const void *b) {
43 return a == b;
44}
src/util.hpp+2
......@@ -83,5 +83,7 @@ uint32_t int_hash(int i);
8383bool int_eq(int a, int b);
8484uint32_t uint64_hash(uint64_t i);
8585bool uint64_eq(uint64_t a, uint64_t b);
86uint32_t ptr_hash(const void *ptr);
87bool ptr_eq(const void *a, const void *b);
8688
8789#endif
test/run_tests.cpp+8-16
......@@ -1244,15 +1244,14 @@ enum Foo {
12441244 FooB,
12451245 Foo1,
12461246};
1247 )SOURCE", 1, R"OUTPUT(export enum enum_Foo {
1247 )SOURCE", 3, R"(export enum enum_Foo {
12481248 A,
12491249 B,
1250 _1,
1251}
1252pub const FooA = enum_Foo.A;
1250 @"1",
1251})", R"(pub const FooA = enum_Foo.A;
12531252pub const FooB = enum_Foo.B;
1254pub const Foo1 = enum_Foo._1;)OUTPUT",
1255 R"OUTPUT(pub const Foo = enum_Foo;)OUTPUT");
1253pub const Foo1 = enum_Foo.@"1";)",
1254 R"(pub const Foo = enum_Foo;)");
12561255
12571256 add_parseh_case("restrict -> noalias", R"SOURCE(
12581257void foo(void *restrict bar, void *restrict);
......@@ -1279,15 +1278,14 @@ enum Bar {
12791278 BarB,
12801279};
12811280void func(struct Foo *a, enum Bar **b);
1282 )SOURCE", 3, R"OUTPUT(export struct struct_Foo {
1281 )SOURCE", 5, R"OUTPUT(export struct struct_Foo {
12831282 x: c_int,
12841283 y: c_int,
1285}
1284})OUTPUT", R"OUTPUT(
12861285export enum enum_Bar {
12871286 A,
12881287 B,
1289}
1290pub const BarA = enum_Bar.A;
1288})OUTPUT", R"OUTPUT(pub const BarA = enum_Bar.A;
12911289pub const BarB = enum_Bar.B;)OUTPUT",
12921290 "pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);",
12931291 R"OUTPUT(pub const Foo = struct_Foo;
......@@ -1325,12 +1323,6 @@ pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT",
13251323 )SOURCE", 1, R"OUTPUT(pub const CHANNEL_COUNT = 24;)OUTPUT");
13261324
13271325
1328 add_parseh_case("overide previous #define", R"SOURCE(
1329#define A_CHAR 'a'
1330#define A_CHAR 'b'
1331 )SOURCE", 1, "pub const A_CHAR = 'b';");
1332
1333
13341326 add_parseh_case("#define referencing another #define", R"SOURCE(
13351327#define THING2 THING1
13361328#define THING1 1234