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
880#define TOK_DOTS 0xcc /* three dots */880#define TOK_DOTS 0xcc /* three dots */
881#define TOK_SHR 0xcd /* unsigned shift right */881#define TOK_SHR 0xcd /* unsigned shift right */
882#define TOK_NOSUBST 0xcf /* means following token has already been pp'd */882#define TOK_NOSUBST 0xcf /* means following token has already been pp'd */
883#define TOK_GNUCOMMA 0xd0 /* ,## preprocessing token */
883 884
884#define TOK_SHL 0x01 /* shift left */885#define TOK_SHL 0x01 /* shift left */
885#define TOK_SAR 0x02 /* signed shift right */886#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
2786 if (gnu_ext && s->type.t &&2786 if (gnu_ext && s->type.t &&
2787 last_tok == TOK_TWOSHARPS && 2787 last_tok == TOK_TWOSHARPS &&
2788 str.len >= 2 && str.str[str.len - 2] == ',') {2788 str.len >= 2 && str.str[str.len - 2] == ',') {
2789 if (*st == TOK_PLCHLDR) {2789 str.len -= 2;
2790 /* suppress ',' '##' */2790 tok_str_add(&str, TOK_GNUCOMMA);
2791 str.len -= 2;2791 }
2792 } else {2792
2793 /* suppress '##' and add variable */2793 for(;;) {
2794 str.len--;
2795 goto add_var;
2796 }
2797 } else {
2798 int t1;2794 int t1;
2799 add_var:2795 TOK_GET(&t1, &st, &cval);
2800 for(;;) {2796 if (!t1)
2801 TOK_GET(&t1, &st, &cval);2797 break;
2802 if (!t1)2798 tok_str_add2(&str, t1, &cval);
2803 break;
2804 tok_str_add2(&str, t1, &cval);
2805 }
2806 }2799 }
2807 } else if (*st != TOK_PLCHLDR) {2800 } else {
2808 /* NOTE: the stream cannot be read when macro2801 /* NOTE: the stream cannot be read when macro
2809 substituing an argument */2802 substituing an argument */
2810 macro_subst(&str, nested_list, st, NULL);2803 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
2817 }2810 }
2818 last_tok = t;2811 last_tok = t;
2819 }2812 }
2813 if (str.len == 0)
2814 tok_str_add(&str, TOK_PLCHLDR);
2820 tok_str_add(&str, 0);2815 tok_str_add(&str, 0);
2821 return str.str;2816 return str.str;
2822}2817}
@@ -2982,9 +2977,9 @@ static int macro_subst_tok(TokenString *tok_str, · 159 unmodified lines
2982 tok_str_add2(&str, tok, &tokc);2977 tok_str_add2(&str, tok, &tokc);
2983 next_nomacro_spc();2978 next_nomacro_spc();
2984 }2979 }
2985 if (!str.len)
2986 tok_str_add(&str, TOK_PLCHLDR);
2987 str.len -= spc;2980 str.len -= spc;
2981 if (str.len == 0)
2982 tok_str_add(&str, TOK_PLCHLDR);
2988 tok_str_add(&str, 0);2983 tok_str_add(&str, 0);
2989 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);2984 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
2990 sa1->d = str.str;2985 sa1->d = str.str;
@@ -3123,6 +3118,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 132 unmodified lines
3123 CValue cval;3118 CValue cval;
3124 struct macro_level ml;3119 struct macro_level ml;
3125 int force_blank;3120 int force_blank;
3121 int gnucomma_index = -1;
3126 3122
3127 /* first scan for '##' operator handling */3123 /* first scan for '##' operator handling */
3128 ptr = macro_str;3124 ptr = macro_str;
@@ -3150,8 +3146,16 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 21 unmodified lines
3150 TOK_GET(&t, &ptr, &cval);3146 TOK_GET(&t, &ptr, &cval);
3151 goto no_subst;3147 goto no_subst;
3152 }3148 }
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 }
3153 s = define_find(t);3156 s = define_find(t);
3154 if (s != NULL) {3157 if (s != NULL) {
3158 int old_len = tok_str->len;
3155 /* if nested substitution, do nothing */3159 /* if nested substitution, do nothing */
3156 if (sym_find2(*nested_list, t)) {3160 if (sym_find2(*nested_list, t)) {
3157 /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */3161 /* 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
3171 *can_read_stream = ml.prev;3175 *can_read_stream = ml.prev;
3172 if (parse_flags & PARSE_FLAG_SPACES)3176 if (parse_flags & PARSE_FLAG_SPACES)
3173 force_blank = 1;3177 force_blank = 1;
3178 if (old_len == tok_str->len)
3179 tok_str_add(tok_str, TOK_PLCHLDR);
3174 } else {3180 } else {
3175 no_subst:3181 no_subst:
3176 if (force_blank) {3182 if (force_blank) {
@@ -3181,6 +3187,15 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 4 unmodified lines
3181 if (!check_space(t, &spc)) 3187 if (!check_space(t, &spc))
3182 tok_str_add2(tok_str, t, &cval);3188 tok_str_add2(tok_str, t, &cval);
3183 }3189 }
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--;
3184 }3199 }
3185 if (macro_str1)3200 if (macro_str1)
3186 tok_str_free(macro_str1);3201 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