From cbc43ae091a468f438f851e454ac4454bb89f476 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 4 Oct 2005 18:06:19 +0000 Subject: [PATCH] re PR preprocessor/13726 (cpp -C -dI loses comments on same line as #include directives) libcpp/ PR preprocessor/13726 * directives.c (check_eol_return_comments): New static function. (parse_include): Add buf parameter. Change all callers. (do_include_common): If not discard comments, turn on save_comments. Pass collected comments to include callback. * include/cpplib.h (struct cpp_callbacks): Add new parameter to include callback: cpp_token list. gcc/ PR preprocessor/13726 * c-ppoutput.c (cb_include): Add comments parameter, and print out any comments passed in. gcc/testsuite/ PR preprocessor/13726 * gcc.dg/cpp/cmdlne-dI-C.c: New test. * gcc.dg/cpp/cmdlne-dI-C.h: New file. From-SVN: r104951 --- gcc/ChangeLog | 6 ++ gcc/c-ppoutput.c | 22 +++++-- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c | 11 ++++ gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h | 1 + libcpp/ChangeLog | 10 ++++ libcpp/directives.c | 81 +++++++++++++++++++++++--- libcpp/include/cpplib.h | 2 +- 8 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c create mode 100644 gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 088f0e7f0f8..c3723cd3c6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-10-04 Ian Lance Taylor + + PR preprocessor/13726 + * c-ppoutput.c (cb_include): Add comments parameter, and print out + any comments passed in. + 2005-10-04 Andrew Pinski * tree.c (annotate_with_file_line): Fix typo. diff --git a/gcc/c-ppoutput.c b/gcc/c-ppoutput.c index 1cdbb67a12c..692ea7a4d75 100644 --- a/gcc/c-ppoutput.c +++ b/gcc/c-ppoutput.c @@ -54,7 +54,7 @@ static void cb_line_change (cpp_reader *, const cpp_token *, int); static void cb_define (cpp_reader *, source_location, cpp_hashnode *); static void cb_undef (cpp_reader *, source_location, cpp_hashnode *); static void cb_include (cpp_reader *, source_location, const unsigned char *, - const char *, int); + const char *, int, const cpp_token **); static void cb_ident (cpp_reader *, source_location, const cpp_string *); static void cb_def_pragma (cpp_reader *, source_location); static void cb_read_pch (cpp_reader *pfile, const char *name, @@ -336,13 +336,27 @@ cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, static void cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, - const unsigned char *dir, const char *header, int angle_brackets) + const unsigned char *dir, const char *header, int angle_brackets, + const cpp_token **comments) { maybe_print_line (line); if (angle_brackets) - fprintf (print.outf, "#%s <%s>\n", dir, header); + fprintf (print.outf, "#%s <%s>", dir, header); else - fprintf (print.outf, "#%s \"%s\"\n", dir, header); + fprintf (print.outf, "#%s \"%s\"", dir, header); + + if (comments != NULL) + { + while (*comments != NULL) + { + if ((*comments)->flags & PREV_WHITE) + putc (' ', print.outf); + cpp_output_token (*comments, print.outf); + ++comments; + } + } + + putc ('\n', print.outf); print.src_line++; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8bc316d3766..a397ea94626 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-10-04 Ian Lance Taylor + + PR preprocessor/13726 + * gcc.dg/cpp/cmdlne-dI-C.c: New test. + * gcc.dg/cpp/cmdlne-dI-C.h: New file. + 2005-10-04 Richard Guenther PR c/23576 diff --git a/gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c b/gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c new file mode 100644 index 00000000000..6b4bfee2288 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c @@ -0,0 +1,11 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. */ +/* PR 13726 */ + +/* { dg-do preprocess } */ +/* { dg-options "-dI -C" } */ + +#include "cmdlne-dI-C.h" /* #include comment */ +/* comment 2 */ + +/* { dg-final { scan-file cmdlne-dI-C.i "#include c+omment" } } */ +/* { dg-final { scan-file cmdlne-dI-C.i "header file c+omment" } } */ diff --git a/gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h b/gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h new file mode 100644 index 00000000000..5021488e4b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h @@ -0,0 +1 @@ +/* header file comment */ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index faf6b93070a..731b1c69b36 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,13 @@ +2005-10-04 Ian Lance Taylor + + PR preprocessor/13726 + * directives.c (check_eol_return_comments): New static function. + (parse_include): Add buf parameter. Change all callers. + (do_include_common): If not discard comments, turn on + save_comments. Pass collected comments to include callback. + * include/cpplib.h (struct cpp_callbacks): Add new parameter to + include callback: cpp_token list. + 2005-09-20 Joseph S. Myers * include/cpplib.h (struct cpp_options): Add extended_identifiers. diff --git a/libcpp/directives.c b/libcpp/directives.c index 7e1167de0b8..7159f07a688 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -95,7 +95,7 @@ static void end_directive (cpp_reader *, int); static void directive_diagnostics (cpp_reader *, const directive *, int); static void run_directive (cpp_reader *, int, const char *, size_t); static char *glue_header_name (cpp_reader *); -static const char *parse_include (cpp_reader *, int *); +static const char *parse_include (cpp_reader *, int *, const cpp_token ***); static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); static unsigned int read_flag (cpp_reader *, unsigned int); static int strtoul_for_line (const uchar *, unsigned int, unsigned long *); @@ -220,6 +220,46 @@ check_eol (cpp_reader *pfile) pfile->directive->name); } +/* Ensure there are no stray tokens other than comments at the end of + a directive, and gather the comments. */ +static const cpp_token ** +check_eol_return_comments (cpp_reader *pfile) +{ + size_t c; + size_t capacity = 8; + const cpp_token **buf; + + buf = XNEWVEC (const cpp_token *, capacity); + c = 0; + if (! SEEN_EOL ()) + { + while (1) + { + const cpp_token *tok; + + tok = _cpp_lex_token (pfile); + if (tok->type == CPP_EOF) + break; + if (tok->type != CPP_COMMENT) + cpp_error (pfile, CPP_DL_PEDWARN, + "extra tokens at end of #%s directive", + pfile->directive->name); + else + { + if (c + 1 >= capacity) + { + capacity *= 2; + buf = XRESIZEVEC (const cpp_token *, buf, capacity); + } + buf[c] = tok; + ++c; + } + } + } + buf[c] = NULL; + return buf; +} + /* Called when entering a directive, _Pragma or command-line directive. */ static void start_directive (cpp_reader *pfile) @@ -624,7 +664,8 @@ glue_header_name (cpp_reader *pfile) #pragma dependency. The string is malloced and the caller should free it. Returns NULL on error. */ static const char * -parse_include (cpp_reader *pfile, int *pangle_brackets) +parse_include (cpp_reader *pfile, int *pangle_brackets, + const cpp_token ***buf) { char *fname; const cpp_token *header; @@ -657,7 +698,15 @@ parse_include (cpp_reader *pfile, int *pangle_brackets) return NULL; } - check_eol (pfile); + if (buf == NULL || CPP_OPTION (pfile, discard_comments)) + check_eol (pfile); + else + { + /* If we are not discarding comments, then gather them while + doing the eol check. */ + *buf = check_eol_return_comments (pfile); + } + return fname; } @@ -667,16 +716,27 @@ do_include_common (cpp_reader *pfile, enum include_type type) { const char *fname; int angle_brackets; + const cpp_token **buf = NULL; - fname = parse_include (pfile, &angle_brackets); + /* Re-enable saving of comments if requested, so that the include + callback can dump comments which follow #include. */ + pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + + fname = parse_include (pfile, &angle_brackets, &buf); if (!fname) - return; + { + if (buf) + XDELETEVEC (buf); + return; + } if (!*fname) { cpp_error (pfile, CPP_DL_ERROR, "empty filename in #%s", pfile->directive->name); - free ((void *) fname); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); return; } @@ -690,12 +750,15 @@ do_include_common (cpp_reader *pfile, enum include_type type) if (pfile->cb.include) pfile->cb.include (pfile, pfile->directive_line, - pfile->directive->name, fname, angle_brackets); + pfile->directive->name, fname, angle_brackets, + buf); _cpp_stack_include (pfile, fname, angle_brackets, type); } - free ((void *) fname); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); } static void @@ -1322,7 +1385,7 @@ do_pragma_dependency (cpp_reader *pfile) const char *fname; int angle_brackets, ordering; - fname = parse_include (pfile, &angle_brackets); + fname = parse_include (pfile, &angle_brackets, NULL); if (!fname) return; diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index c84f6243376..3c4d0d6cb5b 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -459,7 +459,7 @@ struct cpp_callbacks void (*dir_change) (cpp_reader *, const char *); void (*include) (cpp_reader *, unsigned int, const unsigned char *, - const char *, int); + const char *, int, const cpp_token **); void (*define) (cpp_reader *, unsigned int, cpp_hashnode *); void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *); void (*ident) (cpp_reader *, unsigned int, const cpp_string *);