aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseyko <seyko2@gmail.com>2015-03-03 14:25:57 +0300
committerseyko <seyko2@gmail.com>2015-03-03 14:25:57 +0300
commitb7b9f9f51170bd1616ee56acfef9c6bf20b9cf3f (patch)
treeb31eb010c27630fdc5eeb8cd9b8c9c1548b3153f
parent50cdccf3efaa13dd11d1533b73fb34e0429d5cd6 (diff)
downloadtinycc-b7b9f9f51170bd1616ee56acfef9c6bf20b9cf3f.tar.gz
tinycc-b7b9f9f51170bd1616ee56acfef9c6bf20b9cf3f.tar.bz2
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
-rw-r--r--libtcc.c10
-rw-r--r--tcc.c3
-rw-r--r--tcc.h2
-rw-r--r--tccpp.c91
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);
}