aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2015-04-23 23:27:36 +0200
committergrischka <grischka>2015-04-23 23:27:36 +0200
commit72e8ff11e9802e219e4880fe6ad0796beaf7fce2 (patch)
tree9a5326659133ad32a1e7491f0a1bc6f86ea39e42
parent7c27186a83cefd7845d4840ef25bd08c8b65cd3b (diff)
downloadtinycc-72e8ff11e9802e219e4880fe6ad0796beaf7fce2.tar.gz
tinycc-72e8ff11e9802e219e4880fe6ad0796beaf7fce2.tar.bz2
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).
-rw-r--r--tccpp.c47
-rw-r--r--tcctok.h2
2 files changed, 38 insertions, 11 deletions
diff --git a/tccpp.c b/tccpp.c
index 77d40d5..05e7c1f 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -1114,7 +1114,6 @@ ST_FUNC void define_undef(Sym *s)
define_print(s, 1);
table_ident[v - TOK_IDENT]->sym_define = NULL;
}
- s->v = 0;
}
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)
{
- int val;
-
- next();
+ next_nomacro();
if (tok == TOK_pack) {
/*
This may be:
@@ -1399,7 +1396,7 @@ static void pragma_parse(TCCState *s1)
}
s1->pack_stack_ptr--;
} else {
- val = 0;
+ int val = 0;
if (tok != ')') {
if (tok == TOK_ASM_push) {
next();
@@ -1408,18 +1405,17 @@ static void pragma_parse(TCCState *s1)
s1->pack_stack_ptr++;
skip(',');
}
- if (tok != TOK_CINT) {
- pack_error:
- tcc_error("invalid pack pragma");
- }
+ if (tok != TOK_CINT)
+ goto pragma_err;
val = tokc.i;
if (val < 1 || val > 16 || (val & (val - 1)) != 0)
- goto pack_error;
+ goto pragma_err;
next();
}
*s1->pack_stack_ptr = val;
- skip(')');
}
+ if (tok != ')')
+ goto pragma_err;
} else if (tok == TOK_comment) {
if (s1->ms_extensions) {
next();
@@ -1446,11 +1442,40 @@ static void pragma_parse(TCCState *s1)
} else {
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) {
add_cached_include(s1, file->filename, TOK_once);
} else {
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 */
diff --git a/tcctok.h b/tcctok.h
index 4db9d1c..3de3ae2 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -155,6 +155,8 @@
#endif
DEF(TOK_comment, "comment")
DEF(TOK_lib, "lib")
+ DEF(TOK_push_macro, "push_macro")
+ DEF(TOK_pop_macro, "pop_macro")
DEF(TOK_once, "once")
/* builtin functions or variables */