tccpp: alternative #pragma push/pop_macro

using next_nomacro() so that for example
    #define push_macro foobar
does not affect how the pragma works (same behavior
as gcc, albeit not MS's cl).
master
grischka 2015-04-23 23:27:36 +02:00
parent 7c27186a83
commit 72e8ff11e9
2 changed files with 38 additions and 11 deletions

47
tccpp.c
View File

@ -1114,7 +1114,6 @@ ST_FUNC void define_undef(Sym *s)
define_print(s, 1); define_print(s, 1);
table_ident[v - TOK_IDENT]->sym_define = NULL; table_ident[v - TOK_IDENT]->sym_define = NULL;
} }
s->v = 0;
} }
ST_INLN Sym *define_find(int v) ST_INLN Sym *define_find(int v)
@ -1378,9 +1377,7 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if
static void pragma_parse(TCCState *s1) static void pragma_parse(TCCState *s1)
{ {
int val; next_nomacro();
next();
if (tok == TOK_pack) { if (tok == TOK_pack) {
/* /*
This may be: This may be:
@ -1399,7 +1396,7 @@ static void pragma_parse(TCCState *s1)
} }
s1->pack_stack_ptr--; s1->pack_stack_ptr--;
} else { } else {
val = 0; int val = 0;
if (tok != ')') { if (tok != ')') {
if (tok == TOK_ASM_push) { if (tok == TOK_ASM_push) {
next(); next();
@ -1408,18 +1405,17 @@ static void pragma_parse(TCCState *s1)
s1->pack_stack_ptr++; s1->pack_stack_ptr++;
skip(','); skip(',');
} }
if (tok != TOK_CINT) { if (tok != TOK_CINT)
pack_error: goto pragma_err;
tcc_error("invalid pack pragma");
}
val = tokc.i; val = tokc.i;
if (val < 1 || val > 16 || (val & (val - 1)) != 0) if (val < 1 || val > 16 || (val & (val - 1)) != 0)
goto pack_error; goto pragma_err;
next(); next();
} }
*s1->pack_stack_ptr = val; *s1->pack_stack_ptr = val;
skip(')');
} }
if (tok != ')')
goto pragma_err;
} else if (tok == TOK_comment) { } else if (tok == TOK_comment) {
if (s1->ms_extensions) { if (s1->ms_extensions) {
next(); next();
@ -1446,11 +1442,40 @@ static void pragma_parse(TCCState *s1)
} else { } else {
tcc_warning("#pragma comment(lib) is ignored"); tcc_warning("#pragma comment(lib) is ignored");
} }
} else if (tok == TOK_push_macro || tok == TOK_pop_macro) {
int t = tok, v;
Sym *s;
if (next_nomacro(), tok != '(')
goto pragma_err;
if (next_nomacro(), tok != TOK_STR)
goto pragma_err;
v = tok_alloc(tokc.cstr->data, tokc.cstr->size - 1)->tok;
if (next_nomacro(), tok != ')')
goto pragma_err;
if (t == TOK_push_macro) {
while (NULL == (s = define_find(v)))
define_push(v, 0, NULL, NULL);
s->type.ref = s; /* set push boundary */
} else {
for (s = define_stack; s; s = s->prev)
if (s->v == v && s->type.ref == s) {
s->type.ref = NULL;
break;
}
}
if (s)
table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
else
tcc_warning("unbalanced #pragma pop_macro");
} else if (tok == TOK_once) { } else if (tok == TOK_once) {
add_cached_include(s1, file->filename, TOK_once); add_cached_include(s1, file->filename, TOK_once);
} else { } else {
tcc_warning("unknown #pragma %s", get_tok_str(tok, &tokc)); tcc_warning("unknown #pragma %s", get_tok_str(tok, &tokc));
} }
return;
pragma_err:
tcc_error("malformed #pragma directive");
} }
/* is_bof is true if first non space token at beginning of file */ /* is_bof is true if first non space token at beginning of file */

View File

@ -155,6 +155,8 @@
#endif #endif
DEF(TOK_comment, "comment") DEF(TOK_comment, "comment")
DEF(TOK_lib, "lib") DEF(TOK_lib, "lib")
DEF(TOK_push_macro, "push_macro")
DEF(TOK_pop_macro, "pop_macro")
DEF(TOK_once, "once") DEF(TOK_once, "once")
/* builtin functions or variables */ /* builtin functions or variables */