Implement fteqcc's "nosave" specifier.

Of course, it's "@nosave" for traditional progs, but that's only a define
away.
This commit is contained in:
Bill Currie 2013-01-07 14:35:34 +09:00
parent 955e3ee258
commit 76a69d9a53
3 changed files with 19 additions and 1 deletions

View file

@ -92,6 +92,7 @@ typedef struct {
unsigned is_long:1; unsigned is_long:1;
unsigned is_typedef:1; unsigned is_typedef:1;
unsigned is_overload:1; unsigned is_overload:1;
unsigned nosave:1;
} specifier_t; } specifier_t;
extern type_t type_invalid; extern type_t type_invalid;

View file

@ -329,6 +329,7 @@ static keyword_t at_keywords[] = {
{"extern", EXTERN }, {"extern", EXTERN },
{"static", STATIC }, {"static", STATIC },
{"sizeof", SIZEOF }, {"sizeof", SIZEOF },
{"nosave", NOSAVE },
}; };
// These keywords require the QuakeForge VM to be of any use. ie, they cannot // These keywords require the QuakeForge VM to be of any use. ie, they cannot

View file

@ -145,7 +145,7 @@ int yylex (void);
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS %token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS
%token NIL IFBE IFB IFAE IFA SWITCH CASE DEFAULT ENUM TYPEDEF %token NIL IFBE IFB IFAE IFA SWITCH CASE DEFAULT ENUM TYPEDEF
%token ARGS EXTERN STATIC SYSTEM SIZEOF OVERLOAD %token ARGS EXTERN STATIC SYSTEM NOSAVE OVERLOAD
%token <op> STRUCT %token <op> STRUCT
%token <type> TYPE %token <type> TYPE
%token <symbol> OBJECT TYPE_NAME %token <symbol> OBJECT TYPE_NAME
@ -248,6 +248,7 @@ spec_merge (specifier_t spec, specifier_t new)
spec.is_typedef = new.is_typedef; spec.is_typedef = new.is_typedef;
} }
spec.is_overload |= new.is_overload; spec.is_overload |= new.is_overload;
spec.nosave |= new.nosave;
return spec; return spec;
} }
@ -394,6 +395,8 @@ external_decl
} else { } else {
initialize_def ($1, type, 0, current_symtab->space, initialize_def ($1, type, 0, current_symtab->space,
spec.storage); spec.storage);
if ($1->s.def)
$1->s.def->nosave |= spec.nosave;
} }
} }
| var_decl var_initializer | var_decl var_initializer
@ -412,6 +415,8 @@ external_decl
} else { } else {
initialize_def ($1, type, $2, current_symtab->space, initialize_def ($1, type, $2, current_symtab->space,
spec.storage); spec.storage);
if ($1->s.def)
$1->s.def->nosave |= spec.nosave;
} }
} }
| function_decl | function_decl
@ -438,6 +443,11 @@ storage_class
| SYSTEM { $$ = make_spec (0, sc_system, 0, 0); } | SYSTEM { $$ = make_spec (0, sc_system, 0, 0); }
| TYPEDEF { $$ = make_spec (0, sc_global, 1, 0); } | TYPEDEF { $$ = make_spec (0, sc_global, 1, 0); }
| OVERLOAD { $$ = make_spec (0, current_storage, 0, 1); } | OVERLOAD { $$ = make_spec (0, current_storage, 0, 1); }
| NOSAVE
{
$$ = make_spec (0, current_storage, 0, 0);
$$.nosave = 1;
}
; ;
optional_specifiers optional_specifiers
@ -901,6 +911,8 @@ decl
space = pr.near_data; space = pr.near_data;
type = find_type (append_type ($1->type, spec.type)); type = find_type (append_type ($1->type, spec.type));
initialize_def ($1, type, $2, space, sc); initialize_def ($1, type, $2, space, sc);
if ($1->s.def)
$1->s.def->nosave |= $<spec>0.nosave;
} }
; ;
@ -961,6 +973,8 @@ non_code_func
specifier_t spec = $<spec>-1; specifier_t spec = $<spec>-1;
initialize_def (sym, sym->type, $2, current_symtab->space, initialize_def (sym, sym->type, $2, current_symtab->space,
spec.storage); spec.storage);
if (sym->s.def)
sym->s.def->nosave |= spec.nosave;
} }
| /* emtpy */ | /* emtpy */
{ {
@ -973,6 +987,8 @@ non_code_func
} else { } else {
initialize_def (sym, sym->type, 0, current_symtab->space, initialize_def (sym, sym->type, 0, current_symtab->space,
spec.storage); spec.storage);
if (sym->s.def)
sym->s.def->nosave |= spec.nosave;
} }
} }
; ;