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).
Unified · Split
| @@ -1114,7 +1114,6 @@ ST_FUNC void define_undef(Sym *s) · 1113 unmodified lines | |||
| 1114 | define_print(s, 1); | 1114 | define_print(s, 1); |
| 1115 | table_ident[v - TOK_IDENT]->sym_define = NULL; | 1115 | table_ident[v - TOK_IDENT]->sym_define = NULL; |
| 1116 | } | 1116 | } |
| 1117 | s->v = 0; | ||
| 1118 | } | 1117 | } |
| 1119 | 1118 | ||
| 1120 | ST_INLN Sym *define_find(int v) | 1119 | ST_INLN Sym *define_find(int v) |
| @@ -1378,9 +1377,7 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if · 257 unmodified lines | |||
| 1378 | 1377 | ||
| 1379 | static void pragma_parse(TCCState *s1) | 1378 | static void pragma_parse(TCCState *s1) |
| 1380 | { | 1379 | { |
| 1381 | int val; | 1380 | next_nomacro(); |
| 1382 | |||
| 1383 | next(); | ||
| 1384 | if (tok == TOK_pack) { | 1381 | if (tok == TOK_pack) { |
| 1385 | /* | 1382 | /* |
| 1386 | This may be: | 1383 | This may be: |
| @@ -1399,7 +1396,7 @@ static void pragma_parse(TCCState *s1) · 12 unmodified lines | |||
| 1399 | } | 1396 | } |
| 1400 | s1->pack_stack_ptr--; | 1397 | s1->pack_stack_ptr--; |
| 1401 | } else { | 1398 | } else { |
| 1402 | val = 0; | 1399 | int val = 0; |
| 1403 | if (tok != ')') { | 1400 | if (tok != ')') { |
| 1404 | if (tok == TOK_ASM_push) { | 1401 | if (tok == TOK_ASM_push) { |
| 1405 | next(); | 1402 | next(); |
| @@ -1408,18 +1405,17 @@ static void pragma_parse(TCCState *s1) · 2 unmodified lines | |||
| 1408 | s1->pack_stack_ptr++; | 1405 | s1->pack_stack_ptr++; |
| 1409 | skip(','); | 1406 | skip(','); |
| 1410 | } | 1407 | } |
| 1411 | if (tok != TOK_CINT) { | 1408 | if (tok != TOK_CINT) |
| 1412 | pack_error: | 1409 | goto pragma_err; |
| 1413 | tcc_error("invalid pack pragma"); | ||
| 1414 | } | ||
| 1415 | val = tokc.i; | 1410 | val = tokc.i; |
| 1416 | if (val < 1 || val > 16 || (val & (val - 1)) != 0) | 1411 | if (val < 1 || val > 16 || (val & (val - 1)) != 0) |
| 1417 | goto pack_error; | 1412 | goto pragma_err; |
| 1418 | next(); | 1413 | next(); |
| 1419 | } | 1414 | } |
| 1420 | *s1->pack_stack_ptr = val; | 1415 | *s1->pack_stack_ptr = val; |
| 1421 | skip(')'); | ||
| 1422 | } | 1416 | } |
| 1417 | if (tok != ')') | ||
| 1418 | goto pragma_err; | ||
| 1423 | } else if (tok == TOK_comment) { | 1419 | } else if (tok == TOK_comment) { |
| 1424 | if (s1->ms_extensions) { | 1420 | if (s1->ms_extensions) { |
| 1425 | next(); | 1421 | next(); |
| @@ -1446,11 +1442,40 @@ static void pragma_parse(TCCState *s1) · 20 unmodified lines | |||
| 1446 | } else { | 1442 | } else { |
| 1447 | tcc_warning("#pragma comment(lib) is ignored"); | 1443 | tcc_warning("#pragma comment(lib) is ignored"); |
| 1448 | } | 1444 | } |
| 1445 | } else if (tok == TOK_push_macro || tok == TOK_pop_macro) { | ||
| 1446 | int t = tok, v; | ||
| 1447 | Sym *s; | ||
| 1448 | |||
| 1449 | if (next_nomacro(), tok != '(') | ||
| 1450 | goto pragma_err; | ||
| 1451 | if (next_nomacro(), tok != TOK_STR) | ||
| 1452 | goto pragma_err; | ||
| 1453 | v = tok_alloc(tokc.cstr->data, tokc.cstr->size - 1)->tok; | ||
| 1454 | if (next_nomacro(), tok != ')') | ||
| 1455 | goto pragma_err; | ||
| 1456 | if (t == TOK_push_macro) { | ||
| 1457 | while (NULL == (s = define_find(v))) | ||
| 1458 | define_push(v, 0, NULL, NULL); | ||
| 1459 | s->type.ref = s; /* set push boundary */ | ||
| 1460 | } else { | ||
| 1461 | for (s = define_stack; s; s = s->prev) | ||
| 1462 | if (s->v == v && s->type.ref == s) { | ||
| 1463 | s->type.ref = NULL; | ||
| 1464 | break; | ||
| 1465 | } | ||
| 1466 | } | ||
| 1467 | if (s) | ||
| 1468 | table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL; | ||
| 1469 | else | ||
| 1470 | tcc_warning("unbalanced #pragma pop_macro"); | ||
| 1449 | } else if (tok == TOK_once) { | 1471 | } else if (tok == TOK_once) { |
| 1450 | add_cached_include(s1, file->filename, TOK_once); | 1472 | add_cached_include(s1, file->filename, TOK_once); |
| 1451 | } else { | 1473 | } else { |
| 1452 | tcc_warning("unknown #pragma %s", get_tok_str(tok, &tokc)); | 1474 | tcc_warning("unknown #pragma %s", get_tok_str(tok, &tokc)); |
| 1453 | } | 1475 | } |
| 1476 | return; | ||
| 1477 | pragma_err: | ||
| 1478 | tcc_error("malformed #pragma directive"); | ||
| 1454 | } | 1479 | } |
| 1455 | 1480 | ||
| 1456 | /* is_bof is true if first non space token at beginning of file */ | 1481 | /* is_bof is true if first non space token at beginning of file */ |
| @@ -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 | DEF(TOK_once, "once") | 160 | DEF(TOK_once, "once") |
| 159 | 161 | ||
| 160 | /* builtin functions or variables */ | 162 | /* builtin functions or variables */ |