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 | TCC_OPTION_I, | 1647 | TCC_OPTION_I, |
| 1648 | TCC_OPTION_D, | 1648 | TCC_OPTION_D, |
| 1649 | TCC_OPTION_U, | 1649 | TCC_OPTION_U, |
| 1650 | TCC_OPTION_P, | ||
| 1650 | TCC_OPTION_L, | 1651 | TCC_OPTION_L, |
| 1651 | TCC_OPTION_B, | 1652 | TCC_OPTION_B, |
| 1652 | TCC_OPTION_l, | 1653 | TCC_OPTION_l, |
| @@ -1695,6 +1696,7 @@ static const TCCOption tcc_options[] = { · 42 unmodified lines | |||
| 1695 | { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, | 1696 | { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, |
| 1696 | { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, | 1697 | { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, |
| 1697 | { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, | 1698 | { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, |
| 1699 | { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | ||
| 1698 | { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, | 1700 | { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, |
| 1699 | { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, | 1701 | { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, |
| 1700 | { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 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 | tcc_warning("-E: some compiler action already specified (%d)", s->output_type); | 1932 | tcc_warning("-E: some compiler action already specified (%d)", s->output_type); |
| 1931 | s->output_type = TCC_OUTPUT_PREPROCESS; | 1933 | s->output_type = TCC_OUTPUT_PREPROCESS; |
| 1932 | break; | 1934 | break; |
| 1935 | case TCC_OPTION_P: | ||
| 1936 | s->Pflag = atoi(optarg) + 1; | ||
| 1937 | break; | ||
| 1933 | case TCC_OPTION_MD: | 1938 | case TCC_OPTION_MD: |
| 1934 | s->gen_deps = 1; | 1939 | s->gen_deps = 1; |
| 1935 | break; | 1940 | break; |
| @@ -45,6 +45,8 @@ static void help(void) · 44 unmodified lines | |||
| 45 | " -Idir add include path 'dir'\n" | 45 | " -Idir add include path 'dir'\n" |
| 46 | " -Dsym[=val] define 'sym' with value 'val'\n" | 46 | " -Dsym[=val] define 'sym' with value 'val'\n" |
| 47 | " -Usym undefine 'sym'\n" | 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 | "Linker options:\n" | 50 | "Linker options:\n" |
| 49 | " -Ldir add library path 'dir'\n" | 51 | " -Ldir add library path 'dir'\n" |
| 50 | " -llib link with dynamic or static library 'lib'\n" | 52 | " -llib link with dynamic or static library 'lib'\n" |
| @@ -656,6 +656,11 @@ struct TCCState { · 655 unmodified lines | |||
| 656 | 656 | ||
| 657 | /* output file for preprocessing (-E) */ | 657 | /* output file for preprocessing (-E) */ |
| 658 | FILE *ppfp; | 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 | /* for -MD/-MF: collected dependencies for this compilation */ | 665 | /* for -MD/-MF: collected dependencies for this compilation */ |
| 661 | char **target_deps; | 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 | /* Preprocess the current file */ | 3156 | /* Preprocess the current file */ |
| 3137 | ST_FUNC int tcc_preprocess(TCCState *s1) | 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 | if (tok == TOK_EOF) { | 3178 | if (tok == TOK_EOF) { |
| 3159 | break; | 3179 | break; |
| 3160 | } else if (file != file_ref) { | 3180 | } else if (file != file_ref) { |
| 3181 | if (file_ref) | ||
| 3182 | line_macro_output(file_ref, "", s1); | ||
| 3161 | goto print_line; | 3183 | goto print_line; |
| 3162 | } else if (tok == TOK_LINEFEED) { | 3184 | } else if (tok == TOK_LINEFEED) { |
| 3163 | if (!token_seen) | 3185 | if (!token_seen) |
| @@ -3166,18 +3188,20 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 2 unmodified lines | |||
| 3166 | token_seen = 0; | 3188 | token_seen = 0; |
| 3167 | } else if (!token_seen) { | 3189 | } else if (!token_seen) { |
| 3168 | d = file->line_num - file->line_ref; | 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 | print_line: | 3192 | print_line: |
| 3171 | iptr_new = s1->include_stack_ptr; | 3193 | s = ""; |
| 3172 | s = iptr_new > iptr ? " 1" | 3194 | if (tcc_state->Pflag == LINE_MACRO_OUTPUT_FORMAT_GCC) { |
| 3173 | : iptr_new < iptr ? " 2" | 3195 | iptr_new = s1->include_stack_ptr; |
| 3174 | : iptr_new > s1->include_stack ? " 3" | 3196 | s = iptr_new > iptr ? " 1" |
| 3175 | : "" | 3197 | : iptr_new < iptr ? " 2" |
| 3176 | ; | 3198 | : iptr_new > s1->include_stack ? " 3" |
| 3177 | iptr = iptr_new; | 3199 | : "" |
| 3178 | fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s); | 3200 | ; |
| 3201 | } | ||
| 3202 | line_macro_output(file, s, s1); | ||
| 3179 | } else { | 3203 | } else { |
| 3180 | while (d) | 3204 | while (d > 0) |
| 3181 | fputs("\n", s1->ppfp), --d; | 3205 | fputs("\n", s1->ppfp), --d; |
| 3182 | } | 3206 | } |
| 3183 | file->line_ref = (file_ref = file)->line_num; | 3207 | file->line_ref = (file_ref = file)->line_num; |