]> gcc.gnu.org Git - gcc.git/blame - gcc/scan-decls.c
formatting tweaks
[gcc.git] / gcc / scan-decls.c
CommitLineData
7936052f 1/* scan-decls.c - Extracts declarations from cpp output.
7a208c0b 2 Copyright (C) 1993, 1995 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
7936052f
PB
20#include <stdio.h>
21#include <ctype.h>
ffde73b0 22#include "hconfig.h"
b3ca463c 23#include "cpplib.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;
b3ca463c 84 int old_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
PB
93 CPP_SET_WRITTEN (pfile, 0);
94 token = cpp_get_token (pfile);
95
7936052f
PB
96 handle_statement:
97 current_extern_C = 0;
98 saw_extern = 0;
e9cd0b25 99 saw_inline = 0;
b3ca463c 100 if (token == CPP_RBRACE)
7936052f 101 {
e174accc 102 /* Pop an 'extern "C"' nesting level, if appropriate. */
7936052f
PB
103 if (extern_C_braces_length
104 && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
105 extern_C_braces_length--;
106 brace_nesting--;
107 goto new_statement;
108 }
b3ca463c 109 if (token == CPP_LBRACE)
7936052f
PB
110 {
111 brace_nesting++;
112 goto new_statement;
113 }
b3ca463c 114 if (token == CPP_EOF)
7936052f 115 return 0;
b3ca463c 116 if (token == CPP_SEMICOLON)
7936052f 117 goto new_statement;
b3ca463c 118 if (token != CPP_NAME)
7936052f 119 goto new_statement;
7a208c0b
RK
120
121 prev_id_start = 0;
122 declarator_start = 0;
7936052f
PB
123 for (;;)
124 {
b3ca463c
PB
125 int start_written = CPP_WRITTEN (pfile);
126 token = cpp_get_token (pfile);
7a208c0b 127 handle_token:
b3ca463c 128 switch (token)
7936052f 129 {
b3ca463c 130 case CPP_LPAREN:
0f41302f 131 /* Looks like this is the start of a formal parameter list. */
b3ca463c 132 if (prev_id_start)
7936052f
PB
133 {
134 int nesting = 1;
b3ca463c
PB
135 int have_arg_list = 0;
136 cpp_buffer *fbuf = cpp_file_buffer (pfile);
137 long func_lineno;
138 cpp_buf_line_and_col (fbuf, &func_lineno, NULL);
7936052f
PB
139 for (;;)
140 {
b3ca463c
PB
141 token = cpp_get_token (pfile);
142 if (token == CPP_LPAREN)
7936052f 143 nesting++;
b3ca463c 144 else if (token == CPP_RPAREN)
e174accc 145 {
b3ca463c
PB
146 nesting--;
147 if (nesting == 0)
148 break;
e174accc 149 }
b3ca463c
PB
150 else if (token == CPP_EOF)
151 break;
152 else if (token == CPP_NAME || token == CPP_3DOTS)
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);
164 if (token == CPP_LBRACE)
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
RK
173 case CPP_OTHER:
174 if (CPP_WRITTEN (pfile) == start_written + 1
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;
194 handle_comma:
195 /* Handle multiple declarators in a single declaration,
196 as in: extern char *strcpy (), *strcat (), ... ; */
197 if (declarator_start == 0)
198 declarator_start = prev_id_start;
199 CPP_SET_WRITTEN (pfile, declarator_start);
200 break;
b3ca463c 201 case CPP_NAME:
7a208c0b
RK
202 /* "inline" and "extern" are recognized but skipped */
203 if (strcmp (pfile->token_buffer, "inline") == 0)
204 {
205 saw_inline = 1;
206 CPP_SET_WRITTEN (pfile, start_written);
207 }
208 if (strcmp (pfile->token_buffer, "extern") == 0)
209 {
210 saw_extern = 1;
211 CPP_SET_WRITTEN (pfile, start_written);
212 token = cpp_get_non_space_token (pfile);
213 if (token == CPP_STRING
214 && strcmp (pfile->token_buffer, "\"C\"") == 0)
215 {
216 CPP_SET_WRITTEN (pfile, start_written);
217 current_extern_C = 1;
218 token = cpp_get_non_space_token (pfile);
219 if (token == CPP_LBRACE)
220 {
221 brace_nesting++;
222 extern_C_braces[extern_C_braces_length++]
223 = brace_nesting;
224 goto new_statement;
225 }
226 }
227 else
228 goto handle_token;
229 break;
230 }
0f41302f 231 /* This may be the name of a variable or function. */
b3ca463c
PB
232 prev_id_start = start_written;
233 prev_id_end = CPP_WRITTEN (pfile);
234 break;
235
236 case CPP_EOF:
237 return; /* ??? FIXME */
238
239 case CPP_LBRACE: case CPP_RBRACE: case CPP_DIRECTIVE:
240 goto new_statement; /* handle_statement? */
241
242 case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT: case CPP_POP:
0f41302f 243 /* Skip initial white space. */
7a208c0b
RK
244 if (start_written == 0)
245 CPP_SET_WRITTEN (pfile, 0);
b3ca463c
PB
246 break;
247
248 default:
7b15e61e 249 prev_id_start = 0;
7936052f 250 }
7936052f
PB
251 }
252}
This page took 0.307578 seconds and 5 git commands to generate.