History

tccasm: Don't ignore # in preprocessor directives

Our preprocessor throws away # line-comments in asm mode. It did so also inside preprocessor directives, thereby removing stringification. Parse defines in non-asm mode (but retain '.' as identifier character inside macro definitions).

Michael Matz committed 10 years ago

Commit dd57a341 parent e7ef0874 files · +50 −26Browse files

Unified · Split

4 files
  1. tcc.h +6 −0
  2. tccasm.c +2 −0
  3. tccpp.c +24 −21
  4. tests/asmtest.S +18 −5
tcc.h+6−0
@@ -1175,10 +1175,16 @@ ST_DATA TokenSym **table_ident; · 1174 unmodified lines
1175#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */1175#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */
1176#define PARSE_FLAG_TOK_STR 0x0040 /* return parsed strings instead of TOK_PPSTR */1176#define PARSE_FLAG_TOK_STR 0x0040 /* return parsed strings instead of TOK_PPSTR */
1177 1177
1178/* isidnum_table flags: */
1179#define IS_SPC 1
1180#define IS_ID 2
1181#define IS_NUM 4
1182
1178ST_FUNC TokenSym *tok_alloc(const char *str, int len);1183ST_FUNC TokenSym *tok_alloc(const char *str, int len);
1179ST_FUNC const char *get_tok_str(int v, CValue *cv);1184ST_FUNC const char *get_tok_str(int v, CValue *cv);
1180ST_FUNC void begin_macro(TokenString *str, int alloc);1185ST_FUNC void begin_macro(TokenString *str, int alloc);
1181ST_FUNC void end_macro(void);1186ST_FUNC void end_macro(void);
1187ST_FUNC void set_idnum(int c, int val);
1182ST_FUNC void save_parse_state(ParseState *s);1188ST_FUNC void save_parse_state(ParseState *s);
1183ST_FUNC void restore_parse_state(ParseState *s);1189ST_FUNC void restore_parse_state(ParseState *s);
1184ST_INLN void tok_str_new(TokenString *s);1190ST_INLN void tok_str_new(TokenString *s);
tccasm.c+2−0
@@ -916,6 +916,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess) · 915 unmodified lines
916 ch = file->buf_ptr[0];916 ch = file->buf_ptr[0];
917 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;917 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
918 parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;918 parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
919 set_idnum('.', IS_ID);
919 if (do_preprocess)920 if (do_preprocess)
920 parse_flags |= PARSE_FLAG_PREPROCESS;921 parse_flags |= PARSE_FLAG_PREPROCESS;
921 next();922 next();
@@ -1036,6 +1037,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len) · 114 unmodified lines
1036 tcc_close();1037 tcc_close();
1037 1038
1038 parse_flags = saved_parse_flags;1039 parse_flags = saved_parse_flags;
1040 set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
1039 macro_ptr = saved_macro_ptr;1041 macro_ptr = saved_macro_ptr;
1040}1042}
1041 1043
tccpp.c+24−21
@@ -53,11 +53,6 @@ static struct TinyAlloc *toksym_alloc; · 52 unmodified lines
53static struct TinyAlloc *tokstr_alloc;53static struct TinyAlloc *tokstr_alloc;
54static struct TinyAlloc *cstr_alloc;54static struct TinyAlloc *cstr_alloc;
55 55
56/* isidnum_table flags: */
57#define IS_SPC 1
58#define IS_ID 2
59#define IS_NUM 4
60
61static TokenString *macro_stack;56static TokenString *macro_stack;
62 57
63static const char tcc_keywords[] = 58static const char tcc_keywords[] =
@@ -819,6 +814,11 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p) · 755 unmodified lines
819 return p;814 return p;
820}815}
821 816
817ST_FUNC void set_idnum(int c, int val)
818{
819 isidnum_table[c - CH_EOF] = val;
820}
821
822#define cinp minp822#define cinp minp
823 823
824static inline void skip_spaces(void)824static inline void skip_spaces(void)
@@ -1453,13 +1453,15 @@ ST_FUNC void parse_define(void) · 628 unmodified lines
1453 /* XXX: should check if same macro (ANSI) */1453 /* XXX: should check if same macro (ANSI) */
1454 first = NULL;1454 first = NULL;
1455 t = MACRO_OBJ;1455 t = MACRO_OBJ;
1456 /* We have to parse the whole define as if not in asm mode, in particular
1457 no line comment with '#' must be ignored. Also for function
1458 macros the argument list must be parsed without '.' being an ID
1459 character. */
1460 parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
1456 /* '(' must be just after macro definition for MACRO_FUNC */1461 /* '(' must be just after macro definition for MACRO_FUNC */
1457 parse_flags |= PARSE_FLAG_SPACES;
1458 next_nomacro_spc();1462 next_nomacro_spc();
1459 if (tok == '(') {1463 if (tok == '(') {
1460 /* must be able to parse TOK_DOTS (in asm mode '.' can be part of identifier) */1464 set_idnum('.', 0);
1461 parse_flags &= ~PARSE_FLAG_ASM_FILE;
1462 isidnum_table['.' - CH_EOF] = 0;
1463 next_nomacro();1465 next_nomacro();
1464 ps = &first;1466 ps = &first;
1465 if (tok != ')') for (;;) {1467 if (tok != ')') for (;;) {
@@ -1487,14 +1489,17 @@ ST_FUNC void parse_define(void) · 21 unmodified lines
1487 }1489 }
1488 next_nomacro_spc();1490 next_nomacro_spc();
1489 t = MACRO_FUNC;1491 t = MACRO_FUNC;
1490 parse_flags |= (saved_parse_flags & PARSE_FLAG_ASM_FILE);
1491 isidnum_table['.' - CH_EOF] =
1492 (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0;
1493 }1492 }
1494 1493
1495 tokstr_buf.len = 0;1494 tokstr_buf.len = 0;
1496 spc = 2;1495 spc = 2;
1497 parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;1496 parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
1497 /* The body of a macro definition should be parsed such that identifiers
1498 are parsed like the file mode determines (i.e. with '.' being an
1499 ID character in asm mode). But '#' should be retained instead of
1500 regarded as line comment leader, so still don't set ASM_FILE
1501 in parse_flags. */
1502 set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
1498 while (tok != TOK_LINEFEED && tok != TOK_EOF) {1503 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1499 /* remove spaces around ## and after '#' */1504 /* remove spaces around ## and after '#' */
1500 if (TOK_TWOSHARPS == tok) {1505 if (TOK_TWOSHARPS == tok) {
@@ -2673,7 +2678,7 @@ maybe_newline: · 1172 unmodified lines
2673 if (isnum(c)) {2678 if (isnum(c)) {
2674 t = '.';2679 t = '.';
2675 goto parse_num;2680 goto parse_num;
2676 } else if ((parse_flags & PARSE_FLAG_ASM_FILE)2681 } else if ((isidnum_table['.' - CH_EOF] & IS_ID)
2677 && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {2682 && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
2678 *--p = c = '.';2683 *--p = c = '.';
2679 goto parse_ident_fast;2684 goto parse_ident_fast;
@@ -3470,10 +3475,8 @@ ST_FUNC void preprocess_start(TCCState *s1) · 790 unmodified lines
3470 s1->pack_stack[0] = 0;3475 s1->pack_stack[0] = 0;
3471 s1->pack_stack_ptr = s1->pack_stack;3476 s1->pack_stack_ptr = s1->pack_stack;
3472 3477
3473 isidnum_table['$' - CH_EOF] =3478 set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
3474 s1->dollars_in_identifiers ? IS_ID : 0;3479 set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
3475 isidnum_table['.' - CH_EOF] =
3476 (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0;
3477 buf = tcc_malloc(3 + strlen(file->filename));3480 buf = tcc_malloc(3 + strlen(file->filename));
3478 sprintf(buf, "\"%s\"", file->filename);3481 sprintf(buf, "\"%s\"", file->filename);
3479 tcc_undefine_symbol(s1, "__BASE_FILE__");3482 tcc_undefine_symbol(s1, "__BASE_FILE__");
@@ -3505,14 +3508,14 @@ ST_FUNC void tccpp_new(TCCState *s) · 25 unmodified lines
3505 3508
3506 /* init isid table */3509 /* init isid table */
3507 for(i = CH_EOF; i<128; i++)3510 for(i = CH_EOF; i<128; i++)
3508 isidnum_table[i - CH_EOF]3511 set_idnum(i,
3509 = is_space(i) ? IS_SPC3512 is_space(i) ? IS_SPC
3510 : isid(i) ? IS_ID3513 : isid(i) ? IS_ID
3511 : isnum(i) ? IS_NUM3514 : isnum(i) ? IS_NUM
3512 : 0;3515 : 0);
3513 3516
3514 for(i = 128; i<256; i++)3517 for(i = 128; i<256; i++)
3515 isidnum_table[i - CH_EOF] = IS_ID;3518 set_idnum(i, IS_ID);
3516 3519
3517 /* init allocators */3520 /* init allocators */
3518 tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);3521 tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
tests/asmtest.S+18−5
@@ -16,10 +16,17 @@ · 15 unmodified lines
16 .skip 316 .skip 3
17 .skip 15, 0x9017 .skip 15, 0x90
18 .string "hello\0world"18 .string "hello\0world"
19 19/* Macro expansion should work like with C, the #n shouldn't be parsed
20 as asm line comment */
21#define __stringify(n) #n
22#define stringify(n) __stringify(n)
23 .skip 8,0x90
24 .asciz stringify(BLA)
25 .skip 8,0x90
26
27# 28 "asmtest.S" # a line directive (and a line comment)
28 movl %eax, %ebx # some more asm comment
20/* some label tests */29/* some label tests */
21
22 movl %eax, %ebx
23L1:30L1:
24 movl %eax, %ebx31 movl %eax, %ebx
25 mov 0x10000, %eax32 mov 0x10000, %eax
@@ -572,8 +579,8 @@ int $0x10 · 546 unmodified lines
572 pusha579 pusha
573 popa580 popa
574#endif581#endif
575 clc582 clc # another comment
576 cld583 cld # a comment with embedded ' tick
577 cli584 cli
578 clts585 clts
579 cmc586 cmc
@@ -676,8 +683,10 @@ int $0x10 · 96 unmodified lines
676 lar %eax,%dx683 lar %eax,%dx
677 lar %ax,%edx684 lar %ax,%edx
678 lar %eax,%edx685 lar %eax,%edx
686#ifdef __x86_64__
679 lar %ax,%rdx687 lar %ax,%rdx
680 lar %eax,%rdx688 lar %eax,%rdx
689#endif
681 emms690 emms
682 movd %edx, %mm3691 movd %edx, %mm3
683 movd 0x1000, %mm2692 movd 0x1000, %mm2
@@ -820,7 +829,11 @@ nop · 136 unmodified lines
820 .long 145 + 2b829 .long 145 + 2b
821 .word 164, 0830 .word 164, 0
822 .org 2b+32831 .org 2b+32
832#ifdef __x86_64__
823 .quad 1b833 .quad 1b
834#else
835 .long 1b
836#endif
824.popsection837.popsection
8253: mov %eax,%ecx8383: mov %eax,%ecx
8264:8394:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t