]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/scan-decls.c
Oops, missed ChangeLog in last checkin...
[thirdparty/gcc.git] / gcc / scan-decls.c
CommitLineData
7936052f 1/* scan-decls.c - Extracts declarations from cpp output.
af841dbd
JL
2 Copyright (C) 1993, 1995, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
7936052f
PB
4
5This program is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
95d83698 17Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
7936052f 18
ba7ff9f9 19 Written by Per Bothner <bothner@cygnus.com>, July 1993. */
7936052f 20
ffde73b0 21#include "hconfig.h"
b04cd507 22#include "system.h"
b3ca463c 23#include "cpplib.h"
d6f4ec51 24#include "scan.h"
7936052f 25
95d75019
KG
26static void skip_to_closing_brace PARAMS ((cpp_reader *));
27
7936052f
PB
28int brace_nesting = 0;
29
30/* The first extern_C_braces_length elements of extern_C_braces
31 indicate the (brace nesting levels of) left braces that were
e174accc 32 prefixed by extern "C". */
7936052f
PB
33int extern_C_braces_length = 0;
34char extern_C_braces[20];
35#define in_extern_C_brace (extern_C_braces_length>0)
36
37/* True if the function declaration currently being scanned is
e174accc 38 prefixed by extern "C". */
7936052f
PB
39int current_extern_C = 0;
40
e9cd0b25 41static void
b3ca463c
PB
42skip_to_closing_brace (pfile)
43 cpp_reader *pfile;
e9cd0b25
PB
44{
45 int nesting = 1;
46 for (;;)
47 {
3a2b2c7a 48 enum cpp_ttype token = cpp_get_token (pfile);
b3ca463c 49 if (token == CPP_EOF)
e9cd0b25 50 break;
1368ee70 51 if (token == CPP_OPEN_BRACE)
e9cd0b25 52 nesting++;
1368ee70 53 if (token == CPP_CLOSE_BRACE && --nesting == 0)
e9cd0b25
PB
54 break;
55 }
56}
57
ba7ff9f9 58/* This function scans a C source file (actually, the output of cpp),
7a208c0b
RK
59 reading from FP. It looks for function declarations, and
60 external variable declarations.
61
62 The following grammar (as well as some extra stuff) is recognized:
63
64 declaration:
65 (decl-specifier)* declarator ("," declarator)* ";"
66 decl-specifier:
67 identifier
68 keyword
69 extern "C"
70 declarator:
71 (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
72 ptr-operator:
73 ("*" | "&") ("const" | "volatile")*
74 dname:
75 identifier
76
77Here dname is the actual name being declared.
78*/
ba7ff9f9 79
7936052f 80int
b3ca463c
PB
81scan_decls (pfile, argc, argv)
82 cpp_reader *pfile;
973838fd
KG
83 int argc ATTRIBUTE_UNUSED;
84 char **argv ATTRIBUTE_UNUSED;
7936052f 85{
e9cd0b25 86 int saw_extern, saw_inline;
1d300e19 87 int start_written;
7a208c0b
RK
88 /* If declarator_start is non-zero, it marks the start of the current
89 declarator. If it is zero, we are either still parsing the
0f41302f 90 decl-specs, or prev_id_start marks the start of the declarator. */
7a208c0b 91 int declarator_start;
a544cfd2 92 int prev_id_start, prev_id_end = 0;
3a2b2c7a 93 enum cpp_ttype token;
b3ca463c 94
7936052f 95 new_statement:
b3ca463c 96 CPP_SET_WRITTEN (pfile, 0);
1d300e19 97 start_written = 0;
b3ca463c
PB
98 token = cpp_get_token (pfile);
99
7936052f
PB
100 handle_statement:
101 current_extern_C = 0;
102 saw_extern = 0;
e9cd0b25 103 saw_inline = 0;
1368ee70 104 if (token == CPP_OPEN_BRACE)
7936052f 105 {
e174accc 106 /* Pop an 'extern "C"' nesting level, if appropriate. */
7936052f
PB
107 if (extern_C_braces_length
108 && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
109 extern_C_braces_length--;
110 brace_nesting--;
111 goto new_statement;
112 }
1368ee70 113 if (token == CPP_OPEN_BRACE)
7936052f
PB
114 {
115 brace_nesting++;
116 goto new_statement;
117 }
b3ca463c 118 if (token == CPP_EOF)
7936052f 119 return 0;
b3ca463c 120 if (token == CPP_SEMICOLON)
7936052f 121 goto new_statement;
b3ca463c 122 if (token != CPP_NAME)
7936052f 123 goto new_statement;
7a208c0b
RK
124
125 prev_id_start = 0;
126 declarator_start = 0;
7936052f
PB
127 for (;;)
128 {
b3ca463c 129 switch (token)
7936052f 130 {
1368ee70 131 case CPP_OPEN_PAREN:
0f41302f 132 /* Looks like this is the start of a formal parameter list. */
b3ca463c 133 if (prev_id_start)
7936052f
PB
134 {
135 int nesting = 1;
b3ca463c
PB
136 int have_arg_list = 0;
137 cpp_buffer *fbuf = cpp_file_buffer (pfile);
3a2b2c7a 138 unsigned int func_lineno = CPP_BUF_LINE (fbuf);
7936052f
PB
139 for (;;)
140 {
b3ca463c 141 token = cpp_get_token (pfile);
1368ee70 142 if (token == CPP_OPEN_PAREN)
7936052f 143 nesting++;
1368ee70 144 else if (token == CPP_CLOSE_PAREN)
e174accc 145 {
b3ca463c
PB
146 nesting--;
147 if (nesting == 0)
148 break;
e174accc 149 }
b3ca463c
PB
150 else if (token == CPP_EOF)
151 break;
1368ee70 152 else if (token == CPP_NAME || token == CPP_ELLIPSIS)
b3ca463c 153 have_arg_list = 1;
7936052f 154 }
b3ca463c
PB
155 recognized_function (pfile->token_buffer + prev_id_start,
156 prev_id_end - prev_id_start,
e174accc
RS
157 (saw_inline ? 'I'
158 : in_extern_C_brace || current_extern_C
159 ? 'F' : 'f'),
b3ca463c
PB
160 pfile->token_buffer, prev_id_start,
161 have_arg_list,
162 fbuf->nominal_fname, func_lineno);
163 token = cpp_get_non_space_token (pfile);
1368ee70 164 if (token == CPP_OPEN_BRACE)
e9cd0b25
PB
165 {
166 /* skip body of (normally) inline function */
b3ca463c 167 skip_to_closing_brace (pfile);
e9cd0b25
PB
168 goto new_statement;
169 }
7a208c0b 170 goto maybe_handle_comma;
7936052f 171 }
b3ca463c 172 break;
7a208c0b 173 case CPP_OTHER:
973838fd 174 if (CPP_WRITTEN (pfile) == (size_t) start_written + 1
7a208c0b
RK
175 && (CPP_PWRITTEN (pfile)[-1] == '*'
176 || CPP_PWRITTEN (pfile)[-1] == '&'))
177 declarator_start = start_written;
178 else
179 goto handle_statement;
180 break;
181 case CPP_COMMA:
b3ca463c
PB
182 case CPP_SEMICOLON:
183 if (prev_id_start && saw_extern)
7936052f 184 {
b3ca463c
PB
185 recognized_extern (pfile->token_buffer + prev_id_start,
186 prev_id_end - prev_id_start,
187 pfile->token_buffer,
188 prev_id_start);
7936052f 189 }
0f41302f 190 /* ... fall through ... */
7a208c0b
RK
191 maybe_handle_comma:
192 if (token != CPP_COMMA)
193 goto new_statement;
47c3ed98 194#if 0
7a208c0b 195 handle_comma:
47c3ed98 196#endif
7a208c0b
RK
197 /* Handle multiple declarators in a single declaration,
198 as in: extern char *strcpy (), *strcat (), ... ; */
199 if (declarator_start == 0)
200 declarator_start = prev_id_start;
201 CPP_SET_WRITTEN (pfile, declarator_start);
202 break;
b3ca463c 203 case CPP_NAME:
7a208c0b
RK
204 /* "inline" and "extern" are recognized but skipped */
205 if (strcmp (pfile->token_buffer, "inline") == 0)
206 {
207 saw_inline = 1;
208 CPP_SET_WRITTEN (pfile, start_written);
209 }
210 if (strcmp (pfile->token_buffer, "extern") == 0)
211 {
212 saw_extern = 1;
213 CPP_SET_WRITTEN (pfile, start_written);
214 token = cpp_get_non_space_token (pfile);
215 if (token == CPP_STRING
216 && strcmp (pfile->token_buffer, "\"C\"") == 0)
217 {
218 CPP_SET_WRITTEN (pfile, start_written);
219 current_extern_C = 1;
220 token = cpp_get_non_space_token (pfile);
1368ee70 221 if (token == CPP_OPEN_BRACE)
7a208c0b
RK
222 {
223 brace_nesting++;
224 extern_C_braces[extern_C_braces_length++]
225 = brace_nesting;
226 goto new_statement;
227 }
228 }
229 else
1d300e19 230 continue;
7a208c0b
RK
231 break;
232 }
0f41302f 233 /* This may be the name of a variable or function. */
b3ca463c
PB
234 prev_id_start = start_written;
235 prev_id_end = CPP_WRITTEN (pfile);
236 break;
237
238 case CPP_EOF:
1d300e19 239 return 0;
b3ca463c 240
1368ee70 241 case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE: case CPP_DIRECTIVE:
b3ca463c
PB
242 goto new_statement; /* handle_statement? */
243
244 case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT: case CPP_POP:
0f41302f 245 /* Skip initial white space. */
7a208c0b
RK
246 if (start_written == 0)
247 CPP_SET_WRITTEN (pfile, 0);
b3ca463c
PB
248 break;
249
250 default:
7b15e61e 251 prev_id_start = 0;
7936052f 252 }
1d300e19
KG
253
254 start_written = CPP_WRITTEN (pfile);
255 token = cpp_get_token (pfile);
7936052f
PB
256 }
257}