From cc71b96c38fd08121fce12d16bd17a5f8b29aea9 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 22 Sep 2022 00:05:22 +0200 Subject: [PATCH] Rearranging code somewhat. --- CMakeLists.txt | 4 +- src/compiler/sema_decls.c | 77 ++++++++++++++++++++++++++------ src/compiler/sema_errors.c | 11 +++++ src/compiler/sema_types.c | 15 +++++++ src/compiler/semantic_analyser.c | 22 --------- src/utils/lib.h | 1 + 6 files changed, 93 insertions(+), 37 deletions(-) create mode 100644 src/compiler/sema_errors.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c943a2972..a3bd2f863 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,7 +254,9 @@ add_executable(c3c src/compiler/tilde_codegen_type.c src/compiler/windows_support.c src/compiler/codegen_asm.c - src/compiler/asm_target.c src/compiler/llvm_codegen_builtins.c) + src/compiler/asm_target.c + src/compiler/llvm_codegen_builtins.c + src/compiler/sema_errors.c) target_include_directories(c3c PRIVATE diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 9c674ae60..06e2b064d 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -5,10 +5,59 @@ #include "sema_internal.h" +static inline bool sema_analyse_func_macro(SemaContext *context, Decl *decl, bool is_func); +static inline bool sema_analyse_func(SemaContext *context, Decl *decl); +static inline bool sema_analyse_macro(SemaContext *context, Decl *decl); +static inline bool sema_analyse_signature(SemaContext *context, Signature *sig); +static inline Type *sema_analyse_function_signature(SemaContext *context, Decl *parent, CallABI abi, Signature *signature, bool is_real_function); +static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl); +static inline bool sema_check_param_uniqueness_and_type(Decl **decls, Decl *current, unsigned current_index, unsigned count); + +static inline bool sema_analyse_method(SemaContext *context, Decl *decl); static inline bool sema_is_valid_method_param(SemaContext *context, Decl *param, Type *parent_type); +static inline bool sema_analyse_macro_method(SemaContext *context, Decl *decl); +static inline bool unit_add_base_extension_method(CompilationUnit *unit, Type *parent_type, Decl *method_like); +static inline bool unit_add_method_like(CompilationUnit *unit, Type *parent_type, Decl *method_like); + +static bool sema_analyse_operator_common(Decl *method, TypeInfo **rtype_ptr, Decl ***params_ptr, uint32_t parameters); +static inline Decl *operator_in_module(SemaContext *c, Module *module, OperatorOverload operator_overload); +static inline bool sema_analyse_operator_element_at(Decl *method); +static inline bool sema_analyse_operator_element_set(Decl *method); +static inline bool sema_analyse_operator_len(Decl *method); +static bool sema_check_operator_method_validity(Decl *method); +static inline const char *method_name_by_decl(Decl *method_like); + static bool sema_analyse_struct_union(SemaContext *context, Decl *decl); +static bool sema_analyse_bitstruct(SemaContext *context, Decl *decl); +static bool sema_analyse_union_members(SemaContext *context, Decl *decl, Decl **members); +static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl **members); +static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent, Decl *decl); +static inline bool sema_analyse_bitstruct_member(SemaContext *context, Decl *decl, unsigned index, bool allow_overlap); + +static inline bool sema_analyse_doc_header(AstId doc, Decl **params, Decl **extra_params, bool *pure_ref); + +static const char *attribute_domain_to_string(AttributeDomain domain); +static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, AttributeDomain domain); +static bool sema_analyse_attributes_inner(SemaContext *context, Decl *decl, Attr** attrs, AttributeDomain domain, Decl *top, int counter); static bool sema_analyse_attributes(SemaContext *context, Decl *decl, Attr** attrs, AttributeDomain domain); static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl); +static bool sema_check_section(SemaContext *context, Attr *attr); +static inline bool sema_analyse_attribute_decl(SemaContext *c, Decl *decl); + +static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl); +bool sema_analyse_decl_type(SemaContext *context, Type *type, SourceSpan span); +static inline bool sema_analyse_define(SemaContext *c, Decl *decl); +static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl); + +static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit); +static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl); +static Module *module_instantiate_generic(Module *module, Path *path, TypeInfo **parms); + +static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param, bool *has_default); +static inline bool sema_analyse_enum(SemaContext *context, Decl *decl); +static inline bool sema_analyse_error(SemaContext *context, Decl *decl); + + static bool sema_check_section(SemaContext *context, Attr *attr) { const char *section_string = attr->exprs[0]->const_expr.string.chars; @@ -23,6 +72,8 @@ static bool sema_check_section(SemaContext *context, Attr *attr) StringSlice section = slice_next_token(&slice, ','); StringSlice attrs = slice_next_token(&slice, ','); StringSlice stub_size_str = slice_next_token(&slice, ','); + (void)attrs; + (void)stub_size_str; if (slice.len) { @@ -79,8 +130,6 @@ static inline bool sema_check_param_uniqueness_and_type(Decl **decls, Decl *curr return true; } - - static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent, Decl *decl) { assert(!decl->unit || decl->unit->module->is_generic); @@ -205,6 +254,7 @@ static bool sema_analyse_union_members(SemaContext *context, Decl *decl, Decl ** if (!max_size) { + REMINDER("Check if this should really be allowed."); decl->strukt.size = 0; decl->alignment = 1; return true; @@ -1079,7 +1129,7 @@ static inline bool sema_analyse_error(SemaContext *context, Decl *decl) return success; } -static inline const char *name_by_decl(Decl *method_like) +static inline const char *method_name_by_decl(Decl *method_like) { switch (method_like->decl_kind) { @@ -1149,6 +1199,7 @@ static inline Decl *operator_in_module(SemaContext *c, Module *module, OperatorO } return NULL; } + Decl *sema_find_operator(SemaContext *context, Expr *expr, OperatorOverload operator_overload) { Decl *ambiguous = NULL; @@ -1264,7 +1315,7 @@ static inline bool unit_add_method_like(CompilationUnit *unit, Type *parent_type Decl *method = sema_find_extension_method_in_module(unit->module, parent_type, name); if (method) { - SEMA_ERROR(method_like, "This %s is already defined in this module.", name_by_decl(method_like)); + SEMA_ERROR(method_like, "This %s is already defined in this module.", method_name_by_decl(method_like)); SEMA_NOTE(method, "The previous definition was here."); return false; } @@ -1275,7 +1326,8 @@ static inline bool unit_add_method_like(CompilationUnit *unit, Type *parent_type method = sema_resolve_method(unit, parent, name, &ambiguous, &private); if (method) { - SEMA_ERROR(method_like, "This %s is already defined for '%s'.", name_by_decl(method_like), parent_type->name); + SEMA_ERROR(method_like, "This %s is already defined for '%s'.", + method_name_by_decl(method_like), parent_type->name); SEMA_NOTE(method, "The previous definition was here."); return false; } @@ -1948,6 +2000,7 @@ static inline bool sema_analyse_func_macro(SemaContext *context, Decl *decl, boo if (!sema_analyse_attributes(context, decl, decl->attributes, is_func ? ATTR_FUNC : ATTR_MACRO)) return decl_poison(decl); return true; } + static inline bool sema_analyse_func(SemaContext *context, Decl *decl) { DEBUG_LOG("----Analysing function %s", decl->name); @@ -2442,8 +2495,9 @@ static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl) assert(parameter_count > 0); if (parameter_count != vec_size(params)) { - sema_error_at(extend_span_with_token(params[0]->span, VECLAST(params)->span), - "The generic module expected %d arguments, but you only supplied %d, did you make a mistake?", + assert(vec_size(params)); + sema_error_at(extend_span_with_token(params[0]->span, vectail(params)->span), + "The generic module expected %d arguments, but you supplied %d, did you make a mistake?", parameter_count, vec_size(decl->define_decl.generic_params)); return decl_poison(decl); @@ -2451,13 +2505,11 @@ static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl) scratch_buffer_clear(); scratch_buffer_append_len(module->name->module, module->name->len); scratch_buffer_append("$$"); - VECEACH(decl->define_decl.generic_params, i) - { - TypeInfo *type_info = decl->define_decl.generic_params[i]; + FOREACH_BEGIN_IDX(i, TypeInfo *type_info, decl->define_decl.generic_params) if (!sema_resolve_type_info(c, type_info)) return decl_poison(decl); if (i != 0) scratch_buffer_append_char('.'); type_mangle_introspect_name_to_buffer(type_info->type->canonical); - } + FOREACH_END(); TokenType ident_type = TOKEN_IDENT; const char *path_string = scratch_buffer_interned(); Module *instantiated_module = global_context_find_module(path_string); @@ -2543,9 +2595,6 @@ static inline bool sema_analyse_define(SemaContext *c, Decl *decl) return sema_analyse_parameterized_define(c, decl); } - - - bool sema_analyse_decl(SemaContext *context, Decl *decl) { if (decl->resolve_status == RESOLVE_DONE) return decl_ok(decl); diff --git a/src/compiler/sema_errors.c b/src/compiler/sema_errors.c new file mode 100644 index 000000000..1535f9a1d --- /dev/null +++ b/src/compiler/sema_errors.c @@ -0,0 +1,11 @@ +// Copyright (c) 2022 Christoffer Lerno. All rights reserved. +// Use of this source code is governed by a LGPLv3.0 +// a copy of which can be found in the LICENSE file. + +#include "sema_internal.h" + +void sema_shadow_error(Decl *decl, Decl *old) +{ + SEMA_ERROR(decl, "'%s' would shadow a previous declaration.", decl->name); + SEMA_NOTE(old, "The previous use of '%s' was here.", decl->name); +} \ No newline at end of file diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 98dff387e..09924546c 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -15,6 +15,21 @@ static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_in return true; } +bool sema_resolve_type_info(SemaContext *context, TypeInfo *type_info) +{ + return sema_resolve_type_info_maybe_inferred(context, type_info, false); +} + +bool sema_resolve_type_info_maybe_inferred(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type) +{ + if (!sema_resolve_type_shallow(context, type_info, allow_inferred_type, false)) return false; + Type *type = type_no_optional(type_info->type); + // usize and similar typedefs will not have a decl. + if (type->type_kind == TYPE_TYPEDEF && type->decl == NULL) return true; + if (!type_is_user_defined(type)) return true; + return sema_analyse_decl(context, type->decl); +} + bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, ArraySize *len_ref) { Expr *len_expr = type_info->array.len; diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 87808b8df..48b8f7000 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -5,28 +5,6 @@ #include #include "sema_internal.h" -void sema_shadow_error(Decl *decl, Decl *old) -{ - SEMA_ERROR(decl, "'%s' would shadow a previous declaration.", decl->name); - SEMA_NOTE(old, "The previous use of '%s' was here.", decl->name); -} - -bool sema_resolve_type_info_maybe_inferred(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type) -{ - if (!sema_resolve_type_shallow(context, type_info, allow_inferred_type, false)) return false; - Type *type = type_no_optional(type_info->type); - // usize and similar typedefs will not have a decl. - if (type->type_kind == TYPE_TYPEDEF && type->decl == NULL) return true; - if (!type_is_user_defined(type)) return true; - return sema_analyse_decl(context, type->decl); -} - -bool sema_resolve_type_info(SemaContext *context, TypeInfo *type_info) -{ - return sema_resolve_type_info_maybe_inferred(context, type_info, false); -} - - void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags) { unsigned depth = context->active_scope.depth + 1; diff --git a/src/utils/lib.h b/src/utils/lib.h index 2e2febc57..d03b3fbf8 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -302,6 +302,7 @@ void* CONCAT(foreach_vec_, __LINE__) = (vec__); unsigned CONCAT(foreach_len_, __ #else #define VECLAST(_vec) (vec_size(_vec) ? (_vec)[vec_size(_vec) - 1] : NULL) #endif +#define vectail(_vec) (_vec)[vec_size(_vec) - 1] #if IS_GCC || IS_CLANG