(store_constructor, ARRAY_TYPE): Use code for non-integer INDEX for
[official-gcc.git] / gcc / scan-decls.c
blob6fbc8ee9a8e78c675d8f6073ceb9bc3508e1efb2
1 /* scan-decls.c - Extracts declarations from cpp output.
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 Written by Per Bothner <bothner@cygnus.com>, July 1993. */
20 #include <stdio.h>
21 #include <ctype.h>
22 #include "hconfig.h"
23 #include "scan.h"
25 sstring buf;
26 sstring rtype;
27 sstring arg_list;
29 int brace_nesting = 0;
31 /* The first extern_C_braces_length elements of extern_C_braces
32 indicate the (brace nesting levels of) left braces that were
33 prefixed by extern "C". */
34 int extern_C_braces_length = 0;
35 char extern_C_braces[20];
36 #define in_extern_C_brace (extern_C_braces_length>0)
38 /* True if the function declaration currently being scanned is
39 prefixed by extern "C". */
40 int current_extern_C = 0;
42 static void
43 skip_to_closing_brace (fp)
44 FILE *fp;
46 int nesting = 1;
47 for (;;)
49 int c = get_token (fp, &buf);
50 if (c == EOF)
51 break;
52 if (c == '{')
53 nesting++;
54 if (c == '}' && --nesting == 0)
55 break;
59 /* This function scans a C source file (actually, the output of cpp),
60 reading from FP. It looks for function declarations, and certain
61 other interesting sequences (external variables and macros). */
63 int
64 scan_decls (fp)
65 FILE *fp;
67 int c;
68 int saw_extern, saw_inline;
70 new_statement:
71 c = get_token (fp, &buf);
72 handle_statement:
73 current_extern_C = 0;
74 saw_extern = 0;
75 saw_inline = 0;
76 if (c == '}')
78 /* Pop an 'extern "C"' nesting level, if appropriate. */
79 if (extern_C_braces_length
80 && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
81 extern_C_braces_length--;
82 brace_nesting--;
83 goto new_statement;
85 if (c == '{')
87 brace_nesting++;
88 goto new_statement;
90 if (c == EOF)
91 return 0;
92 if (c == ';')
93 goto new_statement;
94 if (c != IDENTIFIER_TOKEN)
95 goto new_statement;
96 rtype.ptr = rtype.base;
97 if (SSTRING_LENGTH (&buf) > 16
98 && strncmp (buf.base, "__DEFINED_MACRO_", 16) == 0)
100 /* For certain interesting macro names, fixproto puts
101 #ifdef FOO
102 __DEFINED_MACRO_FOO
103 #endif
104 into the file to be pre-processed. So if we see __DEFINED_MACRO_FOO,
105 it means FOO was defined, which we may want to make a note of. */
106 recognized_macro (buf.base+16);
107 goto new_statement;
109 if (strcmp (buf.base, "inline") == 0)
111 saw_inline = 1;
112 c = get_token (fp, &buf);
114 if (strcmp (buf.base, "extern") == 0)
116 saw_extern = 1;
117 c = get_token (fp, &buf);
118 if (c == STRING_TOKEN && strcmp (buf.base, "C") == 0)
120 current_extern_C = 1;
121 c = get_token (fp, &buf);
122 if (c == '{')
124 brace_nesting++;
125 extern_C_braces[extern_C_braces_length++] = brace_nesting;
126 goto new_statement;
128 c = get_token (fp, &buf);
131 for (;;)
133 int followingc = getc (fp); /* char following token in buf */
135 MAKE_SSTRING_SPACE (&rtype, 1);
136 *rtype.ptr = 0;
138 if (c == IDENTIFIER_TOKEN)
140 int nextc = skip_spaces (fp, followingc);
141 if (nextc == '(')
143 int nesting = 1;
144 int func_lineno = source_lineno;
145 char *args;
147 arg_list.ptr = arg_list.base;
148 for (;;)
150 c = getc (fp);
151 if (c == '(')
152 nesting++;
153 else if (c == ')')
154 if (--nesting == 0)
155 break;
156 if (c == EOF)
157 break;
158 if (c == '\n')
160 c = ' ';
161 source_lineno++;
162 lineno++;
164 SSTRING_PUT (&arg_list, c);
166 SSTRING_PUT (&arg_list, '\0');
167 args = arg_list.base;
168 while (*args == ' ')
169 args++;
170 recognized_function (buf.base,
171 (saw_inline ? 'I'
172 : in_extern_C_brace || current_extern_C
173 ? 'F' : 'f'),
174 rtype.base, args,
175 source_filename.base, func_lineno);
176 c = get_token (fp, &buf);
177 if (c == '{')
179 /* skip body of (normally) inline function */
180 skip_to_closing_brace (fp);
181 goto new_statement;
183 goto handle_statement;
185 else if (nextc == ';' && saw_extern)
187 recognized_extern (buf.base, rtype.base);
188 goto new_statement;
190 else
191 ungetc (nextc, fp);
193 else if (followingc != EOF)
194 ungetc (followingc, fp);
195 if (c == ';' || c == '{' || c == '}' || c == EOF)
196 goto handle_statement;
197 sstring_append (&rtype, &buf);
198 if (followingc == ' ' || followingc == '\t' || followingc == '\n')
199 SSTRING_PUT (&rtype, ' ');
200 c = get_token (fp, &buf);