aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tcc.h1
-rw-r--r--tccasm.c5
-rw-r--r--tccgen.c1
-rw-r--r--tccpp.c34
-rw-r--r--tcctok.h2
-rw-r--r--tests/tests2/77_push_pop_macro.c23
-rw-r--r--tests/tests2/77_push_pop_macro.expect5
-rw-r--r--tests/tests2/Makefile3
8 files changed, 71 insertions, 3 deletions
diff --git a/tcc.h b/tcc.h
index a0b4894..52baf58 100644
--- a/tcc.h
+++ b/tcc.h
@@ -326,6 +326,7 @@
typedef struct TokenSym {
struct TokenSym *hash_next;
struct Sym *sym_define; /* direct pointer to define */
+ struct Sym *sym_define_stack; /* direct pointer to a push_macro stack */
struct Sym *sym_label; /* direct pointer to label */
struct Sym *sym_struct; /* direct pointer to structure */
struct Sym *sym_identifier; /* direct pointer to identifier */
diff --git a/tccasm.c b/tccasm.c
index 3fa6f07..f67c1a6 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -292,7 +292,7 @@ static void asm_free_labels(TCCState *st)
{
Sym *s, *s1;
Section *sec;
-
+
for(s = st->asm_labels; s != NULL; s = s1) {
s1 = s->prev;
/* define symbol value in object file */
@@ -305,6 +305,9 @@ static void asm_free_labels(TCCState *st)
}
/* remove label */
table_ident[s->v - TOK_IDENT]->sym_label = NULL;
+ if (s->asm_label) {
+ tcc_free(s->asm_label);
+ }
sym_free(s);
}
st->asm_labels = NULL;
diff --git a/tccgen.c b/tccgen.c
index 5275b47..103c955 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -152,7 +152,6 @@ static inline Sym *sym_malloc(void)
ST_INLN void sym_free(Sym *sym)
{
sym->next = sym_free_first;
- tcc_free(sym->asm_label);
sym_free_first = sym;
}
diff --git a/tccpp.c b/tccpp.c
index 42ebf48..4d9430d 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -222,6 +222,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
table_ident[i] = ts;
ts->tok = tok_ident++;
ts->sym_define = NULL;
+ ts->sym_define_stack = NULL;
ts->sym_label = NULL;
ts->sym_struct = NULL;
ts->sym_identifier = NULL;
@@ -1446,6 +1447,39 @@ 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 push_macro = (tok == TOK_push_macro);
+ next();
+ skip('(');
+ if (tok != TOK_STR) {
+ expect("\"");
+ } else {
+ int len = strlen((char *)tokc.cstr->data);
+ tcc_open_bf(s1, "<push_pop_macro>", len);
+ memcpy(file->buffer, tokc.cstr->data, len);
+ ch = file->buf_ptr[0];
+ next_nomacro();
+ if (tok >= TOK_IDENT) {
+ Sym *s = table_ident[tok - TOK_IDENT]->sym_define;
+ Sym *ss = table_ident[tok - TOK_IDENT]->sym_define_stack;
+ if (push_macro) {
+ if (s) {
+ s->prev_tok = ss;
+ table_ident[tok - TOK_IDENT]->sym_define_stack = s;
+ }
+ } else {
+ if (ss) {
+ table_ident[tok - TOK_IDENT]->sym_define = ss;
+ table_ident[tok - TOK_IDENT]->sym_define_stack = ss->prev_tok;
+ }
+ }
+ }
+ tcc_close();
+ }
+ next();
+ skip(')');
+ } else {
+ tcc_warning("unknown #pragma %s", get_tok_str(tok, &tokc));
}
}
diff --git a/tcctok.h b/tcctok.h
index 5e1cf07..ace81dc 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")
/* builtin functions or variables */
#ifndef TCC_ARM_EABI
diff --git a/tests/tests2/77_push_pop_macro.c b/tests/tests2/77_push_pop_macro.c
new file mode 100644
index 0000000..1f0b1bc
--- /dev/null
+++ b/tests/tests2/77_push_pop_macro.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int main()
+{
+ #define abort "111"
+ printf("abort = %s\n", abort);
+
+ #pragma push_macro("abort")
+ #undef abort
+ #define abort "222"
+ printf("abort = %s\n", abort);
+
+ #pragma push_macro("abort")
+ #undef abort
+ #define abort "333"
+ printf("abort = %s\n", abort);
+
+ #pragma pop_macro("abort")
+ printf("abort = %s\n", abort);
+
+ #pragma pop_macro("abort")
+ printf("abort = %s\n", abort);
+}
diff --git a/tests/tests2/77_push_pop_macro.expect b/tests/tests2/77_push_pop_macro.expect
new file mode 100644
index 0000000..d8a5530
--- /dev/null
+++ b/tests/tests2/77_push_pop_macro.expect
@@ -0,0 +1,5 @@
+abort = 111
+abort = 222
+abort = 333
+abort = 222
+abort = 111
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index a5a18fb..87daf7b 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -95,7 +95,8 @@ TESTS = \
73_arm64.test \
74_nocode_wanted.test \
75_array_in_struct_init.test \
- 76_dollars_in_identifiers.test
+ 76_dollars_in_identifiers.test \
+ 77_push_pop_macro.test
# 34_array_assignment.test -- array assignment is not in C standard