tcc -E -P do not output a #line directive, a gcc compatible option tcc -E -P1 don't follow a gcc preprocessor style and do output a standard #line directive. In such case we don't lose a location info when we going to compile a resulting file wtith a compiler not understanding a gnu style line info.
Unified · Split
| @@ -1647,6 +1647,7 @@ enum { · 1646 unmodified lines | ||
| 1647 | 1647 | TCC_OPTION_I, |
| 1648 | 1648 | TCC_OPTION_D, |
| 1649 | 1649 | TCC_OPTION_U, |
| 1650 | + TCC_OPTION_P, | |
| 1650 | 1651 | TCC_OPTION_L, |
| 1651 | 1652 | TCC_OPTION_B, |
| 1652 | 1653 | TCC_OPTION_l, |
| @@ -1695,6 +1696,7 @@ static const TCCOption tcc_options[] = { · 42 unmodified lines | ||
| 1695 | 1696 | { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, |
| 1696 | 1697 | { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, |
| 1697 | 1698 | { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, |
| 1699 | + { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | |
| 1698 | 1700 | { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, |
| 1699 | 1701 | { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, |
| 1700 | 1702 | { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| @@ -1930,6 +1932,9 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 229 unmodified lines | ||
| 1930 | 1932 | tcc_warning("-E: some compiler action already specified (%d)", s->output_type); |
| 1931 | 1933 | s->output_type = TCC_OUTPUT_PREPROCESS; |
| 1932 | 1934 | break; |
| 1935 | + case TCC_OPTION_P: | |
| 1936 | + s->Pflag = atoi(optarg) + 1; | |
| 1937 | + break; | |
| 1933 | 1938 | case TCC_OPTION_MD: |
| 1934 | 1939 | s->gen_deps = 1; |
| 1935 | 1940 | break; |
| @@ -45,6 +45,8 @@ static void help(void) · 44 unmodified lines | ||
| 45 | 45 | " -Idir add include path 'dir'\n" |
| 46 | 46 | " -Dsym[=val] define 'sym' with value 'val'\n" |
| 47 | 47 | " -Usym undefine 'sym'\n" |
| 48 | + " -P do not output a #line directive\n" | |
| 49 | + " -P1 use a #line directive in output instead of the gcc style\n" | |
| 48 | 50 | "Linker options:\n" |
| 49 | 51 | " -Ldir add library path 'dir'\n" |
| 50 | 52 | " -llib link with dynamic or static library 'lib'\n" |
| @@ -656,6 +656,11 @@ struct TCCState { · 655 unmodified lines | ||
| 656 | 656 | |
| 657 | 657 | /* output file for preprocessing (-E) */ |
| 658 | 658 | FILE *ppfp; |
| 659 | + enum { | |
| 660 | + LINE_MACRO_OUTPUT_FORMAT_GCC, | |
| 661 | + LINE_MACRO_OUTPUT_FORMAT_NONE, | |
| 662 | + LINE_MACRO_OUTPUT_FORMAT_STD, | |
| 663 | + } Pflag; | |
| 659 | 664 | |
| 660 | 665 | /* for -MD/-MF: collected dependencies for this compilation */ |
| 661 | 666 | char **target_deps; |
| @@ -3133,6 +3133,26 @@ ST_FUNC void preprocess_new(void) · 3132 unmodified lines | ||
| 3133 | 3133 | } |
| 3134 | 3134 | } |
| 3135 | 3135 | |
| 3136 | +static void line_macro_output(BufferedFile *f, const char *s, TCCState *s1) | |
| 3137 | +{ | |
| 3138 | + switch (s1->Pflag) { | |
| 3139 | + case LINE_MACRO_OUTPUT_FORMAT_STD: | |
| 3140 | + /* "tcc -E -P1" case */ | |
| 3141 | + fprintf(s1->ppfp, "# line %d \"%s\"\n", f->line_num, f->filename); | |
| 3142 | + break; | |
| 3143 | + | |
| 3144 | + case LINE_MACRO_OUTPUT_FORMAT_NONE: | |
| 3145 | + /* "tcc -E -P" case: don't output a line directive */ | |
| 3146 | + break; | |
| 3147 | + | |
| 3148 | + case LINE_MACRO_OUTPUT_FORMAT_GCC: | |
| 3149 | + default: | |
| 3150 | + /* "tcc -E" case: a gcc standard by default */ | |
| 3151 | + fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, s); | |
| 3152 | + break; | |
| 3153 | + } | |
| 3154 | +} | |
| 3155 | + | |
| 3136 | 3156 | /* Preprocess the current file */ |
| 3137 | 3157 | ST_FUNC int tcc_preprocess(TCCState *s1) |
| 3138 | 3158 | { |
| @@ -3158,6 +3178,8 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 19 unmodified lines | ||
| 3158 | 3178 | if (tok == TOK_EOF) { |
| 3159 | 3179 | break; |
| 3160 | 3180 | } else if (file != file_ref) { |
| 3181 | + if (file_ref) | |
| 3182 | + line_macro_output(file_ref, "", s1); | |
| 3161 | 3183 | goto print_line; |
| 3162 | 3184 | } else if (tok == TOK_LINEFEED) { |
| 3163 | 3185 | if (!token_seen) |
| @@ -3166,18 +3188,20 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 2 unmodified lines | ||
| 3166 | 3188 | token_seen = 0; |
| 3167 | 3189 | } else if (!token_seen) { |
| 3168 | 3190 | d = file->line_num - file->line_ref; |
| 3169 | − if (file != file_ref || d < 0 || d >= 8) { | |
| 3191 | + if (file != file_ref || d >= 8) { | |
| 3170 | 3192 | print_line: |
| 3171 | − iptr_new = s1->include_stack_ptr; | |
| 3172 | − s = iptr_new > iptr ? " 1" | |
| 3173 | − : iptr_new < iptr ? " 2" | |
| 3174 | − : iptr_new > s1->include_stack ? " 3" | |
| 3175 | − : "" | |
| 3176 | − ; | |
| 3177 | − iptr = iptr_new; | |
| 3178 | − fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s); | |
| 3193 | + s = ""; | |
| 3194 | + if (tcc_state->Pflag == LINE_MACRO_OUTPUT_FORMAT_GCC) { | |
| 3195 | + iptr_new = s1->include_stack_ptr; | |
| 3196 | + s = iptr_new > iptr ? " 1" | |
| 3197 | + : iptr_new < iptr ? " 2" | |
| 3198 | + : iptr_new > s1->include_stack ? " 3" | |
| 3199 | + : "" | |
| 3200 | + ; | |
| 3201 | + } | |
| 3202 | + line_macro_output(file, s, s1); | |
| 3179 | 3203 | } else { |
| 3180 | − while (d) | |
| 3204 | + while (d > 0) | |
| 3181 | 3205 | fputs("\n", s1->ppfp), --d; |
| 3182 | 3206 | } |
| 3183 | 3207 | file->line_ref = (file_ref = file)->line_num; |