From f521a0dd77e1ebbd9e84140093ddb8d65a0cb153 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 1 Jul 2024 13:31:41 +0200 Subject: [PATCH] FOREACH_BEGIN / VECEACH replaced by FOREACH / FOREACH_IDX --- src/build/build_options.c | 10 +- src/build/builder.c | 22 +-- src/build/project.c | 28 ++-- src/compiler/abi/c_abi_riscv.c | 4 +- src/compiler/abi/c_abi_x64.c | 18 +-- src/compiler/abi/c_abi_x86.c | 12 +- src/compiler/ast.c | 17 +-- src/compiler/codegen_general.c | 10 +- src/compiler/compiler.c | 43 +++--- src/compiler/compiler_internal.h | 12 +- src/compiler/copying.c | 32 ++--- src/compiler/expr.c | 14 +- src/compiler/headers.c | 87 ++++++----- src/compiler/json_output.c | 22 +-- src/compiler/libraries.c | 31 ++-- src/compiler/linker.c | 37 +++-- src/compiler/llvm_codegen.c | 80 ++++++----- src/compiler/llvm_codegen_debug_info.c | 14 +- src/compiler/llvm_codegen_expr.c | 77 +++++----- src/compiler/llvm_codegen_function.c | 32 +++-- src/compiler/llvm_codegen_module.c | 8 +- src/compiler/llvm_codegen_stmt.c | 47 +++--- src/compiler/llvm_codegen_storeload.c | 5 +- src/compiler/llvm_codegen_type.c | 35 +++-- src/compiler/parse_expr.c | 3 +- src/compiler/parse_global.c | 38 ++--- src/compiler/parse_stmt.c | 10 +- src/compiler/parser_internal.h | 4 +- src/compiler/sema_asm.c | 10 +- src/compiler/sema_casts.c | 45 +++--- src/compiler/sema_decls.c | 94 ++++++------ src/compiler/sema_expr.c | 158 +++++++++++--------- src/compiler/sema_initializers.c | 34 ++--- src/compiler/sema_internal.h | 5 +- src/compiler/sema_liveness.c | 92 ++++++------ src/compiler/sema_name_resolution.c | 87 +++++------ src/compiler/sema_passes.c | 190 +++++++++++-------------- src/compiler/sema_stmts.c | 101 ++++++------- src/compiler/sema_types.c | 10 +- src/compiler/semantic_analyser.c | 27 ++-- src/compiler/source_file.c | 6 +- src/compiler/tilde_codegen.c | 38 ++--- src/compiler/types.c | 35 ++--- src/utils/lib.h | 20 ++- src/utils/taskqueue.c | 7 +- 45 files changed, 844 insertions(+), 867 deletions(-) diff --git a/src/build/build_options.c b/src/build/build_options.c index f27e63241..857f9f959 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -430,20 +430,22 @@ void update_feature_flags(const char ***flags, const char ***removed_flags, cons // Remove from opposite list using string equality // More elegant would be using a Set or Map, but that's overkill // for something that's likely just 1-2 values. - FOREACH_BEGIN_IDX(i, const char *value, *to_remove_from) + FOREACH_IDX(i, const char *, value, *to_remove_from) + { if (str_eq(value, arg)) { vec_erase_ptr_at(*to_remove_from, i); break; } - FOREACH_END(); + } // First we check that it's not in the list const char ***to_add_to_ref = add ? flags : removed_flags; - FOREACH_BEGIN(const char *value, *to_add_to_ref) + FOREACH(const char *, value, *to_add_to_ref) + { // If we have a match, we don't add it. if (str_eq(value, arg)) return; - FOREACH_END(); + } // No match, so add it. vec_add(*to_add_to_ref, arg); diff --git a/src/build/builder.c b/src/build/builder.c index 7c4f98f5c..ca67b9fe6 100644 --- a/src/build/builder.c +++ b/src/build/builder.c @@ -208,24 +208,28 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions * target->backend = options->backend; // Remove feature flags - FOREACH_BEGIN(const char *remove_feature, options->removed_feature_names) - FOREACH_BEGIN_IDX(i, const char *feature, target->feature_list) + FOREACH(const char *, remove_feature, options->removed_feature_names) + { + FOREACH_IDX(i, const char *, feature, target->feature_list) + { if (str_eq(feature, remove_feature)) { vec_erase_ptr_at(target->feature_list, i); break; } - FOREACH_END(); - FOREACH_END(); + } + } // Add feature flags - FOREACH_BEGIN(const char *add_feature, options->feature_names) - FOREACH_BEGIN_IDX(i, const char *feature, target->feature_list) + FOREACH(const char *, add_feature, options->feature_names) + { + FOREACH_IDX(i, const char *, feature, target->feature_list) + { if (str_eq(feature, add_feature)) goto NEXT; - FOREACH_END(); + } vec_add(target->feature_list, add_feature); - NEXT:; - FOREACH_END(); + NEXT:; + } target->read_stdin = options->read_stdin; diff --git a/src/build/project.c b/src/build/project.c index 717a7d7b9..20a8553ea 100644 --- a/src/build/project.c +++ b/src/build/project.c @@ -240,9 +240,10 @@ static void check_json_keys(const char* valid_keys[][2], size_t key_count, JSONO INLINE void append_strings_to_strings(const char*** list_of_strings_ptr, const char **strings_to_append) { - FOREACH_BEGIN(const char *string, strings_to_append) + FOREACH(const char *, string, strings_to_append) + { vec_add(*list_of_strings_ptr, string); - FOREACH_END(); + } } static void target_append_strings(JSONObject *json, const char *type, const char ***list_ptr, const char *base, const char *override, const char *add, bool is_default) @@ -290,9 +291,7 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg if (exec_add) { assert(target->exec); - FOREACH_BEGIN(const char *exec_command, exec_add) - vec_add(target->exec, exec_command); - FOREACH_END(); + FOREACH(const char *, exec_command, exec_add) vec_add(target->exec, exec_command); } target->output_dir = get_string(json, "output", type, target->output_dir); @@ -336,14 +335,15 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg // Dependencies target_append_strings(json, type, &target->libs, "dependencies", "dependencies-override", "dependencies-add", is_default); - FOREACH_BEGIN(const char *name, target->libs) + FOREACH(const char *, name, target->libs) + { if (!str_is_valid_lowercase_name(name)) { char *name_copy = strdup(name); str_ellide_in_place(name_copy, 32); error_exit("Error reading %s: invalid library target '%s'.", PROJECT_JSON, name_copy); } - FOREACH_END(); + } // debug-info static const char *debug_infos[3] = { @@ -430,13 +430,14 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg const char **features = get_valid_array(json, "features", type, false); if (features) { - FOREACH_BEGIN(const char *feature, features) + FOREACH(const char *, feature, features) + { if (!str_is_valid_constant(feature)) { error_exit("Error reading 'features': '%s' is not a valid feature name.", feature); } vec_add(target->feature_list, feature); - FOREACH_END(); + } } // x86vec @@ -543,9 +544,8 @@ static void project_add_target(Project *project, BuildTarget *default_target, J vec_add(project->targets, target); target->name = name; target->type = target_type; - VECEACH(project->targets, i) + FOREACH(BuildTarget *, other_target, project->targets) { - BuildTarget *other_target = project->targets[i]; if (other_target == target) continue; if (strcmp(other_target->name, target->name) == 0) { @@ -611,9 +611,8 @@ static void project_add_targets(Project *project, JSONObject *project_data) */ static BuildTarget *project_select_default_target(Project *project) { - VECEACH(project->targets, i) + FOREACH(BuildTarget *, target, project->targets) { - BuildTarget *target = project->targets[i]; if (target->type == TARGET_TYPE_EXECUTABLE) return target; } return project->targets[0]; @@ -637,9 +636,8 @@ BuildTarget *project_select_target(Project *project, const char *optional_target { return project_select_default_target(project); } - VECEACH(project->targets, i) + FOREACH(BuildTarget *, target, project->targets) { - BuildTarget *target = project->targets[i]; if (str_eq(target->name, optional_target)) return target; } error_exit("No build target named '%s' was found in %s. Was it misspelled?", optional_target, PROJECT_JSON); diff --git a/src/compiler/abi/c_abi_riscv.c b/src/compiler/abi/c_abi_riscv.c index ae6bf0742..9863592ab 100644 --- a/src/compiler/abi/c_abi_riscv.c +++ b/src/compiler/abi/c_abi_riscv.c @@ -77,10 +77,8 @@ static bool riscv_detect_fpcc_struct_internal(Type *type, unsigned current_offse { // Unions aren't eligible unless they're empty (which is caught above). if (type->type_kind == TYPE_UNION) return false; - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - Decl *member = members[i]; if (!riscv_detect_fpcc_struct_internal(member->type, (unsigned)(current_offset + member->offset), field1_ref, diff --git a/src/compiler/abi/c_abi_x64.c b/src/compiler/abi/c_abi_x64.c index 12b1b9ef0..cec6a8b21 100644 --- a/src/compiler/abi/c_abi_x64.c +++ b/src/compiler/abi/c_abi_x64.c @@ -137,10 +137,9 @@ ABIArgInfo *x64_classify_reg_call_struct_type_check(Type *type, Registers *neede // Variable array structs are always passed by pointer. if (type->decl->has_variable_array) return x64_indirect_return_result(type); - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - Type *member_type = type_lowering(members[i]->type->canonical); + Type *member_type = type_lowering(member->type->canonical); ABIArgInfo *member_info; Registers temp_needed_registers = { 0, 0 }; if (x64_type_is_structure(member_type)) @@ -235,9 +234,8 @@ void x64_classify_struct_union(Type *type, ByteSize offset_base, X64Class *curre bool is_union = type->type_kind == TYPE_UNION; Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, members) { - Decl *member = members[i]; ByteSize offset = offset_base + member->offset; // The only case a 256-bit or a 512-bit wide vector could be used is when // the struct contains a single 256-bit or 512-bit field. Early check @@ -362,10 +360,10 @@ static Decl *x64_get_member_at_offset(Decl *decl, unsigned offset) if (type_size(decl->type) <= offset) return NULL; Decl **members = decl->strukt.members; Decl *last_match = NULL; - VECEACH(members, i) + FOREACH(Decl *, member, members) { - if (members[i]->offset > (MemberIndex)offset) break; - last_match = members[i]; + if (member->offset > (MemberIndex)offset) break; + last_match = member; } assert(last_match); return last_match; @@ -456,10 +454,8 @@ bool x64_bits_contain_no_user_data(Type *type, unsigned start, unsigned end) } if (type->type_kind == TYPE_STRUCT || type->type_kind == TYPE_UNION) { - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - Decl *member = members[i]; unsigned offset = member->offset; if (offset >= end) break; unsigned field_start = offset < start ? start - offset : 0; diff --git a/src/compiler/abi/c_abi_x86.c b/src/compiler/abi/c_abi_x86.c index 54a0e398b..6d152d02c 100644 --- a/src/compiler/abi/c_abi_x86.c +++ b/src/compiler/abi/c_abi_x86.c @@ -21,9 +21,9 @@ static bool type_is_union_struct_with_simd_vector(Type *type) if (!type_is_union_or_strukt(type)) return false; Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, members) { - Type *member_type = members[i]->type; + Type *member_type = type_lowering(member->type); if (type_is_simd_vector(member_type)) return true; if (type_is_union_struct_with_simd_vector(member_type)) return true; } @@ -141,9 +141,9 @@ static bool x86_should_return_type_in_reg(Type *type) // If all can be passed in registers, then pass in register // (remember we already limited the size!) Decl** members = type->decl->strukt.members; - VECEACH (members, i) + FOREACH(Decl *, member, members) { - Type *member_type = members[i]->type->canonical; + Type *member_type = member->type->canonical; if (!x86_should_return_type_in_reg(member_type)) return false; } return true; @@ -237,9 +237,9 @@ static inline bool x86_can_expand_indirect_aggregate_arg(Type *type) ByteSize size = 0; Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, members) { - Type *member_type = type_lowering(members[i]->type); + Type *member_type = type_lowering(member->type); switch (member_type->type_kind) { case TYPE_I32: diff --git a/src/compiler/ast.c b/src/compiler/ast.c index f820243e8..5d9c64c13 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -340,14 +340,13 @@ void decl_append_links_to_global(Decl *decl) CompilationUnit *unit = decl->unit; if (unit && unit->links) { - FOREACH_BEGIN(const char *link, unit->links) - global_context_add_link(link); - FOREACH_END(); + FOREACH(const char *, link, unit->links) global_context_add_link(link); unit->links = NULL; // Don't register twice } if (decl->has_link) { - FOREACH_BEGIN(Attr* attr, decl->attributes) + FOREACH(Attr *, attr, decl->attributes) + { if (attr->attr_kind != ATTRIBUTE_LINK) continue; if (!attr->exprs) continue; unsigned args = vec_size(attr->exprs); @@ -357,7 +356,7 @@ void decl_append_links_to_global(Decl *decl) if (!string) continue; global_context_add_link(string->const_expr.bytes.ptr); } - FOREACH_END(); + } } } @@ -432,13 +431,9 @@ bool decl_needs_prefix(Decl *decl) Decl *decl_find_enum_constant(Decl *decl, const char *name) { - VECEACH(decl->enums.values, i) + FOREACH(Decl *, enum_constant, decl->enums.values) { - Decl *enum_constant = decl->enums.values[i]; - if (enum_constant->name == name) - { - return enum_constant; - } + if (enum_constant->name == name) return enum_constant; } return NULL; } diff --git a/src/compiler/codegen_general.c b/src/compiler/codegen_general.c index 3139f98b9..159d13acb 100644 --- a/src/compiler/codegen_general.c +++ b/src/compiler/codegen_general.c @@ -16,10 +16,9 @@ Type *type_abi_find_single_struct_element(Type *type) if (type->decl->has_variable_array) return NULL; Type *found = NULL; - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - Type *field_type = type_lowering(members[i]->type); + Type *field_type = type_lowering(member->type); // Already one field found, not single field. if (found) return NULL; @@ -186,12 +185,11 @@ bool type_is_homogenous_aggregate(Type *type, Type **base, unsigned *elements) if (type->decl->has_variable_array) return false; *elements = 0; { - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { unsigned member_mult = 1; // Flatten the type. - Type *member_type = type_lowering(members[i]->type); + Type *member_type = type_lowering(member->type); // Go down deep into a nester array. while (member_type->type_kind == TYPE_ARRAY) { diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 0edc6aa2c..c441190d5 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -77,11 +77,11 @@ void compiler_init(const char *std_lib_dir) static void compiler_lex(void) { - VECEACH(global_context.sources, i) + FOREACH(const char *, source, global_context.sources) { bool loaded = false; const char *error; - File *file = source_file_load(global_context.sources[i], &loaded, &error); + File *file = source_file_load(source, &loaded, &error); if (!file) error_exit(error); if (loaded) continue; Lexer lexer = { .file = file }; @@ -293,11 +293,11 @@ void compiler_parse(void) { puts("# input-files-begin"); } - VECEACH(global_context.sources, i) + FOREACH(const char *, source, global_context.sources) { bool loaded = false; const char *error; - File *file = source_file_load(global_context.sources[i], &loaded, &error); + File *file = source_file_load(source, &loaded, &error); if (!file) error_exit(error); if (loaded) continue; if (!parse_file(file)) has_error = true; @@ -666,9 +666,8 @@ void compiler_compile(void) static const char **target_expand_source_names(const char** dirs, const char **suffix_list, int suffix_count, bool error_on_mismatch) { const char **files = NULL; - VECEACH(dirs, i) + FOREACH(const char *, name, dirs) { - const char *name = dirs[i]; INFO_LOG("Searching for sources in %s", name); size_t name_len = strlen(name); if (name_len < 1) goto INVALID_NAME; @@ -768,7 +767,8 @@ static void setup_bool_define(const char *id, bool value) void vendor_fetch(BuildOptions *options) { unsigned count = 0; - FOREACH_BEGIN(const char *lib, options->libraries_to_fetch) + FOREACH(const char *, lib, options->libraries_to_fetch) + { const char *resource = str_printf("/c3lang/vendor/releases/download/latest/%s.c3l", lib); printf("Fetching library '%s'...", lib); fflush(stdout); @@ -782,7 +782,7 @@ void vendor_fetch(BuildOptions *options) { printf("FAILED: '%s'\n", error); } - FOREACH_END(); + } if (count == 0) error_exit("Error: Failed to download any libraries."); if (count < vec_size(options->libraries_to_fetch)) error_exit("Error: Only some libraries were downloaded."); } @@ -963,18 +963,20 @@ static void execute_scripts(void) error_exit("Failed to open script dir '%s'", active_target.script_dir); } } - FOREACH_BEGIN(const char *exec, active_target.exec) + FOREACH(const char *, exec, active_target.exec) + { StringSlice execs = slice_from_string(exec); StringSlice call = slice_next_token(&execs, ' '); - if (call.len < 3 || call.ptr[call.len - 3] != '.' || call.ptr[call.len - 2] != 'c' || call.ptr[call.len - 2] != '3') + if (call.len < 3 || call.ptr[call.len - 3] != '.' || call.ptr[call.len - 2] != 'c' || + call.ptr[call.len - 2] != '3') { (void) execute_cmd(exec, false); continue; } scratch_buffer_clear(); scratch_buffer_append_len(call.ptr, call.len); - (void)compile_and_invoke(scratch_buffer_to_string(), execs.len ? execs.ptr : ""); - FOREACH_END(); + (void) compile_and_invoke(scratch_buffer_to_string(), execs.len ? execs.ptr : ""); + } dir_change(old_path); free(old_path); } @@ -997,10 +999,11 @@ void compile() global_context.sources = active_target.sources; TokenType type = TOKEN_CONST_IDENT; - FOREACH_BEGIN(const char *feature_flag, active_target.feature_list) + FOREACH(const char *, feature_flag, active_target.feature_list) + { feature_flag = symtab_preset(feature_flag, TOKEN_CONST_IDENT); - htable_set(&global_context.features, (void *)feature_flag, (void *)feature_flag); - FOREACH_END(); + htable_set(&global_context.features, (void *) feature_flag, (void *) feature_flag); + } setup_int_define("C_SHORT_SIZE", platform_target.width_c_short, type_int); setup_int_define("C_INT_SIZE", platform_target.width_c_int, type_int); @@ -1068,9 +1071,10 @@ void global_context_add_generic_decl(Decl *decl) void global_context_add_link(const char *link) { - FOREACH_BEGIN(const char *existing_link, global_context.links) + FOREACH(const char *, existing_link, global_context.links) + { if (str_eq(link, existing_link)) return; - FOREACH_END(); + } vec_add(global_context.links, link); } @@ -1081,9 +1085,10 @@ SectionId global_context_register_section(const char *section) scratch_buffer_append(section); TokenType type = TOKEN_INVALID_TOKEN; const char *result = scratch_buffer_interned(); - FOREACH_BEGIN_IDX(i, const char *candidate, global_context.section_list) + FOREACH_IDX(i, const char *, candidate, global_context.section_list) + { if (result == candidate) return i + 1; - FOREACH_END(); + } unsigned len = vec_size(global_context.section_list); if (len >= MAX_SECTIONS) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 4b9f387af..09be41c5f 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3308,16 +3308,12 @@ INLINE void const_init_set_span(ConstInitializer *init, SourceSpan loc) return; case CONST_INIT_ARRAY: { - FOREACH_BEGIN(ConstInitializer *init2, init->init_array.elements) - const_init_set_span(init2, loc); - FOREACH_END(); + FOREACH(ConstInitializer *, init2, init->init_array.elements) const_init_set_span(init2, loc); return; } case CONST_INIT_ARRAY_FULL: { - FOREACH_BEGIN(ConstInitializer *init2, init->init_array_full) - const_init_set_span(init2, loc); - FOREACH_END(); + FOREACH(ConstInitializer *, init2, init->init_array_full) const_init_set_span(init2, loc); return; } case CONST_INIT_ARRAY_VALUE: @@ -3433,9 +3429,7 @@ static inline void exprid_set_span(ExprId expr_id, SourceSpan loc) } static inline void expr_list_set_span(Expr **exprs, SourceSpan loc) { - FOREACH_BEGIN(Expr *expr, exprs) - expr_set_span(expr, loc); - FOREACH_END(); + FOREACH(Expr *, expr, exprs) expr_set_span(expr, loc); } INLINE void expr_replace(Expr *expr, Expr *replacement) { diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 14264021c..a504bc039 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -72,10 +72,7 @@ INLINE void fixup_astid(CopyStruct *c, AstId *astid_ref) Expr **copy_expr_list(CopyStruct *c, Expr **expr_list) { Expr **result = NULL; - VECEACH(expr_list, i) - { - vec_add(result, copy_expr(c, expr_list[i])); - } + FOREACH(Expr *,expr, expr_list) vec_add(result, copy_expr(c, expr)); return result; } @@ -96,10 +93,7 @@ static inline void copy_flow(CopyStruct *c, Ast *ast) static TypeInfo** type_info_copy_list_from_macro(CopyStruct *c, TypeInfo **to_copy) { TypeInfo **result = NULL; - VECEACH(to_copy, i) - { - vec_add(result, copy_type_info(c, to_copy[i])); - } + FOREACH(TypeInfo *, type, to_copy) vec_add(result, copy_type_info(c, type)); return result; } @@ -131,10 +125,9 @@ INLINE DeclId declid_copy_deep(CopyStruct *c, DeclId source) static DesignatorElement **macro_copy_designator_list(CopyStruct *c, DesignatorElement **list) { DesignatorElement **result = NULL; - VECEACH(list, i) + FOREACH(DesignatorElement *, to_copy, list) { DesignatorElement *element = MALLOCS(DesignatorElement); - DesignatorElement *to_copy = list[i]; *element = *to_copy; switch (to_copy->kind) { @@ -206,10 +199,11 @@ void copy_range(CopyStruct *c, Range *range) INLINE ConstInitializer **copy_const_initializer_list(CopyStruct *c, ConstInitializer **initializer_list) { ConstInitializer **initializer = NULL; - FOREACH_BEGIN(ConstInitializer *element, initializer_list) + FOREACH(ConstInitializer *, element, initializer_list) + { copy_const_initializer(c, &element); vec_add(initializer, element); - FOREACH_END(); + } return initializer; } @@ -728,10 +722,7 @@ RETRY: Ast **copy_ast_list(CopyStruct *c, Ast **to_copy) { Ast **result = NULL; - VECEACH(to_copy, i) - { - vec_add(result, ast_copy_deep(c, to_copy[i])); - } + FOREACH(Ast *, ast, to_copy) vec_add(result, ast_copy_deep(c, ast)); return result; } @@ -767,9 +758,9 @@ static Attr **copy_attributes(CopyStruct *c, Attr** attr_list) { if (!attr_list) return attr_list; Attr** list = NULL; - VECEACH(attr_list, i) + FOREACH(Attr *, attribute, attr_list) { - Attr *attribute = attr_list[i]; + Attr *copy = MALLOCS(Attr); *copy = *attribute; MACRO_COPY_EXPR_LIST(copy->exprs); @@ -811,10 +802,7 @@ Decl *copy_lambda_deep(Decl *decl) Decl **copy_decl_list(CopyStruct *c, Decl **decl_list) { Decl **result = NULL; - VECEACH(decl_list, i) - { - vec_add(result, copy_decl(c, decl_list[i])); - } + FOREACH(Decl *, decl, decl_list) vec_add(result, copy_decl(c, decl)); return result; } diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 48ecbf22f..946791428 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -405,9 +405,9 @@ static inline bool expr_cast_is_constant_eval(Expr *expr, ConstantEvalKind eval_ static inline bool expr_list_is_constant_eval(Expr **exprs, ConstantEvalKind eval_kind) { - VECEACH(exprs, i) + FOREACH(Expr *, expr, exprs) { - if (!expr_is_constant_eval(exprs[i], eval_kind)) return false; + if (!expr_is_constant_eval(expr, eval_kind)) return false; } return true; } @@ -559,10 +559,8 @@ static inline ConstInitializer *initializer_for_index(ConstInitializer *initiali if (index > len || !index) return NULL; index = len - index; } - ConstInitializer **sub_values = initializer->init_array.elements; - VECEACH(sub_values, i) + FOREACH(ConstInitializer *, init, initializer->init_array.elements) { - ConstInitializer *init = sub_values[i]; assert(init->kind == CONST_INIT_ARRAY_VALUE); if (init->init_array_value.index == index) return init->init_array_value.element; } @@ -766,11 +764,13 @@ bool expr_is_pure(Expr *expr) case EXPR_CAST: return exprid_is_pure(expr->cast_expr.expr); case EXPR_EXPRESSION_LIST: - VECEACH(expr->expression_list, i) + { + FOREACH(Expr *, e, expr->expression_list) { - if (!expr_is_pure(expr->expression_list[i])) return false; + if (!expr_is_pure(e)) return false; } return true; + } case EXPR_TYPEID_INFO: return exprid_is_pure(expr->typeid_info_expr.parent); case EXPR_SLICE: diff --git a/src/compiler/headers.c b/src/compiler/headers.c index 53f5d6364..5408ccd8d 100644 --- a/src/compiler/headers.c +++ b/src/compiler/headers.c @@ -250,9 +250,10 @@ static void header_gen_function_ptr(HeaderContext *c, Type *type) rtype = type_anyfault; } header_gen_maybe_generate_type(c, rtype, false); - FOREACH_BEGIN_IDX(i, Decl *param, sig->params) + FOREACH(Decl *, param, sig->params) + { header_gen_maybe_generate_type(c, param->type, false); - FOREACH_END(); + } PRINTF("typedef "); header_print_type(c, rtype); @@ -267,11 +268,12 @@ static void header_gen_function_ptr(HeaderContext *c, Type *type) header_print_type(c, type_get_ptr(extra_ret)); PRINTF(" return_ref"); } - FOREACH_BEGIN_IDX(i, Decl *param, sig->params) + FOREACH_IDX(i, Decl *, param, sig->params) + { if (i || extra_ret) PRINTF(", "); header_print_type(c, param->type); if (param->name) PRINTF(" %s", param->name); - FOREACH_END(); + } PRINTF(");\n"); } @@ -317,7 +319,8 @@ static void header_gen_function(HeaderContext *c, Decl *decl, bool print_fn, boo PRINTF(" return_ref"); } } - FOREACH_BEGIN_IDX(i, Decl *param, sig->params) + FOREACH_IDX(i, Decl *, param, sig->params) + { if (print_fn) { if (i || extra_ret) PRINTF(", "); @@ -328,15 +331,15 @@ static void header_gen_function(HeaderContext *c, Decl *decl, bool print_fn, boo { header_gen_maybe_generate_type(c, param->type, false); } - FOREACH_END(); + } if (print_fn) PRINTF(");\n"); } static void header_gen_members(HeaderContext *c, int indent, Decl **members) { - VECEACH(members, i) + int i = 0; + FOREACH(Decl *,member, members) { - Decl *member = members[i]; Type *type = type_flatten_no_export(member->type); switch (member->decl_kind) { @@ -370,7 +373,7 @@ static void header_gen_members(HeaderContext *c, int indent, Decl **members) PRINTF(" %s;\n", member->name); break; } - PRINTF(" __bits%d;\n", i); + PRINTF(" __bits%d;\n", ++i); break; default: UNREACHABLE @@ -452,21 +455,25 @@ static void header_gen_enum(HeaderContext *c, int indent, Decl *decl) { PRINTF("typedef "); header_print_type(c, underlying_type); - PRINTF(" %s;\n", decl_get_extname(decl));FOREACH_BEGIN_IDX(i, Decl *enum_member, decl->enums.values) + PRINTF(" %s;\n", decl_get_extname(decl)); + FOREACH_IDX(i, Decl *, enum_member, decl->enums.values) + { PRINTF("%s %s_%s = %d;\n", decl_get_extname(decl), decl_get_extname(decl), enum_member->name, i); - FOREACH_END(); + } return; } PRINTF("typedef enum %s__\n{\n", decl_get_extname(decl)); - FOREACH_BEGIN(Decl *enum_member, decl->enums.values) + FOREACH(Decl *, enum_member, decl->enums.values) + { PRINTF("\t %s_%s,\n", decl_get_extname(decl), enum_member->name); - FOREACH_END(); + } PRINTF("} %s;\n", decl_get_extname(decl)); } static void header_ensure_member_types_exist(HeaderContext *c, Decl **members) { - FOREACH_BEGIN(Decl *member, members) + FOREACH(Decl *, member, members) + { switch (member->decl_kind) { case DECL_VAR: @@ -481,7 +488,7 @@ static void header_ensure_member_types_exist(HeaderContext *c, Decl **members) default: UNREACHABLE } - FOREACH_END(); + } } static void header_gen_maybe_generate_type(HeaderContext *c, Type *type, bool is_pointer) { @@ -687,12 +694,14 @@ static void header_gen_global_decls(HeaderContext *c, Module **modules, unsigned { Module *module = modules[i]; // Produce all constants. - FOREACH_BEGIN(CompilationUnit *unit, module->units) - FOREACH_BEGIN(Decl *var, unit->vars) + FOREACH(CompilationUnit *, unit, module->units) + { + FOREACH(Decl *, var, unit->vars) + { if (var->var.kind != VARDECL_CONST) continue; header_gen_global_var(c, var, fn_globals, &constants_found); - FOREACH_END(); - FOREACH_END(); + } + } } bool globals_found = false; @@ -701,12 +710,14 @@ static void header_gen_global_decls(HeaderContext *c, Module **modules, unsigned Module *module = modules[i]; // Generate all globals - FOREACH_BEGIN(CompilationUnit *unit, module->units) - FOREACH_BEGIN(Decl *var, unit->vars) + FOREACH(CompilationUnit *, unit, module->units) + { + FOREACH(Decl *, var, unit->vars) + { if (var->var.kind != VARDECL_GLOBAL) continue; header_gen_global_var(c, var, fn_globals, &globals_found); - FOREACH_END(); - FOREACH_END(); + } + } } bool functions_found = false; @@ -715,11 +726,13 @@ static void header_gen_global_decls(HeaderContext *c, Module **modules, unsigned Module *module = modules[i]; // Generate all functions - FOREACH_BEGIN(CompilationUnit *unit, module->units) - FOREACH_BEGIN(Decl *fn, unit->functions) + FOREACH(CompilationUnit *, unit, module->units) + { + FOREACH(Decl *, fn, unit->functions) + { header_gen_function(c, fn, fn_globals, &functions_found); - FOREACH_END(); - FOREACH_END(); + } + } } bool methods_found = false; @@ -731,11 +744,13 @@ static void header_gen_global_decls(HeaderContext *c, Module **modules, unsigned while (top_module->parent_module) top_module = top_module->parent_module; if (top_module->name->module == kw_std) continue; // Generate all functions - FOREACH_BEGIN(CompilationUnit *unit, module->units) - FOREACH_BEGIN(Decl *method, unit->methods) + FOREACH(CompilationUnit *, unit, module->units) + { + FOREACH(Decl *, method, unit->methods) + { header_gen_function(c, method, fn_globals, &methods_found); - FOREACH_END(); - FOREACH_END(); + } + } } } @@ -782,12 +797,14 @@ void header_gen(Module **modules, unsigned module_count) { Module *module = modules[i]; // Produce all constants. - FOREACH_BEGIN(CompilationUnit *unit, module->units) - FOREACH_BEGIN(Decl *type, unit->types) + FOREACH(CompilationUnit *, unit, module->units) + { + FOREACH(Decl *, type, unit->types) + { if (!type->is_export) continue; header_gen_maybe_generate_type(c, type->type, false); - FOREACH_END(); - FOREACH_END(); + } + } process_queue(c); } process_queue(c); diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 854606eb8..f85146b0b 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -18,16 +18,18 @@ static inline void emit_modules(FILE *file) { fputs("\t\"modules\": [\n", file); - FOREACH_BEGIN_IDX(i, Module *module, global_context.module_list) + FOREACH_IDX(i, Module *, module, global_context.module_list) + { if (i != 0) fputs(",\n", file); PRINTF("\t\t\"%s\"", module->name->module); - FOREACH_END(); + } fputs("\n\t],\n", file); fputs("\t\"generic_modules\": [\n", file); - FOREACH_BEGIN_IDX(i, Module *module, global_context.generic_module_list) - if (i != 0) fputs(",\n", file); + FOREACH_IDX(j, Module *, module, global_context.generic_module_list) + { + if (j != 0) fputs(",\n", file); PRINTF("\t\t\"%s\"", module->name->module); - FOREACH_END(); + } fputs("\n\t]\n", file); } @@ -73,10 +75,11 @@ static inline void emit_type_data(FILE *file, Module *module, Decl *type) if (type->decl_kind == DECL_STRUCT || type->decl_kind == DECL_UNION) { fputs(",\n\t\t\t\"members\": {\n", file); - FOREACH_BEGIN_IDX(i, Decl *member, type->strukt.members) + FOREACH_IDX(i, Decl *, member, type->strukt.members) + { if (i != 0) fputs(",\n", file); PRINTF("\t\t\t\t\"%s\"", member->name); - FOREACH_END(); + } fputs("\n\t\t\t}", file); } fputs("\n\t\t}", file); @@ -179,7 +182,8 @@ static inline void emit_func_data(FILE *file, Module *module, Decl *func) print_type(file, type_infoptr(func->func_decl.signature.rtype)); PRINTF("\",\n"); fputs("\t\t\t\"params\": [\n", file); - FOREACH_BEGIN_IDX(i, Decl *decl, func->func_decl.signature.params) + FOREACH_IDX(i, Decl *, decl, func->func_decl.signature.params) + { if (i != 0) fputs(",\n", file); if (!decl) continue; fputs("\t\t\t\t{\n", file); @@ -195,7 +199,7 @@ static inline void emit_func_data(FILE *file, Module *module, Decl *func) } fputs("\"\n", file); fputs("\t\t\t\t}", file); - FOREACH_END(); + } fputs("\n\t\t\t]\n", file); fputs("\n\t\t}", file); diff --git a/src/compiler/libraries.c b/src/compiler/libraries.c index a40ee70d0..21004bdd3 100644 --- a/src/compiler/libraries.c +++ b/src/compiler/libraries.c @@ -108,9 +108,8 @@ static void add_library_dependency(Library *library, Library **library_list, siz { if (library->target_used) return; LibraryTarget *target_found = NULL; - VECEACH(library->targets, j) + FOREACH(LibraryTarget *, target, library->targets) { - LibraryTarget *target = library->targets[j]; if (target->arch_os == active_target.arch_os_target) { target_found = target; @@ -122,13 +121,13 @@ static void add_library_dependency(Library *library, Library **library_list, siz error_exit("Library '%s' cannot be used with arch/os '%s'.", library->provides, arch_os_target[active_target.arch_os_target]); } library->target_used = target_found; - VECEACH(library->depends, i) + FOREACH(const char *, dependency, library->depends) { - add_library_dependency(find_library(library_list, lib_count, library->depends[i]), library_list, lib_count); + add_library_dependency(find_library(library_list, lib_count, dependency), library_list, lib_count); } - VECEACH(target_found->depends, i) + FOREACH(const char *, dependency, target_found->depends) { - add_library_dependency(find_library(library_list, lib_count, target_found->depends[i]), + add_library_dependency(find_library(library_list, lib_count, dependency), library_list, lib_count); } @@ -205,9 +204,9 @@ void resolve_libraries(void) unsigned libdir_count = vec_size(active_target.libdirs); if (libdir_count) { - VECEACH(active_target.libdirs, i) + FOREACH(const char *, dir, active_target.libdirs) { - file_add_wildcard_files(&c3_libs, active_target.libdirs[i], false, &c3lib_suffix, 1); + file_add_wildcard_files(&c3_libs, dir, false, &c3lib_suffix, 1); } } else @@ -217,9 +216,8 @@ void resolve_libraries(void) } Library *libraries[MAX_LIB_DIRS * 2]; size_t lib_count = 0; - VECEACH(c3_libs, i) + FOREACH(const char *, lib, c3_libs) { - const char *lib = c3_libs[i]; JSONObject *json; if (!file_is_dir(lib)) { @@ -234,9 +232,8 @@ void resolve_libraries(void) if (lib_count == MAX_LIB_DIRS * 2) error_exit("Too many libraries added, exceeded %d.", MAX_LIB_DIRS * 2); libraries[lib_count++] = add_library(json, lib); } - VECEACH(active_target.libs, i) + FOREACH(const char *, lib_name, active_target.libs) { - const char *lib_name = active_target.libs[i]; add_library_dependency(find_library(libraries, lib_count, lib_name), libraries, lib_count); } for (size_t i = 0; i < lib_count; i++) @@ -254,13 +251,15 @@ void resolve_libraries(void) "is currently '%s'). Use the '--trust=full' option to enable it.", library->provides, trust_level[active_target.trust_level]); } - FOREACH_BEGIN(const char *exec, library->execs) + FOREACH(const char *, exec, library->execs) + { printf("] Execute '%s' for library '%s':", exec, library->provides); puts(execute_cmd(exec, false)); - FOREACH_END(); - FOREACH_BEGIN(const char *exec, target->execs) + } + FOREACH(const char *, exec, target->execs) + { printf("] Execute '%s' for library '%s':", exec, library->provides); puts(execute_cmd(exec, false)); - FOREACH_END(); + } } } \ No newline at end of file diff --git a/src/compiler/linker.c b/src/compiler/linker.c index 5a2740c58..c12ff56de 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -429,7 +429,8 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type) static void add_linked_libs(const char ***args_ref, const char **libs, bool is_win) { - FOREACH_BEGIN(const char *lib, libs) + FOREACH(const char *, lib, libs) + { INFO_LOG("Linking %s", lib); const char *framework = str_remove_suffix(lib, ".framework"); if (framework) @@ -452,7 +453,7 @@ static void add_linked_libs(const char ***args_ref, const char **libs, bool is_w else { if (str_has_suffix(lib, ".a") || str_has_suffix(lib, ".so") || - str_has_suffix(lib, ".dylib") || str_has_suffix(lib, ".tbd")) + str_has_suffix(lib, ".dylib") || str_has_suffix(lib, ".tbd")) { add_arg(lib); } @@ -461,7 +462,7 @@ static void add_linked_libs(const char ***args_ref, const char **libs, bool is_w add_arg2("-l", lib); } } - FOREACH_END(); + } } static bool linker_setup(const char ***args_ref, const char **files_to_link, unsigned file_count, @@ -541,23 +542,19 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns add_arg(files_to_link[i]); } - VECEACH(active_target.linker_libdirs, i) + FOREACH(const char *, dir, active_target.linker_libdirs) { - add_arg2(lib_path_opt, active_target.linker_libdirs[i]); + add_arg2(lib_path_opt, dir); } - VECEACH(active_target.link_args, i) + FOREACH(const char *, arg, active_target.link_args) { - add_arg(active_target.link_args[i]); + add_arg(arg); } add_linked_libs(args_ref, active_target.linker_libs, use_win); - VECEACH(active_target.library_list, i) + FOREACH(Library *, library, active_target.library_list) { - Library *library = active_target.library_list[i]; LibraryTarget *target = library->target_used; - VECEACH(target->link_flags, j) - { - add_arg(target->link_flags[j]); - } + FOREACH(const char *, flag, target->link_flags) add_arg(flag); add_linked_libs(args_ref, target->linked_libs, use_win); } add_linked_libs(args_ref, global_context.links, use_win); @@ -633,10 +630,10 @@ static bool link_exe(const char *output_file, const char **files_to_link, unsign bool success; const char *arg_list = ""; - VECEACH(args, i) + FOREACH(const char *, arg, args) { arg_list = str_cat(arg_list, " "); - arg_list = str_cat(arg_list, args[i]); + arg_list = str_cat(arg_list, arg); } INFO_LOG("Linker arguments: %s to %d", arg_list, platform_target.object_format); if (active_target.print_linking) puts(arg_list); @@ -688,16 +685,16 @@ bool obj_format_linking_supported(ObjectFormatType format_type) const char *concat_string_parts(const char **args) { unsigned size_needed = 0; - VECEACH(args, i) + FOREACH(const char *, arg, args) { - size_needed += strlen(args[i]) + 1; + size_needed += strlen(arg) + 1; } char *output = malloc_string(size_needed); char *ptr = output; - VECEACH(args, i) + FOREACH(const char *, arg, args) { - unsigned len = (unsigned)strlen(args[i]); - memcpy(ptr, args[i], len); + unsigned len = (unsigned)strlen(arg); + memcpy(ptr, arg, len); ptr += len; *(ptr++) = ' '; } diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index d6c7b5d22..65fb2cedb 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -277,9 +277,8 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_ unsigned alignment = 0; LLVMValueRef *parts = NULL; bool pack = false; - VECEACH(elements, i) + FOREACH(ConstInitializer *, element, elements) { - ConstInitializer *element = elements[i]; assert(element->kind == CONST_INIT_ARRAY_VALUE); MemberIndex element_index = element->init_array_value.index; IndexDiff diff = element_index - current_index; @@ -1301,7 +1300,8 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC for (unsigned i = 0; i < module_count; i++) { Module *module = modules[i]; - FOREACH_BEGIN(Decl *test, module->tests) + FOREACH(Decl *, test, module->tests) + { LLVMValueRef ref; LLVMTypeRef type = opt_test; scratch_buffer_set_extern_decl_name(test, true); @@ -1311,7 +1311,7 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC LLVMValueRef name = llvm_emit_string_const(c, scratch_buffer_to_string(), ".test.name"); vec_add(names, name); vec_add(decls, ref); - FOREACH_END(); + } } unsigned test_count = vec_size(decls); LLVMValueRef name_ref; @@ -1399,7 +1399,8 @@ INLINE GenContext *llvm_gen_benchmarks(Module** modules, unsigned module_count, for (unsigned i = 0; i < module_count; i++) { Module *module = modules[i]; - FOREACH_BEGIN(Decl *benchmark, module->benchmarks) + FOREACH(Decl *, benchmark, module->benchmarks) + { LLVMValueRef ref; LLVMTypeRef type = opt_benchmark; scratch_buffer_set_extern_decl_name(benchmark, true); @@ -1409,7 +1410,7 @@ INLINE GenContext *llvm_gen_benchmarks(Module** modules, unsigned module_count, LLVMValueRef name = llvm_emit_string_const(c, scratch_buffer_to_string(), ".benchmark.name"); vec_add(names, name); vec_add(decls, ref); - FOREACH_END(); + } } unsigned benchmark_count = vec_size(decls); LLVMValueRef name_ref; @@ -1512,10 +1513,9 @@ void **llvm_gen(Module** modules, unsigned module_count) LLVMMetadataRef llvm_get_debug_file(GenContext *c, FileId file_id) { - VECEACH(c->debug.debug_files, i) + FOREACH(DebugFile, file, c->debug.debug_files) { - DebugFile *ref = &c->debug.debug_files[i]; - if (ref->file_id == file_id) return ref->debug_file; + if (file.file_id == file_id) return file.debug_file; } File *f = source_file_by_id(file_id); LLVMMetadataRef file = LLVMDIBuilderCreateFile(c->debug.builder, @@ -1552,28 +1552,32 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context bool only_used = strip_unused(); - FOREACH_BEGIN(CompilationUnit *unit, module->units) - + FOREACH(CompilationUnit *, unit, module->units) + { gencontext_init_file_emit(gen_context, unit); gen_context->debug.compile_unit = unit->llvm.debug_compile_unit; gen_context->debug.file = (DebugFile){ .debug_file = unit->llvm.debug_file, .file_id = unit->file->file_id }; - FOREACH_BEGIN(Decl *method, unit->methods) + FOREACH(Decl *, method, unit->methods) + { if (only_used && !method->is_live) continue; llvm_emit_function_decl(gen_context, method); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *type_decl, unit->types) + FOREACH(Decl *, type_decl, unit->types) + { if (only_used && !type_decl->is_live) continue; llvm_emit_type_decls(gen_context, type_decl); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *enum_decl, unit->enums) + FOREACH(Decl *, enum_decl, unit->enums) + { if (only_used && !enum_decl->is_live) continue; llvm_emit_type_decls(gen_context, enum_decl); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *func, unit->functions) + FOREACH(Decl *, func, unit->functions) + { if (only_used && !func->is_live) continue; if (func->func_decl.attr_test) { @@ -1586,14 +1590,15 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context vec_add(module->benchmarks, func); } llvm_emit_function_decl(gen_context, func); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *func, unit->lambdas) + FOREACH(Decl *, func, unit->lambdas) + { if (only_used && !func->is_live) continue; has_elements = true; llvm_emit_function_decl(gen_context, func); - FOREACH_END(); + } if (active_target.type != TARGET_TYPE_TEST && active_target.type != TARGET_TYPE_BENCHMARK && unit->main_function && unit->main_function->is_synthetic) { @@ -1601,28 +1606,31 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context llvm_emit_function_decl(gen_context, unit->main_function); } - FOREACH_END(); - - FOREACH_BEGIN(CompilationUnit *unit, module->units) + } + FOREACH(CompilationUnit *, unit, module->units) + { gen_context->debug.compile_unit = unit->llvm.debug_compile_unit; gen_context->debug.file = (DebugFile){ .debug_file = unit->llvm.debug_file, .file_id = unit->file->file_id }; - FOREACH_BEGIN(Decl *var, unit->vars) + FOREACH(Decl *, var, unit->vars) + { if (only_used && !var->is_live) continue; has_elements = true; llvm_get_ref(gen_context, var); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *var, unit->vars) + FOREACH(Decl *, var, unit->vars) + { if (only_used && !var->is_live) continue; has_elements = true; llvm_emit_global_variable_init(gen_context, var); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *decl, unit->functions) + FOREACH(Decl *, decl, unit->functions) + { if (decl->func_decl.attr_test && !active_target.testing) continue; if (decl->func_decl.attr_benchmark && !active_target.benchmarking) continue; if (only_used && !decl->is_live) continue; @@ -1631,13 +1639,14 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context has_elements = true; llvm_emit_function_body(gen_context, decl); } - FOREACH_END(); + } - FOREACH_BEGIN(Decl *func, unit->lambdas) + FOREACH(Decl *, func, unit->lambdas) + { if (only_used && !func->is_live) continue; has_elements = true; llvm_emit_function_body(gen_context, func); - FOREACH_END(); + } if (active_target.type != TARGET_TYPE_TEST && active_target.type != TARGET_TYPE_BENCHMARK && unit->main_function && unit->main_function->is_synthetic) { @@ -1645,16 +1654,17 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context llvm_emit_function_body(gen_context, unit->main_function); } - FOREACH_BEGIN(Decl *decl, unit->methods) + FOREACH(Decl *, decl, unit->methods) + { if (only_used && !decl->is_live) continue; if (!decl->func_decl.body) continue; has_elements = true; llvm_emit_function_body(gen_context, decl); - FOREACH_END(); + } gencontext_end_file_emit(gen_context, unit); - FOREACH_END(); + } llvm_emit_dynamic_functions(gen_context, gen_context->dynamic_functions); diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index f9c9c3c8a..6f8e96010 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -337,9 +337,8 @@ static LLVMMetadataRef llvm_debug_enum_type(GenContext *c, Type *type, LLVMMetad Decl **enums = decl->enums.values; bool is_unsigned = type_is_unsigned(enum_real_type); - VECEACH(enums, i) + FOREACH(Decl *, enum_constant, enums) { - Decl *enum_constant = enums[i]; int64_t val = enum_constant->enum_constant.ordinal; LLVMMetadataRef debug_info = LLVMDIBuilderCreateEnumerator( c->debug.builder, @@ -374,7 +373,8 @@ static LLVMMetadataRef llvm_debug_structlike_type(GenContext *c, Type *type, LLV LLVMMetadataRef *elements = NULL; Decl **members = decl->strukt.members; - VECEACH(members, i) + unsigned count = vec_size(members); + for (unsigned i = 0; i < count; i++) { Decl *member = members[i]; LLVMMetadataRef debug_info = llvm_get_debug_member(c, @@ -532,9 +532,9 @@ static LLVMMetadataRef llvm_debug_func_type(GenContext *c, Type *type) { FunctionPrototype *prototype = type_get_resolved_prototype(type); // 1. Generate all the parameter types, this may cause this function to be called again! - VECEACH(prototype->param_types, i) + FOREACH(Type *, param_type, prototype->param_types) { - llvm_get_debug_type(c, prototype->param_types[i]); + llvm_get_debug_type(c, param_type); } // 2. We might be done! if (type->backend_debug_type) return type->backend_debug_type; @@ -552,9 +552,9 @@ static LLVMMetadataRef llvm_debug_func_type(GenContext *c, Type *type) vec_add(buffer, llvm_get_debug_type(c, type_anyfault)); vec_add(buffer, llvm_get_debug_type(c, type_get_ptr(type_no_optional(return_type)))); } - VECEACH(prototype->param_types, i) + FOREACH(Type *, param_type, prototype->param_types) { - vec_add(buffer, llvm_get_debug_type(c, prototype->param_types[i])); + vec_add(buffer, llvm_get_debug_type(c, param_type)); } if (prototype->raw_variadic) { diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 1b88b6978..e17bd155c 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -763,9 +763,8 @@ static inline void llvm_emit_pointer_offset(GenContext *c, BEValue *value, Expr static MemberIndex find_member_index(Decl *parent, Decl *member) { - VECEACH(parent->strukt.members, i) + FOREACH_IDX(i, Decl *, maybe_member, parent->strukt.members) { - Decl *maybe_member = parent->strukt.members[i]; if (member == maybe_member) { return (int)i; @@ -1782,9 +1781,8 @@ static void llvm_emit_const_init_ref(GenContext *c, BEValue *ref, ConstInitializ ConstInitializer **elements = const_init->init_array.elements; MemberIndex current_index = 0; LLVMValueRef *parts = NULL; - VECEACH(elements, i) + FOREACH(ConstInitializer *, element, elements) { - ConstInitializer *element = elements[i]; assert(element->kind == CONST_INIT_ARRAY_VALUE); MemberIndex element_index = element->init_array_value.index; AlignSize alignment; @@ -1838,11 +1836,12 @@ static inline void llvm_emit_initialize_reference_vector(GenContext *c, BEValue LLVMTypeRef llvm_type = llvm_get_type(c, real_type); LLVMValueRef vector_val = LLVMGetUndef(llvm_type); BEValue element_val; - FOREACH_BEGIN_IDX(i, Expr *element, elements) + FOREACH_IDX(i, Expr *, element, elements) + { llvm_emit_expr(c, &element_val, element); llvm_value_rvalue(c, &element_val); vector_val = LLVMBuildInsertElement(c->builder, vector_val, element_val.value, llvm_const_int(c, type_usz, i), ""); - FOREACH_END(); + } llvm_store_raw(c, ref, vector_val); } @@ -1855,12 +1854,14 @@ INLINE void llvm_emit_initialize_reference_bitstruct_array(GenContext *c, BEValu AlignSize alignment = ref->alignment; LLVMValueRef array_ptr = ref->value; // Now walk through the elements. - FOREACH_BEGIN_IDX(i, Expr *init, elements) + FOREACH_IDX(i, Expr *, init, elements) + { Decl *member = bitstruct->bitstruct.members[i]; BEValue val; llvm_emit_expr(c, &val, init); - llvm_emit_update_bitstruct_array(c, array_ptr, alignment, type, is_bitswap, member, llvm_load_value_store(c, &val)); - FOREACH_END(); + llvm_emit_update_bitstruct_array(c, array_ptr, alignment, type, is_bitswap, member, + llvm_load_value_store(c, &val)); + } } static inline void llvm_emit_initialize_reference_bitstruct(GenContext *c, BEValue *ref, Decl *bitstruct, Expr** elements) @@ -1876,12 +1877,13 @@ static inline void llvm_emit_initialize_reference_bitstruct(GenContext *c, BEVal TypeSize bits = type_bit_size(underlying_type); // Now walk through the elements. - FOREACH_BEGIN_IDX(i, Expr *init, elements) + FOREACH_IDX(i, Expr *, init, elements) + { Decl *member = bitstruct->bitstruct.members[i]; BEValue val; llvm_emit_expr(c, &val, init); data = llvm_emit_bitstruct_value_update(c, data, bits, type, member, llvm_load_value_store(c, &val)); - FOREACH_END(); + } if (bitstruct_requires_bitswap(bitstruct)) { data = llvm_emit_bswap(c, data); @@ -1918,9 +1920,8 @@ static inline void llvm_emit_initialize_reference_list(GenContext *c, BEValue *r bool is_vector = real_type->type_kind == TYPE_VECTOR; // Now walk through the elements. - VECEACH(elements, i) + FOREACH_IDX(i, Expr *, element, elements) { - Expr *element = elements[i]; BEValue pointer; if (is_struct) { @@ -2076,9 +2077,8 @@ static inline void llvm_emit_initialize_reference_designated_bitstruct_array(Gen AlignSize alignment = ref->alignment; LLVMValueRef array_ptr = ref->value; // Now walk through the elements. - VECEACH(elements, i) + FOREACH(Expr *, designator, elements) { - Expr *designator = elements[i]; assert(vec_size(designator->designator_expr.path) == 1); DesignatorElement *element = designator->designator_expr.path[0]; assert(element->kind == DESIGNATOR_FIELD); @@ -2102,9 +2102,8 @@ static inline void llvm_emit_initialize_reference_designated_bitstruct(GenContex TypeSize bits = type_bit_size(underlying_type); // Now walk through the elements. - VECEACH(elements, i) + FOREACH(Expr *, designator, elements) { - Expr *designator = elements[i]; assert(vec_size(designator->designator_expr.path) == 1); DesignatorElement *element = designator->designator_expr.path[0]; assert(element->kind == DESIGNATOR_FIELD); @@ -2139,9 +2138,8 @@ static inline void llvm_emit_initialize_reference_designated(GenContext *c, BEVa llvm_store_zero(c, ref); // Now walk through the elements. - VECEACH(elements, i) + FOREACH(Expr *, designator, elements) { - Expr *designator = elements[i]; DesignatorElement **last_element = designator->designator_expr.path + vec_size(designator->designator_expr.path) - 1; llvm_emit_initialize_designated_element(c, ref, 0, designator->designator_expr.path, last_element, designator->designator_expr.value, NULL); @@ -4899,10 +4897,9 @@ static void llvm_expand_array_to_args(GenContext *c, Type *param_type, LLVMValue static void llvm_expand_struct_to_args(GenContext *context, Type *param_type, LLVMValueRef expand_ptr, LLVMValueRef *args, unsigned *arg_count_ref, AlignSize alignment) { - Decl **members = param_type->decl->strukt.members; - VECEACH(members, i) + FOREACH_IDX(i, Decl *, member, param_type->decl->strukt.members) { - Type *member_type = members[i]->type; + Type *member_type = member->type; AlignSize load_align; LLVMValueRef member_ptr = llvm_emit_struct_gep_raw(context, expand_ptr, @@ -5658,7 +5655,7 @@ INLINE void llvm_emit_call_invocation(GenContext *c, BEValue *result_value, copy = *prototype; copy.varargs = NULL; - foreach(Expr*, varargs) + FOREACH(Expr *, val, varargs) { vec_add(copy.varargs, type_flatten(val->type)); } @@ -5800,7 +5797,7 @@ INLINE void llvm_emit_varargs_expr(GenContext *c, BEValue *value_ref, Expr **var LLVMTypeRef llvm_array_type = llvm_get_type(c, array); AlignSize alignment = type_alloca_alignment(array); LLVMValueRef array_ref = llvm_emit_alloca(c, llvm_array_type, alignment, varargslots_name); - foreach(Expr*, varargs) + FOREACH_IDX(foreach_index, Expr *, val, varargs) { llvm_emit_expr(c, &inner_temp, val); llvm_value_fold_optional(c, &inner_temp); @@ -5948,11 +5945,12 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr // Emit raw varargs if (prototype->raw_variadic && varargs) { - FOREACH_BEGIN_IDX(i, Expr *vararg, varargs) + FOREACH_IDX(i, Expr *, vararg, varargs) + { BEValue *value_ref = &values[arg_count + i]; llvm_emit_expr(c, value_ref, vararg); llvm_value_fold_optional(c, value_ref); - FOREACH_END(); + } } // 1. Dynamic dispatch. @@ -6029,9 +6027,9 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr static inline void llvm_emit_expression_list_expr(GenContext *c, BEValue *be_value, Expr *expr) { - VECEACH(expr->expression_list, i) + FOREACH(Expr *, e, expr->expression_list) { - llvm_emit_expr(c, be_value, expr->expression_list[i]); + llvm_emit_expr(c, be_value, e); } } @@ -6193,7 +6191,8 @@ static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr updated = (DebugScope) { .lexical_block = macro_def, .inline_loc = loc, .outline_loc = old_inline_location }; } - FOREACH_BEGIN(Decl *val, expr->macro_block.params) + FOREACH(Decl *, val, expr->macro_block.params) + { // Skip vararg if (!val) continue; // In case we have a constant, we never do an emit. The value is already folded. @@ -6232,7 +6231,7 @@ static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr } val->is_value = true; val->backend_value = value.value; - FOREACH_END(); + } c->debug.block_stack = &updated; llvm_emit_return_block(c, be_value, expr->type, expr->macro_block.first_stmt, expr->macro_block.block_exit); @@ -6301,9 +6300,8 @@ static inline void llvm_emit_vector_initializer_list(GenContext *c, BEValue *val Expr **elements = expr->initializer_list; // Now walk through the elements. - VECEACH(elements, i) + FOREACH_IDX(i, Expr *, element, elements) { - Expr *element = elements[i]; llvm_emit_expr(c, &val, element); llvm_value_rvalue(c, &val); vec_value = llvm_update_vector(c, vec_value, val.value, (MemberIndex)i); @@ -6314,9 +6312,8 @@ static inline void llvm_emit_vector_initializer_list(GenContext *c, BEValue *val vec_value = llvm_get_zero_raw(llvm_type); Expr **elements = expr->designated_init_list; - VECEACH(elements, i) + FOREACH(Expr *, designator, elements) { - Expr *designator = elements[i]; assert(vec_size(designator->designator_expr.path) == 1); DesignatorElement *element = designator->designator_expr.path[0]; llvm_emit_expr(c, &val, designator->designator_expr.value); @@ -6368,9 +6365,8 @@ static void llvm_emit_macro_body_expansion(GenContext *c, BEValue *value, Expr * c->debug.block_stack = outline; // Create backend refs on demand. - VECEACH(declarations, i) + FOREACH_IDX(i, Decl *, decl, declarations) { - Decl *decl = declarations[i]; if (!values[i]) continue; if (!decl->backend_ref) llvm_emit_local_var_alloca(c, decl); } @@ -6378,12 +6374,11 @@ static void llvm_emit_macro_body_expansion(GenContext *c, BEValue *value, Expr * c->debug.block_stack = old_inline_loc; // Set the values - VECEACH(values, i) + FOREACH_IDX(j, Expr *, expr, values) { - Expr *expr = values[i]; if (!expr) continue; llvm_emit_expr(c, value, expr); - llvm_store_to_ptr_aligned(c, declarations[i]->backend_ref, value, declarations[i]->alignment); + llvm_store_to_ptr_aligned(c, declarations[j]->backend_ref, value, declarations[j]->alignment); } c->debug.block_stack = outline; @@ -6450,13 +6445,13 @@ void llvm_emit_catch_unwrap(GenContext *c, BEValue *value, Expr *expr) PUSH_CATCH_VAR_BLOCK(addr.value, catch_block); - VECEACH(expr->catch_unwrap_expr.exprs, i) + FOREACH(Expr *, e, expr->catch_unwrap_expr.exprs) { BEValue val; LLVMBasicBlockRef block = llvm_basic_block_new(c, "testblock"); llvm_emit_br(c, block); llvm_emit_block(c, block); - llvm_emit_expr(c, &val, expr->catch_unwrap_expr.exprs[i]); + llvm_emit_expr(c, &val, e); llvm_value_fold_optional(c, &val); } diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index 0a30c74de..d737cf21c 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -89,12 +89,11 @@ static void llvm_expand_from_args(GenContext *c, Type *type, LLVMValueRef ref, u case TYPE_STRUCT: { LLVMTypeRef struct_type = llvm_get_type(c, type); - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH_IDX(i, Decl *, member, type->decl->strukt.members) { AlignSize element_align; LLVMValueRef target = llvm_emit_struct_gep_raw(c, ref, struct_type, i, alignment, &element_align); - llvm_expand_from_args(c, members[i]->type, target, index, element_align); + llvm_expand_from_args(c, member->type, target, index, element_align); } return; } @@ -480,9 +479,10 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, FunctionPrototype *pro if (signature) { // Generate LLVMValueRef's for all parameters, so we can use them as local vars in code - FOREACH_BEGIN_IDX(i, Decl *param, signature->params) + FOREACH_IDX(i, Decl *, param, signature->params) + { llvm_emit_func_parameter(c, param, prototype->abi_args[i], &arg, i); - FOREACH_END(); + } } LLVMSetCurrentDebugLocation2(c->builder, NULL); @@ -505,11 +505,12 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, FunctionPrototype *pro // Move panic blocks last, this is just overall nicer to read, and might be better from // a performance POV - FOREACH_BEGIN(LLVMBasicBlockRef panic_block, c->panic_blocks) + FOREACH(LLVMBasicBlockRef, panic_block, c->panic_blocks) + { if (last_block == panic_block) continue; LLVMMoveBasicBlockAfter(panic_block, last_block); last_block = panic_block; - FOREACH_END(); + } // erase alloca point if (LLVMGetInstructionParent(alloca_point)) @@ -548,14 +549,15 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs) LLVMTypeRef types[3] = { c->ptr_type, c->ptr_type, c->typeid_type }; LLVMTypeRef entry_type = LLVMStructType(types, 3, false); LLVMValueRef *entries = VECNEW(LLVMValueRef, len); - FOREACH_BEGIN(Decl *func, funcs) + FOREACH(Decl *, func, funcs) + { Type *type = typeget(func->func_decl.type_parent); Decl *proto = declptrzero(func->func_decl.interface_method); LLVMValueRef proto_ref = proto ? llvm_get_ref(c, proto) : llvm_get_selector(c, func->name); - LLVMValueRef vals[3] = { llvm_get_ref(c, func), proto_ref, llvm_get_typeid(c, type) }; + LLVMValueRef vals[3] = {llvm_get_ref(c, func), proto_ref, llvm_get_typeid(c, type)}; LLVMValueRef entry = LLVMConstNamedStruct(entry_type, vals, 3); vec_add(entries, entry); - FOREACH_END(); + } LLVMValueRef array = LLVMConstArray(entry_type, entries, len); LLVMValueRef global = LLVMAddGlobal(c->module, LLVMTypeOf(array), "$c3_dynamic"); LLVMSetLinkage(global, LLVMInternalLinkage); @@ -573,7 +575,8 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs) LLVMBasicBlockRef last_block; LLVMBuilderRef builder = llvm_create_function_entry(c, initializer, &last_block); - FOREACH_BEGIN(Decl *decl, funcs) + FOREACH(Decl *, decl, funcs) + { Type *type = typeget(decl->func_decl.type_parent); scratch_buffer_clear(); scratch_buffer_append("$ct.dyn."); @@ -581,10 +584,11 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs) LLVMValueRef global = llvm_add_global_raw(c, scratch_buffer_copy(), c->dtable_type, 0); Decl *proto = declptrzero(decl->func_decl.interface_method); LLVMValueRef proto_ref = proto ? llvm_get_ref(c, proto) : llvm_get_selector(c, decl->name); - LLVMValueRef vals[3] = { llvm_get_ref(c, decl), proto_ref, LLVMConstNull(c->ptr_type) }; + LLVMValueRef vals[3] = {llvm_get_ref(c, decl), proto_ref, LLVMConstNull(c->ptr_type)}; LLVMSetInitializer(global, LLVMConstNamedStruct(c->dtable_type, vals, 3)); LLVMValueRef type_id_ptr = LLVMBuildIntToPtr(builder, llvm_get_typeid(c, type), c->ptr_type, ""); - LLVMValueRef dtable_ref = LLVMBuildStructGEP2(builder, c->introspect_type, type_id_ptr, INTROSPECT_INDEX_DTABLE, ""); + LLVMValueRef dtable_ref = LLVMBuildStructGEP2(builder, c->introspect_type, type_id_ptr, INTROSPECT_INDEX_DTABLE, + ""); LLVMBasicBlockRef check = LLVMAppendBasicBlockInContext(c->context, initializer, "dtable_check"); LLVMBuildBr(builder, check); LLVMPositionBuilderAtEnd(builder, check); @@ -603,7 +607,7 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs) LLVMPositionBuilderAtEnd(builder, after_check); LLVMBuildStore(builder, global, phi); last_block = after_check; - FOREACH_END(); + } LLVMBuildRet(builder, NULL); LLVMDisposeBuilder(builder); diff --git a/src/compiler/llvm_codegen_module.c b/src/compiler/llvm_codegen_module.c index a045f42eb..95fa9f936 100644 --- a/src/compiler/llvm_codegen_module.c +++ b/src/compiler/llvm_codegen_module.c @@ -98,9 +98,8 @@ void gencontext_begin_module(GenContext *c) // This would seem to indicate that we should change Type / actual type. c->ast_alloca_addr_space = target_alloca_addr_space(); - VECEACH(global_context.type, i) + FOREACH(Type *, type, global_context.type) { - Type *type = global_context.type[i]; type->backend_type = NULL; type->backend_debug_type = NULL; type->backend_typeid = NULL; @@ -109,10 +108,9 @@ void gencontext_begin_module(GenContext *c) case TYPE_ENUM: case TYPE_FAULTTYPE: { - Decl **values = type->decl->enums.values; - VECEACH(values, j) + FOREACH(Decl *, value, type->decl->enums.values) { - values[j]->backend_ref = NULL; + value->backend_ref = NULL; } FALLTHROUGH; } diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index e6dd3398c..876c58a9a 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -682,9 +682,8 @@ static void llvm_emit_switch_body_if_chain(GenContext *c, bool is_type_switch) { LLVMBasicBlockRef next = NULL; - VECEACH(cases, i) + FOREACH(Ast *, case_stmt, cases) { - Ast *case_stmt = cases[i]; LLVMBasicBlockRef block = case_stmt->case_stmt.backend_block; if (case_stmt == default_case) continue; BEValue be_value; @@ -1098,10 +1097,11 @@ void gencontext_emit_next_stmt(GenContext *context, Ast *ast) ? exit_block : cases[default_index]->case_stmt.backend_block, &be_value); - FOREACH_BEGIN(Ast *case_ast, cases) + FOREACH(Ast *, case_ast, cases) + { if (!case_ast->case_stmt.body) continue; LLVMAddDestination(instr, case_ast->case_stmt.backend_block); - FOREACH_END(); + } if (default_index < 0) LLVMAddDestination(instr, exit_block); return; @@ -1180,12 +1180,13 @@ static inline void llvm_emit_assert_stmt(GenContext *c, Ast *ast) if (vec_size(args)) { fmt = err_msg; - FOREACH_BEGIN(Expr *arg, args) + FOREACH(Expr *, arg, args) + { BEValue var; llvm_emit_expr(c, &var, arg); llvm_emit_any_from_value(c, &var, arg->type); vec_add(values, var); - FOREACH_END(); + } } else { @@ -1261,7 +1262,8 @@ static inline void llvm_emit_asm_block_stmt(GenContext *c, Ast *ast) { data = codegen_create_asm(ast); clobbers = clobber_list.string; - FOREACH_BEGIN(ExprAsmArg * var, block->output_vars) + FOREACH(ExprAsmArg *, var, block->output_vars) + { codegen_new_constraint(&clobber_list); if (var->kind == ASM_ARG_MEMVAR) { @@ -1295,9 +1297,10 @@ static inline void llvm_emit_asm_block_stmt(GenContext *c, Ast *ast) } Decl *decl = result_decls[result_count] = var->ident.ident_decl; result_types[result_count++] = llvm_get_type(c, decl->type); - FOREACH_END(); + } - FOREACH_BEGIN(ExprAsmArg *val, block->input) + FOREACH(ExprAsmArg *, val, block->input) + { BEValue value; codegen_new_constraint(&clobber_list); pointer_type[param_count] = NULL; @@ -1335,7 +1338,7 @@ static inline void llvm_emit_asm_block_stmt(GenContext *c, Ast *ast) llvm_value_rvalue(c, &value); param_types[param_count] = LLVMTypeOf(value.value); args[param_count++] = value.value; - FOREACH_END(); + } for (int i = 0; i < CLOBBER_FLAG_ELEMENTS; i++) @@ -1428,11 +1431,11 @@ LLVMValueRef llvm_emit_empty_string_const(GenContext *c) LLVMValueRef llvm_emit_zstring_named(GenContext *c, const char *str, const char *extname) { - VECEACH(c->reusable_constants, i) + FOREACH(ReusableConstant, constant, c->reusable_constants) { - if (strcmp(str, c->reusable_constants[i].string) == 0 && strcmp(extname, c->reusable_constants[i].name) == 0) + if (str_eq(str, constant.string) && str_eq(extname, constant.name)) { - return c->reusable_constants[i].value; + return constant.value; } } @@ -1502,15 +1505,16 @@ void llvm_emit_panic(GenContext *c, const char *message, SourceSpan loc, const c LLVMTypeRef llvm_array_type = llvm_get_type(c, any_array); AlignSize alignment = type_alloca_alignment(any_array); LLVMValueRef array_ref = llvm_emit_alloca(c, llvm_array_type, alignment, varargslots_name); - VECEACH(varargs, i) + unsigned vacount = vec_size(varargs); + for (unsigned i = 0; i < vacount; i++) { AlignSize store_alignment; LLVMValueRef slot = llvm_emit_array_gep_raw(c, - array_ref, - llvm_array_type, - i, - alignment, - &store_alignment); + array_ref, + llvm_array_type, + i, + alignment, + &store_alignment); llvm_store_to_ptr_aligned(c, slot, &varargs[i], store_alignment); } BEValue value; @@ -1604,10 +1608,11 @@ void llvm_emit_stmt(GenContext *c, Ast *ast) case AST_DECLS_STMT: { BEValue value; - FOREACH_BEGIN(Decl *decl, ast->decls_stmt) + FOREACH(Decl *, decl, ast->decls_stmt) + { if (!decl) continue; llvm_emit_local_decl(c, decl, &value); - FOREACH_END(); + } break; } case AST_BREAK_STMT: diff --git a/src/compiler/llvm_codegen_storeload.c b/src/compiler/llvm_codegen_storeload.c index f2be4186c..14476dfcd 100644 --- a/src/compiler/llvm_codegen_storeload.c +++ b/src/compiler/llvm_codegen_storeload.c @@ -122,10 +122,9 @@ LLVMValueRef llvm_store_zero(GenContext *c, BEValue *ref) if (type->type_kind == TYPE_STRUCT) { Decl *decl = type->decl; - Decl **members = decl->strukt.members; - VECEACH(members, i) + FOREACH_IDX(i, Decl *, member, decl->strukt.members) { - if (!type_size(members[i]->type)) continue; + if (!type_size(member->type)) continue; BEValue member_ref; llvm_emit_struct_member_ref(c, ref, &member_ref, i); llvm_store_zero(c, &member_ref); diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index e7827b0e3..5c17335d4 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -34,14 +34,13 @@ static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl) // Avoid recursive issues. decl->type->backend_type = type; Decl **members = decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, members) { - Decl *member = members[i]; if (member->padding) { vec_add(types, llvm_const_padding_type(c, member->padding)); } - vec_add(types, llvm_get_type(c, members[i]->type)); + vec_add(types, llvm_get_type(c, member->type)); } if (decl->strukt.padding) { @@ -111,10 +110,9 @@ static void param_expand(GenContext *context, LLVMTypeRef** params_ref, Type *ty return; case TYPE_STRUCT: { - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - param_expand(context, params_ref, members[i]->type); + param_expand(context, params_ref, member->type); } return; } @@ -127,15 +125,15 @@ static void param_expand(GenContext *context, LLVMTypeRef** params_ref, Type *ty { ByteSize largest = 0; Type *largest_type = NULL; - Decl **members = type->decl->strukt.members; // Clang: Unions can be here only in degenerative cases - all the fields are same // after flattening. Thus we have to use the "largest" field. - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - if (type_size(type) > largest) + Type *member_type = member->type; + if (type_size(member_type) > largest) { - largest = type_size(type); - type = type->canonical; + largest = type_size(member_type); + largest_type = type_flatten(member_type); } } if (!largest) return; @@ -256,14 +254,14 @@ LLVMTypeRef llvm_update_prototype_abi(GenContext *c, FunctionPrototype *prototyp } // Add in all of the required arguments. - VECEACH(prototype->param_types, i) + FOREACH_IDX(i, Type *, type, prototype->param_types) { - add_func_type_param(c, prototype->param_types[i], prototype->abi_args[i], params); + add_func_type_param(c, type, prototype->abi_args[i], params); } - VECEACH(prototype->varargs, i) + FOREACH_IDX(j, Type *, type, prototype->varargs) { - add_func_type_param(c, prototype->varargs[i], prototype->abi_varargs[i], params); + add_func_type_param(c, type, prototype->abi_varargs[j], params); } return retval; } @@ -532,8 +530,8 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type) LLVMValueRef val = llvm_generate_introspection_global(c, NULL, type, INTROSPECT_TYPE_ENUM, type_base(type), elements, names, is_external); LLVMTypeRef val_type; - - VECEACH(associated_values, ai) + unsigned count = vec_size(associated_values); + for (unsigned ai = 0; ai < count; ai++) { val_type = NULL; bool mixed = false; @@ -575,9 +573,8 @@ static LLVMValueRef llvm_get_introspection_for_struct_union(GenContext *c, Type Decl *decl = type->decl; Decl **decls = decl->strukt.members; LLVMValueRef ref = llvm_generate_temp_introspection_global(c, type); - VECEACH(decls, i) + FOREACH(Decl *, member_decl, decls) { - Decl *member_decl = decls[i]; if (decl_is_struct_type(member_decl)) { llvm_get_typeid(c, member_decl->type); diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 05a76c9f0..b123a572f 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -773,9 +773,8 @@ Expr *parse_initializer_list(ParseContext *c, Expr *left) Expr **exprs = NULL; if (!parse_arg_list(c, &exprs, TOKEN_RBRACE, NULL, true)) return poisoned_expr; int designated = -1; - VECEACH(exprs, i) + FOREACH(Expr *, expr, exprs) { - Expr *expr = exprs[i]; if (expr->expr_kind == EXPR_DESIGNATOR) { if (designated == 0) diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index cfe2568f2..d86cce79f 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -253,15 +253,16 @@ bool parse_module(ParseContext *c, AstId contracts) Attr** attrs = NULL; bool is_cond; if (!parse_attributes(c, &attrs, &visibility, NULL, &is_cond)) return false; - FOREACH_BEGIN(Attr *attr, attrs) + FOREACH(Attr *, attr, attrs) + { if (attr->is_custom) RETURN_PRINT_ERROR_AT(false, attr, "Custom attributes cannot be used with 'module'."); switch (attr->attr_kind) { case ATTRIBUTE_LINK: - { - unsigned args = vec_size(attr->exprs); - if (args < 1) RETURN_PRINT_ERROR_AT(false, attr, "'@link' needs at least 1 argument."); - } + { + unsigned args = vec_size(attr->exprs); + if (args < 1) RETURN_PRINT_ERROR_AT(false, attr, "'@link' needs at least 1 argument."); + } vec_add(c->unit->attr_links, attr); continue; case ATTRIBUTE_IF: @@ -276,20 +277,23 @@ bool parse_module(ParseContext *c, AstId contracts) continue; case ATTRIBUTE_EXPORT: if (attr->exprs) RETURN_PRINT_ERROR_AT(false, attr, "Expected no arguments to '@export'"); - if (c->unit->export_by_default) RETURN_PRINT_ERROR_AT(false, attr, "'@export' appeared more than once."); + if (c->unit->export_by_default) + RETURN_PRINT_ERROR_AT(false, attr, "'@export' appeared more than once."); c->unit->export_by_default = true; continue; case ATTRIBUTE_EXTERN: { if (vec_size(attr->exprs) != 1) { - RETURN_PRINT_ERROR_AT(false, attr, "Expected 1 argument to '@extern(..), not %d'.", vec_size(attr->exprs)); + RETURN_PRINT_ERROR_AT(false, attr, "Expected 1 argument to '@extern(..), not %d'.", + vec_size(attr->exprs)); } Expr *expr = attr->exprs[0]; if (!expr_is_const_string(expr)) RETURN_PRINT_ERROR_AT(false, expr, "Expected a constant string."); if (c->unit->module->extname) { - RETURN_PRINT_ERROR_AT(false, attr, "External name for the module may only be declared in one location."); + RETURN_PRINT_ERROR_AT(false, attr, + "External name for the module may only be declared in one location."); } c->unit->module->extname = expr->const_expr.bytes.ptr; continue; @@ -298,7 +302,7 @@ bool parse_module(ParseContext *c, AstId contracts) break; } RETURN_PRINT_ERROR_AT(false, attr, "'%s' cannot be used after a module declaration.", attr->name); - FOREACH_END(); + } c->unit->default_visibility = visibility; CONSUME_EOS_OR_RET(false); return true; @@ -1034,9 +1038,10 @@ bool parse_attributes(ParseContext *c, Attr ***attributes_ref, Visibility *visib } } const char *name = attr->name; - FOREACH_BEGIN(Attr *other_attr, *attributes_ref) + FOREACH(Attr *, other_attr, *attributes_ref) + { if (other_attr->name == name) RETURN_PRINT_ERROR_AT(false, attr, "Repeat of attribute '%s' here.", name); - FOREACH_END(); + } vec_add(*attributes_ref, attr); } return true; @@ -1107,10 +1112,11 @@ static inline Decl *parse_global_declaration(ParseContext *c) // Copy the attributes to the other variables. if (attributes) { - FOREACH_BEGIN(Decl *d, decls) + FOREACH(Decl *, d, decls) + { if (d == decl) continue; d->attributes = copy_attributes_single(attributes); - FOREACH_END(); + } } // If we have multiple decls, then we return that as a bundled decl_globals if (decls) @@ -2103,9 +2109,8 @@ static inline Decl *parse_fault_declaration(ParseContext *c) fault_const->enum_constant.parent = declid(decl); fault_const->enum_constant.ordinal = ordinal; ordinal++; - VECEACH(decl->enums.values, i) + FOREACH(Decl *, other_constant, decl->enums.values) { - Decl *other_constant = decl->enums.values[i]; if (other_constant->name == name) { PRINT_ERROR_AT(fault_const, "This fault value was declared twice."); @@ -2196,9 +2201,8 @@ static inline Decl *parse_enum_declaration(ParseContext *c) { return poisoned_decl; } - VECEACH(decl->enums.values, i) + FOREACH(Decl *, other_constant, decl->enums.values) { - Decl *other_constant = decl->enums.values[i]; if (other_constant->name == name) { PRINT_ERROR_AT(enum_const, "This enum constant is declared twice."); diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 32e247346..9d12c73e6 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -62,10 +62,11 @@ static Ast *parse_decl_stmt_after_type(ParseContext *c, TypeInfo *type) } if (attributes) { - FOREACH_BEGIN(Decl *d, decls) + FOREACH(Decl *, d, decls) + { if (d == decl) continue; d->attributes = copy_attributes_single(attributes); - FOREACH_END(); + } } ast->decls_stmt = decls; ast->ast_kind = AST_DECLS_STMT; @@ -105,11 +106,12 @@ static inline Ast *parse_declaration_stmt(ParseContext *c) result->declare_stmt->visibility = VISIBLE_LOCAL; return result; } - FOREACH_BEGIN(Decl *var, result->decls_stmt) + FOREACH(Decl *, var, result->decls_stmt) + { var->var.is_threadlocal = is_threadlocal; var->var.is_static = is_static || is_threadlocal; var->visibility = VISIBLE_LOCAL; - FOREACH_END(); + } return result; } diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index c63a962c0..c5d889ca3 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -66,9 +66,7 @@ INLINE void add_decl_to_list(Decl ***list, Decl *decl) { if (decl->decl_kind == DECL_GLOBALS) { - FOREACH_BEGIN(Decl *d, decl->decls) - vec_add(*list, d); - FOREACH_END(); + FOREACH(Decl *, d, decl->decls) vec_add(*list, d); return; } vec_add(*list, decl); diff --git a/src/compiler/sema_asm.c b/src/compiler/sema_asm.c index ccd735710..350cfecb3 100644 --- a/src/compiler/sema_asm.c +++ b/src/compiler/sema_asm.c @@ -202,9 +202,10 @@ static inline bool sema_check_asm_arg_reg(SemaContext *context, AsmInlineBlock * static inline ExprAsmArg *asm_reg_find_decl(ExprAsmArg **args, Decl *decl, AsmArgKind kind) { - FOREACH_BEGIN(ExprAsmArg *val, args) + FOREACH(ExprAsmArg *, val, args) + { if (val->kind == kind && val->ident.ident_decl == decl) return val; - FOREACH_END(); + } return NULL; } @@ -275,10 +276,7 @@ static inline void asm_reg_add_input(AsmInlineBlock *block, ExprAsmArg *arg) asm_add_input(block, arg); } ADD_CLOBBER:; - foreach(ExprAsmArg *, block->output_vars) - { - val->ident.early_clobber = true; - } + FOREACH(ExprAsmArg *, val, block->output_vars) val->ident.early_clobber = true; } static inline bool sema_check_asm_var(SemaContext *context, AsmInlineBlock *block, AsmInstruction *instr, AsmArgType arg_type, Expr *expr) diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index ac2e89b4b..214f3939b 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -580,9 +580,10 @@ static void expr_recursively_rewrite_untyped_list(Expr *expr, Expr **list) expr->expr_kind = EXPR_INITIALIZER_LIST; expr->initializer_list = list; expr->resolve_status = RESOLVE_NOT_DONE; - FOREACH_BEGIN(Expr *inner, list) + FOREACH(Expr *, inner, list) + { expr_recursively_rewrite_untyped_list(inner, inner->const_expr.untyped_list); - FOREACH_END(); + } } @@ -797,9 +798,10 @@ static bool rule_ulist_to_struct(CastContext *cc, bool is_explicit, bool is_sile vec_size(members), size); } if (!sema_analyse_decl(cc->context, strukt)) return false; - FOREACH_BEGIN_IDX(i, Expr *expr, expressions) + FOREACH_IDX(i, Expr *, expr, expressions) + { if (!may_cast(cc->context, expr, members[i]->type, false, is_silent)) return false; - FOREACH_END(); + } return true; } @@ -816,18 +818,20 @@ static bool rule_ulist_to_vecarr(CastContext *cc, bool is_explicit, bool is_sile cc->to->array.len, size); } Type *base = cc->to->array.base; - FOREACH_BEGIN(Expr *expr, expressions) + FOREACH(Expr *, expr, expressions) + { if (!may_cast(cc->context, expr, base, false, is_silent)) return false; - FOREACH_END(); + } return true; } static bool rule_ulist_to_slice(CastContext *cc, bool is_explicit, bool is_silent) { Type *base = cc->to->array.base; - FOREACH_BEGIN(Expr *expr, cc->expr->const_expr.untyped_list) + FOREACH(Expr *, expr, cc->expr->const_expr.untyped_list) + { if (!may_cast(cc->context, expr, base, false, is_silent)) return false; - FOREACH_END(); + } return true; } @@ -841,9 +845,10 @@ static bool rule_ulist_to_inferred(CastContext *cc, bool is_explicit, bool is_si RETURN_CAST_ERROR(cc->expr, "This untyped list would infer to a zero elements, which is not allowed."); } Type *base = cc->to->array.base; - FOREACH_BEGIN(Expr *expr, expressions) + FOREACH(Expr *, expr, expressions) + { if (!may_cast(cc->context, expr, base, false, is_silent)) return false; - FOREACH_END(); + } return true; } @@ -1024,10 +1029,11 @@ static bool rule_ptr_to_interface(CastContext *cc, bool is_explicit, bool is_sil { Type *interface = cc->to; Decl *pointee_decl = pointee->decl; - FOREACH_BEGIN(TypeInfo *interface_type, pointee_decl->interfaces) + FOREACH(TypeInfo *, interface_type, pointee_decl->interfaces) + { if (!sema_resolve_type_info(cc->context, interface_type, RESOLVE_TYPE_DEFAULT)) return false; if (interface_type->type == interface) return true; - FOREACH_END(); + } } if (is_silent) return false; RETURN_CAST_ERROR(cc->expr, "%s cannot be implicitly cast to %s, but you can use an explicit " @@ -1042,9 +1048,10 @@ static bool rule_interface_to_interface(CastContext *cc, bool is_explicit, bool Type *from_interface = cc->from; Type *interface = cc->to->canonical; if (!sema_resolve_type_decl(cc->context, from_interface)) return false; - FOREACH_BEGIN(TypeInfo *parent, from_interface->decl->interfaces) + FOREACH(TypeInfo *, parent, from_interface->decl->interfaces) + { if (parent->type->canonical == interface) return true; - FOREACH_END(); + } if (is_silent) return false; RETURN_CAST_ERROR(cc->expr, "%s is not a parent interface of %s, but you can insert an explicit cast '(%s)value' to enforce the (unsafe) conversion.", type_quoted_error_string(cc->to), type_quoted_error_string(from_interface), @@ -1357,17 +1364,19 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const case CONST_INIT_ARRAY: { Type *element_type = type_flatten(to_type)->array.base; - FOREACH_BEGIN(ConstInitializer *element, initializer->init_array.elements) + FOREACH(ConstInitializer *, element, initializer->init_array.elements) + { vector_const_initializer_convert_to_type(context, element, element_type); - FOREACH_END(); + } break; } case CONST_INIT_ARRAY_FULL: { Type *element_type = type_flatten(to_type)->array.base; - FOREACH_BEGIN(ConstInitializer *element, initializer->init_array_full) + FOREACH(ConstInitializer *, element, initializer->init_array_full) + { vector_const_initializer_convert_to_type(context, element, element_type); - FOREACH_END(); + } break; } case CONST_INIT_VALUE: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index af3501bee..0412ef88c 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -355,9 +355,9 @@ static bool sema_analyse_union_members(SemaContext *context, Decl *decl) decl->strukt.union_rep = max_alignment_element; // All members share the same alignment - VECEACH(members, i) + FOREACH(Decl *, member, members) { - members[i]->alignment = decl->alignment; + member->alignment = decl->alignment; } assert(max_size); @@ -1481,10 +1481,9 @@ static bool sema_analyse_operator_common(SemaContext *context, Decl *method, Typ if (!signature->rtype) RETURN_SEMA_ERROR(method, "The return value must be explicitly typed for '%s'.", method->name); - VECEACH(params, i) + FOREACH(Decl *, param, params) { - Decl *param = params[i]; - if (!params[i]->var.type_info) + if (!param->var.type_info) { RETURN_SEMA_ERROR(param, "All parameters must be explicitly typed for '%s'.", method->name); } @@ -1497,18 +1496,17 @@ static inline Decl *operator_in_module(SemaContext *c, Module *module, OperatorO { if (module->is_generic) return NULL; Decl **extensions = module->private_method_extensions; - VECEACH(extensions, j) + FOREACH(Decl *, extension, extensions) { - Decl *extension = extensions[j]; if (extension->operator == operator_overload) { unit_register_external_symbol(c->compilation_unit, extension); return extension; } } - VECEACH(module->sub_modules, i) + FOREACH(Module *, sub_module, module->sub_modules) { - return operator_in_module(c, module->sub_modules[i], operator_overload); + return operator_in_module(c, sub_module, operator_overload); } return NULL; } @@ -1518,10 +1516,8 @@ Decl *sema_find_operator(SemaContext *context, Type *type, OperatorOverload oper type = type->canonical; if (!type_may_have_sub_elements(type)) return NULL; Decl *def = type->decl; - Decl **funcs = def->methods; - VECEACH(funcs, i) + FOREACH(Decl *, func, def->methods) { - Decl *func = funcs[i]; if (func->operator == operator_overload) { unit_register_external_symbol(context->compilation_unit, func); @@ -1531,10 +1527,9 @@ Decl *sema_find_operator(SemaContext *context, Type *type, OperatorOverload oper Decl *extension = operator_in_module(context, context->compilation_unit->module, operator_overload); if (extension) return extension; - Decl **imports = context->unit->imports; - VECEACH(imports, i) + FOREACH(Decl *, import, context->unit->imports) { - extension = operator_in_module(context, imports[i]->import.module, operator_overload); + extension = operator_in_module(context, import->import.module, operator_overload); if (extension) return extension; } return NULL; @@ -1628,9 +1623,10 @@ bool sema_decl_if_cond(SemaContext *context, Decl *decl) INLINE Attr* method_find_overload_attribute(Decl *method) { - FOREACH_BEGIN(Attr *attr, method->attributes) + FOREACH(Attr *, attr, method->attributes) + { if (attr->attr_kind == ATTRIBUTE_OPERATOR) return attr; - FOREACH_END(); + } UNREACHABLE } @@ -1882,13 +1878,15 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl */ static Decl *sema_interface_method_by_name(Decl *interface, const char *name) { - FOREACH_BEGIN(Decl *method, interface->interface_methods) + FOREACH(Decl *, method, interface->interface_methods) + { if (method->name == name) return method; - FOREACH_END(); - FOREACH_BEGIN(TypeInfo *parent_type, interface->interfaces) + } + FOREACH(TypeInfo *, parent_type, interface->interfaces) + { Decl *res = sema_interface_method_by_name(parent_type->type->decl, name); if (res) return res; - FOREACH_END(); + } return NULL; } @@ -1925,7 +1923,8 @@ static inline Decl *sema_find_interface_for_method(SemaContext *context, Canonic Decl *first_interface = NULL; // Walk through all implemented interfaces. - FOREACH_BEGIN(TypeInfo *proto, parent_type->decl->interfaces) + FOREACH(TypeInfo *, proto, parent_type->decl->interfaces) + { Decl *interface = proto->type->decl; Decl *match = sema_interface_method_by_name(interface, name); if (!match) continue; @@ -1944,7 +1943,7 @@ static inline Decl *sema_find_interface_for_method(SemaContext *context, Canonic // Update the match. first_match = match; first_interface = interface; - FOREACH_END(); + } // No match => return NULL. if (!first_match) return NULL; @@ -2006,16 +2005,18 @@ static inline bool sema_compare_method_with_interface(SemaContext *context, Decl } // Check each param. - FOREACH_BEGIN_IDX(i, Decl *param, this_params) + FOREACH_IDX(i, Decl *, param, this_params) + { if (i == 0) continue; if (param->type->canonical != any_params[i]->type->canonical) { - SEMA_ERROR(vartype(param), "The prototype argument has type %s, but in this function it has type %s. Please make them match.", + SEMA_ERROR(vartype(param), + "The prototype argument has type %s, but in this function it has type %s. Please make them match.", type_quoted_error_string(any_params[i]->type), type_quoted_error_string(param->type)); SEMA_NOTE(vartype(any_params[i]), "The interface definition is here."); return false; } - FOREACH_END(); + } return true; } @@ -2636,7 +2637,8 @@ static bool sema_analyse_attributes_inner(SemaContext *context, Decl *decl, Attr } // Walk through all of the attributes. - FOREACH_BEGIN(Attr *attr, attrs) + FOREACH(Attr *, attr, attrs) + { if (attr->is_custom) { if (!sema_analyse_custom_attribute(context, decl, attr, domain, top, erase_decl)) return false; @@ -2647,7 +2649,7 @@ static bool sema_analyse_attributes_inner(SemaContext *context, Decl *decl, Attr if (!sema_analyse_attribute(context, decl, attr, domain, erase_decl)) return false; } if (*erase_decl) return true; - FOREACH_END(); + } return true; } @@ -2679,15 +2681,14 @@ static inline bool sema_analyse_doc_header(SemaContext *context, AstId doc, const char *param_name = directive->contract_stmt.param.name; Decl *extra_param = NULL; Decl *param = NULL; - VECEACH(params, j) + FOREACH(Decl *, other_param, params) { - param = params[j]; + param = other_param; if (param && param->name == param_name) goto NEXT; } - VECEACH(extra_params, j) + FOREACH(Decl *, extra, extra_params) { - assert(extra_params); - param = extra_params[j]; + param = extra; if (param && param->name == param_name) goto NEXT; } RETURN_SEMA_ERROR(&directive->contract_stmt.param, "There is no parameter '%s', did you misspell it?", param_name); @@ -3629,7 +3630,8 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, { unsigned decls = 0; Decl* params_decls[MAX_PARAMS]; - VECEACH(module->parameters, i) + unsigned count = vec_size(module->parameters); + for (unsigned i = 0; i < count; i++) { const char *param_name = module->parameters[i]; bool is_value = str_is_valid_constant(param_name); @@ -3667,10 +3669,9 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, Module *new_module = compiler_find_or_create_module(path, NULL); new_module->is_generic = false; new_module->generic_module = module; - CompilationUnit **units = module->units; - VECEACH(units, i) + FOREACH(CompilationUnit *, unit, module->units) { - vec_add(new_module->units, unit_copy(new_module, units[i])); + vec_add(new_module->units, unit_copy(new_module, unit)); } CompilationUnit *first_context = new_module->units[0]; for (unsigned i = 0; i < decls; i++) @@ -3691,7 +3692,8 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Module *module, Expr **params, bool mangled) { // First resolve - FOREACH_BEGIN_IDX(i, Expr *param, params) + FOREACH_IDX(i, Expr *, param, params) + { if (param->expr_kind == EXPR_TYPEINFO) { TypeInfo *type_info = param->type_expr; @@ -3730,7 +3732,7 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo } assert(expr_is_const(param)); } - FOREACH_END(); + } scratch_buffer_clear(); if (mangled) @@ -3742,8 +3744,9 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo { scratch_buffer_append("(<"); } - FOREACH_BEGIN_IDX(i, Expr *param, params) - if (i != 0) + FOREACH_IDX(j, Expr *, param, params) + { + if (j != 0) { scratch_buffer_append(mangled ? "$" : ", "); } @@ -3807,7 +3810,7 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo } } } - FOREACH_END(); + } scratch_buffer_append(mangled ? "$" : ">)"); return true; } @@ -3824,7 +3827,8 @@ static bool sema_analyse_generic_module_contracts(SemaContext *c, Module *module SemaContext temp_context; assert(ast->contract_stmt.kind == CONTRACT_REQUIRE); SemaContext *new_context = context_transform_for_eval(c, &temp_context, module->units[0]); - FOREACH_BEGIN(Expr *expr, ast->contract_stmt.contract.decl_exprs->expression_list) + FOREACH(Expr *, expr, ast->contract_stmt.contract.decl_exprs->expression_list) + { CondResult res = sema_check_comp_time_bool(new_context, expr); if (res == COND_MISSING) goto FAIL; if (res == COND_TRUE) continue; @@ -3839,10 +3843,10 @@ static bool sema_analyse_generic_module_contracts(SemaContext *c, Module *module sema_error_at(c, error_span, "Parameter(s) failed validation: %s", ast->contract_stmt.contract.expr_string); } - FAIL: + FAIL: sema_context_destroy(&temp_context); return false; - FOREACH_END(); + } sema_context_destroy(&temp_context); } return true; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index ee06b8d98..931874c29 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1217,9 +1217,9 @@ static inline int sema_call_find_index_of_named_parameter(SemaContext *context, SEMA_ERROR(expr, "A name was expected here."); return -1; } - VECEACH(func_params, i) + FOREACH_IDX(i, Decl *, func_param, func_params) { - if (func_params[i] && func_params[i]->name == name) return (int)i; + if (func_param && func_param->name == name) return (int) i; } SEMA_ERROR(expr, "There's no parameter with the name '%s'.", name); return -1; @@ -1721,7 +1721,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call { if (variadic == VARIADIC_RAW) { - foreach(Expr*, varargs) + FOREACH(Expr*, val, varargs) { // 12a. Analyse the expression. if (callee.macro) @@ -1747,7 +1747,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call } else { - foreach(Expr*, varargs) + FOREACH(Expr*, val, varargs) { // 11e. A simple variadic value: if (!sema_analyse_expr_rhs(context, variadic_type, val, true, no_match_ref)) return false; @@ -1920,9 +1920,8 @@ static inline Type *context_unify_returns(SemaContext *context) if (all_returns_need_casts) { assert(common_type != type_wildcard); - VECEACH(context->returns, i) + FOREACH(Ast *, return_stmt, context->returns) { - Ast *return_stmt = context->returns[i]; if (!return_stmt) continue; Expr *ret_expr = return_stmt->return_stmt.expr; if (!ret_expr) @@ -2008,9 +2007,8 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s unsigned vararg_index = sig->vararg_index; Expr **args = call_expr->call_expr.arguments; - VECEACH(params, i) + FOREACH_IDX(i, Decl *, param, params) { - Decl *param = params[i]; if (i == vararg_index) { if (!param) continue; @@ -2142,13 +2140,14 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s macro_context.yield_body = macro_body ? macro_body->macro_body_expr.body : NULL; macro_context.yield_params = body_params; macro_context.yield_context = context; - FOREACH_BEGIN(Expr *expr, call_expr->call_expr.varargs) + FOREACH(Expr *, expr, call_expr->call_expr.varargs) + { if (expr->resolve_status == RESOLVE_DONE) continue; Expr *expr_inner = expr_copy(expr); expr->expr_kind = EXPR_OTHER_CONTEXT; expr->expr_other_context.inner = expr_inner; expr->expr_other_context.context = context; - FOREACH_END(); + } macro_context.macro_varargs = call_expr->call_expr.varargs; macro_context.original_inline_line = context->original_inline_line ? context->original_inline_line : call_expr->span.row; macro_context.original_module = context->original_module ? context->original_module : context->compilation_unit->module; @@ -2156,9 +2155,8 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s BlockExit** block_exit_ref = CALLOCS(BlockExit*); macro_context.block_exit_ref = block_exit_ref; - VECEACH(params, i) + FOREACH(Decl *, param, params) { - Decl *param = params[i]; // Skip raw vararg if (!param) continue; if (!sema_add_local(¯o_context, param)) goto EXIT_FAIL; @@ -2197,9 +2195,8 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s if (rtype) { bool inferred_len = type_len_is_inferred(rtype); - VECEACH(macro_context.returns, i) + FOREACH(Ast *, return_stmt, macro_context.returns) { - Ast *return_stmt = macro_context.returns[i]; if (!return_stmt) { assert(may_be_optional); @@ -2284,9 +2281,8 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s if (!result) goto NOT_CT; if (!expr_is_constant_eval(result, CONSTANT_EVAL_CONSTANT_VALUE)) goto NOT_CT; bool only_ct_params = true; - VECEACH(params, i) + FOREACH(Decl *, param, params) { - Decl *param = params[i]; // Skip raw vararg if (!param) continue; switch (param->var.kind) @@ -2409,9 +2405,8 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c first_defer->defer_stmt.prev_defer = context->active_scope.defer_last; context->active_scope.defer_last = macro_defer; } - VECEACH(params, i) + FOREACH(Decl *, param, params) { - Decl *param = params[i]; if (!sema_add_local(context, param)) return SCOPE_POP_ERROR(); } Ast *ast = copy_ast_single(macro_context->yield_body); @@ -3848,10 +3843,9 @@ static inline bool sema_expr_fold_to_member(Expr *expr, Expr *parent, Decl *memb goto EVAL; case CONST_INIT_STRUCT: { - Decl **members = init->type->decl->strukt.members; - VECEACH(members, i) + FOREACH_IDX(i, Decl *, other_member, init->type->decl->strukt.members) { - if (members[i] == member) + if (other_member == member) { result = init->init_struct[i]; goto EVAL; @@ -4431,10 +4425,11 @@ CHECK_DEEPER: // Look at interface parents if (!member && decl->decl_kind == DECL_INTERFACE) { - FOREACH_BEGIN(TypeInfo *parent_interface, decl->interfaces) + FOREACH(TypeInfo *, parent_interface, decl->interfaces) + { member = sema_resolve_method(context->unit, parent_interface->type->decl, kw, &ambiguous, &private); if (member) break; - FOREACH_END(); + } } if (ambiguous) { @@ -4678,7 +4673,7 @@ static inline bool sema_expr_analyse_expr_list(SemaContext *context, Expr *expr) { bool success = true; ByteSize last = vec_size(expr->expression_list) - 1; - VECEACH(expr->expression_list, i) + for (unsigned i = 0; i <= last; i++) { Expr *checked_expr = expr->expression_list[i]; if (!sema_analyse_expr(context, checked_expr)) return false; @@ -7339,7 +7334,8 @@ static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr { if (!sema_set_abi_alignment(context, type, &align)) return false; } - FOREACH_BEGIN_IDX(i, DesignatorElement *element, path) + FOREACH_IDX(i, DesignatorElement *, element, path) + { Decl *member; ArraySize index = 0; Type *result_type; @@ -7362,7 +7358,7 @@ static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr align = type_min_alignment(size * index, align); } type = result_type; - FOREACH_END(); + } expr_rewrite_const_int(expr, type_isz, align); return true; } @@ -7612,11 +7608,12 @@ static inline bool sema_may_reuse_lambda(SemaContext *context, Decl *lambda, Typ { Signature *sig = &lambda->func_decl.signature; if (typeget(sig->rtype)->canonical != types[0]) return false; - FOREACH_BEGIN_IDX(i, Decl *param, sig->params) + FOREACH_IDX(i, Decl *, param, sig->params) + { TypeInfo *info = vartype(param); assert(info && types[i + 1]); // NOLINT if (info->type->canonical != types[i + 1]) return false; - FOREACH_END(); + } return true; } @@ -7633,7 +7630,8 @@ INLINE bool lambda_parameter_match(Decl **ct_lambda_params, Decl *candidate) unsigned param_count = vec_size(ct_lambda_params); assert(vec_size(candidate->func_decl.lambda_ct_parameters) == param_count); if (!param_count) return true; - FOREACH_BEGIN_IDX(i, Decl *param, candidate->func_decl.lambda_ct_parameters) + FOREACH_IDX(i, Decl *, param, candidate->func_decl.lambda_ct_parameters) + { Decl *ct_param = ct_lambda_params[i]; if (!param->var.is_read) continue; assert(ct_param->resolve_status == RESOLVE_DONE || param->resolve_status == RESOLVE_DONE); @@ -7643,19 +7641,21 @@ INLINE bool lambda_parameter_match(Decl **ct_lambda_params, Decl *candidate) case VARDECL_LOCAL_CT_TYPE: case VARDECL_PARAM_CT_TYPE: if (ct_param->var.init_expr->type_expr->type->canonical != - param->var.init_expr->type_expr->type->canonical) return false; + param->var.init_expr->type_expr->type->canonical) + return false; break; case VARDECL_LOCAL_CT: case VARDECL_PARAM_CT: assert(expr_is_const(ct_param->var.init_expr)); assert(expr_is_const(param->var.init_expr)); if (!expr_const_compare(&ct_param->var.init_expr->const_expr, - ¶m->var.init_expr->const_expr, BINARYOP_EQ)) return false; + ¶m->var.init_expr->const_expr, BINARYOP_EQ)) + return false; break; default: UNREACHABLE } - FOREACH_END(); + } return true; } @@ -7668,10 +7668,12 @@ static inline Decl *sema_find_cached_lambda(SemaContext *context, Type *func_typ if (func_type) { Type *raw = func_type->canonical->pointer->function.prototype->raw_type; - FOREACH_BEGIN(Decl *candidate, original->func_decl.generated_lambda) + FOREACH(Decl *, candidate, original->func_decl.generated_lambda) + { if (raw == candidate->type->function.prototype->raw_type && - lambda_parameter_match(ct_lambda_parameters, candidate)) return candidate; - FOREACH_END(); + lambda_parameter_match(ct_lambda_parameters, candidate)) + return candidate; + } return NULL; } Signature *sig = &original->func_decl.signature; @@ -7680,18 +7682,22 @@ static inline Decl *sema_find_cached_lambda(SemaContext *context, Type *func_typ if (!rtype) return NULL; Type *types[200]; types[0] = rtype; - FOREACH_BEGIN_IDX(i, Decl *param, sig->params) + FOREACH_IDX(i, Decl *, param, sig->params) + { TypeInfo *info = vartype(param); if (!info) return NULL; Type *type = sema_evaluate_type_copy(context, info); if (!type) return NULL; assert(i < 198); types[i + 1] = type; - FOREACH_END(); + } - FOREACH_BEGIN(Decl *candidate, original->func_decl.generated_lambda) - if (sema_may_reuse_lambda(context, candidate, types) && lambda_parameter_match(ct_lambda_parameters, candidate)) return candidate; - FOREACH_END(); + FOREACH(Decl *, candidate, original->func_decl.generated_lambda) + { + if (sema_may_reuse_lambda(context, candidate, types) && + lambda_parameter_match(ct_lambda_parameters, candidate)) + return candidate; + } return NULL; } @@ -7737,13 +7743,14 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo Decl *fault = poisoned_decl; if (io_error && io_error->decl_kind == DECL_FAULT) { - FOREACH_BEGIN(Decl *f, io_error->enums.values) + FOREACH(Decl *, f, io_error->enums.values) + { if (f->name == kw_FILE_NOT_FOUND) { fault = f; break; } - FOREACH_END(); + } } global_context.io_error_file_not_found = fault; } @@ -7833,11 +7840,12 @@ static inline bool sema_expr_analyse_lambda(SemaContext *context, Type *target_t { RETURN_SEMA_ERROR(expr, "The lambda doesn't match the required type %s.", type_quoted_error_string(target_type)); } - FOREACH_BEGIN_IDX(i, Decl *param, sig->params) + FOREACH_IDX(i, Decl *, param, sig->params) + { if (param->var.type_info) continue; if (!to_sig) goto FAIL_NO_INFER; param->var.type_info = type_info_id_new_base(to_sig->params[i]->type, param->span); - FOREACH_END(); + } CompilationUnit *unit = decl->unit = context->unit; assert(!decl->name); scratch_buffer_clear(); @@ -8157,14 +8165,15 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Type *infer_ty assert(index < 0x10000); Decl *decl = NULL; // Try to find the original param. - FOREACH_BEGIN(Decl *val, context->macro_params) + FOREACH(Decl *, val, context->macro_params) + { if (!val) continue; if (val->va_index == index && val->var.kind == VARDECL_PARAM) { decl = val; break; } - FOREACH_END(); + } // Not found, so generate a new. if (!decl) { @@ -8219,14 +8228,15 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Type *infer_ty Decl *decl = NULL; // Try to find the original param. - FOREACH_BEGIN(Decl *val, context->macro_params) + FOREACH(Decl *, val, context->macro_params) + { if (!val) continue; if (val->var.kind == VARDECL_PARAM_REF && val->va_index == index) { decl = val; break; } - FOREACH_END(); + } // Not found, so generate a new. if (!decl) { @@ -8269,15 +8279,17 @@ static inline bool sema_expr_analyse_ct_and_or(SemaContext *context, Expr *expr) assert(expr->resolve_status == RESOLVE_RUNNING); bool is_and = expr->ct_and_or_expr.is_and; Expr **exprs = expr->ct_and_or_expr.args; - FOREACH_BEGIN(Expr *single_expr, exprs) + FOREACH(Expr *, single_expr, exprs) + { if (!sema_analyse_expr(context, single_expr)) return false; - if (!expr_is_const_bool(single_expr)) RETURN_SEMA_ERROR(single_expr, "Expected this to evaluate to a constant boolean."); + if (!expr_is_const_bool(single_expr)) + RETURN_SEMA_ERROR(single_expr, "Expected this to evaluate to a constant boolean."); if (single_expr->const_expr.b != is_and) { expr_rewrite_const_bool(expr, type_bool, !is_and); return true; } - FOREACH_END(); + } expr_rewrite_const_bool(expr, type_bool, is_and); return true; } @@ -8294,7 +8306,8 @@ typedef enum ConcatType_ bool sema_concat_join_arrays(SemaContext *context, Expr *expr, Expr **exprs, Type *type, ArraySize len) { ConstInitializer **inits = VECNEW(ConstInitializer*, len); - FOREACH_BEGIN(Expr *element, exprs) + FOREACH(Expr *, element, exprs) + { assert(element->const_expr.const_kind == CONST_INITIALIZER); ConstInitType init_type = element->const_expr.initializer->kind; switch (init_type) @@ -8306,12 +8319,11 @@ bool sema_concat_join_arrays(SemaContext *context, Expr *expr, Expr **exprs, Typ default: RETURN_SEMA_ERROR(element, "Only fully initialized arrays may be concatenated."); } - ConstInitializer **element_inits = element->const_expr.initializer->init_array_full; - VECEACH(element_inits, i) + FOREACH(ConstInitializer *, init, element->const_expr.initializer->init_array_full) { - vec_add(inits, element_inits[i]); + vec_add(inits, init); } - FOREACH_END(); + } expr->expr_kind = EXPR_CONST; expr->resolve_status = RESOLVE_DONE; expr->type = type; @@ -8342,9 +8354,7 @@ bool sema_append_const_array(SemaContext *context, Expr *expr, Expr *list, Expr ConstInitializer **inits = VECNEW(ConstInitializer*, len); if (!is_empty_slice) { - FOREACH_BEGIN(ConstInitializer *i, init->init_array_full) - vec_add(inits, i); - FOREACH_END(); + FOREACH(ConstInitializer *, i, init->init_array_full) vec_add(inits, i); } unsigned elements = vec_size(exprs); for (unsigned i = 1; i < elements; i++) @@ -8376,12 +8386,13 @@ bool sema_concat_join_bytes(Expr *expr, Expr **exprs, ArraySize len) bool is_bytes = exprs[0]->const_expr.const_kind == CONST_BYTES; char *data = malloc_arena(len + 1); char *current = data; - FOREACH_BEGIN(Expr *element, exprs) + FOREACH(Expr *, element, exprs) + { size_t str_len = element->const_expr.bytes.len; if (!str_len) continue; memcpy(current, element->const_expr.bytes.ptr, str_len); current += str_len; - FOREACH_END(); + } *current = '\0'; expr->expr_kind = EXPR_CONST; expr->const_expr = (ExprConst) { @@ -8510,9 +8521,10 @@ static inline bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *conca Expr *single_expr = exprs[i]; if (expr_is_const_untyped_list(single_expr)) { - FOREACH_BEGIN(Expr *expr_untyped, single_expr->const_expr.untyped_list) + FOREACH(Expr *, expr_untyped, single_expr->const_expr.untyped_list) + { vec_add(untyped_exprs, expr_untyped); - FOREACH_END(); + } continue; } ConstInitializer *init = single_expr->const_expr.initializer; @@ -8521,9 +8533,10 @@ static inline bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *conca if (init->kind == CONST_INIT_ZERO && init->type == type_untypedlist) continue; RETURN_SEMA_ERROR(single_expr, "Expected a full array here."); } - FOREACH_BEGIN(ConstInitializer *val, init->init_array_full) + FOREACH(ConstInitializer *, val, init->init_array_full) + { vec_add(untyped_exprs, val->init_value); - FOREACH_END(); + } } concat_expr->expr_kind = EXPR_CONST; concat_expr->type = type_untypedlist; @@ -8632,7 +8645,8 @@ static inline bool sema_expr_analyse_ct_offsetof(SemaContext *context, Expr *exp ByteSize offset = 0; Type *type = decl->type; - FOREACH_BEGIN_IDX(i, DesignatorElement *element, path) + FOREACH_IDX(i, DesignatorElement *, element, path) + { Decl *member; ArraySize index = 0; Type *result_type; @@ -8654,7 +8668,7 @@ static inline bool sema_expr_analyse_ct_offsetof(SemaContext *context, Expr *exp offset += type_size(result_type) * index; } type = result_type; - FOREACH_END(); + } expr_rewrite_const_int(expr, type_isz, offset); @@ -9004,10 +9018,11 @@ static MemberIndex len_from_const_initializer(ConstInitializer *init) case CONST_INIT_ARRAY: { MemberIndex max = 0; - FOREACH_BEGIN(ConstInitializer *element, init->init_array.elements) + FOREACH(ConstInitializer *, element, init->init_array.elements) + { assert(element->kind == CONST_INIT_ARRAY_VALUE); if (element->init_array_value.index > max) max = element->init_array_value.index; - FOREACH_END(); + } return max; } case CONST_INIT_ARRAY_FULL: @@ -9188,9 +9203,10 @@ bool sema_expr_check_discard(SemaContext *context, Expr *expr) { if (expr->expr_kind == EXPR_EXPRESSION_LIST) { - FOREACH_BEGIN(Expr *expr_element, expr->expression_list) + FOREACH(Expr *, expr_element, expr->expression_list) + { if (!sema_expr_check_discard(context, expr_element)) return false; - FOREACH_END(); + } return true; } if (expr->expr_kind == EXPR_SUBSCRIPT_ASSIGN || expr->expr_kind == EXPR_SLICE_ASSIGN) return true; diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index 572573989..1fe5bec1b 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -196,9 +196,8 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte return true; } ConstInitializer **inits = MALLOC(sizeof(ConstInitializer *) * vec_size(elements)); - VECEACH(elements, i) + FOREACH_IDX(i, Expr *, expr, elements) { - Expr *expr = elements[i]; if (expr_is_const_initializer(expr)) { inits[i] = expr->const_expr.initializer; @@ -358,9 +357,8 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex const_init->kind = CONST_INIT_ARRAY_FULL; const_init->type = type_flatten(initializer->type); ConstInitializer **inits = VECNEW(ConstInitializer*, vec_size(elements)); - VECEACH(elements, i) + FOREACH(Expr *, expr, elements) { - Expr *expr = elements[i]; if (expr_is_const_initializer(expr)) { vec_add(inits, expr->const_expr.initializer); @@ -381,14 +379,17 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex static inline bool sema_expr_analyse_untyped_initializer(SemaContext *context, Expr *initializer) { Expr **init_list = initializer->initializer_list; - FOREACH_BEGIN(Expr *element, init_list) + FOREACH(Expr *, element, init_list) + { if (!sema_analyse_expr(context, element)) return false; if (!expr_is_const(element)) { - SEMA_ERROR(element, "An untyped list can only have constant elements, you can try to type the list by prefixing the type, e.g. 'int[2] { a, b }'."); - return false; + RETURN_SEMA_ERROR(element, "An untyped list can only have " + "constant elements, you can try " + "to type the list by prefixing the type, " + "e.g. 'int[2] { a, b }'."); } - FOREACH_END(); + } initializer->expr_kind = EXPR_CONST; initializer->const_expr = (ExprConst) { .const_kind = CONST_UNTYPED_LIST, .untyped_list = init_list }; initializer->type = type_untypedlist; @@ -407,9 +408,8 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type Type *inner_type = NULL; bool is_inferred = type_is_inferred(flattened); int bitmember_count_without_value = 0; - VECEACH(init_expressions, i) + FOREACH(Expr *, expr, init_expressions) { - Expr *expr = init_expressions[i]; Decl *member; Type *result = sema_expr_analyse_designator(context, original, expr, &max_index, &member); if (!result) return false; @@ -528,10 +528,8 @@ static void sema_create_const_initializer_from_designated_init(ConstInitializer const_init->type = type_flatten(initializer->type); // Loop through the initializers. - Expr **init_expressions = initializer->initializer_list; - VECEACH(init_expressions, i) + FOREACH(Expr *, expr, initializer->initializer_list) { - Expr *expr = init_expressions[i]; DesignatorElement **path = expr->designator_expr.path; Expr *value = expr->designator_expr.value; assert(value); @@ -804,11 +802,11 @@ static inline void sema_update_const_initializer_with_designator_struct(ConstIni { // Allocate array containing all elements { a, b, c ... } ConstInitializer **const_inits = MALLOC(sizeof(ConstInitializer *) * vec_size(elements)); - VECEACH(elements, i) + FOREACH_IDX(i, Decl *, el, elements) { // Create zero initializers for each of those { a: zeroinit, b: zeroinit, ... } ConstInitializer *element_init = MALLOCS(ConstInitializer); - element_init->type = type_flatten(elements[i]->type); + element_init->type = type_flatten(el->type); element_init->kind = CONST_INIT_ZERO; const_inits[i] = element_init; } @@ -1178,9 +1176,8 @@ MemberIndex sema_get_initializer_const_array_size(SemaContext *context, Expr *in Expr **initializers = initializer->designated_init_list; MemberIndex size = 0; // Otherwise we assume everything's a designator. - VECEACH(initializers, i) + FOREACH(Expr *, sub_initializer, initializers) { - Expr *sub_initializer = initializers[i]; assert(sub_initializer->expr_kind == EXPR_DESIGNATOR); DesignatorElement *element = sub_initializer->designator_expr.path[0]; @@ -1265,9 +1262,8 @@ static Decl *sema_resolve_element_for_name(SemaContext *context, Decl **decls, D } const char *name = field->identifier_expr.ident; unsigned old_index = *index; - VECEACH(decls, i) + FOREACH_IDX(i, Decl *, decl, decls) { - Decl *decl = decls[i]; // The simple case, we have a match. if (decl->name == name) { diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 917a00651..b366917bd 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -123,9 +123,10 @@ INLINE bool sema_set_alloca_alignment(SemaContext *context, Type *type, AlignSiz INLINE Attr* attr_find_kind(Attr **attrs, AttributeType attr_type) { - FOREACH_BEGIN(Attr *attr, attrs) + FOREACH(Attr *, attr, attrs) + { if (attr->attr_kind == attr_type) return attr; - FOREACH_END(); + } return NULL; } diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 6498490c5..d5da08f73 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -45,9 +45,7 @@ INLINE void sema_trace_astid_liveness(AstId astid) static void sema_trace_expr_list_liveness(Expr **exprlist) { - FOREACH_BEGIN(Expr *arg, exprlist) - sema_trace_expr_liveness(arg); - FOREACH_END(); + FOREACH(Expr *, arg, exprlist) sema_trace_expr_liveness(arg); } static void sema_trace_stmt_chain_liveness(AstId astid) @@ -73,7 +71,8 @@ static void sema_trace_stmt_chain_liveness(AstId astid) } static void sema_trace_asm_arg_list(ExprAsmArg **list) { - FOREACH_BEGIN(ExprAsmArg *asm_arg, list) + FOREACH(ExprAsmArg *, asm_arg, list) + { switch (asm_arg->kind) { case ASM_ARG_ADDR: @@ -91,7 +90,7 @@ static void sema_trace_asm_arg_list(ExprAsmArg **list) continue; } UNREACHABLE - FOREACH_END(); + } } static void sema_trace_stmt_liveness(Ast *ast) @@ -158,9 +157,7 @@ static void sema_trace_stmt_liveness(Ast *ast) } case AST_DECLS_STMT: { - FOREACH_BEGIN(Decl *decl, ast->decls_stmt) - sema_trace_decl_liveness(decl); - FOREACH_END(); + FOREACH(Decl *, decl, ast->decls_stmt) sema_trace_decl_liveness(decl); return; } case AST_FOR_STMT: @@ -178,9 +175,7 @@ static void sema_trace_stmt_liveness(Ast *ast) case AST_IF_CATCH_SWITCH_STMT: sema_trace_exprid_liveness(ast->switch_stmt.cond); { - FOREACH_BEGIN(Ast *casestm, ast->switch_stmt.cases) - sema_trace_stmt_liveness(casestm); - FOREACH_END(); + FOREACH(Ast *, casestm, ast->switch_stmt.cases) sema_trace_stmt_liveness(casestm); } return; case AST_CASE_STMT: @@ -226,9 +221,7 @@ static void sema_trace_const_initializer_liveness(ConstInitializer *const_init) } case CONST_INIT_ARRAY: { - FOREACH_BEGIN(ConstInitializer *i, const_init->init_array.elements) - sema_trace_const_initializer_liveness(i); - FOREACH_END(); + FOREACH(ConstInitializer *, i, const_init->init_array.elements) sema_trace_const_initializer_liveness(i); return; } case CONST_INIT_UNION: @@ -363,9 +356,7 @@ RETRY: { sema_trace_decl_liveness(expr->catch_unwrap_expr.decl); } - FOREACH_BEGIN(Expr *e, expr->catch_unwrap_expr.exprs) - sema_trace_expr_liveness(e); - FOREACH_END(); + FOREACH(Expr *, e, expr->catch_unwrap_expr.exprs) sema_trace_expr_liveness(e); return; } case EXPR_CONST: @@ -379,9 +370,7 @@ RETRY: return; case EXPR_COND: { - FOREACH_BEGIN(Expr *e, expr->cond_expr) - sema_trace_expr_liveness(e); - FOREACH_END(); + FOREACH(Expr *, e, expr->cond_expr) sema_trace_expr_liveness(e); return; } case EXPR_DECL: @@ -398,9 +387,7 @@ RETRY: return; case EXPR_INITIALIZER_LIST: { - FOREACH_BEGIN(Expr *e, expr->initializer_list) - sema_trace_expr_liveness(e); - FOREACH_END(); + FOREACH(Expr *, e, expr->initializer_list) sema_trace_expr_liveness(e); return; } case EXPR_LAMBDA: @@ -408,9 +395,7 @@ RETRY: return; case EXPR_MACRO_BLOCK: { - FOREACH_BEGIN(Decl *val, expr->macro_block.params) - sema_trace_decl_liveness(val); - FOREACH_END(); + FOREACH(Decl *, val, expr->macro_block.params) sema_trace_decl_liveness(val); sema_trace_stmt_chain_liveness(expr->macro_block.first_stmt); return; } @@ -419,12 +404,8 @@ RETRY: return; case EXPR_MACRO_BODY_EXPANSION: { - FOREACH_BEGIN(Decl *arg, expr->body_expansion_expr.declarations) - sema_trace_decl_liveness(arg); - FOREACH_END(); - FOREACH_BEGIN(Expr *arg, expr->body_expansion_expr.values) - sema_trace_expr_liveness(arg); - FOREACH_END(); + FOREACH(Decl *, arg, expr->body_expansion_expr.declarations) sema_trace_decl_liveness(arg); + FOREACH(Expr *, arg, expr->body_expansion_expr.values) sema_trace_expr_liveness(arg); sema_trace_stmt_liveness(astptrzero(expr->body_expansion_expr.first_stmt)); return; } @@ -498,28 +479,37 @@ void sema_trace_liveness(void) } bool keep_tests = active_target.testing; bool keep_benchmarks = active_target.benchmarking; - FOREACH_BEGIN(Decl *function, global_context.method_extensions) + FOREACH(Decl *, function, global_context.method_extensions) + { if (function->func_decl.attr_dynamic) function->no_strip = true; if (function->is_export || function->no_strip) sema_trace_decl_liveness(function); - FOREACH_END(); - FOREACH_BEGIN(Module *module, global_context.module_list) - FOREACH_BEGIN(CompilationUnit *unit, module->units) - FOREACH_BEGIN(Decl *function, unit->functions) - if (function->is_export || function->no_strip || function->func_decl.attr_finalizer || function->func_decl.attr_init || - (function->func_decl.attr_test && keep_tests) || - (function->func_decl.attr_benchmark && keep_benchmarks)) sema_trace_decl_liveness(function); - FOREACH_END(); - FOREACH_BEGIN(Decl *method, unit->methods) + } + FOREACH(Module *, module, global_context.module_list) + { + FOREACH(CompilationUnit *, unit, module->units) + { + FOREACH(Decl *, function, unit->functions) + { + if (function->is_export || function->no_strip || function->func_decl.attr_finalizer || + function->func_decl.attr_init || + (function->func_decl.attr_test && keep_tests) || + (function->func_decl.attr_benchmark && keep_benchmarks)) + sema_trace_decl_liveness(function); + } + FOREACH(Decl *, method, unit->methods) + { if (method->is_export || method->no_strip) sema_trace_decl_liveness(method); - FOREACH_END(); - FOREACH_BEGIN(Decl *var, unit->vars) + } + FOREACH(Decl *, var, unit->vars) + { if (var->is_export || var->no_strip) sema_trace_decl_liveness(var); - FOREACH_END(); - FOREACH_BEGIN(Decl *method, unit->local_method_extensions) + } + FOREACH(Decl *, method, unit->local_method_extensions) + { if (method->is_export || method->no_strip) sema_trace_decl_liveness(method); - FOREACH_END(); - FOREACH_END(); - FOREACH_END(); + } + } + } } @@ -540,9 +530,7 @@ INLINE void sema_trace_decl_dynamic_methods(Decl *decl) } static void sema_trace_func_liveness(Signature *sig) { - FOREACH_BEGIN(Decl *param, sig->params) - sema_trace_decl_liveness(param); - FOREACH_END(); + FOREACH(Decl *, param, sig->params) sema_trace_decl_liveness(param); sema_trace_type_liveness(typeget(sig->rtype)); } diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index 16f7a91bf..647c84132 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -67,9 +67,8 @@ void sema_decl_stack_push(Decl *decl) static void add_members_to_decl_stack(Decl *decl) { - VECEACH(decl->methods, i) + FOREACH(Decl *, func, decl->methods) { - Decl *func = decl->methods[i]; sema_decl_stack_push(func); } while (decl->decl_kind == DECL_DISTINCT) @@ -80,29 +79,23 @@ static void add_members_to_decl_stack(Decl *decl) } if (decl_is_enum_kind(decl)) { - Decl **members = decl->enums.parameters; - VECEACH(members, i) - { - sema_decl_stack_push(members[i]); - } + FOREACH(Decl *, member, decl->enums.parameters) sema_decl_stack_push(member); } if (decl->decl_kind == DECL_INTERFACE) { - FOREACH_BEGIN(TypeInfo *parent_interface, decl->interfaces) - FOREACH_BEGIN(Decl *interface, parent_interface->type->decl->interface_methods) + FOREACH(TypeInfo *, parent_interface, decl->interfaces) + { + FOREACH(Decl *, interface, parent_interface->type->decl->interface_methods) + { sema_decl_stack_push(interface); - FOREACH_END(); - FOREACH_END(); - FOREACH_BEGIN(Decl *interface, decl->interface_methods) - sema_decl_stack_push(interface); - FOREACH_END(); + } + } + FOREACH(Decl *, interface, decl->interface_methods) sema_decl_stack_push(interface); } if (decl_is_struct_type(decl) || decl->decl_kind == DECL_BITSTRUCT) { - Decl **members = decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, decl->strukt.members) { - Decl *member = members[i]; if (member->name == NULL) { add_members_to_decl_stack(member); @@ -137,9 +130,8 @@ static Decl *sema_find_decl_in_private_imports(Decl **imports, NameResolve *name // 1. Loop over imports. Path *path = name_resolve->path; const char *symbol = name_resolve->symbol; - VECEACH(imports, i) + FOREACH(Decl *, import, imports) { - Decl *import = imports[i]; if (import->import.module->is_generic != want_generic) continue; if (!import->import.import_private_as_public) continue; // Is the decl in the import. @@ -180,9 +172,8 @@ static Decl *sema_find_decl_in_private_imports(Decl **imports, NameResolve *name static inline bool sema_is_path_found(Module **modules, Path *path, bool want_generic) { - VECEACH(modules, i) + FOREACH(Module *, module, modules) { - Module *module = modules[i]; if (module->is_generic != want_generic) continue; if (matches_subpath(module->name, path)) { @@ -195,9 +186,8 @@ static inline bool sema_is_path_found(Module **modules, Path *path, bool want_ge Decl *sema_find_decl_in_modules(Module **module_list, Path *path, const char *interned_name) { bool path_found = false; - VECEACH(module_list, i) + FOREACH(Module *, module, module_list) { - Module *module = module_list[i]; Decl *decl = sema_find_decl_in_module(module, path, interned_name, &path_found); if (decl) return decl; } @@ -239,9 +229,8 @@ static bool decl_is_visible(CompilationUnit *unit, Decl *decl) lookup = lookup->parent_module; } - VECEACH(unit->imports, i) + FOREACH(Decl *, import, unit->imports) { - Decl *import = unit->imports[i]; Module *import_module = import->import.module; if (import_module == module) return true; if (module_inclusion_match(import_module, module)) return true; @@ -284,12 +273,10 @@ static Decl *sema_find_decl_in_global(CompilationUnit *unit, DeclTable *table, M } // Else go through the list - Decl **decl_list = decls->decl_list; Decl *ambiguous = NULL; Decl *decl = NULL; - VECEACH(decl_list, i) + FOREACH(Decl *, candidate, decls->decl_list) { - Decl *candidate = decl_list[i]; if (path && !matches_subpath(decl_module(candidate)->name, path)) continue; if (!decl_is_visible(unit, candidate)) { @@ -365,9 +352,10 @@ static Decl *sema_resolve_path_symbol(SemaContext *context, NameResolve *name_re static inline Decl *sema_find_ct_local(SemaContext *context, const char *symbol) { Decl **locals = context->ct_locals; - FOREACH_BEGIN(Decl *cur, locals) + FOREACH(Decl *, cur, locals) + { if (cur->name == symbol) return cur; - FOREACH_END(); + } return NULL; } @@ -517,22 +505,24 @@ INLINE Decl *sema_resolve_symbol_common(SemaContext *context, NameResolve *name_ if (name_resolve->suppress_error) return NULL; bool path_found = false; Module *module_with_path = NULL; - FOREACH_BEGIN(Module *module, global_context.module_list) + FOREACH(Module *, module, global_context.module_list) + { if (matches_subpath(module->name, name_resolve->path)) { module_with_path = module; break; } - FOREACH_END(); + } if (!module_with_path) { - FOREACH_BEGIN(Module *module, global_context.generic_module_list) + FOREACH(Module *, module, global_context.generic_module_list) + { if (matches_subpath(module->name, name_resolve->path)) { module_with_path = module; break; } - FOREACH_END(); + } } if (module_with_path) { @@ -568,9 +558,8 @@ INLINE Decl *sema_resolve_symbol_common(SemaContext *context, NameResolve *name_ Decl *sema_find_extension_method_in_list(Decl **extensions, Type *type, const char *method_name) { - VECEACH(extensions, i) + FOREACH(Decl *, extension, extensions) { - Decl *extension = extensions[i]; if (extension->name != method_name) continue; if (type_infoptr(extension->func_decl.type_parent)->type->canonical == type) return extension; } @@ -601,8 +590,10 @@ Decl *sema_resolve_method_in_module(Module *module, Type *actual_type, const cha if (found && search_type == METHOD_SEARCH_CURRENT) return found; // We are now searching submodules, so hide the private ones. if (search_type == METHOD_SEARCH_CURRENT) search_type = METHOD_SEARCH_SUBMODULE_CURRENT; - FOREACH_BEGIN(Module *mod, module->sub_modules) - Decl *new_found = sema_resolve_method_in_module(mod, actual_type, method_name, private_found, ambiguous, search_type); + FOREACH(Module *, mod, module->sub_modules) + { + Decl *new_found = sema_resolve_method_in_module(mod, actual_type, method_name, private_found, ambiguous, + search_type); if (!new_found) continue; if (found) { @@ -610,7 +601,7 @@ Decl *sema_resolve_method_in_module(Module *module, Type *actual_type, const cha return found; } found = new_found; - FOREACH_END(); + } // We might have it ambiguous due to searching sub modules. return found; } @@ -620,17 +611,16 @@ Decl *sema_resolve_method(CompilationUnit *unit, Decl *type, const char *method_ // Interface, prefer interface methods. if (type->decl_kind == DECL_INTERFACE) { - FOREACH_BEGIN(Decl *method, type->interface_methods) + FOREACH(Decl *, method, type->interface_methods) + { if (method_name == method->name) return method; - FOREACH_END(); + } } // Look through natively defined methods. - FOREACH_BEGIN(Decl *method, type->methods) - if (method_name == method->name) - { - return method; - } - FOREACH_END(); + FOREACH(Decl *, method, type->methods) + { + if (method_name == method->name) return method; + } return sema_resolve_type_method(unit, type->type, method_name, ambiguous_ref, private_ref); } @@ -734,9 +724,8 @@ Decl *sema_resolve_type_method(CompilationUnit *unit, Type *type, const char *me } // 2. Lookup in imports - VECEACH(unit->imports, i) + FOREACH(Decl *, import, unit->imports) { - Decl *import = unit->imports[i]; if (import->import.module->is_generic) continue; Decl *new_found = sema_resolve_method_in_module(import->import.module, type, method_name, diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 728184c23..6fb703610 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -64,10 +64,9 @@ void sema_analysis_pass_process_imports(Module *module) DEBUG_LOG("Pass: Importing dependencies for files in module '%s'.", module->name->module); unsigned total_import_count = 0; - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { // 1. Loop through each context in the module. - CompilationUnit *unit = module->units[index]; DEBUG_LOG("Checking imports for %s.", unit->file->name); // 2. Loop through imports @@ -125,9 +124,9 @@ NEXT:; INLINE void register_global_decls(CompilationUnit *unit, Decl **decls) { - VECEACH(decls, i) + FOREACH(Decl *, decl, decls) { - unit_register_global_decl(unit, decls[i]); + unit_register_global_decl(unit, decl); } vec_resize(decls, 0); } @@ -166,12 +165,13 @@ static Decl **sema_load_include(CompilationUnit *unit, Decl *decl) } SemaContext context; sema_context_init(&context, unit); - FOREACH_BEGIN(Attr *attr, decl->attributes) + FOREACH(Attr *, attr, decl->attributes) + { if (attr->attr_kind != ATTRIBUTE_IF) { RETURN_PRINT_ERROR_AT(NULL, attr, "Invalid attribute for '$include'."); } - FOREACH_END(); + } bool success = sema_analyse_ct_expr(&context, decl->include.filename); sema_context_destroy(&context); if (success) return NULL; @@ -192,17 +192,16 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) } SemaContext context; sema_context_init(&context, unit); - FOREACH_BEGIN(Attr *attr, decl->attributes) + FOREACH(Attr *, attr, decl->attributes) + { if (attr->attr_kind != ATTRIBUTE_IF) { RETURN_PRINT_ERROR_AT(NULL, attr, "Invalid attribute for '$exec'."); } - FOREACH_END(); + } Expr *filename = decl->exec_decl.filename; bool success = sema_analyse_ct_expr(&context, filename); - FOREACH_BEGIN(Expr *arg, decl->exec_decl.args) - success &= sema_analyse_ct_expr(&context, arg); - FOREACH_END(); + FOREACH(Expr *, arg, decl->exec_decl.args) success &= sema_analyse_ct_expr(&context, arg); sema_context_destroy(&context); if (!success) return NULL; if (!expr_is_const_string(filename)) @@ -217,7 +216,8 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) scratch_buffer_append(file_str); scratch_buffer_append(" "); } - FOREACH_BEGIN_IDX(i, Expr *arg, decl->exec_decl.args) + FOREACH_IDX(i, Expr *, arg, decl->exec_decl.args) + { if (i) scratch_buffer_append(" "); assert(expr_is_const(arg)); switch (arg->const_expr.const_kind) @@ -238,7 +238,8 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) case CONST_TYPEID: if (!arg->const_expr.typeid->name) { - RETURN_PRINT_ERROR_AT(NULL, arg, "The type '%s' has no trivial name.", type_quoted_error_string(arg->const_expr.typeid)); + RETURN_PRINT_ERROR_AT(NULL, arg, "The type '%s' has no trivial name.", + type_quoted_error_string(arg->const_expr.typeid)); } scratch_buffer_append(arg->const_expr.typeid->name); continue; @@ -252,10 +253,11 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) case CONST_INITIALIZER: case CONST_UNTYPED_LIST: case CONST_MEMBER: - RETURN_PRINT_ERROR_AT(NULL, arg, "Bytes, initializers and member references may not be used as arguments."); + RETURN_PRINT_ERROR_AT(NULL, arg, + "Bytes, initializers and member references may not be used as arguments."); } UNREACHABLE - FOREACH_END(); + } File *file; // TODO fix Win32 char *old_path = NULL; @@ -295,11 +297,13 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) INLINE void register_includes(CompilationUnit *unit, Decl **decls) { - FOREACH_BEGIN(Decl *include, decls) - Decl **include_decls = include->decl_kind == DECL_CT_EXEC ? sema_run_exec(unit, include) : sema_load_include(unit, include); - VECEACH(include_decls, i) + FOREACH(Decl *, include, decls) + { + Decl **include_decls = include->decl_kind == DECL_CT_EXEC + ? sema_run_exec(unit, include) + : sema_load_include(unit, include); + FOREACH(Decl *, decl, include_decls) { - Decl *decl = include_decls[i]; if (decl->is_cond) { vec_add(unit->global_cond_decls, decl); @@ -309,7 +313,7 @@ INLINE void register_includes(CompilationUnit *unit, Decl **decls) unit_register_global_decl(unit, decl); } } - FOREACH_END(); + } } void sema_process_includes(CompilationUnit *unit) @@ -327,9 +331,8 @@ void sema_process_includes(CompilationUnit *unit) void sema_analysis_pass_register_global_declarations(Module *module) { DEBUG_LOG("Pass: Register globals for module '%s'.", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; if (unit->if_attr) continue; assert(!unit->ct_includes); unit->module = module; @@ -347,9 +350,8 @@ void sema_analysis_pass_register_global_declarations(Module *module) void sema_analysis_pass_register_conditional_units(Module *module) { DEBUG_LOG("Pass: Register conditional units for %s", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; // All ct_includes should already be registered. assert(!unit->ct_includes); @@ -379,7 +381,8 @@ void sema_analysis_pass_register_conditional_units(Module *module) } CHECK_LINK: if (!unit->attr_links) goto RELEASE_CONTEXT; - FOREACH_BEGIN(Attr* attr, unit->attr_links) + FOREACH(Attr*, attr, unit->attr_links) + { Expr **exprs = attr->exprs; unsigned args = vec_size(exprs); assert(args > 0 && "Should already have been checked."); @@ -394,7 +397,7 @@ CHECK_LINK: if (!expr_is_const_string(string)) { PRINT_ERROR_AT(string, "Expected a constant string here, usage is: " - "'@link([cond1, ]link1, link2, ...)'."); + "'@link([cond1, ]link1, link2, ...)'."); goto FAIL_CONTEXT; } if (add) @@ -402,7 +405,7 @@ CHECK_LINK: vec_add(unit->links, string->const_expr.bytes.ptr); } } - FOREACH_END(); + } RELEASE_CONTEXT: sema_context_destroy(&context); register_global_decls(unit, unit->global_decls); @@ -419,16 +422,14 @@ FAIL_CONTEXT: void sema_analysis_pass_register_conditional_declarations(Module *module) { DEBUG_LOG("Pass: Register conditional declarations for module '%s'.", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; unit->module = module; DEBUG_LOG("Processing %s.", unit->file->name); RETRY:; Decl **decls = unit->global_cond_decls; - VECEACH(decls, i) + FOREACH(Decl *, decl, decls) { - Decl *decl = decls[i]; SemaContext context; sema_context_init(&context, unit); if (sema_decl_if_cond(&context, decl)) @@ -453,15 +454,14 @@ RETRY_INCLUDES: void sema_analysis_pass_ct_assert(Module *module) { DEBUG_LOG("Pass: $assert checks %s", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { SemaContext context; - sema_context_init(&context, module->units[index]); - Decl **asserts = context.unit->ct_asserts; + sema_context_init(&context, unit); bool success = true; - VECEACH(asserts, i) + FOREACH(Decl *, assert, context.unit->ct_asserts) { - if (!sema_analyse_ct_assert_stmt(&context, asserts[i]->ct_assert_decl)) + if (!sema_analyse_ct_assert_stmt(&context, assert->ct_assert_decl)) { success = false; break; @@ -476,15 +476,14 @@ void sema_analysis_pass_ct_assert(Module *module) void sema_analysis_pass_ct_echo(Module *module) { DEBUG_LOG("Pass: $echo checks %s", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { SemaContext context; - sema_context_init(&context, module->units[index]); - Decl **echos = context.unit->ct_echos; + sema_context_init(&context, unit); bool success = true; - VECEACH(echos, i) + FOREACH(Decl *, echo, context.unit->ct_echos) { - if (!sema_analyse_ct_echo_stmt(&context, echos[i]->ct_echo_decl)) + if (!sema_analyse_ct_echo_stmt(&context, echo->ct_echo_decl)) { success = false; break; @@ -534,13 +533,20 @@ INLINE void sema_analyse_inner_func_ptr(SemaContext *c, Decl *decl) if (!sema_resolve_type_decl(c, func)) decl_poison(decl); } +INLINE void sema_analyse_decls(SemaContext *context, Decl **decls) +{ + FOREACH(Decl *, decl, decls) + { + sema_analyse_decl(context, decl); + } +} + void sema_analysis_pass_decls(Module *module) { DEBUG_LOG("Pass: Decl analysis %s", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; SemaContext context; sema_context_init(&context, unit); context.active_scope = (DynamicScope) @@ -550,51 +556,27 @@ void sema_analysis_pass_decls(Module *module) .label_start = 0, .current_local = 0, }; - VECEACH(unit->attributes, i) + sema_analyse_decls(&context, unit->attributes); + sema_analyse_decls(&context, unit->enums); + FOREACH(Decl *, decl, unit->types) { - sema_analyse_decl(&context, unit->attributes[i]); - } - VECEACH(unit->enums, i) - { - sema_analyse_decl(&context, unit->enums[i]); - } - VECEACH(unit->types, i) - { - Decl *decl = unit->types[i]; sema_analyse_decl(&context, decl); sema_analyse_inner_func_ptr(&context, decl); } - VECEACH(unit->macros, i) - { - sema_analyse_decl(&context, unit->macros[i]); - } - VECEACH(unit->methods, i) - { - sema_analyse_decl(&context, unit->methods[i]); - } - VECEACH(unit->macro_methods, i) - { - sema_analyse_decl(&context, unit->macro_methods[i]); - } - VECEACH(unit->vars, i) - { - sema_analyse_decl(&context, unit->vars[i]); - } - VECEACH(unit->functions, i) - { - sema_analyse_decl(&context, unit->functions[i]); - } + sema_analyse_decls(&context, unit->macros); + sema_analyse_decls(&context, unit->methods); + sema_analyse_decls(&context, unit->macro_methods); + sema_analyse_decls(&context, unit->vars); + sema_analyse_decls(&context, unit->functions); if (unit->main_function && unit->main_function->is_synthetic) { sema_analyse_decl(&context, unit->main_function); } - VECEACH(unit->generic_defines, i) + sema_analyse_decls(&context, unit->generic_defines); + FOREACH(TypeInfo *, info, unit->check_type_variable_array) { - sema_analyse_decl(&context, unit->generic_defines[i]); - } - FOREACH_BEGIN(TypeInfo *info, unit->check_type_variable_array) sema_check_type_variable_array(&context, info); - FOREACH_END(); + } sema_context_destroy(&context); } DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); @@ -604,21 +586,18 @@ void sema_analysis_pass_lambda(Module *module) { DEBUG_LOG("Extra pass: Lambda analysis %s", module->name->module); - VECEACH(module->units, index) + while (vec_size(module->lambdas_to_evaluate)) { - while (vec_size(module->lambdas_to_evaluate)) + Decl *lambda = VECLAST(module->lambdas_to_evaluate); + CompilationUnit *unit = lambda->unit; + SemaContext context; + sema_context_init(&context, unit); + vec_pop(module->lambdas_to_evaluate); + if (analyse_func_body(&context, lambda)) { - Decl *lambda = VECLAST(module->lambdas_to_evaluate); - CompilationUnit *unit = lambda->unit; - SemaContext context; - sema_context_init(&context, unit); - vec_pop(module->lambdas_to_evaluate); - if (analyse_func_body(&context, lambda)) - { - vec_add(unit->lambdas, lambda); - } - sema_context_destroy(&context); + vec_add(unit->lambdas, lambda); } + sema_context_destroy(&context); } DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); @@ -627,12 +606,12 @@ void sema_analysis_pass_lambda(Module *module) static inline bool sema_check_interfaces(SemaContext *context, Decl *decl) { Decl **store = sema_decl_stack_store(); - FOREACH_BEGIN(Decl *method, decl->methods) - sema_decl_stack_push(method); - FOREACH_END(); - FOREACH_BEGIN(TypeInfo *interface_type, decl->interfaces) + FOREACH(Decl *, method, decl->methods) sema_decl_stack_push(method); + FOREACH(TypeInfo *, interface_type, decl->interfaces) + { Decl *interface = interface_type->type->decl; - FOREACH_BEGIN(Decl *method, interface->interface_methods) + FOREACH(Decl *, method, interface->interface_methods) + { Decl *matching_method = sema_decl_stack_resolve_symbol(method->name); if (!matching_method) { @@ -658,8 +637,8 @@ static inline bool sema_check_interfaces(SemaContext *context, Decl *decl) sema_decl_stack_restore(store); return false; } - FOREACH_END(); - FOREACH_END(); + } + } sema_decl_stack_restore(store); return true; } @@ -668,12 +647,12 @@ void sema_analysis_pass_interface(Module *module) { DEBUG_LOG("Pass: Interface analysis %s", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; SemaContext context; sema_context_init(&context, unit); - FOREACH_BEGIN(Decl *decl, unit->types) + FOREACH(Decl *, decl, unit->types) + { switch (decl->decl_kind) { case DECL_DISTINCT: @@ -701,18 +680,17 @@ void sema_analysis_pass_functions(Module *module) { DEBUG_LOG("Pass: Function analysis %s", module->name->module); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; SemaContext context; sema_context_init(&context, unit); - VECEACH(unit->methods, i) + FOREACH(Decl *, method, unit->methods) { - analyse_func_body(&context, unit->methods[i]); + analyse_func_body(&context, method); } - VECEACH(unit->functions, i) + FOREACH(Decl *, func, unit->functions) { - analyse_func_body(&context, unit->functions[i]); + analyse_func_body(&context, func); } if (unit->main_function && unit->main_function->is_synthetic) analyse_func_body(&context, unit->main_function); sema_context_destroy(&context); diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index f55b4fb83..498d3127a 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -83,11 +83,12 @@ static inline bool sema_analyse_assert_stmt(SemaContext *context, Ast *statement { if (!sema_analyse_ct_expr(context, message_expr)) return false; if (!expr_is_const_string(message_expr)) RETURN_SEMA_ERROR(message_expr, "Expected a constant string as the error message."); - FOREACH_BEGIN(Expr *e, statement->assert_stmt.args) + FOREACH(Expr *, e, statement->assert_stmt.args) + { if (!sema_analyse_expr(context, e)) return false; if (IS_OPTIONAL(e)) RETURN_SEMA_ERROR(e, "Optionals cannot be used as assert arguments, use '?" "?', '!' or '!!' to fix this."); if (type_is_void(e->type)) RETURN_SEMA_ERROR(e, "This expression is of type 'void', did you make a mistake?"); - FOREACH_END(); + } } CondResult result_no_resolve = COND_MISSING; @@ -259,11 +260,8 @@ static void sema_unwrappable_from_catch_in_else(SemaContext *c, Expr *cond) } if (!last || last->expr_kind != EXPR_CATCH_UNWRAP) return; - Expr **unwrapped = last->catch_unwrap_expr.exprs; - - VECEACH(unwrapped, i) + FOREACH(Expr *, expr, last->catch_unwrap_expr.exprs) { - Expr *expr = unwrapped[i]; if (expr->expr_kind != EXPR_IDENTIFIER) continue; Decl *decl = expr->identifier_expr.decl; if (decl->decl_kind != DECL_VAR) continue; @@ -293,11 +291,8 @@ static inline bool assert_create_from_contract(SemaContext *context, Ast *direct Expr *declexpr = directive->contract_stmt.contract.decl_exprs; assert(declexpr->expr_kind == EXPR_EXPRESSION_LIST); - Expr **exprs = declexpr->expression_list; - - VECEACH(exprs, j) + FOREACH(Expr *, expr, declexpr->expression_list) { - Expr *expr = exprs[j]; if (expr->expr_kind == EXPR_DECL) { SEMA_ERROR(expr, "Only expressions are allowed."); @@ -358,16 +353,16 @@ static inline bool sema_return_optional_check_is_valid_in_scope(SemaContext *con if (!expr_is_const(inner)) return true; assert(ret_expr->inner_expr->const_expr.const_kind == CONST_ERR); Decl *fault = ret_expr->inner_expr->const_expr.enum_err_val; - FOREACH_BEGIN(Decl *opt, context->call_env.opt_returns) + FOREACH(Decl *, opt, context->call_env.opt_returns) + { if (opt->decl_kind == DECL_FAULT) { if (fault->type->decl == opt) return true; continue; } if (opt == fault) return true; - FOREACH_END(); - SEMA_ERROR(ret_expr, "This value does not match declared optional returns, it needs to be declared with the other optional returns."); - return false; + } + RETURN_SEMA_ERROR(ret_expr, "This value does not match declared optional returns, it needs to be declared with the other optional returns."); } static bool sema_analyse_macro_constant_ensures(SemaContext *context, Expr *ret_expr) @@ -396,7 +391,8 @@ static bool sema_analyse_macro_constant_ensures(SemaContext *context, Expr *ret_ Expr *checks = copy_expr_single(directive->contract_stmt.contract.decl_exprs); assert(checks->expr_kind == EXPR_EXPRESSION_LIST); Expr **exprs = checks->expression_list; - FOREACH_BEGIN(Expr *expr, exprs) + FOREACH(Expr *, expr, exprs) + { if (expr->expr_kind == EXPR_DECL) { SEMA_ERROR(expr, "Only expressions are allowed."); @@ -417,7 +413,7 @@ static bool sema_analyse_macro_constant_ensures(SemaContext *context, Expr *ret_ SEMA_ERROR(ret_expr, "%s", comment); success = false; goto END; - FOREACH_END(); + } } END: SCOPE_END; @@ -858,11 +854,9 @@ static inline bool sema_analyse_try_unwrap_chain(SemaContext *context, Expr *exp assert(cond_type == COND_TYPE_UNWRAP_BOOL || cond_type == COND_TYPE_UNWRAP); assert(expr->expr_kind == EXPR_TRY_UNWRAP_CHAIN); - Expr **chain = expr->try_unwrap_chain_expr; - VECEACH(expr->try_unwrap_chain_expr, i) + FOREACH(Expr *, chain_element, expr->try_unwrap_chain_expr) { - Expr *chain_element = chain[i]; if (chain_element->expr_kind == EXPR_TRY_UNWRAP) { if (!sema_analyse_try_unwrap(context, chain_element)) return false; @@ -952,10 +946,8 @@ static inline bool sema_analyse_catch_unwrap(SemaContext *context, Expr *expr) expr->catch_unwrap_expr.lhs = NULL; } RESOLVE_EXPRS:; - Expr **exprs = expr->catch_unwrap_expr.exprs; - VECEACH(exprs, i) + FOREACH(Expr *, fail, expr->catch_unwrap_expr.exprs) { - Expr *fail = exprs[i]; if (!sema_analyse_expr(context, fail)) return false; if (!type_is_optional(fail->type)) { @@ -972,10 +964,8 @@ static void sema_remove_unwraps_from_try(SemaContext *c, Expr *cond) assert(cond->expr_kind == EXPR_COND); Expr *last = VECLAST(cond->cond_expr); if (!last || last->expr_kind != EXPR_TRY_UNWRAP_CHAIN) return; - Expr **chain = last->try_unwrap_chain_expr; - VECEACH(chain, i) + FOREACH(Expr *, expr, last->try_unwrap_chain_expr) { - Expr *expr = chain[i]; if (expr->expr_kind != EXPR_TRY_UNWRAP) continue; if (expr->try_unwrap_expr.assign_existing) continue; if (expr->try_unwrap_expr.optional) @@ -1195,7 +1185,8 @@ static inline bool sema_analyse_cond(SemaContext *context, Expr *expr, CondType static inline bool sema_analyse_decls_stmt(SemaContext *context, Ast *statement) { bool should_nop = true; - FOREACH_BEGIN_IDX(i, Decl *decl, statement->decls_stmt) + FOREACH_IDX(i, Decl *, decl, statement->decls_stmt) + { VarDeclKind kind = decl->var.kind; if (kind == VARDECL_LOCAL_CT_TYPE || kind == VARDECL_LOCAL_CT) { @@ -1207,7 +1198,7 @@ static inline bool sema_analyse_decls_stmt(SemaContext *context, Ast *statement) if (!sema_analyse_var_decl(context, decl, true)) return false; should_nop = false; } - FOREACH_END(); + } if (should_nop) statement->ast_kind = AST_NOP_STMT; return true; } @@ -2069,13 +2060,14 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement) if (statement->nextcase_stmt.is_default) { Ast *default_ast = NULL; - FOREACH_BEGIN(Ast *cs, cases) + FOREACH(Ast *, cs, cases) + { if (cs->ast_kind == AST_DEFAULT_STMT) { default_ast = cs; break; } - FOREACH_END(); + } if (!default_ast) RETURN_SEMA_ERROR(statement, "There is no 'default' in the switch to jump to."); statement->nextcase_stmt.defer_id = context_get_defers(context, context->active_scope.defer_last, parent->switch_stmt.defer, true); statement->nextcase_stmt.case_switch_stmt = astid(default_ast); @@ -2111,12 +2103,9 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement) SEMA_NOTE(statement, "The 'switch' here uses expected a type '%s'.", type_to_error_string(cond->type)); return false; } - cases = parent->switch_stmt.cases; - Type *type = type_info->type->canonical; - VECEACH(cases, i) + FOREACH(Ast *, case_stmt, parent->switch_stmt.cases) { - Ast *case_stmt = cases[i]; if (case_stmt->ast_kind == AST_DEFAULT_STMT) continue; Expr *expr = exprptr(case_stmt->case_stmt.expr); if (expr_is_const(expr) && expr->const_expr.typeid == type) @@ -2137,9 +2126,8 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement) if (expr_is_const(value)) { - VECEACH(parent->switch_stmt.cases, i) + FOREACH(Ast *, case_stmt, parent->switch_stmt.cases) { - Ast *case_stmt = parent->switch_stmt.cases[i]; Expr *from = exprptr(case_stmt->case_stmt.expr); if (case_stmt->ast_kind == AST_DEFAULT_STMT) continue; if (!expr_is_const(from)) goto VARIABLE_JUMP; @@ -2347,7 +2335,8 @@ INLINE const char *create_missing_enums_in_switch_error(Ast **cases, unsigned ca scratch_buffer_printf("%u enum values were not handled in the switch: ", missing); } unsigned printed = 0; - FOREACH_BEGIN(Decl *decl, enums) + FOREACH(Decl *, decl, enums) + { for (unsigned i = 0; i < case_count; i++) { Expr *e = exprptr(cases[i]->case_stmt.expr); @@ -2366,7 +2355,7 @@ INLINE const char *create_missing_enums_in_switch_error(Ast **cases, unsigned ca } if (printed == missing) goto DONE; CONTINUE:; - FOREACH_END(); + } DONE:; if (missing == 1) { @@ -2916,7 +2905,8 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement assert(init_expr->expr_kind == EXPR_EXPRESSION_LIST); // Check the list of expressions. - FOREACH_BEGIN(Expr *expr, init_expr->expression_list) + FOREACH(Expr *, expr, init_expr->expression_list) + { // Only a subset of declarations are allowed. We check this here. if (expr->expr_kind == EXPR_DECL) { @@ -2931,7 +2921,7 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement } // If expression evaluate it and make sure it is constant. if (!sema_analyse_ct_expr(context, expr)) goto FAILED; - FOREACH_END(); + } } ExprId condition = statement->for_stmt.cond; ExprId incr = statement->for_stmt.incr; @@ -2970,9 +2960,10 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement current = &compound_stmt->next; // Copy and evaluate all the expressions in "incr" - FOREACH_BEGIN(Expr *expr, incr_list) // NOLINT + FOREACH(Expr *, expr, incr_list) + { if (!sema_analyse_ct_expr(context, copy_expr_single(expr))) goto FAILED; - FOREACH_END(); + } } // Analysis is done turn the generated statements into a compound statement for lowering. statement->ast_kind = AST_COMPOUND_STMT; @@ -3086,9 +3077,8 @@ static bool sema_analyse_ensure(SemaContext *context, Ast *directive) Expr *declexpr = directive->contract_stmt.contract.decl_exprs; assert(declexpr->expr_kind == EXPR_EXPRESSION_LIST); - VECEACH(declexpr->expression_list, j) + FOREACH(Expr *, expr, declexpr->expression_list) { - Expr *expr = declexpr->expression_list[j]; if (expr->expr_kind == EXPR_DECL) { SEMA_ERROR(expr, "Only expressions are allowed."); @@ -3102,7 +3092,8 @@ static bool sema_analyse_optional_returns(SemaContext *context, Ast *directive) { Ast **returns = NULL; context->call_env.opt_returns = NULL; - FOREACH_BEGIN(Ast *ret, directive->contract_stmt.faults) + FOREACH(Ast *, ret, directive->contract_stmt.faults) + { if (ret->contract_fault.resolved) continue; TypeInfo *type_info = ret->contract_fault.type; const char *ident = ret->contract_fault.ident; @@ -3118,9 +3109,8 @@ static bool sema_analyse_optional_returns(SemaContext *context, Ast *directive) } Decl *decl = type->decl; Decl **enums = decl->enums.values; - VECEACH(enums, j) + FOREACH(Decl *, opt_value, enums) { - Decl *opt_value = enums[j]; if (opt_value->name == ident) { ret->contract_fault.decl = opt_value; @@ -3129,9 +3119,9 @@ static bool sema_analyse_optional_returns(SemaContext *context, Ast *directive) } } RETURN_SEMA_ERROR(ret, "No fault value '%s' found.", ident); -NEXT:; + NEXT:; vec_add(context->call_env.opt_returns, ret->contract_fault.decl); - FOREACH_END(); + } return true; } @@ -3209,18 +3199,18 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func) Decl **lambda_params = NULL; SCOPE_START assert(context->active_scope.depth == 1); - Decl **params = signature->params; - VECEACH(params, i) + FOREACH(Decl *, param, signature->params) { - if (!sema_add_local(context, params[i])) return false; + if (!sema_add_local(context, param)) return false; } if (func->func_decl.is_lambda) { lambda_params = copy_decl_list_single(func->func_decl.lambda_ct_parameters); - FOREACH_BEGIN(Decl *ct_param, lambda_params) + FOREACH(Decl *, ct_param, lambda_params) + { ct_param->var.is_read = false; if (!sema_add_local(context, ct_param)) return false; - FOREACH_END(); + } } AstId assert_first = 0; AstId *next = &assert_first; @@ -3240,9 +3230,10 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func) SCOPE_END; if (lambda_params) { - FOREACH_BEGIN_IDX(i, Decl *ct_param, lambda_params) + FOREACH_IDX(i, Decl *, ct_param, lambda_params) + { func->func_decl.lambda_ct_parameters[i]->var.is_read = ct_param->var.is_read; - FOREACH_END(); + } } return true; } diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index f47a94e83..47ec5c265 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -545,9 +545,8 @@ static uint32_t hash_function(Signature *sig) uintptr_t hash = sig->variadic == VARIADIC_RAW ? 0 : 1; hash = hash * 31 + (uintptr_t)flatten_raw_function_type(type_infoptr(sig->rtype)->type); Decl **params = sig->params; - VECEACH(params, i) + FOREACH(Decl *, param, params) { - Decl *param = params[i]; hash = hash * 31 + (uintptr_t)flatten_raw_function_type(param->type->canonical); } return (uint32_t)((hash >> 16) ^ hash); @@ -597,9 +596,9 @@ static inline Type *func_create_new_func_proto(Signature *sig, CallABI abi, uint scratch_buffer_append("fn "); type_append_name_to_scratch(proto->rtype); scratch_buffer_append_char('('); - foreach(Type*, proto->param_types) + FOREACH_IDX(index, Type *, val, proto->param_types) { - if (foreach_index != 0) scratch_buffer_append(", "); + if (index != 0) scratch_buffer_append(", "); type_append_name_to_scratch(val); } scratch_buffer_append_char(')'); @@ -684,9 +683,8 @@ static int compare_function(Signature *sig, FunctionPrototype *proto) unsigned param_count = vec_size(params); if (param_count != vec_size(other_params)) return -1; if (!compare_func_param(type_infoptr(sig->rtype)->type, proto->rtype)) return -1; - VECEACH(params, i) + FOREACH_IDX(i, Decl *, param, params) { - Decl *param = params[i]; Type *other_param = other_params[i]; if (!compare_func_param(param->type, other_param->canonical)) return -1; } diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 73a623592..15a56f9db 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -20,7 +20,6 @@ void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags) Ast *previous_defer = context->active_scope.in_defer; AstId parent_defer = context->active_scope.defer_last; unsigned last_local = context->active_scope.current_local; - assert(parent_defer < 1000000); // Defer and expression blocks introduce their own return/break/continue // otherwise just merge with the old flags. if (flags & (SCOPE_EXPR_BLOCK | SCOPE_MACRO)) @@ -189,9 +188,8 @@ void sema_analyze_stage(Module *module, AnalysisStage stage) static void register_generic_decls(CompilationUnit *unit, Decl **decls) { - VECEACH(decls, i) + FOREACH(Decl *, decl, decls) { - Decl *decl = decls[i]; if (decl->visibility == VISIBLE_LOCAL) continue; decl->unit = unit; switch (decl->decl_kind) @@ -233,13 +231,11 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls) } } - static void analyze_generic_module(Module *module) { assert(module->parameters && module->is_generic); - VECEACH(module->units, index) + FOREACH(CompilationUnit *, unit, module->units) { - CompilationUnit *unit = module->units[index]; register_generic_decls(unit, unit->global_decls); register_generic_decls(unit, unit->global_cond_decls); } @@ -249,14 +245,15 @@ static void sema_analyze_to_stage(AnalysisStage stage) { if (stage <= ANALYSIS_MODULE_TOP) { - VECEACH(global_context.generic_module_list, i) + + FOREACH(Module *, module, global_context.generic_module_list) { - sema_analyze_stage(global_context.generic_module_list[i], stage); + sema_analyze_stage(module, stage); } } - VECEACH(global_context.module_list, i) + FOREACH(Module *, module, global_context.module_list) { - sema_analyze_stage(global_context.module_list[i], stage); + sema_analyze_stage(module, stage); } halt_on_error(); } @@ -425,9 +422,10 @@ void sema_analysis_run(void) global_context.core_module = compiler_find_or_create_module(core_path, NULL); // We parse the generic modules, just by storing the decls. - FOREACH_BEGIN(Module *module, global_context.generic_module_list) + FOREACH(Module *, module, global_context.generic_module_list) + { analyze_generic_module(module); - FOREACH_END(); + } for (AnalysisStage stage = ANALYSIS_NOT_BEGUN + 1; stage <= ANALYSIS_LAST; stage++) { @@ -436,13 +434,14 @@ void sema_analysis_run(void) RESOLVE_LAMBDA:; bool found_lambda = false; - FOREACH_BEGIN(Module *module, global_context.module_list) + FOREACH(Module *, module, global_context.module_list) + { if (vec_size(module->lambdas_to_evaluate)) { sema_analysis_pass_lambda(module); found_lambda = true; } - FOREACH_END(); + } if (found_lambda) goto RESOLVE_LAMBDA; halt_on_error(); diff --git a/src/compiler/source_file.c b/src/compiler/source_file.c index 917023f04..078bdf0f4 100644 --- a/src/compiler/source_file.c +++ b/src/compiler/source_file.c @@ -49,12 +49,12 @@ File *source_file_load(const char *filename, bool *already_loaded, const char ** return NULL; } - VECEACH(global_context.loaded_sources, index) + FOREACH(File *, file, global_context.loaded_sources) { - if (strcmp(global_context.loaded_sources[index]->full_path, full_path) == 0) + if (strcmp(file->full_path, full_path) == 0) { if (already_loaded) *already_loaded = true; - return global_context.loaded_sources[index]; + return file; } } if (vec_size(global_context.loaded_sources) == MAX_FILES) diff --git a/src/compiler/tilde_codegen.c b/src/compiler/tilde_codegen.c index 25d1d5be5..98977b64e 100644 --- a/src/compiler/tilde_codegen.c +++ b/src/compiler/tilde_codegen.c @@ -397,31 +397,35 @@ static TildeContext *tilde_gen_module(Module *module, TB_FeatureSet *feature_set codegen_setup_object_names(module, &context->ir_filename, &context->asm_filename, &context->object_filename); context->module = tb_module; - FOREACH_BEGIN(CompilationUnit *unit, module->units) - + FOREACH(CompilationUnit *, unit, module->units) + { REMINDER("Add debug info"); /* gencontext_init_file_emit(gen_context, unit); context->debug.compile_unit = unit->llvm.debug_compile_unit; gen_context->debug.file = unit->llvm.debug_file;*/ - FOREACH_BEGIN(Decl *initializer, unit->xxlizers) + FOREACH(Decl *, initializer, unit->xxlizers) + { REMINDER("Add xxlizer"); //tilde_emit_xxlizer(gen_context, initializer); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *method, unit->methods) + FOREACH(Decl *, method, unit->methods) + { tilde_emit_function_decl(context, method); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *type_decl, unit->types) + FOREACH(Decl *, type_decl, unit->types) + { tilde_emit_type_decls(context, type_decl); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *enum_decl, unit->enums) + FOREACH(Decl *, enum_decl, unit->enums) + { tilde_emit_type_decls(context, enum_decl); - FOREACH_END(); + } - FOREACH_BEGIN(Decl *func, unit->functions) + FOREACH(Decl *, func, unit->functions) if (func->func_decl.attr_test) { if (!active_target.testing) continue; @@ -442,21 +446,21 @@ static TildeContext *tilde_gen_module(Module *module, TB_FeatureSet *feature_set FOREACH_END(); - FOREACH_BEGIN(CompilationUnit *unit, module->units) + FOREACH(CompilationUnit *, unit, module->units) /*--- TODO context->debug.compile_unit = unit->llvm.debug_compile_unit; context->debug.file = unit->llvm.debug_file; */ - FOREACH_BEGIN(Decl *var, unit->vars) + FOREACH(Decl *, var, unit->vars) tilde_get_ref(context, var); FOREACH_END(); - FOREACH_BEGIN(Decl *var, unit->vars) + FOREACH(Decl *, var, unit->vars) // TODO tilde_emit_global_variable_init(context, var); FOREACH_END(); - FOREACH_BEGIN(Decl *decl, unit->functions) + FOREACH(Decl *, decl, unit->functions) if (decl->func_decl.attr_test && !active_target.testing) continue; if (decl->func_decl.body) tilde_emit_function_body(context, decl); FOREACH_END(); @@ -466,7 +470,7 @@ static TildeContext *tilde_gen_module(Module *module, TB_FeatureSet *feature_set tilde_emit_function_body(context, unit->main_function); } - FOREACH_BEGIN(Decl *decl, unit->methods) + FOREACH(Decl *, decl, unit->methods) if (decl->func_decl.body) tilde_emit_function_body(context, decl); FOREACH_END(); @@ -619,7 +623,7 @@ const char *tilde_codegen(void *context) TB_DebugFormat debug_format = is_win32 ? TB_DEBUGFMT_CODEVIEW : TB_DEBUGFMT_DWARF; if (active_target.debug_info == DEBUG_INFO_NONE) debug_format = TB_DEBUGFMT_NONE; - FOREACH_BEGIN(TB_Function *function, c->functions) + FOREACH(TB_Function *, function, c->functions) if (!tb_module_compile_function(c->module, function, TB_ISEL_FAST)) { error_exit("Failed to compile function."); diff --git a/src/compiler/types.c b/src/compiler/types.c index e5e67bdf3..a4bdbf83a 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -496,12 +496,12 @@ Type *type_find_largest_union_element(Type *type) assert(type->type_kind == TYPE_UNION); ByteSize largest = 0; Type *largest_type = NULL; - Decl **members = type->decl->strukt.members; - VECEACH(members, i) + FOREACH(Decl *, member, type->decl->strukt.members) { - if (type_size(type) > largest) + Type *member_type = member->type; + if (type_size(member_type) > largest) { - largest = type_size(type); + largest = type_size(member_type); largest_type = type->canonical; } } @@ -684,14 +684,15 @@ bool type_func_match(Type *fn_type, Type *rtype, unsigned arg_count, ...) if (vec_size(sig->params) != arg_count) return false; va_list ap; va_start(ap, arg_count); - FOREACH_BEGIN(Decl* decl, sig->params) + FOREACH(Decl *, decl, sig->params) + { Type *arg = va_arg(ap, Type*); if (decl->type->canonical != arg->canonical) { va_end(ap); return false; } - FOREACH_END(); + } va_end(ap); return true; } @@ -1014,10 +1015,10 @@ static inline bool array_structurally_equivalent_to_struct(Type *array, Type *ty MemberIndex offset = 0; AlignSize align_size = type_abi_alignment(array); Type *array_base = array->array.base; - VECEACH(members, i) + FOREACH(Decl *, member, members) { - if (!type_is_structurally_equivalent(array_base, members[i]->type)) return false; - if (members[i]->offset != offset) return false; + if (!type_is_structurally_equivalent(array_base, member->type)) return false; + if (member->offset != offset) return false; offset += align_size; } return true; @@ -1034,12 +1035,11 @@ bool type_is_structurally_equivalent(Type *type1, Type *type2) // noting that there is only structural equivalence if it fills out the if (type2->type_kind == TYPE_UNION) { - Decl **members = type2->decl->strukt.members; // If any member is structurally equivalent, then // the cast is valid. - VECEACH(members, i) + FOREACH(Decl *, member, type2->decl->strukt.members) { - if (type_is_structurally_equivalent(type1, members[i]->type)) return true; + if (type_is_structurally_equivalent(type1, member->type)) return true; } // In this case we can't get a match. return false; @@ -1062,9 +1062,9 @@ bool type_is_structurally_equivalent(Type *type1, Type *type2) { // If any member is structurally equivalent, then // the cast is valid. - VECEACH(members, i) + FOREACH(Decl *, member, members) { - if (type_is_structurally_equivalent(members[i]->type, type2)) return true; + if (type_is_structurally_equivalent(member->type, type2)) return true; } return false; } @@ -1075,11 +1075,12 @@ bool type_is_structurally_equivalent(Type *type1, Type *type2) Decl **other_members = type2->decl->strukt.members; // For structs / errors, all members must match. - VECEACH(members, i) + FOREACH_IDX(i, Decl *, member, members) { - if (!type_is_structurally_equivalent(members[i]->type, other_members[i]->type)) return false; - if (members[i]->offset != other_members[i]->offset) return false; + if (!type_is_structurally_equivalent(member->type, other_members[i]->type)) return false; + if (member->offset != other_members[i]->offset) return false; } + return true; } diff --git a/src/utils/lib.h b/src/utils/lib.h index c100d8fbb..7652f7490 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -317,18 +317,16 @@ static inline void* expand_(void *vec, size_t element_size) #define CONCAT_INNER(a, b) a ## b #define CONCAT(a, b) CONCAT_INNER(a, b) -#define VECEACH(_vec, _index) \ - for (unsigned (_index) = 0, CONCAT(__vecsize_, __LINE__) = vec_size(_vec); (_index) < CONCAT(__vecsize_, __LINE__); (_index)++) -#define foreach(type__, vec__) \ - type__* foreach_vec__ = vec__; unsigned foreach_len__ = vec_size(foreach_vec__); \ - type__ val; if (foreach_vec__) val = foreach_vec__[0]; \ - for (unsigned foreach_index = 0; foreach_index < foreach_len__; val = foreach_vec__[++foreach_index]) -#define FOREACH_BEGIN_IDX(idx__, decl__, vec__) \ -;void* CONCAT(foreach_vec_, __LINE__) = (vec__); unsigned CONCAT(foreach_len_, __LINE__) = vec_size(CONCAT(foreach_vec_, __LINE__)); \ - for (unsigned idx__ = 0; idx__ < CONCAT(foreach_len_, __LINE__); idx__++) { decl__ = ((void**)CONCAT(foreach_vec_, __LINE__))[idx__]; -#define FOREACH_END() } do {} while (0) -#define FOREACH_BEGIN(decl__, vec__) FOREACH_BEGIN_IDX(CONCAT(idx__, __LINE__), decl__, vec__) +#define FOREACH(type__, name__, vec__) \ +type__* CONCAT(foreach_vec_, __LINE__) = (vec__); type__* CONCAT(foreach_vecend_, __LINE__) = CONCAT(foreach_vec_, __LINE__) + vec_size(CONCAT(foreach_vec_, __LINE__)); \ +type__* CONCAT(foreach_it_, __LINE__) = CONCAT(foreach_vec_, __LINE__); \ +for (type__ name__ ; CONCAT(foreach_it_, __LINE__) < CONCAT(foreach_vecend_, __LINE__) ? (name__ = *CONCAT(foreach_it_, __LINE__), true) : false; CONCAT(foreach_it_, __LINE__)++) + +#define FOREACH_IDX(idx__, type__, name__, vec__) \ +type__* CONCAT(foreach_vec_, __LINE__) = (vec__); uint32_t CONCAT(foreach_vecsize_, __LINE__) = vec_size(CONCAT(foreach_vec_, __LINE__)); \ +uint32_t idx__ = 0; \ +for (type__ name__ ; idx__ < CONCAT(foreach_vecsize_, __LINE__) ? (name__ = CONCAT(foreach_vec_, __LINE__)[idx__], true) : false; idx__++) #define VECNEW(_type, _capacity) ((_type *)(vec_new_(sizeof(_type), _capacity) + 1)) #define vec_add(vec_, value_) do { \ diff --git a/src/utils/taskqueue.c b/src/utils/taskqueue.c index fe8148b62..512277619 100644 --- a/src/utils/taskqueue.c +++ b/src/utils/taskqueue.c @@ -105,9 +105,10 @@ void taskqueue_run(int threads, Task **task_list) void taskqueue_run(int threads, Task **task_list) { - FOREACH_BEGIN(Task *task, task_list) - task->task(task->arg); - FOREACH_END(); + FOREACH(Task *, task, task_list) + { + task->task(task->arg); + } } #endif \ No newline at end of file