From b7b9f9f51170bd1616ee56acfef9c6bf20b9cf3f Mon Sep 17 00:00:00 2001 From: seyko Date: Tue, 3 Mar 2015 14:25:57 +0300 Subject: [PATCH] A gcc preprocessor option -dD added With this option on a defines are included into the output (inside comments). This will allow to debug a problems like: In file included from math.c:8: In file included from /usr/include/math.h:43: /usr/include/bits/nan.h:52: warning: NAN redefined --- libtcc.c | 10 +++++++ tcc.c | 3 ++ tcc.h | 2 ++ tccpp.c | 91 ++++++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 84 insertions(+), 22 deletions(-) diff --git a/libtcc.c b/libtcc.c index 3581ffb..72524eb 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1656,6 +1656,7 @@ enum { TCC_OPTION_b, TCC_OPTION_g, TCC_OPTION_c, + TCC_OPTION_d, TCC_OPTION_float_abi, TCC_OPTION_static, TCC_OPTION_shared, @@ -1709,6 +1710,7 @@ static const TCCOption tcc_options[] = { #endif { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, { "c", TCC_OPTION_c, 0 }, + { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, #ifdef TCC_TARGET_ARM { "mfloat-abi", TCC_OPTION_float_abi, TCC_OPTION_HAS_ARG }, #endif @@ -1848,6 +1850,14 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) tcc_warning("-c: some compiler action already specified (%d)", s->output_type); s->output_type = TCC_OUTPUT_OBJ; break; + case TCC_OPTION_d: + if (*optarg != 'D') { + if (s->warn_unsupported) + goto unsupported_option; + tcc_error("invalid option -- '%s'", r); + } + s->dflag = 1; + break; #ifdef TCC_TARGET_ARM case TCC_OPTION_float_abi: /* tcc doesn't support soft float yet */ diff --git a/tcc.c b/tcc.c index 7b19114..ce03d3b 100644 --- a/tcc.c +++ b/tcc.c @@ -47,6 +47,7 @@ static void help(void) " -Usym undefine 'sym'\n" " -P do not output a #line directive\n" " -P1 use a #line directive in output instead of the gcc style\n" + " -dD put a define directive in the output (inside a comment)\n" "Linker options:\n" " -Ldir add library path 'dir'\n" " -llib link with dynamic or static library 'lib'\n" @@ -307,6 +308,8 @@ int main(int argc, char **argv) start_time = getclock_us(); tcc_set_output_type(s, s->output_type); + if (s->output_type == TCC_OUTPUT_PREPROCESS) + print_defines(); /* compile or add each files or library */ for(i = ret = 0; i < s->nb_files && ret == 0; i++) { diff --git a/tcc.h b/tcc.h index f268aed..34d3248 100644 --- a/tcc.h +++ b/tcc.h @@ -661,6 +661,7 @@ struct TCCState { LINE_MACRO_OUTPUT_FORMAT_NONE, LINE_MACRO_OUTPUT_FORMAT_STD, } Pflag; + int dflag; /* for keeping a -dD value */ /* for -MD/-MF: collected dependencies for this compilation */ char **target_deps; @@ -1155,6 +1156,7 @@ ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg); ST_FUNC void define_undef(Sym *s); ST_INLN Sym *define_find(int v); ST_FUNC void free_defines(Sym *b); +void print_defines(void); ST_FUNC Sym *label_find(int v); ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); ST_FUNC void label_pop(Sym **ptop, Sym *slast); diff --git a/tccpp.c b/tccpp.c index 18f3063..25d9ca9 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1049,6 +1049,55 @@ static int macro_is_equal(const int *a, const int *b) return !(*a || *b); } +static void define_print(Sym *s, int is_undef) +{ + int c, t; + CValue cval; + const int *str; + Sym *arg; + + if (tcc_state->dflag == 0 || !s || !tcc_state->ppfp) + return; + + if (file) { + c = file->line_num - file->line_ref - 1; + if (c > 0) { + while (c--) + fputs("\n", tcc_state->ppfp); + file->line_ref = file->line_num; + } + } + + if (is_undef) { + fprintf(tcc_state->ppfp, "// #undef %s\n", get_tok_str(s->v, NULL)); + return; + } + + fprintf(tcc_state->ppfp, "// #define %s", get_tok_str(s->v, NULL)); + arg = s->next; + if (arg) { + char *sep = "("; + while (arg) { + fprintf(tcc_state->ppfp, "%s%s", sep, get_tok_str(arg->v & ~SYM_FIELD, NULL)); + sep = ","; + arg = arg->next; + } + fprintf(tcc_state->ppfp, ")"); + } + + str = s->d; + if (str) + fprintf(tcc_state->ppfp, " "); + + while (str) { + TOK_GET(&t, &str, &cval); + if (!t) + break; + fprintf(tcc_state->ppfp, "%s", get_tok_str(t, &cval)); + } + fprintf(tcc_state->ppfp, "\n"); +} + /* defines handling */ ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) { @@ -1062,6 +1111,7 @@ ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) s->d = str; s->next = first_arg; table_ident[v - TOK_IDENT]->sym_define = s; + define_print(s, 0); } /* undefined a define symbol. Its name is just set to zero */ @@ -1069,8 +1119,10 @@ ST_FUNC void define_undef(Sym *s) { int v; v = s->v; - if (v >= TOK_IDENT && v < tok_ident) + if (v >= TOK_IDENT && v < tok_ident) { + define_print(s, 1); table_ident[v - TOK_IDENT]->sym_define = NULL; + } s->v = 0; } @@ -1103,6 +1155,22 @@ ST_FUNC void free_defines(Sym *b) define_stack = b; } +void print_defines(void) +{ + Sym *top, *s; + int v; + + top = define_stack; + while (top) { + v = top->v; + if (v >= TOK_IDENT && v < tok_ident) { + s = table_ident[v - TOK_IDENT]->sym_define; + define_print(s, 0); + } + top = top->prev; + } +} + /* label lookup */ ST_FUNC Sym *label_find(int v) { @@ -1192,23 +1260,6 @@ static int expr_preprocess(void) return c != 0; } -#if defined(PARSE_DEBUG) || defined(PP_DEBUG) -static void tok_print(int *str) -{ - int t; - CValue cval; - - printf("<"); - while (1) { - TOK_GET(&t, &str, &cval); - if (!t) - break; - printf("%s", get_tok_str(t, &cval)); - } - printf(">\n"); -} -#endif - /* parse after #define */ ST_FUNC void parse_define(void) { @@ -1279,10 +1330,6 @@ ST_FUNC void parse_define(void) if (spc == 1) --str.len; /* remove trailing space */ tok_str_add(&str, 0); -#ifdef PP_DEBUG - printf("define %s %d: ", get_tok_str(v, NULL), t); - tok_print(str.str); -#endif define_push(v, t, str.str, first); }