History

tccpp.c: fix GNU comma handling

This requires moving TOK_PLCHLDR handling, but the new logic should make things easier even if (when?) GNU comma handling is removed. (Somewhat confusingly, GCC no longer supports GNU commas. See http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html for a description of past and current GCC behaviour.)

Philip committed 11 years ago

Commit 2f90db41 parent 2f50cef2 files · +35 −19Browse files

Unified · Split

2 files
  1. tcc.h +1 −0
  2. tccpp.c +34 −19
tcc.h+1−0
@@ -880,6 +880,7 @@ struct TCCState { · 879 unmodified lines
880880 #define TOK_DOTS 0xcc /* three dots */
881881 #define TOK_SHR 0xcd /* unsigned shift right */
882882 #define TOK_NOSUBST 0xcf /* means following token has already been pp'd */
883+#define TOK_GNUCOMMA 0xd0 /* ,## preprocessing token */
883884
884885 #define TOK_SHL 0x01 /* shift left */
885886 #define TOK_SAR 0x02 /* signed shift right */
tccpp.c+34−19
@@ -2786,25 +2786,18 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 2785 unmodified lines
27862786 if (gnu_ext && s->type.t &&
27872787 last_tok == TOK_TWOSHARPS &&
27882788 str.len >= 2 && str.str[str.len - 2] == ',') {
2789− if (*st == TOK_PLCHLDR) {
2790− /* suppress ',' '##' */
2791− str.len -= 2;
2792− } else {
2793− /* suppress '##' and add variable */
2794− str.len--;
2795− goto add_var;
2796− }
2797− } else {
2789+ str.len -= 2;
2790+ tok_str_add(&str, TOK_GNUCOMMA);
2791+ }
2792+
2793+ for(;;) {
27982794 int t1;
2799− add_var:
2800− for(;;) {
2801− TOK_GET(&t1, &st, &cval);
2802− if (!t1)
2803− break;
2804− tok_str_add2(&str, t1, &cval);
2805− }
2795+ TOK_GET(&t1, &st, &cval);
2796+ if (!t1)
2797+ break;
2798+ tok_str_add2(&str, t1, &cval);
28062799 }
2807− } else if (*st != TOK_PLCHLDR) {
2800+ } else {
28082801 /* NOTE: the stream cannot be read when macro
28092802 substituing an argument */
28102803 macro_subst(&str, nested_list, st, NULL);
@@ -2817,6 +2810,8 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 6 unmodified lines
28172810 }
28182811 last_tok = t;
28192812 }
2813+ if (str.len == 0)
2814+ tok_str_add(&str, TOK_PLCHLDR);
28202815 tok_str_add(&str, 0);
28212816 return str.str;
28222817 }
@@ -2982,9 +2977,9 @@ static int macro_subst_tok(TokenString *tok_str, · 159 unmodified lines
29822977 tok_str_add2(&str, tok, &tokc);
29832978 next_nomacro_spc();
29842979 }
2985− if (!str.len)
2986− tok_str_add(&str, TOK_PLCHLDR);
29872980 str.len -= spc;
2981+ if (str.len == 0)
2982+ tok_str_add(&str, TOK_PLCHLDR);
29882983 tok_str_add(&str, 0);
29892984 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
29902985 sa1->d = str.str;
@@ -3123,6 +3118,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 132 unmodified lines
31233118 CValue cval;
31243119 struct macro_level ml;
31253120 int force_blank;
3121+ int gnucomma_index = -1;
31263122
31273123 /* first scan for '##' operator handling */
31283124 ptr = macro_str;
@@ -3150,8 +3146,16 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 21 unmodified lines
31503146 TOK_GET(&t, &ptr, &cval);
31513147 goto no_subst;
31523148 }
3149+ if (t == TOK_GNUCOMMA) {
3150+ if (gnucomma_index != -1)
3151+ tcc_error("two GNU commas in the same macro");
3152+ gnucomma_index = tok_str->len;
3153+ tok_str_add(tok_str, ',');
3154+ TOK_GET(&t, &ptr, &cval);
3155+ }
31533156 s = define_find(t);
31543157 if (s != NULL) {
3158+ int old_len = tok_str->len;
31553159 /* if nested substitution, do nothing */
31563160 if (sym_find2(*nested_list, t)) {
31573161 /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */
@@ -3171,6 +3175,8 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 13 unmodified lines
31713175 *can_read_stream = ml.prev;
31723176 if (parse_flags & PARSE_FLAG_SPACES)
31733177 force_blank = 1;
3178+ if (old_len == tok_str->len)
3179+ tok_str_add(tok_str, TOK_PLCHLDR);
31743180 } else {
31753181 no_subst:
31763182 if (force_blank) {
@@ -3181,6 +3187,15 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 4 unmodified lines
31813187 if (!check_space(t, &spc))
31823188 tok_str_add2(tok_str, t, &cval);
31833189 }
3190+ if (gnucomma_index != -1) {
3191+ if (tok_str->len >= gnucomma_index+2) {
3192+ if (tok_str->str[gnucomma_index+1] == TOK_PLCHLDR)
3193+ tok_str->len -= 2;
3194+ gnucomma_index = -1;
3195+ }
3196+ }
3197+ if (tok_str->len && tok_str->str[tok_str->len-1] == TOK_PLCHLDR)
3198+ tok_str->len--;
31843199 }
31853200 if (macro_str1)
31863201 tok_str_free(macro_str1);

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