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