aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZack Weinberg <zack@wolery.cumb.org>2000-02-10 00:26:47 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-02-10 00:26:47 +0000
commit564ad5f49e3f4d9d55e972d8ed66ac12bd2c83dc (patch)
treeb97b41fd2091f08d292e94d18de3493399ff1087 /gcc
parent3a75e42e813997b8144619d6031b729690639922 (diff)
downloadgcc-564ad5f49e3f4d9d55e972d8ed66ac12bd2c83dc.zip
gcc-564ad5f49e3f4d9d55e972d8ed66ac12bd2c83dc.tar.gz
gcc-564ad5f49e3f4d9d55e972d8ed66ac12bd2c83dc.tar.bz2
cpphash.c (macarg): Hoist all the flag diddling out of the function...
* cpphash.c (macarg): Hoist all the flag diddling out of the function... (macroexpand): ... and out of the loop that calls macarg. Skip over the initial paren before macro arguments with cpp_get_non_space_token; point may be some distance before that paren. Abort if it's not there. * cpplib.c (parse_clear_mark): Delete function. (parse_set_mark, parse_goto_mark): Make static. (ACTIVE_MARK_P): New macro. (skip_block_comment, skip_line_comment): Do not bump the line if ACTIVE_MARK_P is true. (cpp_pop_buffer): The buffer to be popped may not have an active mark. (cpp_get_token): When looking for the initial paren before macro arguments, only set a mark in a file buffer, Always return to that mark before proceeding to call macroexpand or return a NAME token. * cpplib.h: Remove prototypes of parse_set_mark, parse_clear_mark, parse_goto_mark. (struct cpp_options): Rename 'put_out_comments' to 'discard_comments' and invert its sense. * cppinit.c, cpphash.c, cpplib.c: All users of put_out_comments changed to use discard_comments, with opposite sense. From-SVN: r31879
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/cpphash.c50
-rw-r--r--gcc/cppinit.c3
-rw-r--r--gcc/cpplib.c125
-rw-r--r--gcc/cpplib.h8
-rw-r--r--gcc/testsuite/gcc.dg/20000209-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/20000209-2.c17
7 files changed, 172 insertions, 94 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 42cc6b6..3e6a9a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+2000-02-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpphash.c (macarg): Hoist all the flag diddling out of the
+ function...
+ (macroexpand): ... and out of the loop that calls macarg.
+ Skip over the initial paren before macro arguments with
+ cpp_get_non_space_token; point may be some distance before
+ that paren. Abort if it's not there.
+
+ * cpplib.c (parse_clear_mark): Delete function.
+ (parse_set_mark, parse_goto_mark): Make static.
+ (ACTIVE_MARK_P): New macro.
+ (skip_block_comment, skip_line_comment): Do not bump the line
+ if ACTIVE_MARK_P is true.
+ (cpp_pop_buffer): The buffer to be popped may not have an
+ active mark.
+ (cpp_get_token): When looking for the initial paren before
+ macro arguments, only set a mark in a file buffer, Always
+ return to that mark before proceeding to call macroexpand or
+ return a NAME token.
+
+ * cpplib.h: Remove prototypes of parse_set_mark,
+ parse_clear_mark, parse_goto_mark.
+ (struct cpp_options): Rename 'put_out_comments' to
+ 'discard_comments' and invert its sense.
+ * cppinit.c, cpphash.c, cpplib.c: All users of
+ put_out_comments changed to use discard_comments, with
+ opposite sense.
+
2000-02-09 Clinton Popetz <cpopetz@cygnus.com>
* function.c (thread_prologue_and_epilogue_insns): Don't delete
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index 9da1daa..8a178f3 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -773,27 +773,22 @@ macarg (pfile, rest_args)
{
int paren = 0;
enum cpp_token token;
- char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
- CPP_OPTIONS (pfile)->put_out_comments = 0;
/* Try to parse as much of the argument as exists at this
input stack level. */
- pfile->no_macro_expand++;
- pfile->no_directives++;
- CPP_OPTIONS (pfile)->no_line_commands++;
for (;;)
{
token = cpp_get_token (pfile);
switch (token)
{
case CPP_EOF:
- goto done;
+ return token;
case CPP_POP:
/* If we've hit end of file, it's an error (reported by caller).
Ditto if it's the end of cpp_expand_to_buffer text.
If we've hit end of macro, just continue. */
if (!CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- goto done;
+ return token;
break;
case CPP_LPAREN:
paren++;
@@ -811,18 +806,10 @@ macarg (pfile, rest_args)
found:
/* Remove ',' or ')' from argument buffer. */
CPP_ADJUST_WRITTEN (pfile, -1);
- goto done;
+ return token;
default:;
}
}
-
-done:
- CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
- CPP_OPTIONS (pfile)->no_line_commands--;
- pfile->no_macro_expand--;
- pfile->no_directives--;
-
- return token;
}
@@ -1023,7 +1010,7 @@ macroexpand (pfile, hp)
if (nargs >= 0)
{
- enum cpp_token token = CPP_EOF;
+ enum cpp_token token;
args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
@@ -1040,8 +1027,20 @@ macroexpand (pfile, hp)
macarg absorbed the rest of the args. */
i = 0;
rest_args = 0;
- rest_args = 0;
- FORWARD (1); /* Discard open-parenthesis before first arg. */
+
+ /* Skip over the opening parenthesis. */
+ CPP_OPTIONS (pfile)->discard_comments++;
+ CPP_OPTIONS (pfile)->no_line_commands++;
+ pfile->no_macro_expand++;
+ pfile->no_directives++;
+
+ token = cpp_get_non_space_token (pfile);
+ if (token != CPP_LPAREN)
+ cpp_ice (pfile, "macroexpand: unexpected token %d (wanted LPAREN)",
+ token);
+ CPP_ADJUST_WRITTEN (pfile, -1);
+
+ token = CPP_EOF;
do
{
if (rest_args)
@@ -1058,14 +1057,17 @@ macroexpand (pfile, hp)
else
token = macarg (pfile, 0);
if (token == CPP_EOF || token == CPP_POP)
- {
- cpp_error_with_line (pfile, start_line, start_column,
- "unterminated macro call");
- return;
- }
+ cpp_error_with_line (pfile, start_line, start_column,
+ "unterminated macro call");
i++;
}
while (token == CPP_COMMA);
+ CPP_OPTIONS (pfile)->discard_comments--;
+ CPP_OPTIONS (pfile)->no_line_commands--;
+ pfile->no_macro_expand--;
+ pfile->no_directives--;
+ if (token != CPP_RPAREN)
+ return;
/* If we got one arg but it was just whitespace, call that 0 args. */
if (i == 1)
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 102e815..fa67ee2 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -408,6 +408,7 @@ cpp_options_init (opts)
opts->dollars_in_ident = 1;
opts->cplusplus_comments = 1;
opts->warn_import = 1;
+ opts->discard_comments = 1;
opts->pending =
(struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
@@ -1600,7 +1601,7 @@ cpp_handle_option (pfile, argc, argv)
break;
case 'C':
- opts->put_out_comments = 1;
+ opts->discard_comments = 0;
break;
case 'E': /* -E comes from cc -E; ignore it. */
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index e1061f1..7abb331 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -35,6 +35,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
(Note that it is false while we're expanding macro *arguments*.) */
#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
+/* ACTIVE_MARK_P is true if there's a live mark in the buffer, in which
+ case CPP_BUMP_LINE must not be called. */
+#define ACTIVE_MARK_P() (CPP_BUFFER (pfile)->mark != -1)
+
/* External declarations. */
extern HOST_WIDEST_INT cpp_parse_expr PARAMS ((cpp_reader *));
@@ -100,6 +104,8 @@ static int consider_directive_while_skipping PARAMS ((cpp_reader *,
IF_STACK_FRAME *));
static void skip_block_comment PARAMS ((cpp_reader *));
static void skip_line_comment PARAMS ((cpp_reader *));
+static void parse_set_mark PARAMS ((cpp_reader *));
+static void parse_goto_mark PARAMS ((cpp_reader *));
/* Here is the actual list of #-directives.
This table is ordered by frequency of occurrence; the numbers
@@ -282,8 +288,11 @@ skip_block_comment (pfile)
return;
}
else if (c == '\n' || c == '\r')
- /* \r cannot be a macro escape marker here. */
- CPP_BUMP_LINE (pfile);
+ {
+ /* \r cannot be a macro escape marker here. */
+ if (!ACTIVE_MARK_P())
+ CPP_BUMP_LINE (pfile);
+ }
else if (c == '/' && prev_c == '*')
return;
else if (c == '*' && prev_c == '/'
@@ -315,7 +324,8 @@ skip_line_comment (pfile)
else if (c == '\r')
{
/* \r cannot be a macro escape marker here. */
- CPP_BUMP_LINE (pfile);
+ if (!ACTIVE_MARK_P())
+ CPP_BUMP_LINE (pfile);
if (CPP_OPTIONS (pfile)->warn_comments)
cpp_warning (pfile, "backslash-newline within line comment");
}
@@ -376,7 +386,7 @@ skip_comment (pfile, m)
}
/* Identical to skip_comment except that it copies the comment into the
- token_buffer. This is used if put_out_comments. */
+ token_buffer. This is used if !discard_comments. */
static int
copy_comment (pfile, m)
cpp_reader *pfile;
@@ -764,6 +774,8 @@ cpp_pop_buffer (pfile)
cpp_reader *pfile;
{
cpp_buffer *buf = CPP_BUFFER (pfile);
+ if (ACTIVE_MARK_P())
+ cpp_ice (pfile, "mark active in cpp_pop_buffer");
(*buf->cleanup) (buf, pfile);
CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
free (buf);
@@ -2337,16 +2349,16 @@ cpp_get_token (pfile)
goto op2;
comment:
- if (opts->put_out_comments)
- c = copy_comment (pfile, c);
- else
+ if (opts->discard_comments)
c = skip_comment (pfile, c);
+ else
+ c = copy_comment (pfile, c);
if (c != ' ')
goto randomchar;
/* Comments are equivalent to spaces.
For -traditional, a comment is equivalent to nothing. */
- if (opts->traditional || opts->put_out_comments)
+ if (opts->traditional || !opts->discard_comments)
return CPP_COMMENT;
else
{
@@ -2629,50 +2641,50 @@ cpp_get_token (pfile)
decide this is not a macro call and leave things that way. */
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
{
- int is_macro_call, macbuf_whitespace = 0;
+ int macbuf_whitespace = 0;
+
+ while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+ {
+ U_CHAR *point = CPP_BUFFER (pfile)->cur;
+ for (;;)
+ {
+ cpp_skip_hspace (pfile);
+ c = PEEKC ();
+ if (c == '\n')
+ FORWARD(1);
+ else
+ break;
+ }
+ if (point != CPP_BUFFER (pfile)->cur)
+ macbuf_whitespace = 1;
+ if (c == '(')
+ goto is_macro_call;
+ else if (c != EOF)
+ goto not_macro_call;
+ cpp_pop_buffer (pfile);
+ }
parse_set_mark (pfile);
for (;;)
{
cpp_skip_hspace (pfile);
c = PEEKC ();
- is_macro_call = c == '(';
- if (c != EOF)
- {
- if (c != '\n')
- break;
- CPP_BUMP_LINE (pfile);
- FORWARD (1);
- }
- else
- {
- if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- {
- if (CPP_BUFFER (pfile)->mark !=
- (CPP_BUFFER (pfile)->cur
- - CPP_BUFFER (pfile)->buf))
- macbuf_whitespace = 1;
-
- /* The mark goes away automatically when
- the buffer is popped. */
- cpp_pop_buffer (pfile);
- parse_set_mark (pfile);
- }
- else
- break;
- }
+ if (c == '\n')
+ FORWARD(1);
+ else
+ break;
}
- if (!is_macro_call)
- {
- parse_goto_mark (pfile);
- if (macbuf_whitespace)
- CPP_PUTC (pfile, ' ');
- }
- else
- parse_clear_mark (pfile);
- if (!is_macro_call)
- return CPP_NAME;
+ parse_goto_mark (pfile);
+
+ if (c == '(')
+ goto is_macro_call;
+
+ not_macro_call:
+ if (macbuf_whitespace)
+ CPP_PUTC (pfile, ' ');
+ return CPP_NAME;
}
+ is_macro_call:
/* This is now known to be a macro call.
Expand the macro, reading arguments as needed,
and push the expansion on the input stack. */
@@ -3142,40 +3154,27 @@ cpp_read_check_assertion (pfile)
/* Remember the current position of PFILE. */
-void
+static void
parse_set_mark (pfile)
cpp_reader *pfile;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
- if (ip->mark != -1)
- cpp_ice (pfile, "ip->mark != -1 in parse_set_mark");
+ if (ACTIVE_MARK_P())
+ cpp_ice (pfile, "mark active in parse_set_mark");
ip->mark = ip->cur - ip->buf;
}
-/* Clear the current mark - we no longer need it. */
-
-void
-parse_clear_mark (pfile)
- cpp_reader *pfile;
-{
- cpp_buffer *ip = CPP_BUFFER (pfile);
- if (ip->mark == -1)
- cpp_ice (pfile, "ip->mark == -1 in parse_clear_mark");
-
- ip->mark = -1;
-}
-
/* Backup the current position of PFILE to that saved in its mark,
and clear the mark. */
-void
+static void
parse_goto_mark (pfile)
cpp_reader *pfile;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
- if (ip->mark == -1)
- cpp_ice (pfile, "ip->mark == -1 in parse_goto_mark");
+ if (!ACTIVE_MARK_P())
+ cpp_ice (pfile, "mark not active in parse_goto_mark");
ip->cur = ip->buf + ip->mark;
ip->mark = -1;
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index fc85a02..e0bf7ae 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -59,10 +59,6 @@ enum cpp_token {
typedef enum cpp_token (*parse_underflow_t) PARAMS((cpp_reader *));
typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
-extern void parse_set_mark PARAMS ((cpp_reader *));
-extern void parse_clear_mark PARAMS ((cpp_reader *));
-extern void parse_goto_mark PARAMS ((cpp_reader *));
-
extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
@@ -356,9 +352,9 @@ struct cpp_options {
char chill;
- /* Nonzero means copy comments into the output file. */
+ /* Nonzero means don't copy comments into the output file. */
- char put_out_comments;
+ char discard_comments;
/* Nonzero means process the ANSI trigraph sequences. */
diff --git a/gcc/testsuite/gcc.dg/20000209-1.c b/gcc/testsuite/gcc.dg/20000209-1.c
new file mode 100644
index 0000000..fe71058
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20000209-1.c
@@ -0,0 +1,34 @@
+/* { dg-do preprocess } */
+
+/* Tests for line numbering around function-like macro calls.
+ Bug found by Mark Mitchell. */
+
+#define f(x) x
+#define g f
+
+f (3);
+#error here /* { dg-error "here" "case 0" } */
+
+f
+ (3);
+#error here /* { dg-error "here" "case 1" } */
+
+(f
+ )(3);
+#error here /* { dg-error "here" "case 2" } */
+
+g
+ (3);
+#error here /* { dg-error "here" "case 3" } */
+
+(g
+ )(3);
+#error here /* { dg-error "here" "case 4" } */
+
+f /* some
+ text */ (3);
+#error here /* { dg-error "here" "case 5" } */
+
+(g /* some
+ text */ )(3);
+#error here /* { dg-error "here" "case 6" } */
diff --git a/gcc/testsuite/gcc.dg/20000209-2.c b/gcc/testsuite/gcc.dg/20000209-2.c
new file mode 100644
index 0000000..621a00b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20000209-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* Distilled from glibc sources. Tests preprocessor corner cases. */
+
+#define NO_PAREN(rest...) rest
+#define DEFINE_CATEGORY(category, items) \
+const int _nl_value_type_##category[] = { NO_PAREN items }
+
+DEFINE_CATEGORY
+(
+ LC_COLLATE,
+ (
+ 1,
+ 2,
+ 3,
+ ));
+
+DEFINE_CATEGORY(LC_CTYPE, (1, 2, 3));