The above pragmas are used in the mingw headers. Thise pragmas are implemented in gcc-4.5+ and current clang.
Unified · Split
| @@ -326,6 +326,7 @@ · 325 unmodified lines | |||
| 326 | typedef struct TokenSym { | 326 | typedef struct TokenSym { |
| 327 | struct TokenSym *hash_next; | 327 | struct TokenSym *hash_next; |
| 328 | struct Sym *sym_define; /* direct pointer to define */ | 328 | struct Sym *sym_define; /* direct pointer to define */ |
| 329 | struct Sym *sym_define_stack; /* direct pointer to a push_macro stack */ | ||
| 329 | struct Sym *sym_label; /* direct pointer to label */ | 330 | struct Sym *sym_label; /* direct pointer to label */ |
| 330 | struct Sym *sym_struct; /* direct pointer to structure */ | 331 | struct Sym *sym_struct; /* direct pointer to structure */ |
| 331 | struct Sym *sym_identifier; /* direct pointer to identifier */ | 332 | struct Sym *sym_identifier; /* direct pointer to identifier */ |
| @@ -292,7 +292,7 @@ static void asm_free_labels(TCCState *st) · 291 unmodified lines | |||
| 292 | { | 292 | { |
| 293 | Sym *s, *s1; | 293 | Sym *s, *s1; |
| 294 | Section *sec; | 294 | Section *sec; |
| 295 | 295 | ||
| 296 | for(s = st->asm_labels; s != NULL; s = s1) { | 296 | for(s = st->asm_labels; s != NULL; s = s1) { |
| 297 | s1 = s->prev; | 297 | s1 = s->prev; |
| 298 | /* define symbol value in object file */ | 298 | /* define symbol value in object file */ |
| @@ -305,6 +305,9 @@ static void asm_free_labels(TCCState *st) · 6 unmodified lines | |||
| 305 | } | 305 | } |
| 306 | /* remove label */ | 306 | /* remove label */ |
| 307 | table_ident[s->v - TOK_IDENT]->sym_label = NULL; | 307 | table_ident[s->v - TOK_IDENT]->sym_label = NULL; |
| 308 | if (s->asm_label) { | ||
| 309 | tcc_free(s->asm_label); | ||
| 310 | } | ||
| 308 | sym_free(s); | 311 | sym_free(s); |
| 309 | } | 312 | } |
| 310 | st->asm_labels = NULL; | 313 | st->asm_labels = NULL; |
| @@ -152,7 +152,6 @@ static inline Sym *sym_malloc(void) · 151 unmodified lines | |||
| 152 | ST_INLN void sym_free(Sym *sym) | 152 | ST_INLN void sym_free(Sym *sym) |
| 153 | { | 153 | { |
| 154 | sym->next = sym_free_first; | 154 | sym->next = sym_free_first; |
| 155 | tcc_free(sym->asm_label); | ||
| 156 | sym_free_first = sym; | 155 | sym_free_first = sym; |
| 157 | } | 156 | } |
| 158 | 157 | ||
| @@ -222,6 +222,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) · 221 unmodified lines | |||
| 222 | table_ident[i] = ts; | 222 | table_ident[i] = ts; |
| 223 | ts->tok = tok_ident++; | 223 | ts->tok = tok_ident++; |
| 224 | ts->sym_define = NULL; | 224 | ts->sym_define = NULL; |
| 225 | ts->sym_define_stack = NULL; | ||
| 225 | ts->sym_label = NULL; | 226 | ts->sym_label = NULL; |
| 226 | ts->sym_struct = NULL; | 227 | ts->sym_struct = NULL; |
| 227 | ts->sym_identifier = NULL; | 228 | ts->sym_identifier = NULL; |
| @@ -1446,6 +1447,39 @@ static void pragma_parse(TCCState *s1) · 1218 unmodified lines | |||
| 1446 | } else { | 1447 | } else { |
| 1447 | tcc_warning("#pragma comment(lib) is ignored"); | 1448 | tcc_warning("#pragma comment(lib) is ignored"); |
| 1448 | } | 1449 | } |
| 1450 | } else if ((tok == TOK_push_macro) || (tok == TOK_pop_macro)) { | ||
| 1451 | int push_macro = (tok == TOK_push_macro); | ||
| 1452 | next(); | ||
| 1453 | skip('('); | ||
| 1454 | if (tok != TOK_STR) { | ||
| 1455 | expect("\""); | ||
| 1456 | } else { | ||
| 1457 | int len = strlen((char *)tokc.cstr->data); | ||
| 1458 | tcc_open_bf(s1, "<push_pop_macro>", len); | ||
| 1459 | memcpy(file->buffer, tokc.cstr->data, len); | ||
| 1460 | ch = file->buf_ptr[0]; | ||
| 1461 | next_nomacro(); | ||
| 1462 | if (tok >= TOK_IDENT) { | ||
| 1463 | Sym *s = table_ident[tok - TOK_IDENT]->sym_define; | ||
| 1464 | Sym *ss = table_ident[tok - TOK_IDENT]->sym_define_stack; | ||
| 1465 | if (push_macro) { | ||
| 1466 | if (s) { | ||
| 1467 | s->prev_tok = ss; | ||
| 1468 | table_ident[tok - TOK_IDENT]->sym_define_stack = s; | ||
| 1469 | } | ||
| 1470 | } else { | ||
| 1471 | if (ss) { | ||
| 1472 | table_ident[tok - TOK_IDENT]->sym_define = ss; | ||
| 1473 | table_ident[tok - TOK_IDENT]->sym_define_stack = ss->prev_tok; | ||
| 1474 | } | ||
| 1475 | } | ||
| 1476 | } | ||
| 1477 | tcc_close(); | ||
| 1478 | } | ||
| 1479 | next(); | ||
| 1480 | skip(')'); | ||
| 1481 | } else { | ||
| 1482 | tcc_warning("unknown #pragma %s", get_tok_str(tok, &tokc)); | ||
| 1449 | } | 1483 | } |
| 1450 | } | 1484 | } |
| 1451 | 1485 | ||
| @@ -155,6 +155,8 @@ · 154 unmodified lines | |||
| 155 | #endif | 155 | #endif |
| 156 | DEF(TOK_comment, "comment") | 156 | DEF(TOK_comment, "comment") |
| 157 | DEF(TOK_lib, "lib") | 157 | DEF(TOK_lib, "lib") |
| 158 | DEF(TOK_push_macro, "push_macro") | ||
| 159 | DEF(TOK_pop_macro, "pop_macro") | ||
| 158 | 160 | ||
| 159 | /* builtin functions or variables */ | 161 | /* builtin functions or variables */ |
| 160 | #ifndef TCC_ARM_EABI | 162 | #ifndef TCC_ARM_EABI |
| @@ -0,0 +1,23 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | int main() | ||
| 4 | { | ||
| 5 | #define abort "111" | ||
| 6 | printf("abort = %s\n", abort); | ||
| 7 | |||
| 8 | #pragma push_macro("abort") | ||
| 9 | #undef abort | ||
| 10 | #define abort "222" | ||
| 11 | printf("abort = %s\n", abort); | ||
| 12 | |||
| 13 | #pragma push_macro("abort") | ||
| 14 | #undef abort | ||
| 15 | #define abort "333" | ||
| 16 | printf("abort = %s\n", abort); | ||
| 17 | |||
| 18 | #pragma pop_macro("abort") | ||
| 19 | printf("abort = %s\n", abort); | ||
| 20 | |||
| 21 | #pragma pop_macro("abort") | ||
| 22 | printf("abort = %s\n", abort); | ||
| 23 | } | ||
| @@ -0,0 +1,5 @@ | |||
| 1 | abort = 111 | ||
| 2 | abort = 222 | ||
| 3 | abort = 333 | ||
| 4 | abort = 222 | ||
| 5 | abort = 111 | ||
| @@ -95,7 +95,8 @@ TESTS = \ · 94 unmodified lines | |||
| 95 | 73_arm64.test \ | 95 | 73_arm64.test \ |
| 96 | 74_nocode_wanted.test \ | 96 | 74_nocode_wanted.test \ |
| 97 | 75_array_in_struct_init.test \ | 97 | 75_array_in_struct_init.test \ |
| 98 | 76_dollars_in_identifiers.test | 98 | 76_dollars_in_identifiers.test \ |
| 99 | 77_push_pop_macro.test | ||
| 99 | 100 | ||
| 100 | # 34_array_assignment.test -- array assignment is not in C standard | 101 | # 34_array_assignment.test -- array assignment is not in C standard |
| 101 | 102 | ||