Introduce #pragma naked
When applied to a function #pragma naked merely disables the "should return a value" warning for the function. It's intended to be used with functions that return a value via #emit instead of the normal return statement. This pragma works only on function definitions, not declarations. It's also pretty stupid - the function may be defined way after this directive and it won't stop on things coming in between. For example, here all declarations between #pragma naked and f() are effectively ignored: #pragma naked new x; // ignored forward g(); // ignored native n(); // ignored f() { // f() becomes naked } Note that #pragma naked does not affect generated code in any way, unlike e.g. __declspec(naked) or __attribute__((naked)) in C/C++ where the compiler omits the code for the prolog and epilog.
This commit is contained in:
parent
6943995219
commit
53221dd2cc
@ -219,6 +219,7 @@ typedef struct s_symbol {
|
||||
#define uRETNONE 0x10
|
||||
|
||||
#define flgDEPRICATED 0x01 /* symbol is deprecated (avoid use) */
|
||||
#define flagNAKED 0x10 /* function is naked */
|
||||
|
||||
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
|
||||
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
|
||||
@ -808,6 +809,7 @@ SC_VDECL char *pc_deprecate; /* if non-NULL, mark next declaration as deprecate
|
||||
SC_VDECL int sc_curstates; /* ID of the current state list */
|
||||
SC_VDECL int pc_optimize; /* (peephole) optimization level */
|
||||
SC_VDECL int pc_memflags; /* special flags for the stack/heap usage */
|
||||
SC_VDECL int pc_naked; /* if true mark following function as naked */
|
||||
|
||||
SC_VDECL constvalue sc_automaton_tab; /* automaton table */
|
||||
SC_VDECL constvalue sc_state_tab; /* state table */
|
||||
|
@ -843,6 +843,7 @@ static void resetglobals(void)
|
||||
pc_deprecate=NULL;
|
||||
sc_curstates=0;
|
||||
pc_memflags=0;
|
||||
pc_naked=FALSE;
|
||||
}
|
||||
|
||||
static void initglobals(void)
|
||||
@ -3513,6 +3514,10 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
|
||||
char *ptr= (sym->documentation!=NULL) ? sym->documentation : "";
|
||||
error(234,symbolname,ptr); /* deprecated (probably a public function) */
|
||||
} /* if */
|
||||
if (pc_naked) {
|
||||
sym->flags|=flagNAKED;
|
||||
pc_naked=FALSE;
|
||||
} /* if */
|
||||
begcseg();
|
||||
sym->usage|=uDEFINE; /* set the definition flag */
|
||||
if (stock)
|
||||
@ -3572,7 +3577,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
|
||||
if ((lastst!=tRETURN) && (lastst!=tGOTO)){
|
||||
ldconst(0,sPRI);
|
||||
ffret(strcmp(sym->name,uENTRYFUNC)!=0);
|
||||
if ((sym->usage & uRETVALUE)!=0) {
|
||||
if ((sym->usage & uRETVALUE)!=0 && (sym->flags & flagNAKED)==0) {
|
||||
char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
|
||||
funcdisplayname(symname,sym->name);
|
||||
error(209,symname); /* function should return a value */
|
||||
@ -5748,7 +5753,7 @@ static void doreturn(void)
|
||||
} else {
|
||||
/* this return statement contains no expression */
|
||||
ldconst(0,sPRI);
|
||||
if ((rettype & uRETVALUE)!=0) {
|
||||
if ((rettype & uRETVALUE)!=0 && (sym->flags & flagNAKED)==0) {
|
||||
char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
|
||||
assert(curfunc!=NULL);
|
||||
funcdisplayname(symname,curfunc->name);
|
||||
|
@ -1168,6 +1168,8 @@ static int command(void)
|
||||
if (comma)
|
||||
lptr++;
|
||||
} while (comma);
|
||||
} else if (strcmp(str,"naked")==0) {
|
||||
pc_naked=TRUE;
|
||||
} else {
|
||||
error(207); /* unknown #pragma */
|
||||
} /* if */
|
||||
|
@ -433,7 +433,7 @@ static void checkfunction(value *lval)
|
||||
/* function is defined, can now check the return value (but make an
|
||||
* exception for directly recursive functions)
|
||||
*/
|
||||
if (sym!=curfunc && (sym->usage & uRETVALUE)==0) {
|
||||
if (sym!=curfunc && (sym->usage & uRETVALUE)==0 && (sym->flags & flagNAKED)==0) {
|
||||
char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
|
||||
funcdisplayname(symname,sym->name);
|
||||
error(209,symname); /* function should return a value */
|
||||
|
@ -90,6 +90,7 @@ SC_VDEFINE char *pc_deprecate=NULL;/* if non-null, mark next declaration as depr
|
||||
SC_VDEFINE int sc_curstates=0; /* ID of the current state list */
|
||||
SC_VDEFINE int pc_optimize=sOPTIMIZE_NOMACRO; /* (peephole) optimization level */
|
||||
SC_VDEFINE int pc_memflags=0; /* special flags for the stack/heap usage */
|
||||
SC_VDEFINE int pc_naked=FALSE; /* if true mark following function as naked */
|
||||
|
||||
SC_VDEFINE constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
|
||||
SC_VDEFINE constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */
|
||||
|
Loading…
x
Reference in New Issue
Block a user