Mercurial > hg > CbC > CbC_gcc
annotate gcc/gengtype-parse.c @ 90:99e7b6776dd1
implemeted __rectype expression. add CbC-exanples/fact-rectype.s
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 25 Dec 2011 04:04:42 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Process source files and output type information. |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2 Copyright (C) 2006, 2007, 2010 Free Software Foundation, Inc. |
0 | 3 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
4 This file is part of GCC. |
0 | 5 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
6 GCC is free software; you can redistribute it and/or modify it under |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
7 the terms of the GNU General Public License as published by the Free |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
8 Software Foundation; either version 3, or (at your option) any later |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
9 version. |
0 | 10 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
14 for more details. |
0 | 15 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
16 You should have received a copy of the GNU General Public License |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
17 along with GCC; see the file COPYING3. If not see |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
18 <http://www.gnu.org/licenses/>. */ |
0 | 19 |
20 #include "bconfig.h" | |
21 #include "system.h" | |
22 #include "gengtype.h" | |
23 | |
24 /* This is a simple recursive-descent parser which understands a subset of | |
25 the C type grammar. | |
26 | |
27 Rule functions are suffixed _seq if they scan a sequence of items; | |
28 _opt if they may consume zero tokens; _seqopt if both are true. The | |
29 "consume_" prefix indicates that a sequence of tokens is parsed for | |
30 syntactic correctness and then thrown away. */ | |
31 | |
32 /* Simple one-token lookahead mechanism. */ | |
33 | |
34 struct token | |
35 { | |
36 const char *value; | |
37 int code; | |
38 bool valid; | |
39 }; | |
40 static struct token T; | |
41 | |
42 /* Retrieve the code of the current token; if there is no current token, | |
43 get the next one from the lexer. */ | |
44 static inline int | |
45 token (void) | |
46 { | |
47 if (!T.valid) | |
48 { | |
49 T.code = yylex (&T.value); | |
50 T.valid = true; | |
51 } | |
52 return T.code; | |
53 } | |
54 | |
55 /* Retrieve the value of the current token (if any) and mark it consumed. | |
56 The next call to token() will get another token from the lexer. */ | |
57 static inline const char * | |
58 advance (void) | |
59 { | |
60 T.valid = false; | |
61 return T.value; | |
62 } | |
63 | |
64 /* Diagnostics. */ | |
65 | |
66 /* This array is indexed by the token code minus CHAR_TOKEN_OFFSET. */ | |
67 static const char *const token_names[] = { | |
68 "GTY", | |
69 "typedef", | |
70 "extern", | |
71 "static", | |
72 "union", | |
73 "struct", | |
74 "enum", | |
75 "VEC", | |
76 "DEF_VEC_[OP]", | |
77 "DEF_VEC_I", | |
78 "DEF_VEC_ALLOC_[IOP]", | |
79 "...", | |
80 "ptr_alias", | |
81 "nested_ptr", | |
82 "a param<N>_is option", | |
83 "a number", | |
84 "a scalar type", | |
85 "an identifier", | |
86 "a string constant", | |
87 "a character constant", | |
88 "an array declarator", | |
89 }; | |
90 | |
91 /* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */ | |
92 static const char *const token_value_format[] = { | |
93 "%s", | |
94 "'%s'", | |
95 "'%s'", | |
96 "'%s'", | |
97 "'\"%s\"'", | |
98 "\"'%s'\"", | |
99 "'[%s]'", | |
100 }; | |
101 | |
102 /* Produce a printable representation for a token defined by CODE and | |
103 VALUE. This sometimes returns pointers into malloc memory and | |
104 sometimes not, therefore it is unsafe to free the pointer it | |
105 returns, so that memory is leaked. This does not matter, as this | |
106 function is only used for diagnostics, and in a successful run of | |
107 the program there will be none. */ | |
108 static const char * | |
109 print_token (int code, const char *value) | |
110 { | |
111 if (code < CHAR_TOKEN_OFFSET) | |
112 return xasprintf ("'%c'", code); | |
113 else if (code < FIRST_TOKEN_WITH_VALUE) | |
114 return xasprintf ("'%s'", token_names[code - CHAR_TOKEN_OFFSET]); | |
115 else if (!value) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
116 return token_names[code - CHAR_TOKEN_OFFSET]; /* don't quote these */ |
0 | 117 else |
118 return xasprintf (token_value_format[code - FIRST_TOKEN_WITH_VALUE], | |
119 value); | |
120 } | |
121 | |
122 /* Convenience wrapper around print_token which produces the printable | |
123 representation of the current token. */ | |
124 static inline const char * | |
125 print_cur_token (void) | |
126 { | |
127 return print_token (T.code, T.value); | |
128 } | |
129 | |
130 /* Report a parse error on the current line, with diagnostic MSG. | |
131 Behaves as standard printf with respect to additional arguments and | |
132 format escapes. */ | |
133 static void ATTRIBUTE_PRINTF_1 | |
134 parse_error (const char *msg, ...) | |
135 { | |
136 va_list ap; | |
137 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
138 fprintf (stderr, "%s:%d: parse error: ", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
139 get_input_file_name (lexer_line.file), lexer_line.line); |
0 | 140 |
141 va_start (ap, msg); | |
142 vfprintf (stderr, msg, ap); | |
143 va_end (ap); | |
144 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
145 fputc ('\n', stderr); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
146 |
0 | 147 hit_error = true; |
148 } | |
149 | |
150 /* If the next token does not have code T, report a parse error; otherwise | |
151 return the token's value. */ | |
152 static const char * | |
153 require (int t) | |
154 { | |
155 int u = token (); | |
156 const char *v = advance (); | |
157 if (u != t) | |
158 { | |
159 parse_error ("expected %s, have %s", | |
160 print_token (t, 0), print_token (u, v)); | |
161 return 0; | |
162 } | |
163 return v; | |
164 } | |
165 | |
166 /* If the next token does not have one of the codes T1 or T2, report a | |
167 parse error; otherwise return the token's value. */ | |
168 static const char * | |
169 require2 (int t1, int t2) | |
170 { | |
171 int u = token (); | |
172 const char *v = advance (); | |
173 if (u != t1 && u != t2) | |
174 { | |
175 parse_error ("expected %s or %s, have %s", | |
176 print_token (t1, 0), print_token (t2, 0), | |
177 print_token (u, v)); | |
178 return 0; | |
179 } | |
180 return v; | |
181 } | |
182 | |
183 /* Near-terminals. */ | |
184 | |
185 /* C-style string constant concatenation: STRING+ | |
186 Bare STRING should appear nowhere else in this file. */ | |
187 static const char * | |
188 string_seq (void) | |
189 { | |
190 const char *s1, *s2; | |
191 size_t l1, l2; | |
192 char *buf; | |
193 | |
194 s1 = require (STRING); | |
195 if (s1 == 0) | |
196 return ""; | |
197 while (token () == STRING) | |
198 { | |
199 s2 = advance (); | |
200 | |
201 l1 = strlen (s1); | |
202 l2 = strlen (s2); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
203 buf = XRESIZEVEC (char, CONST_CAST (char *, s1), l1 + l2 + 1); |
0 | 204 memcpy (buf + l1, s2, l2 + 1); |
205 XDELETE (CONST_CAST (char *, s2)); | |
206 s1 = buf; | |
207 } | |
208 return s1; | |
209 } | |
210 | |
211 /* typedef_name: either an ID, or VEC(x,y) which is translated to VEC_x_y. | |
212 Use only where VEC(x,y) is legitimate, i.e. in positions where a | |
213 typedef name may appear. */ | |
214 static const char * | |
215 typedef_name (void) | |
216 { | |
217 if (token () == VEC_TOKEN) | |
218 { | |
219 const char *c1, *c2, *r; | |
220 advance (); | |
221 require ('('); | |
222 c1 = require2 (ID, SCALAR); | |
223 require (','); | |
224 c2 = require (ID); | |
225 require (')'); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
226 r = concat ("VEC_", c1, "_", c2, (char *) 0); |
0 | 227 free (CONST_CAST (char *, c1)); |
228 free (CONST_CAST (char *, c2)); | |
229 return r; | |
230 } | |
231 else | |
232 return require (ID); | |
233 } | |
234 | |
235 /* Absorb a sequence of tokens delimited by balanced ()[]{}. */ | |
236 static void | |
237 consume_balanced (int opener, int closer) | |
238 { | |
239 require (opener); | |
240 for (;;) | |
241 switch (token ()) | |
242 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
243 default: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
244 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
245 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
246 case '(': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
247 consume_balanced ('(', ')'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
248 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
249 case '[': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
250 consume_balanced ('[', ']'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
251 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
252 case '{': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
253 consume_balanced ('{', '}'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
254 break; |
0 | 255 |
256 case '}': | |
257 case ']': | |
258 case ')': | |
259 if (token () != closer) | |
260 parse_error ("unbalanced delimiters - expected '%c', have '%c'", | |
261 closer, token ()); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
262 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
263 return; |
0 | 264 |
265 case EOF_TOKEN: | |
266 parse_error ("unexpected end of file within %c%c-delimited construct", | |
267 opener, closer); | |
268 return; | |
269 } | |
270 } | |
271 | |
272 /* Absorb a sequence of tokens, possibly including ()[]{}-delimited | |
273 expressions, until we encounter a semicolon outside any such | |
274 delimiters; absorb that too. If IMMEDIATE is true, it is an error | |
275 if the semicolon is not the first token encountered. */ | |
276 static void | |
277 consume_until_semi (bool immediate) | |
278 { | |
279 if (immediate && token () != ';') | |
280 require (';'); | |
281 for (;;) | |
282 switch (token ()) | |
283 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
284 case ';': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
285 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
286 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
287 default: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
288 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
289 break; |
0 | 290 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
291 case '(': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
292 consume_balanced ('(', ')'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
293 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
294 case '[': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
295 consume_balanced ('[', ']'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
296 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
297 case '{': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
298 consume_balanced ('{', '}'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
299 break; |
0 | 300 |
301 case '}': | |
302 case ']': | |
303 case ')': | |
304 parse_error ("unmatched '%c' while scanning for ';'", token ()); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
305 return; |
0 | 306 |
307 case EOF_TOKEN: | |
308 parse_error ("unexpected end of file while scanning for ';'"); | |
309 return; | |
310 } | |
311 } | |
312 | |
313 /* Absorb a sequence of tokens, possibly including ()[]{}-delimited | |
314 expressions, until we encounter a comma or semicolon outside any | |
315 such delimiters; absorb that too. If IMMEDIATE is true, it is an | |
316 error if the comma or semicolon is not the first token encountered. | |
317 Returns true if the loop ended with a comma. */ | |
318 static bool | |
319 consume_until_comma_or_semi (bool immediate) | |
320 { | |
321 if (immediate && token () != ',' && token () != ';') | |
322 require2 (',', ';'); | |
323 for (;;) | |
324 switch (token ()) | |
325 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
326 case ',': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
327 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
328 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
329 case ';': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
330 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
331 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
332 default: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
333 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
334 break; |
0 | 335 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
336 case '(': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
337 consume_balanced ('(', ')'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
338 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
339 case '[': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
340 consume_balanced ('[', ']'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
341 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
342 case '{': |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
343 consume_balanced ('{', '}'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
344 break; |
0 | 345 |
346 case '}': | |
347 case ']': | |
348 case ')': | |
349 parse_error ("unmatched '%s' while scanning for ',' or ';'", | |
350 print_cur_token ()); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
351 return false; |
0 | 352 |
353 case EOF_TOKEN: | |
354 parse_error ("unexpected end of file while scanning for ',' or ';'"); | |
355 return false; | |
356 } | |
357 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
358 |
0 | 359 |
360 /* GTY(()) option handling. */ | |
361 static type_p type (options_p *optsp, bool nested); | |
362 | |
363 /* Optional parenthesized string: ('(' string_seq ')')? */ | |
364 static options_p | |
365 str_optvalue_opt (options_p prev) | |
366 { | |
367 const char *name = advance (); | |
368 const char *value = ""; | |
369 if (token () == '(') | |
370 { | |
371 advance (); | |
372 value = string_seq (); | |
373 require (')'); | |
374 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
375 return create_string_option (prev, name, value); |
0 | 376 } |
377 | |
378 /* absdecl: type '*'* | |
379 -- a vague approximation to what the C standard calls an abstract | |
380 declarator. The only kinds that are actually used are those that | |
381 are just a bare type and those that have trailing pointer-stars. | |
382 Further kinds should be implemented if and when they become | |
383 necessary. Used only within GTY(()) option values, therefore | |
384 further GTY(()) tags within the type are invalid. Note that the | |
385 return value has already been run through adjust_field_type. */ | |
386 static type_p | |
387 absdecl (void) | |
388 { | |
389 type_p ty; | |
390 options_p opts; | |
391 | |
392 ty = type (&opts, true); | |
393 while (token () == '*') | |
394 { | |
395 ty = create_pointer (ty); | |
396 advance (); | |
397 } | |
398 | |
399 if (opts) | |
400 parse_error ("nested GTY(()) options are invalid"); | |
401 | |
402 return adjust_field_type (ty, 0); | |
403 } | |
404 | |
405 /* Type-option: '(' absdecl ')' */ | |
406 static options_p | |
407 type_optvalue (options_p prev, const char *name) | |
408 { | |
409 type_p ty; | |
410 require ('('); | |
411 ty = absdecl (); | |
412 require (')'); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
413 return create_type_option (prev, name, ty); |
0 | 414 } |
415 | |
416 /* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */ | |
417 static options_p | |
418 nestedptr_optvalue (options_p prev) | |
419 { | |
420 type_p ty; | |
421 const char *from, *to; | |
422 | |
423 require ('('); | |
424 ty = absdecl (); | |
425 require (','); | |
426 to = string_seq (); | |
427 require (','); | |
428 from = string_seq (); | |
429 require (')'); | |
430 | |
431 return create_nested_ptr_option (prev, ty, to, from); | |
432 } | |
433 | |
434 /* One GTY(()) option: | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
435 ID str_optvalue_opt |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
436 | PTR_ALIAS type_optvalue |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
437 | PARAM_IS type_optvalue |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
438 | NESTED_PTR nestedptr_optvalue |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
439 */ |
0 | 440 static options_p |
441 option (options_p prev) | |
442 { | |
443 switch (token ()) | |
444 { | |
445 case ID: | |
446 return str_optvalue_opt (prev); | |
447 | |
448 case PTR_ALIAS: | |
449 advance (); | |
450 return type_optvalue (prev, "ptr_alias"); | |
451 | |
452 case PARAM_IS: | |
453 return type_optvalue (prev, advance ()); | |
454 | |
455 case NESTED_PTR: | |
456 advance (); | |
457 return nestedptr_optvalue (prev); | |
458 | |
459 default: | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
460 parse_error ("expected an option keyword, have %s", print_cur_token ()); |
0 | 461 advance (); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
462 return create_string_option (prev, "", ""); |
0 | 463 } |
464 } | |
465 | |
466 /* One comma-separated list of options. */ | |
467 static options_p | |
468 option_seq (void) | |
469 { | |
470 options_p o; | |
471 | |
472 o = option (0); | |
473 while (token () == ',') | |
474 { | |
475 advance (); | |
476 o = option (o); | |
477 } | |
478 return o; | |
479 } | |
480 | |
481 /* GTY marker: 'GTY' '(' '(' option_seq? ')' ')' */ | |
482 static options_p | |
483 gtymarker (void) | |
484 { | |
485 options_p result = 0; | |
486 require (GTY_TOKEN); | |
487 require ('('); | |
488 require ('('); | |
489 if (token () != ')') | |
490 result = option_seq (); | |
491 require (')'); | |
492 require (')'); | |
493 return result; | |
494 } | |
495 | |
496 /* Optional GTY marker. */ | |
497 static options_p | |
498 gtymarker_opt (void) | |
499 { | |
500 if (token () != GTY_TOKEN) | |
501 return 0; | |
502 return gtymarker (); | |
503 } | |
504 | |
505 /* Declarators. The logic here is largely lifted from c-parser.c. | |
506 Note that we do not have to process abstract declarators, which can | |
507 appear only in parameter type lists or casts (but see absdecl, | |
508 above). Also, type qualifiers are thrown out in gengtype-lex.l so | |
509 we don't have to do it. */ | |
510 | |
511 /* array_and_function_declarators_opt: | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
512 \epsilon |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
513 array_and_function_declarators_opt ARRAY |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
514 array_and_function_declarators_opt '(' ... ')' |
0 | 515 |
516 where '...' indicates stuff we ignore except insofar as grouping | |
517 symbols ()[]{} must balance. | |
518 | |
519 Subroutine of direct_declarator - do not use elsewhere. */ | |
520 | |
521 static type_p | |
522 array_and_function_declarators_opt (type_p ty) | |
523 { | |
524 if (token () == ARRAY) | |
525 { | |
526 const char *array = advance (); | |
527 return create_array (array_and_function_declarators_opt (ty), array); | |
528 } | |
529 else if (token () == '(') | |
530 { | |
531 /* We don't need exact types for functions. */ | |
532 consume_balanced ('(', ')'); | |
533 array_and_function_declarators_opt (ty); | |
534 return create_scalar_type ("function type"); | |
535 } | |
536 else | |
537 return ty; | |
538 } | |
539 | |
540 static type_p inner_declarator (type_p, const char **, options_p *); | |
541 | |
542 /* direct_declarator: | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
543 '(' inner_declarator ')' |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
544 gtymarker_opt ID array_and_function_declarators_opt |
0 | 545 |
546 Subroutine of declarator, mutually recursive with inner_declarator; | |
547 do not use elsewhere. */ | |
548 static type_p | |
549 direct_declarator (type_p ty, const char **namep, options_p *optsp) | |
550 { | |
551 /* The first token in a direct-declarator must be an ID, a | |
552 GTY marker, or an open parenthesis. */ | |
553 switch (token ()) | |
554 { | |
555 case GTY_TOKEN: | |
556 *optsp = gtymarker (); | |
557 /* fall through */ | |
558 case ID: | |
559 *namep = require (ID); | |
560 break; | |
561 | |
562 case '(': | |
563 advance (); | |
564 ty = inner_declarator (ty, namep, optsp); | |
565 require (')'); | |
566 break; | |
567 | |
568 default: | |
569 parse_error ("expected '(', 'GTY', or an identifier, have %s", | |
570 print_cur_token ()); | |
571 /* Do _not_ advance if what we have is a close squiggle brace, as | |
572 we will get much better error recovery that way. */ | |
573 if (token () != '}') | |
574 advance (); | |
575 return 0; | |
576 } | |
577 return array_and_function_declarators_opt (ty); | |
578 } | |
579 | |
580 /* The difference between inner_declarator and declarator is in the | |
581 handling of stars. Consider this declaration: | |
582 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
583 char * (*pfc) (void) |
0 | 584 |
585 It declares a pointer to a function that takes no arguments and | |
586 returns a char*. To construct the correct type for this | |
587 declaration, the star outside the parentheses must be processed | |
588 _before_ the function type, the star inside the parentheses must | |
589 be processed _after_ the function type. To accomplish this, | |
590 declarator() creates pointers before recursing (it is actually | |
591 coded as a while loop), whereas inner_declarator() recurses before | |
592 creating pointers. */ | |
593 | |
594 /* inner_declarator: | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
595 '*' inner_declarator |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
596 direct_declarator |
0 | 597 |
598 Mutually recursive subroutine of direct_declarator; do not use | |
599 elsewhere. */ | |
600 | |
601 static type_p | |
602 inner_declarator (type_p ty, const char **namep, options_p *optsp) | |
603 { | |
604 if (token () == '*') | |
605 { | |
606 type_p inner; | |
607 advance (); | |
608 inner = inner_declarator (ty, namep, optsp); | |
609 if (inner == 0) | |
610 return 0; | |
611 else | |
612 return create_pointer (ty); | |
613 } | |
614 else | |
615 return direct_declarator (ty, namep, optsp); | |
616 } | |
617 | |
618 /* declarator: '*'+ direct_declarator | |
619 | |
620 This is the sole public interface to this part of the grammar. | |
621 Arguments are the type known so far, a pointer to where the name | |
622 may be stored, and a pointer to where GTY options may be stored. | |
623 Returns the final type. */ | |
624 | |
625 static type_p | |
626 declarator (type_p ty, const char **namep, options_p *optsp) | |
627 { | |
628 *namep = 0; | |
629 *optsp = 0; | |
630 while (token () == '*') | |
631 { | |
632 advance (); | |
633 ty = create_pointer (ty); | |
634 } | |
635 return direct_declarator (ty, namep, optsp); | |
636 } | |
637 | |
638 /* Types and declarations. */ | |
639 | |
640 /* Structure field(s) declaration: | |
641 ( | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
642 type bitfield ';' |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
643 | type declarator bitfield? ( ',' declarator bitfield? )+ ';' |
0 | 644 )+ |
645 | |
646 Knows that such declarations must end with a close brace (or, | |
647 erroneously, at EOF). | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
648 */ |
0 | 649 static pair_p |
650 struct_field_seq (void) | |
651 { | |
652 pair_p f = 0; | |
653 type_p ty, dty; | |
654 options_p opts, dopts; | |
655 const char *name; | |
656 bool another; | |
657 | |
658 do | |
659 { | |
660 ty = type (&opts, true); | |
661 /* Another piece of the IFCVT_EXTRA_FIELDS special case, see type(). */ | |
662 if (!ty && token () == '}') | |
663 break; | |
664 | |
665 if (!ty || token () == ':') | |
666 { | |
667 consume_until_semi (false); | |
668 continue; | |
669 } | |
670 | |
671 do | |
672 { | |
673 dty = declarator (ty, &name, &dopts); | |
674 /* There could be any number of weird things after the declarator, | |
675 notably bitfield declarations and __attribute__s. If this | |
676 function returns true, the last thing was a comma, so we have | |
677 more than one declarator paired with the current type. */ | |
678 another = consume_until_comma_or_semi (false); | |
679 | |
680 if (!dty) | |
681 continue; | |
682 | |
683 if (opts && dopts) | |
684 parse_error ("two GTY(()) options for field %s", name); | |
685 if (opts && !dopts) | |
686 dopts = opts; | |
687 | |
688 f = create_field_at (f, dty, name, dopts, &lexer_line); | |
689 } | |
690 while (another); | |
691 } | |
692 while (token () != '}' && token () != EOF_TOKEN); | |
693 return nreverse_pairs (f); | |
694 } | |
695 | |
696 /* This is called type(), but what it parses (sort of) is what C calls | |
697 declaration-specifiers and specifier-qualifier-list: | |
698 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
699 SCALAR |
0 | 700 | ID // typedef |
701 | (STRUCT|UNION) ID? gtymarker? ( '{' gtymarker? struct_field_seq '}' )? | |
702 | ENUM ID ( '{' ... '}' )? | |
703 | |
704 Returns a partial type; under some conditions (notably | |
705 "struct foo GTY((...)) thing;") it may write an options | |
706 structure to *OPTSP. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
707 */ |
0 | 708 static type_p |
709 type (options_p *optsp, bool nested) | |
710 { | |
711 const char *s; | |
712 *optsp = 0; | |
713 switch (token ()) | |
714 { | |
715 case SCALAR: | |
716 s = advance (); | |
717 return create_scalar_type (s); | |
718 | |
719 case ID: | |
720 case VEC_TOKEN: | |
721 s = typedef_name (); | |
722 return resolve_typedef (s, &lexer_line); | |
723 | |
724 case STRUCT: | |
725 case UNION: | |
726 { | |
727 options_p opts = 0; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
728 /* GTY annotations follow attribute syntax |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
729 GTY_BEFORE_ID is for union/struct declarations |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
730 GTY_AFTER_ID is for variable declarations. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
731 enum |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
732 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
733 NO_GTY, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
734 GTY_BEFORE_ID, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
735 GTY_AFTER_ID |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
736 } is_gty = NO_GTY; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
737 bool is_union = (token () == UNION); |
0 | 738 advance (); |
739 | |
740 /* Top-level structures that are not explicitly tagged GTY(()) | |
741 are treated as mere forward declarations. This is because | |
742 there are a lot of structures that we don't need to know | |
743 about, and some of those have weird macro stuff in them | |
744 that we can't handle. */ | |
745 if (nested || token () == GTY_TOKEN) | |
746 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
747 is_gty = GTY_BEFORE_ID; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
748 opts = gtymarker_opt (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
749 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
750 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
751 if (token () == ID) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
752 s = advance (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
753 else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
754 s = xasprintf ("anonymous:%s:%d", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
755 get_input_file_name (lexer_line.file), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
756 lexer_line.line); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
757 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
758 /* Unfortunately above GTY_TOKEN check does not capture the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
759 typedef struct_type GTY case. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
760 if (token () == GTY_TOKEN) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
761 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
762 is_gty = GTY_AFTER_ID; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
763 opts = gtymarker_opt (); |
0 | 764 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
765 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
766 if (is_gty) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
767 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
768 if (token () == '{') |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
769 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
770 pair_p fields; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
771 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
772 if (is_gty == GTY_AFTER_ID) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
773 parse_error ("GTY must be specified before identifier"); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
774 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
775 advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
776 fields = struct_field_seq (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
777 require ('}'); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
778 return new_structure (s, is_union, &lexer_line, fields, opts); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
779 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
780 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
781 else if (token () == '{') |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
782 consume_balanced ('{', '}'); |
0 | 783 if (opts) |
784 *optsp = opts; | |
785 return find_structure (s, is_union); | |
786 } | |
787 | |
788 case ENUM: | |
789 advance (); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
790 if (token () == ID) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
791 s = advance (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
792 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
793 s = xasprintf ("anonymous:%s:%d", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
794 get_input_file_name (lexer_line.file), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
795 lexer_line.line); |
0 | 796 |
797 if (token () == '{') | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
798 consume_balanced ('{', '}'); |
0 | 799 return create_scalar_type (s); |
800 | |
801 default: | |
802 parse_error ("expected a type specifier, have %s", print_cur_token ()); | |
803 advance (); | |
804 return create_scalar_type ("erroneous type"); | |
805 } | |
806 } | |
807 | |
808 /* Top level constructs. */ | |
809 | |
810 /* Dispatch declarations beginning with 'typedef'. */ | |
811 | |
812 static void | |
813 typedef_decl (void) | |
814 { | |
815 type_p ty, dty; | |
816 const char *name; | |
817 options_p opts; | |
818 bool another; | |
819 | |
820 gcc_assert (token () == TYPEDEF); | |
821 advance (); | |
822 | |
823 ty = type (&opts, false); | |
824 if (!ty) | |
825 return; | |
826 if (opts) | |
827 parse_error ("GTY((...)) cannot be applied to a typedef"); | |
828 do | |
829 { | |
830 dty = declarator (ty, &name, &opts); | |
831 if (opts) | |
832 parse_error ("GTY((...)) cannot be applied to a typedef"); | |
833 | |
834 /* Yet another place where we could have junk (notably attributes) | |
835 after the declarator. */ | |
836 another = consume_until_comma_or_semi (false); | |
837 if (dty) | |
838 do_typedef (name, dty, &lexer_line); | |
839 } | |
840 while (another); | |
841 } | |
842 | |
843 /* Structure definition: type() does all the work. */ | |
844 | |
845 static void | |
846 struct_or_union (void) | |
847 { | |
848 options_p dummy; | |
849 type (&dummy, false); | |
850 /* There may be junk after the type: notably, we cannot currently | |
851 distinguish 'struct foo *function(prototype);' from 'struct foo;' | |
852 ... we could call declarator(), but it's a waste of time at | |
853 present. Instead, just eat whatever token is currently lookahead | |
854 and go back to lexical skipping mode. */ | |
855 advance (); | |
856 } | |
857 | |
858 /* GC root declaration: | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
859 (extern|static) gtymarker? type ID array_declarators_opt (';'|'=') |
0 | 860 If the gtymarker is not present, we ignore the rest of the declaration. */ |
861 static void | |
862 extern_or_static (void) | |
863 { | |
864 options_p opts, opts2, dopts; | |
865 type_p ty, dty; | |
866 const char *name; | |
867 require2 (EXTERN, STATIC); | |
868 | |
869 if (token () != GTY_TOKEN) | |
870 { | |
871 advance (); | |
872 return; | |
873 } | |
874 | |
875 opts = gtymarker (); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
876 ty = type (&opts2, true); /* if we get here, it's got a GTY(()) */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
877 dty = declarator (ty, &name, &dopts); |
0 | 878 |
879 if ((opts && dopts) || (opts && opts2) || (opts2 && dopts)) | |
880 parse_error ("GTY((...)) specified more than once for %s", name); | |
881 else if (opts2) | |
882 opts = opts2; | |
883 else if (dopts) | |
884 opts = dopts; | |
885 | |
886 if (dty) | |
887 { | |
888 note_variable (name, adjust_field_type (dty, opts), opts, &lexer_line); | |
889 require2 (';', '='); | |
890 } | |
891 } | |
892 | |
893 /* Definition of a generic VEC structure: | |
894 | |
895 'DEF_VEC_[IPO]' '(' id ')' ';' | |
896 | |
897 Scalar VECs require slightly different treatment than otherwise - | |
898 that's handled in note_def_vec, we just pass it along.*/ | |
899 static void | |
900 def_vec (void) | |
901 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
902 bool is_scalar = (token () == DEFVEC_I); |
0 | 903 const char *type; |
904 | |
905 require2 (DEFVEC_OP, DEFVEC_I); | |
906 require ('('); | |
907 type = require2 (ID, SCALAR); | |
908 require (')'); | |
909 require (';'); | |
910 | |
911 if (!type) | |
912 return; | |
913 | |
914 note_def_vec (type, is_scalar, &lexer_line); | |
915 note_def_vec_alloc (type, "none", &lexer_line); | |
916 } | |
917 | |
918 /* Definition of an allocation strategy for a VEC structure: | |
919 | |
920 'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';' | |
921 | |
922 For purposes of gengtype, this just declares a wrapper structure. */ | |
923 static void | |
924 def_vec_alloc (void) | |
925 { | |
926 const char *type, *astrat; | |
927 | |
928 require (DEFVEC_ALLOC); | |
929 require ('('); | |
930 type = require2 (ID, SCALAR); | |
931 require (','); | |
932 astrat = require (ID); | |
933 require (')'); | |
934 require (';'); | |
935 | |
936 if (!type || !astrat) | |
937 return; | |
938 | |
939 note_def_vec_alloc (type, astrat, &lexer_line); | |
940 } | |
941 | |
942 /* Parse the file FNAME for GC-relevant declarations and definitions. | |
943 This is the only entry point to this file. */ | |
944 void | |
945 parse_file (const char *fname) | |
946 { | |
947 yybegin (fname); | |
948 for (;;) | |
949 { | |
950 switch (token ()) | |
951 { | |
952 case EXTERN: | |
953 case STATIC: | |
954 extern_or_static (); | |
955 break; | |
956 | |
957 case STRUCT: | |
958 case UNION: | |
959 struct_or_union (); | |
960 break; | |
961 | |
962 case TYPEDEF: | |
963 typedef_decl (); | |
964 break; | |
965 | |
966 case DEFVEC_OP: | |
967 case DEFVEC_I: | |
968 def_vec (); | |
969 break; | |
970 | |
971 case DEFVEC_ALLOC: | |
972 def_vec_alloc (); | |
973 break; | |
974 | |
975 case EOF_TOKEN: | |
976 goto eof; | |
977 | |
978 default: | |
979 parse_error ("unexpected top level token, %s", print_cur_token ()); | |
980 goto eof; | |
981 } | |
982 lexer_toplevel_done = 1; | |
983 } | |
984 | |
985 eof: | |
986 advance (); | |
987 yyend (); | |
988 } |