History

tccpp: Implement __COUNTER__

This requires one more change in how macro arguments are expanded: the standard requires that macro args are expanded before substituting into the replacement list. This implies expanding them only once even when they occur multiple times in the list. TCC expanded them repeatedly in that case. Without __COUNTER__ that's harmless. So, simply always expand arguments (when used without # and ##) once and store the resulting tokens.

Michael Matz committed 9 years ago

Commit 824dceb1 parent 1f3d3955 files · +72 −11Browse files

Unified · Split

5 files
  1. libtcc.c +1 −0
  2. tccpp.c +28 −11
  3. tcctok.h +1 −0
  4. tests/pp/pp-counter.c +27 −0
  5. tests/pp/pp-counter.expect +15 −0
libtcc.c+1−0
@@ -762,6 +762,7 @@ LIBTCCAPI TCCState *tcc_new(void) · 761 unmodified lines
762762 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
763763 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
764764 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
765+ define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
765766 {
766767 /* define __TINYC__ 92X */
767768 char buffer[32]; int a,b,c;
tccpp.c+28−11
@@ -2980,18 +2980,29 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 2979 unmodified lines
29802980 str.len--;
29812981 goto add_var;
29822982 }
2983− } else {
2984− for(;;) {
2985− int t1;
2986− TOK_GET(&t1, &st, &cval);
2987− if (t1 <= 0)
2988− break;
2989− tok_str_add2(&str, t1, &cval);
2990− }
29912983 }
29922984 } else {
29932985 add_var:
2994− macro_subst(&str, nested_list, st);
2986+ if (!s->next) {
2987+ /* Expand arguments tokens and store them. In most
2988+ cases we could also re-expand each argument if
2989+ used multiple times, but not if the argument
2990+ contains the __COUNTER__ macro. */
2991+ TokenString str2;
2992+ sym_push2(&s->next, s->v, s->type.t, 0);
2993+ tok_str_new(&str2);
2994+ macro_subst(&str2, nested_list, st);
2995+ tok_str_add(&str2, 0);
2996+ s->next->d = str2.str;
2997+ }
2998+ st = s->next->d;
2999+ }
3000+ for(;;) {
3001+ int t2;
3002+ TOK_GET(&t2, &st, &cval);
3003+ if (t2 <= 0)
3004+ break;
3005+ tok_str_add2(&str, t2, &cval);
29953006 }
29963007 if (str.len == l0) /* expanded to empty string */
29973008 tok_str_add(&str, TOK_PLCHLDR);
@@ -3180,11 +3191,13 @@ static int macro_subst_tok( · 182 unmodified lines
31803191 CValue cval;
31813192 CString cstr;
31823193 char buf[32];
3194+ static int counter;
31833195
31843196 /* if symbol is a macro, prepare substitution */
31853197 /* special macros */
3186− if (tok == TOK___LINE__) {
3187− snprintf(buf, sizeof(buf), "%d", file->line_num);
3198+ if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
3199+ t = tok == TOK___LINE__ ? file->line_num : counter++;
3200+ snprintf(buf, sizeof(buf), "%d", t);
31883201 cstrval = buf;
31893202 t1 = TOK_PPNUM;
31903203 goto add_cstr1;
@@ -3316,6 +3329,10 @@ static int macro_subst_tok( · 125 unmodified lines
33163329 while (sa) {
33173330 sa1 = sa->prev;
33183331 tok_str_free_str(sa->d);
3332+ if (sa->next) {
3333+ tok_str_free_str(sa->next->d);
3334+ sym_free(sa->next);
3335+ }
33193336 sym_free(sa);
33203337 sa = sa1;
33213338 }
tcctok.h+1−0
@@ -87,6 +87,7 @@ · 86 unmodified lines
8787 DEF(TOK___TIME__, "__TIME__")
8888 DEF(TOK___FUNCTION__, "__FUNCTION__")
8989 DEF(TOK___VA_ARGS__, "__VA_ARGS__")
90+ DEF(TOK___COUNTER__, "__COUNTER__")
9091
9192 /* special identifiers */
9293 DEF(TOK___FUNC__, "__func__")
tests/pp/pp-counter.c+27−0
@@ -0,0 +1,27 @@
1+X1 __COUNTER__
2+X2 __COUNTER__
3+#if __COUNTER__
4+X3 __COUNTER__
5+#endif
6+#define pass(x) x
7+#define a x __COUNTER__ y
8+#define a2 pass(__COUNTER__)
9+#define f(c) c __COUNTER__
10+#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__
11+#define _paste(a,b) a ## b
12+#define paste(a,b) _paste(a,b)
13+#define _paste3(a,b,c) a ## b ## c
14+#define doublepaste(a,b) _paste3(a,b,b)
15+#define str(x) #x
16+X4 a
17+X5 f(a)
18+X6 f(b)
19+X7 f(__COUNTER__)
20+X8 apply(a)
21+X9 apply(f(a))
22+X10 apply(__COUNTER__)
23+X11 apply(a2)
24+X12 str(__COUNTER__)
25+X13 paste(x,__COUNTER__)
26+X14 _paste(x,__COUNTER__)
27+X15 doublepaste(x,__COUNTER__)
tests/pp/pp-counter.expect+15−0
@@ -0,0 +1,15 @@
1+X1 0
2+X2 1
3+X3 3
4+X4 x 4 y
5+X5 x 5 y 6
6+X6 b 7
7+X7 8 9
8+X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13
9+X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18
10+X10 19 19 20 x2 19 21 y2 22
11+X11 23 23 24 x2 23 25 y2 26
12+X12 "__COUNTER__"
13+X13 x27
14+X14 x__COUNTER__
15+X15 x2828

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