diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index e0ff7fdfc..e3ce2d559 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2274,6 +2274,7 @@ void sema_error_prev_at(SourceSpan loc, const char *message, ...); void sema_verror_range(SourceSpan location, const char *message, va_list args); void sema_error(ParseContext *context, const char *message, ...); +void sema_warning_at(SourceSpan loc, const char *message, ...); void sema_shadow_error(Decl *decl, Decl *old); bool sema_type_error_on_binop(Expr *expr); diff --git a/src/compiler/diagnostics.c b/src/compiler/diagnostics.c index 9eac16a3b..f3118013a 100644 --- a/src/compiler/diagnostics.c +++ b/src/compiler/diagnostics.c @@ -160,6 +160,15 @@ void sema_verror_range(SourceSpan location, const char *message, va_list args) global_context.errors_found++; } +void sema_warning_at(SourceSpan loc, const char *message, ...) +{ + if (global_context.suppress_errors) return; + va_list list; + va_start(list, message); + print_error(loc, str_vprintf(message, list), PRINT_TYPE_NOTE); + va_end(list); +} + void sema_error_at(SourceSpan loc, const char *message, ...) { diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index e1cbcebc4..d9a74bcbe 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1547,7 +1547,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, } } decl->is_deprecated = true; - break; + return true; case ATTRIBUTE_WINMAIN: if (decl->name != kw_main) { @@ -2705,8 +2705,15 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local) if (!sema_resolve_type_info_maybe_inferred(context, decl->var.type_info, decl->var.init_expr != NULL)) return decl_poison(decl); - decl->type = decl->var.type_info->type; + Type *type = decl->type = decl->var.type_info->type; if (!sema_analyse_decl_type(context, decl->type, decl->var.type_info->span)) return decl_poison(decl); + + if (type) type = type_no_optional(type); + if (type_is_user_defined(type)) + { + sema_display_deprecated_warning_on_use(context, type->decl, decl->var.type_info->span); + } + bool is_static = decl->var.is_static; if (is_static && context->call_env.pure) { @@ -2783,7 +2790,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local) init_expr->const_expr.is_hex = false; } } - EXIT_OK: + EXIT_OK:; if (!decl->alignment) { if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false; @@ -3155,8 +3162,28 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) } decl->resolve_status = RESOLVE_DONE; sema_context_destroy(&temp_context); + return true; FAILED: sema_context_destroy(&temp_context); return decl_poison(decl); } + +void sema_display_deprecated_warning_on_use(SemaContext *context, Decl *decl, SourceSpan span) +{ + if (!decl->is_deprecated) return; + decl->is_deprecated = false; + FOREACH_BEGIN(Attr *attr, decl->attributes) + if (attr->attr_kind == ATTRIBUTE_DEPRECATED) + { + if (attr->exprs) + { + const char *comment_string = attr->exprs[0]->const_expr.string.chars; + sema_warning_at(span, "'%s' is deprecated: %s.", decl->name, comment_string); + return; + } + break; + } + FOREACH_END(); + sema_warning_at(span, "'%s' is deprecated.", decl->name); +} diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index a18d0ebe4..b2f946a4f 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -837,6 +837,8 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, { if (!sema_analyse_decl(context, decl)) return decl_poison(decl); } + sema_display_deprecated_warning_on_use(context, decl, expr->span); + unit_register_external_symbol(context->compilation_unit, decl); if (decl->decl_kind == DECL_VAR) { @@ -1516,6 +1518,7 @@ static inline bool sema_call_analyse_func_invocation(SemaContext *context, Type } bool is_unused = expr->call_expr.result_unused; + if (!sema_call_analyse_invocation(context, expr, callee, &optional)) return false; Type *rtype = type->function.prototype->rtype; @@ -1653,6 +1656,8 @@ static inline bool sema_expr_analyse_func_call(SemaContext *context, Expr *expr, SEMA_ERROR(expr, "@test functions may not be directly called."); return false; } + sema_display_deprecated_warning_on_use(context, decl, expr->span); + return sema_call_analyse_func_invocation(context, decl->type, expr, @@ -1672,6 +1677,8 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s SEMA_ERROR(call_expr, "Failure evaluating macro, max call depth reached."); return false; } + sema_display_deprecated_warning_on_use(context, decl, call_expr->span); + copy_begin(); Decl **params = copy_decl_list_macro(decl->func_decl.signature.params); Ast *body = copy_ast_macro(astptr(decl->func_decl.body)); diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 5a8dbfc42..b2083a67e 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -104,6 +104,7 @@ void cast_to_max_bit_size(SemaContext *context, Expr *left, Expr *right, Type *l bool cast_decay_array_pointers(SemaContext *context, Expr *expr); INLINE bool sema_set_abi_alignment(SemaContext *context, Type *type, AlignSize *result); INLINE bool sema_set_alloca_alignment(SemaContext *context, Type *type, AlignSize *result); +void sema_display_deprecated_warning_on_use(SemaContext *context, Decl *decl, SourceSpan use); INLINE bool sema_set_abi_alignment(SemaContext *context, Type *type, AlignSize *result) { diff --git a/src/version.h b/src/version.h index 384c24bf0..71dfa4064 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.86" \ No newline at end of file +#define COMPILER_VERSION "0.4.87" \ No newline at end of file