From 204243fe959835ca6bf0b77839a6309c4b66bb5d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 22 Aug 2003 05:26:47 +0000 Subject: [PATCH] better message type checking --- tools/qfcc/include/method.h | 2 ++ tools/qfcc/source/expr.c | 13 ++------- tools/qfcc/source/method.c | 53 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index fbfed5c0b..75890be47 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -89,4 +89,6 @@ struct def_s *emit_methods (methodlist_t *methods, const char *name, void clear_selectors (void); +struct expr_s *method_check_params (method_t *method, struct expr_s *args); + #endif//__method_h diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 9648fca62..719b66799 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2599,17 +2599,8 @@ message_expr (expr_t *receiver, keywordarg_t *message) *a = receiver; if (method) { - def_t def; - expr_t e, *err; - - def.type = method->type; - def.name = method->name; - e.type = ex_def; - e.e.def = &def; - e.line = receiver->line; - e.file = receiver->file; - err = function_expr (&e, args); - if (err->type == ex_error) + expr_t *err; + if ((err = method_check_params (method, args))) return err; } call = function_expr (send_message (super), args); diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 29a15040a..35b6e6f15 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -55,6 +55,7 @@ static __attribute__ ((unused)) const char rcsid[] = #include "emit.h" #include "immediate.h" #include "method.h" +#include "options.h" #include "reloc.h" #include "strpool.h" #include "struct.h" @@ -383,3 +384,55 @@ clear_selectors (void) if (known_methods) Hash_FlushTable (known_methods); } + +expr_t * +method_check_params (method_t *method, expr_t *args) +{ + int i, count, parm_count; + expr_t *a, **arg_list, *err = 0; + type_t *mtype = method->type; + + if (mtype->num_parms == -1) + return 0; + + for (count = 0, a = args; a; a = a->next) + count++; + + if (count > MAX_PARMS) + return error (args, "more than %d parameters", MAX_PARMS); + + if (mtype->num_parms >= 0) + parm_count = mtype->num_parms; + else + parm_count = -mtype->num_parms - 1; + + if (count < parm_count) + return error (args, "too few arguments"); + if (mtype->num_parms >= 0 && count > mtype->num_parms) + return error (args, "too many arguments"); + + arg_list = malloc (count * sizeof (expr_t *)); + for (i = count - 1, a = args; a; a = a->next) + arg_list[i--] = a; + for (i = 2; i < count; i++) { + expr_t *e = arg_list[i]; + type_t *t = get_type (e); + + if (mtype->parm_types[i] == &type_float && e->type == ex_integer) { + convert_int (e); + t = &type_float; + } + if (i < parm_count) { + if (e->type != ex_nil) + if (!type_assignable (mtype->parm_types[i], t)) { + err = error (e, "type mismatch for parameter %d of %s", + i - 1, method->name); + } + } else { + if (e->type == ex_integer && options.warnings.vararg_integer) + warning (e, "passing integer consant into ... function"); + } + } + free (arg_list); + return err; +}