]> 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"
487a6e06 22#include "gansidecl.h"
b3ca463c 23#include "cpplib.h"
d6f4ec51 24#include "scan.h"
7936052f
PB
25
26int brace_nesting = 0;
27
28/* The first extern_C_braces_length elements of extern_C_braces
29 indicate the (brace nesting levels of) left braces that were
e174accc 30 prefixed by extern "C". */
7936052f
PB
31int extern_C_braces_length = 0;
32char extern_C_braces[20];
33#define in_extern_C_brace (extern_C_braces_length>0)
34
35/* True if the function declaration currently being scanned is
e174accc 36 prefixed by extern "C". */
7936052f
PB
37int current_extern_C = 0;
38
e9cd0b25 39static void
b3ca463c
PB
40skip_to_closing_brace (pfile)
41 cpp_reader *pfile;
e9cd0b25
PB
42{
43 int nesting = 1;
44 for (;;)
45 {
b3ca463c
PB
46 enum cpp_token token = cpp_get_token (pfile);
47 if (token == CPP_EOF)
e9cd0b25 48 break;
b3ca463c 49 if (token == CPP_LBRACE)
e9cd0b25 50 nesting++;
b3ca463c 51 if (token == CPP_RBRACE && --nesting == 0)
e9cd0b25
PB
52 break;
53 }
54}
55
ba7ff9f9 56/* This function scans a C source file (actually, the output of cpp),
7a208c0b
RK
57 reading from FP. It looks for function declarations, and
58 external variable declarations.
59
60 The following grammar (as well as some extra stuff) is recognized:
61
62 declaration:
63 (decl-specifier)* declarator ("," declarator)* ";"
64 decl-specifier:
65 identifier
66 keyword
67 extern "C"
68 declarator:
69 (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
70 ptr-operator:
71 ("*" | "&") ("const" | "volatile")*
72 dname:
73 identifier
74
75Here dname is the actual name being declared.
76*/
ba7ff9f9 77
7936052f 78int
b3ca463c
PB
79scan_decls (pfile, argc, argv)
80 cpp_reader *pfile;
81 int argc;
0f41302f 82 char **argv;
7936052f 83{
e9cd0b25 84 int saw_extern, saw_inline;
1d300e19 85 int start_written;
7a208c0b
RK
86 /* If declarator_start is non-zero, it marks the start of the current
87 declarator. If it is zero, we are either still parsing the
0f41302f 88 decl-specs, or prev_id_start marks the start of the declarator. */
7a208c0b 89 int declarator_start;
b3ca463c
PB
90 int prev_id_start, prev_id_end;
91 enum cpp_token token;
92
7936052f 93 new_statement:
b3ca463c 94 CPP_SET_WRITTEN (pfile, 0);
1d300e19 95 start_written = 0;
b3ca463c
PB
96 token = cpp_get_token (pfile);
97
7936052f
PB
98 handle_statement:
99 current_extern_C = 0;
100 saw_extern = 0;
e9cd0b25 101 saw_inline = 0;
b3ca463c 102 if (token == CPP_RBRACE)
7936052f 103 {
e174accc 104 /* Pop an 'extern "C"' nesting level, if appropriate. */
7936052f
PB
105 if (extern_C_braces_length
106 && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
107 extern_C_braces_length--;
108 brace_nesting--;
109 goto new_statement;
110 }
b3ca463c 111 if (token == CPP_LBRACE)
7936052f
PB
112 {
113 brace_nesting++;
114 goto new_statement;
115 }
b3ca463c 116 if (token == CPP_EOF)
7936052f 117 return 0;
b3ca463c 118 if (token == CPP_SEMICOLON)
7936052f 119 goto new_statement;
b3ca463c 120 if (token != CPP_NAME)
7936052f 121 goto new_statement;
7a208c0b
RK
122
123 prev_id_start = 0;
124 declarator_start = 0;
7936052f
PB
125 for (;;)
126 {
b3ca463c 127 switch (token)
7936052f 128 {
b3ca463c 129 case CPP_LPAREN:
0f41302f 130 /* Looks like this is the start of a formal parameter list. */
b3ca463c 131 if (prev_id_start)
7936052f
PB
132 {
133 int nesting = 1;
b3ca463c
PB
134 int have_arg_list = 0;
135 cpp_buffer *fbuf = cpp_file_buffer (pfile);
136 long func_lineno;
137 cpp_buf_line_and_col (fbuf, &func_lineno, NULL);
7936052f
PB
138 for (;;)
139 {
b3ca463c
PB
140 token = cpp_get_token (pfile);
141 if (token == CPP_LPAREN)
7936052f 142 nesting++;
b3ca463c 143 else if (token == CPP_RPAREN)
e174accc 144 {
b3ca463c
PB
145 nesting--;
146 if (nesting == 0)
147 break;
e174accc 148 }
b3ca463c
PB
149 else if (token == CPP_EOF)
150 break;
151 else if (token == CPP_NAME || token == CPP_3DOTS)
152 have_arg_list = 1;
7936052f 153 }
b3ca463c
PB
154 recognized_function (pfile->token_buffer + prev_id_start,
155 prev_id_end - prev_id_start,
e174accc
RS
156 (saw_inline ? 'I'
157 : in_extern_C_brace || current_extern_C
158 ? 'F' : 'f'),
b3ca463c
PB
159 pfile->token_buffer, prev_id_start,
160 have_arg_list,
161 fbuf->nominal_fname, func_lineno);
162 token = cpp_get_non_space_token (pfile);
163 if (token == CPP_LBRACE)
e9cd0b25
PB
164 {
165 /* skip body of (normally) inline function */
b3ca463c 166 skip_to_closing_brace (pfile);
e9cd0b25
PB
167 goto new_statement;
168 }
7a208c0b 169 goto maybe_handle_comma;
7936052f 170 }
b3ca463c 171 break;
7a208c0b
RK
172 case CPP_OTHER:
173 if (CPP_WRITTEN (pfile) == start_written + 1
174 && (CPP_PWRITTEN (pfile)[-1] == '*'
175 || CPP_PWRITTEN (pfile)[-1] == '&'))
176 declarator_start = start_written;
177 else
178 goto handle_statement;
179 break;
180 case CPP_COMMA:
b3ca463c
PB
181 case CPP_SEMICOLON:
182 if (prev_id_start && saw_extern)
7936052f 183 {
b3ca463c
PB
184 recognized_extern (pfile->token_buffer + prev_id_start,
185 prev_id_end - prev_id_start,
186 pfile->token_buffer,
187 prev_id_start);
7936052f 188 }
0f41302f 189 /* ... fall through ... */
7a208c0b
RK
190 maybe_handle_comma:
191 if (token != CPP_COMMA)
192 goto new_statement;
193 handle_comma:
194 /* Handle multiple declarators in a single declaration,
195 as in: extern char *strcpy (), *strcat (), ... ; */
196 if (declarator_start == 0)
197 declarator_start = prev_id_start;
198 CPP_SET_WRITTEN (pfile, declarator_start);
199 break;
b3ca463c 200 case CPP_NAME:
7a208c0b
RK
201 /* "inline" and "extern" are recognized but skipped */
202 if (strcmp (pfile->token_buffer, "inline") == 0)
203 {
204 saw_inline = 1;
205 CPP_SET_WRITTEN (pfile, start_written);
206 }
207 if (strcmp (pfile->token_buffer, "extern") == 0)
208 {
209 saw_extern = 1;
210 CPP_SET_WRITTEN (pfile, start_written);
211 token = cpp_get_non_space_token (pfile);
212 if (token == CPP_STRING
213 && strcmp (pfile->token_buffer, "\"C\"") == 0)
214 {
215 CPP_SET_WRITTEN (pfile, start_written);
216 current_extern_C = 1;
217 token = cpp_get_non_space_token (pfile);
218 if (token == CPP_LBRACE)
219 {
220 brace_nesting++;
221 extern_C_braces[extern_C_braces_length++]
222 = brace_nesting;
223 goto new_statement;
224 }
225 }
226 else
1d300e19 227 continue;
7a208c0b
RK
228 break;
229 }
0f41302f 230 /* This may be the name of a variable or function. */
b3ca463c
PB
231 prev_id_start = start_written;
232 prev_id_end = CPP_WRITTEN (pfile);
233 break;
234
235 case CPP_EOF:
1d300e19 236 return 0;
b3ca463c
PB
237
238 case CPP_LBRACE: case CPP_RBRACE: case CPP_DIRECTIVE:
239 goto new_statement; /* handle_statement? */
240
241 case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT: case CPP_POP:
0f41302f 242 /* Skip initial white space. */
7a208c0b
RK
243 if (start_written == 0)
244 CPP_SET_WRITTEN (pfile, 0);
b3ca463c
PB
245 break;
246
247 default:
7b15e61e 248 prev_id_start = 0;
7936052f 249 }
1d300e19
KG
250
251 start_written = CPP_WRITTEN (pfile);
252 token = cpp_get_token (pfile);
7936052f
PB
253 }
254}