diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index c9ae8370b..1ad2140e2 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -72,6 +72,7 @@ extern type_t type_Method; extern type_t *type_category; extern type_t *type_ivar; extern type_t *type_module; +extern type_t type_va_list; extern type_t *vector_struct; diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 4bdbccfe9..4cbc8d667 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -141,18 +141,15 @@ build_scope (function_t *f, def_t *func, param_t *params) int i; def_t *def; param_t *p; - def_t *argv = 0; + def_t *args = 0; int parm_ofs[MAX_PARMS]; f->scope = new_scope (sc_params, new_defspace (), pr.scope); if (func->type->num_parms < 0) { - def = get_def (&type_integer, ".argc", f->scope, st_local); - def->used = 1; - def_initialized (def); - argv = get_def (&type_pointer, ".argv", f->scope, st_local); - argv->used = 1; - def_initialized (argv); + args = get_def (&type_va_list, ".args", f->scope, st_local); + args->used = 1; + def_initialized (args); } for (p = params, i = 0; p; p = p->next) { @@ -172,12 +169,10 @@ build_scope (function_t *f, def_t *func, param_t *params) i++; } - if (argv) { + if (args) { while (i < MAX_PARMS) { def = get_def (&type_vector, 0, f->scope, st_local); def->used = 1; - if (argv->type == &type_pointer) - argv->type = array_type (&type_vector, MAX_PARMS - i); i++; } } diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 99013b93d..67bd0ce12 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -297,8 +297,10 @@ static keyword_t keywords[] = { {"@selector", SELECTOR, 0, 0, PROG_VERSION}, {"@self", SELF, 0, 0, PROG_VERSION}, {"@this", THIS, 0, 0, PROG_VERSION}, + {"@args", ARGS, 0, 0, PROG_VERSION}, {"@argc", ARGC, 0, 0, PROG_VERSION}, {"@argv", ARGV, 0, 0, PROG_VERSION}, + {"@va_list", TYPE, &type_va_list, 0, PROG_VERSION}, {"@extern", EXTERN, 0, 1, PROG_ID_VERSION}, {"@static", STATIC, 0, 1, PROG_ID_VERSION}, {"@system", SYSTEM, 0, 1, PROG_ID_VERSION}, diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 872a3247e..91adc6b35 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -86,6 +86,9 @@ hashtab_t *merge_local_inits (hashtab_t *dl_1, hashtab_t *dl_2); void restore_local_inits (hashtab_t *def_list); void free_local_inits (hashtab_t *def_list); +expr_t *argc_expr (void); +expr_t *argv_expr (void); + %} %union { @@ -128,7 +131,7 @@ void free_local_inits (hashtab_t *def_list); %token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS NIL %token IFBE IFB IFAE IFA %token SWITCH CASE DEFAULT STRUCT UNION ENUM TYPEDEF SUPER SELF THIS -%token ARGC ARGV EXTERN STATIC SYSTEM SIZEOF +%token ARGS ARGC ARGV EXTERN STATIC SYSTEM SIZEOF %token ELE_START %token TYPE %token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE PROTECTED @@ -823,8 +826,9 @@ expr | expr INCOP { $$ = incop_expr ($2, $1, 1); } | obj_expr { $$ = $1; } | NAME { $$ = new_name_expr ($1); } - | ARGC { $$ = new_name_expr (".argc"); } - | ARGV { $$ = new_name_expr (".argv"); } + | ARGS { $$ = new_name_expr (".args"); } + | ARGC { $$ = argc_expr (); } + | ARGV { $$ = argv_expr (); } | SELF { $$ = new_self_expr (); } | THIS { $$ = new_this_expr (); } | SIZEOF '(' expr ')' { $$ = sizeof_expr ($3, 0); } @@ -1390,3 +1394,17 @@ free_local_inits (hashtab_t *def_list) { Hash_DelTable (def_list); } + +expr_t * +argc_expr (void) +{ + warning (0, "@argc deprecated: use @args.count"); + return binary_expr ('.', new_name_expr (".args"), new_name_expr ("count")); +} + +expr_t * +argv_expr (void) +{ + warning (0, "@argv deprecated: use @args.list"); + return binary_expr ('.', new_name_expr (".args"), new_name_expr ("list")); +} diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index ceb2fb7d2..8b8ad29b8 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -68,7 +68,7 @@ type_t type_string = { ev_string, "string" }; type_t type_float = { ev_float, "float" }; type_t type_vector = { ev_vector, "vector" }; type_t type_entity = { ev_entity, "entity" }; -type_t type_field = { ev_field, "field" }; +type_t type_field = { ev_field, "field", NULL, &type_void }; // type_function is a void() function used for state defs type_t type_function = { ev_func, "function", NULL, &type_void }; @@ -90,6 +90,7 @@ type_t type_Method = { ev_pointer, "Method" }; type_t *type_category; type_t *type_ivar; type_t *type_module; +type_t type_va_list; type_t *vector_struct; @@ -565,6 +566,7 @@ type_size (type_t *type) case ev_type_count: return pr_type_size[type->type]; case ev_struct: + return type->num_parms; case ev_object: case ev_class: for (size = 0, field = type->struct_head; @@ -645,6 +647,20 @@ init_types (void) new_struct_field (type, &type_string, "ivar_name", vis_public); new_struct_field (type, &type_string, "ivar_type", vis_public); new_struct_field (type, &type_integer, "ivar_offset", vis_public); + + init_struct (malloc (sizeof (struct_t)), &type_va_list, 0); + new_struct_field (&type_va_list, &type_integer, "count", vis_public); + type = new_union (0); + new_struct_field (type, &type_string, "string_val", vis_public); + new_struct_field (type, &type_float, "float_val", vis_public); + new_struct_field (type, &type_vector, "vector_val", vis_public); + new_struct_field (type, &type_entity, "entity_val", vis_public); + new_struct_field (type, &type_field, "field_val", vis_public); + new_struct_field (type, &type_function, "func_val", vis_public); + new_struct_field (type, &type_pointer, "pointer_val", vis_public); + new_struct_field (type, &type_integer, "integer_val", vis_public); + new_struct_field (type, &type_uinteger, "uinteger_val", vis_public); + new_struct_field (&type_va_list, pointer_type (type), "list", vis_public); #if 0 type = type_module = new_struct ("obj_module_t"); new_struct_field (type, &type_integer, "version", vis_public);