aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-06-09 17:28:52 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-06-09 17:28:52 -0400
commit7a208c0b6726d7b48b7c78ef8ce91b3f279ec228 (patch)
treea8f7bf11b13480d972c6aea77d35b516ef580646 /gcc
parent37811a734e0548dcc1d24e695db5a153ca42c8ee (diff)
downloadgcc-7a208c0b6726d7b48b7c78ef8ce91b3f279ec228.zip
gcc-7a208c0b6726d7b48b7c78ef8ce91b3f279ec228.tar.gz
gcc-7a208c0b6726d7b48b7c78ef8ce91b3f279ec228.tar.bz2
(scan_decls): Handle declarations with multiple comma-separated
declarators. From-SVN: r9912
Diffstat (limited to 'gcc')
-rw-r--r--gcc/scan-decls.c117
1 files changed, 84 insertions, 33 deletions
diff --git a/gcc/scan-decls.c b/gcc/scan-decls.c
index 602082d..cc44a75 100644
--- a/gcc/scan-decls.c
+++ b/gcc/scan-decls.c
@@ -1,5 +1,5 @@
/* scan-decls.c - Extracts declarations from cpp output.
- Copyright (C) 1993 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1995 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -53,8 +53,26 @@ skip_to_closing_brace (pfile)
}
/* This function scans a C source file (actually, the output of cpp),
- reading from FP. It looks for function declarations, and certain
- other interesting sequences (external variables and macros). */
+ reading from FP. It looks for function declarations, and
+ external variable declarations.
+
+ The following grammar (as well as some extra stuff) is recognized:
+
+ declaration:
+ (decl-specifier)* declarator ("," declarator)* ";"
+ decl-specifier:
+ identifier
+ keyword
+ extern "C"
+ declarator:
+ (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
+ ptr-operator:
+ ("*" | "&") ("const" | "volatile")*
+ dname:
+ identifier
+
+Here dname is the actual name being declared.
+*/
int
scan_decls (pfile, argc, argv)
@@ -64,10 +82,13 @@ scan_decls (pfile, argc, argv)
{
int saw_extern, saw_inline;
int old_written;
+ /* If declarator_start is non-zero, it marks the start of the current
+ declarator. If it is zero, we are either still parsing the
+ decl-specs, or prev_id_start marks the start of the declarator. */
+ int declarator_start;
int prev_id_start, prev_id_end;
enum cpp_token token;
-
new_statement:
CPP_SET_WRITTEN (pfile, 0);
token = cpp_get_token (pfile);
@@ -96,40 +117,18 @@ scan_decls (pfile, argc, argv)
goto new_statement;
if (token != CPP_NAME)
goto new_statement;
- if (strcmp (pfile->token_buffer, "inline") == 0)
- {
- saw_inline = 1;
- CPP_SET_WRITTEN (pfile, 0);
- token = cpp_get_non_space_token (pfile);
- }
- if (strcmp (pfile->token_buffer, "extern") == 0)
- {
- saw_extern = 1;
- CPP_SET_WRITTEN (pfile, 0);
- token = cpp_get_non_space_token (pfile);
- if (token == CPP_STRING
- && strcmp (pfile->token_buffer, "\"C\"") == 0)
- {
- CPP_SET_WRITTEN (pfile, 0);
- current_extern_C = 1;
- token = cpp_get_non_space_token (pfile);
- if (token == CPP_LPAREN)
- {
- brace_nesting++;
- extern_C_braces[extern_C_braces_length++] = brace_nesting;
- goto new_statement;
- }
- token = cpp_get_non_space_token (pfile);
- }
- }
- prev_id_start = NULL;
+
+ prev_id_start = 0;
+ declarator_start = 0;
for (;;)
{
int start_written = CPP_WRITTEN (pfile);
token = cpp_get_token (pfile);
+ handle_token:
switch (token)
{
case CPP_LPAREN:
+ /* Looks like this is the start of a formal parameter list. */
if (prev_id_start)
{
int nesting = 1;
@@ -168,9 +167,18 @@ scan_decls (pfile, argc, argv)
skip_to_closing_brace (pfile);
goto new_statement;
}
- goto handle_statement;
+ goto maybe_handle_comma;
}
break;
+ case CPP_OTHER:
+ if (CPP_WRITTEN (pfile) == start_written + 1
+ && (CPP_PWRITTEN (pfile)[-1] == '*'
+ || CPP_PWRITTEN (pfile)[-1] == '&'))
+ declarator_start = start_written;
+ else
+ goto handle_statement;
+ break;
+ case CPP_COMMA:
case CPP_SEMICOLON:
if (prev_id_start && saw_extern)
{
@@ -179,8 +187,48 @@ scan_decls (pfile, argc, argv)
pfile->token_buffer,
prev_id_start);
}
- goto new_statement;
+ /* ... fall through ... */
+ maybe_handle_comma:
+ if (token != CPP_COMMA)
+ goto new_statement;
+ handle_comma:
+ /* Handle multiple declarators in a single declaration,
+ as in: extern char *strcpy (), *strcat (), ... ; */
+ if (declarator_start == 0)
+ declarator_start = prev_id_start;
+ CPP_SET_WRITTEN (pfile, declarator_start);
+ break;
case CPP_NAME:
+ /* "inline" and "extern" are recognized but skipped */
+ if (strcmp (pfile->token_buffer, "inline") == 0)
+ {
+ saw_inline = 1;
+ CPP_SET_WRITTEN (pfile, start_written);
+ }
+ if (strcmp (pfile->token_buffer, "extern") == 0)
+ {
+ saw_extern = 1;
+ CPP_SET_WRITTEN (pfile, start_written);
+ token = cpp_get_non_space_token (pfile);
+ if (token == CPP_STRING
+ && strcmp (pfile->token_buffer, "\"C\"") == 0)
+ {
+ CPP_SET_WRITTEN (pfile, start_written);
+ current_extern_C = 1;
+ token = cpp_get_non_space_token (pfile);
+ if (token == CPP_LBRACE)
+ {
+ brace_nesting++;
+ extern_C_braces[extern_C_braces_length++]
+ = brace_nesting;
+ goto new_statement;
+ }
+ }
+ else
+ goto handle_token;
+ break;
+ }
+ /* This may be the name of a variable or function. */
prev_id_start = start_written;
prev_id_end = CPP_WRITTEN (pfile);
break;
@@ -192,6 +240,9 @@ scan_decls (pfile, argc, argv)
goto new_statement; /* handle_statement? */
case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT: case CPP_POP:
+ /* Skip initial white space. */
+ if (start_written == 0)
+ CPP_SET_WRITTEN (pfile, 0);
break;
default: