File: | build/gcc/c/c-parser.c |
Warning: | line 8062, column 9 Passed-by-value struct argument contains uninitialized data (e.g., via the field chain: 'src_range.m_start') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Parser for C and Objective-C. |
2 | Copyright (C) 1987-2021 Free Software Foundation, Inc. |
3 | |
4 | Parser actions based on the old Bison parser; structure somewhat |
5 | influenced by and fragments based on the C++ parser. |
6 | |
7 | This file is part of GCC. |
8 | |
9 | GCC is free software; you can redistribute it and/or modify it under |
10 | the terms of the GNU General Public License as published by the Free |
11 | Software Foundation; either version 3, or (at your option) any later |
12 | version. |
13 | |
14 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
15 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
17 | for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with GCC; see the file COPYING3. If not see |
21 | <http://www.gnu.org/licenses/>. */ |
22 | |
23 | /* TODO: |
24 | |
25 | Make sure all relevant comments, and all relevant code from all |
26 | actions, brought over from old parser. Verify exact correspondence |
27 | of syntax accepted. |
28 | |
29 | Add testcases covering every input symbol in every state in old and |
30 | new parsers. |
31 | |
32 | Include full syntax for GNU C, including erroneous cases accepted |
33 | with error messages, in syntax productions in comments. |
34 | |
35 | Make more diagnostics in the front end generally take an explicit |
36 | location rather than implicitly using input_location. */ |
37 | |
38 | #include "config.h" |
39 | #define INCLUDE_UNIQUE_PTR |
40 | #include "system.h" |
41 | #include "coretypes.h" |
42 | #include "target.h" |
43 | #include "function.h" |
44 | #include "c-tree.h" |
45 | #include "timevar.h" |
46 | #include "stringpool.h" |
47 | #include "cgraph.h" |
48 | #include "attribs.h" |
49 | #include "stor-layout.h" |
50 | #include "varasm.h" |
51 | #include "trans-mem.h" |
52 | #include "c-family/c-pragma.h" |
53 | #include "c-lang.h" |
54 | #include "c-family/c-objc.h" |
55 | #include "plugin.h" |
56 | #include "omp-general.h" |
57 | #include "omp-offload.h" |
58 | #include "builtins.h" |
59 | #include "gomp-constants.h" |
60 | #include "c-family/c-indentation.h" |
61 | #include "gimple-expr.h" |
62 | #include "context.h" |
63 | #include "gcc-rich-location.h" |
64 | #include "c-parser.h" |
65 | #include "gimple-parser.h" |
66 | #include "read-rtl-function.h" |
67 | #include "run-rtl-passes.h" |
68 | #include "intl.h" |
69 | #include "c-family/name-hint.h" |
70 | #include "tree-iterator.h" |
71 | #include "tree-pretty-print.h" |
72 | #include "memmodel.h" |
73 | #include "c-family/known-headers.h" |
74 | |
75 | /* We need to walk over decls with incomplete struct/union/enum types |
76 | after parsing the whole translation unit. |
77 | In finish_decl(), if the decl is static, has incomplete |
78 | struct/union/enum type, it is appended to incomplete_record_decls. |
79 | In c_parser_translation_unit(), we iterate over incomplete_record_decls |
80 | and report error if any of the decls are still incomplete. */ |
81 | |
82 | vec<tree> incomplete_record_decls; |
83 | |
84 | void |
85 | set_c_expr_source_range (c_expr *expr, |
86 | location_t start, location_t finish) |
87 | { |
88 | expr->src_range.m_start = start; |
89 | expr->src_range.m_finish = finish; |
90 | if (expr->value) |
91 | set_source_range (expr->value, start, finish); |
92 | } |
93 | |
94 | void |
95 | set_c_expr_source_range (c_expr *expr, |
96 | source_range src_range) |
97 | { |
98 | expr->src_range = src_range; |
99 | if (expr->value) |
100 | set_source_range (expr->value, src_range); |
101 | } |
102 | |
103 | |
104 | /* Initialization routine for this file. */ |
105 | |
106 | void |
107 | c_parse_init (void) |
108 | { |
109 | /* The only initialization required is of the reserved word |
110 | identifiers. */ |
111 | unsigned int i; |
112 | tree id; |
113 | int mask = 0; |
114 | |
115 | /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in |
116 | the c_token structure. */ |
117 | gcc_assert (RID_MAX <= 255)((void)(!(RID_MAX <= 255) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 117, __FUNCTION__), 0 : 0)); |
118 | |
119 | mask |= D_CXXONLY0x0002; |
120 | if (!flag_isoc99) |
121 | mask |= D_C990x0004; |
122 | if (flag_no_asmglobal_options.x_flag_no_asm) |
123 | { |
124 | mask |= D_ASM0x0040 | D_EXT0x0010; |
125 | if (!flag_isoc99) |
126 | mask |= D_EXT890x0020; |
127 | } |
128 | if (!c_dialect_objc ()((c_language & clk_objc) != 0)) |
129 | mask |= D_OBJC0x0080 | D_CXX_OBJC0x0100; |
130 | |
131 | ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX); |
132 | for (i = 0; i < num_c_common_reswords; i++) |
133 | { |
134 | /* If a keyword is disabled, do not enter it into the table |
135 | and so create a canonical spelling that isn't a keyword. */ |
136 | if (c_common_reswords[i].disable & mask) |
137 | { |
138 | if (warn_cxx_compatglobal_options.x_warn_cxx_compat |
139 | && (c_common_reswords[i].disable & D_CXXWARN0x0200)) |
140 | { |
141 | id = get_identifier (c_common_reswords[i].word)(__builtin_constant_p (c_common_reswords[i].word) ? get_identifier_with_length ((c_common_reswords[i].word), strlen (c_common_reswords[i].word )) : get_identifier (c_common_reswords[i].word)); |
142 | C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN)(((struct c_common_identifier *) (id))->node.rid_code = (unsigned char) RID_CXX_COMPAT_WARN); |
143 | C_IS_RESERVED_WORD (id)((tree_not_check2 ((id), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 143, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0) = 1; |
144 | } |
145 | continue; |
146 | } |
147 | |
148 | id = get_identifier (c_common_reswords[i].word)(__builtin_constant_p (c_common_reswords[i].word) ? get_identifier_with_length ((c_common_reswords[i].word), strlen (c_common_reswords[i].word )) : get_identifier (c_common_reswords[i].word)); |
149 | C_SET_RID_CODE (id, c_common_reswords[i].rid)(((struct c_common_identifier *) (id))->node.rid_code = (unsigned char) c_common_reswords[i].rid); |
150 | C_IS_RESERVED_WORD (id)((tree_not_check2 ((id), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 150, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0) = 1; |
151 | ridpointers [(int) c_common_reswords[i].rid] = id; |
152 | } |
153 | |
154 | for (i = 0; i < NUM_INT_N_ENTS1; i++) |
155 | { |
156 | /* We always create the symbols but they aren't always supported. */ |
157 | char name[50]; |
158 | sprintf (name, "__int%d", int_n_data[i].bitsize); |
159 | id = get_identifier (name)(__builtin_constant_p (name) ? get_identifier_with_length ((name ), strlen (name)) : get_identifier (name)); |
160 | C_SET_RID_CODE (id, RID_FIRST_INT_N + i)(((struct c_common_identifier *) (id))->node.rid_code = (unsigned char) RID_FIRST_INT_N + i); |
161 | C_IS_RESERVED_WORD (id)((tree_not_check2 ((id), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 161, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0) = 1; |
162 | |
163 | sprintf (name, "__int%d__", int_n_data[i].bitsize); |
164 | id = get_identifier (name)(__builtin_constant_p (name) ? get_identifier_with_length ((name ), strlen (name)) : get_identifier (name)); |
165 | C_SET_RID_CODE (id, RID_FIRST_INT_N + i)(((struct c_common_identifier *) (id))->node.rid_code = (unsigned char) RID_FIRST_INT_N + i); |
166 | C_IS_RESERVED_WORD (id)((tree_not_check2 ((id), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 166, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0) = 1; |
167 | } |
168 | } |
169 | |
170 | /* A parser structure recording information about the state and |
171 | context of parsing. Includes lexer information with up to two |
172 | tokens of look-ahead; more are not needed for C. */ |
173 | struct GTY(()) c_parser { |
174 | /* The look-ahead tokens. */ |
175 | c_token * GTY((skip)) tokens; |
176 | /* Buffer for look-ahead tokens. */ |
177 | c_token tokens_buf[4]; |
178 | /* How many look-ahead tokens are available (0 - 4, or |
179 | more if parsing from pre-lexed tokens). */ |
180 | unsigned int tokens_avail; |
181 | /* Raw look-ahead tokens, used only for checking in Objective-C |
182 | whether '[[' starts attributes. */ |
183 | vec<c_token, va_gc> *raw_tokens; |
184 | /* The number of raw look-ahead tokens that have since been fully |
185 | lexed. */ |
186 | unsigned int raw_tokens_used; |
187 | /* True if a syntax error is being recovered from; false otherwise. |
188 | c_parser_error sets this flag. It should clear this flag when |
189 | enough tokens have been consumed to recover from the error. */ |
190 | BOOL_BITFIELDunsigned int error : 1; |
191 | /* True if we're processing a pragma, and shouldn't automatically |
192 | consume CPP_PRAGMA_EOL. */ |
193 | BOOL_BITFIELDunsigned int in_pragma : 1; |
194 | /* True if we're parsing the outermost block of an if statement. */ |
195 | BOOL_BITFIELDunsigned int in_if_block : 1; |
196 | /* True if we want to lex a translated, joined string (for an |
197 | initial #pragma pch_preprocess). Otherwise the parser is |
198 | responsible for concatenating strings and translating to the |
199 | execution character set as needed. */ |
200 | BOOL_BITFIELDunsigned int lex_joined_string : 1; |
201 | /* True if, when the parser is concatenating string literals, it |
202 | should translate them to the execution character set (false |
203 | inside attributes). */ |
204 | BOOL_BITFIELDunsigned int translate_strings_p : 1; |
205 | |
206 | /* Objective-C specific parser/lexer information. */ |
207 | |
208 | /* True if we are in a context where the Objective-C "PQ" keywords |
209 | are considered keywords. */ |
210 | BOOL_BITFIELDunsigned int objc_pq_context : 1; |
211 | /* True if we are parsing a (potential) Objective-C foreach |
212 | statement. This is set to true after we parsed 'for (' and while |
213 | we wait for 'in' or ';' to decide if it's a standard C for loop or an |
214 | Objective-C foreach loop. */ |
215 | BOOL_BITFIELDunsigned int objc_could_be_foreach_context : 1; |
216 | /* The following flag is needed to contextualize Objective-C lexical |
217 | analysis. In some cases (e.g., 'int NSObject;'), it is |
218 | undesirable to bind an identifier to an Objective-C class, even |
219 | if a class with that name exists. */ |
220 | BOOL_BITFIELDunsigned int objc_need_raw_identifier : 1; |
221 | /* Nonzero if we're processing a __transaction statement. The value |
222 | is 1 | TM_STMT_ATTR_*. */ |
223 | unsigned int in_transaction : 4; |
224 | /* True if we are in a context where the Objective-C "Property attribute" |
225 | keywords are valid. */ |
226 | BOOL_BITFIELDunsigned int objc_property_attr_context : 1; |
227 | |
228 | /* Whether we have just seen/constructed a string-literal. Set when |
229 | returning a string-literal from c_parser_string_literal. Reset |
230 | in consume_token. Useful when we get a parse error and see an |
231 | unknown token, which could have been a string-literal constant |
232 | macro. */ |
233 | BOOL_BITFIELDunsigned int seen_string_literal : 1; |
234 | |
235 | /* Location of the last consumed token. */ |
236 | location_t last_token_location; |
237 | }; |
238 | |
239 | /* Return a pointer to the Nth token in PARSERs tokens_buf. */ |
240 | |
241 | c_token * |
242 | c_parser_tokens_buf (c_parser *parser, unsigned n) |
243 | { |
244 | return &parser->tokens_buf[n]; |
245 | } |
246 | |
247 | /* Return the error state of PARSER. */ |
248 | |
249 | bool |
250 | c_parser_error (c_parser *parser) |
251 | { |
252 | return parser->error; |
253 | } |
254 | |
255 | /* Set the error state of PARSER to ERR. */ |
256 | |
257 | void |
258 | c_parser_set_error (c_parser *parser, bool err) |
259 | { |
260 | parser->error = err; |
261 | } |
262 | |
263 | |
264 | /* The actual parser and external interface. ??? Does this need to be |
265 | garbage-collected? */ |
266 | |
267 | static GTY (()) c_parser *the_parser; |
268 | |
269 | /* Read in and lex a single token, storing it in *TOKEN. If RAW, |
270 | context-sensitive postprocessing of the token is not done. */ |
271 | |
272 | static void |
273 | c_lex_one_token (c_parser *parser, c_token *token, bool raw = false) |
274 | { |
275 | timevar_push (TV_LEX); |
276 | |
277 | if (raw || vec_safe_length (parser->raw_tokens) == 0) |
278 | { |
279 | token->type = c_lex_with_flags (&token->value, &token->location, |
280 | &token->flags, |
281 | (parser->lex_joined_string |
282 | ? 0 : C_LEX_STRING_NO_JOIN2)); |
283 | token->id_kind = C_ID_NONE; |
284 | token->keyword = RID_MAX; |
285 | token->pragma_kind = PRAGMA_NONE; |
286 | } |
287 | else |
288 | { |
289 | /* Use a token previously lexed as a raw look-ahead token, and |
290 | complete the processing on it. */ |
291 | *token = (*parser->raw_tokens)[parser->raw_tokens_used]; |
292 | ++parser->raw_tokens_used; |
293 | if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens)) |
294 | { |
295 | vec_free (parser->raw_tokens); |
296 | parser->raw_tokens_used = 0; |
297 | } |
298 | } |
299 | |
300 | if (raw) |
301 | goto out; |
302 | |
303 | switch (token->type) |
304 | { |
305 | case CPP_NAME: |
306 | { |
307 | tree decl; |
308 | |
309 | bool objc_force_identifier = parser->objc_need_raw_identifier; |
310 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
311 | parser->objc_need_raw_identifier = false; |
312 | |
313 | if (C_IS_RESERVED_WORD (token->value)((tree_not_check2 ((token->value), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 313, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)) |
314 | { |
315 | enum rid rid_code = C_RID_CODE (token->value)((enum rid) (((struct c_common_identifier *) (token->value ))->node.rid_code)); |
316 | |
317 | if (rid_code == RID_CXX_COMPAT_WARN) |
318 | { |
319 | warning_at (token->location, |
320 | OPT_Wc___compat, |
321 | "identifier %qE conflicts with C++ keyword", |
322 | token->value); |
323 | } |
324 | else if (rid_code >= RID_FIRST_ADDR_SPACE |
325 | && rid_code <= RID_LAST_ADDR_SPACE) |
326 | { |
327 | addr_space_t as; |
328 | as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE); |
329 | targetm.addr_space.diagnose_usage (as, token->location); |
330 | token->id_kind = C_ID_ADDRSPACE; |
331 | token->keyword = rid_code; |
332 | break; |
333 | } |
334 | else if (c_dialect_objc ()((c_language & clk_objc) != 0) && OBJC_IS_PQ_KEYWORD (rid_code)((unsigned int) (rid_code) >= (unsigned int) RID_FIRST_PQ && (unsigned int) (rid_code) <= (unsigned int) RID_LAST_PQ)) |
335 | { |
336 | /* We found an Objective-C "pq" keyword (in, out, |
337 | inout, bycopy, byref, oneway). They need special |
338 | care because the interpretation depends on the |
339 | context. */ |
340 | if (parser->objc_pq_context) |
341 | { |
342 | token->type = CPP_KEYWORD; |
343 | token->keyword = rid_code; |
344 | break; |
345 | } |
346 | else if (parser->objc_could_be_foreach_context |
347 | && rid_code == RID_IN) |
348 | { |
349 | /* We are in Objective-C, inside a (potential) |
350 | foreach context (which means after having |
351 | parsed 'for (', but before having parsed ';'), |
352 | and we found 'in'. We consider it the keyword |
353 | which terminates the declaration at the |
354 | beginning of a foreach-statement. Note that |
355 | this means you can't use 'in' for anything else |
356 | in that context; in particular, in Objective-C |
357 | you can't use 'in' as the name of the running |
358 | variable in a C for loop. We could potentially |
359 | try to add code here to disambiguate, but it |
360 | seems a reasonable limitation. */ |
361 | token->type = CPP_KEYWORD; |
362 | token->keyword = rid_code; |
363 | break; |
364 | } |
365 | /* Else, "pq" keywords outside of the "pq" context are |
366 | not keywords, and we fall through to the code for |
367 | normal tokens. */ |
368 | } |
369 | else if (c_dialect_objc ()((c_language & clk_objc) != 0) && OBJC_IS_PATTR_KEYWORD (rid_code)((((unsigned int) (rid_code) >= (unsigned int) RID_FIRST_PATTR && (unsigned int) (rid_code) <= (unsigned int) RID_LAST_PATTR )) || rid_code == RID_CLASS)) |
370 | { |
371 | /* We found an Objective-C "property attribute" |
372 | keyword (getter, setter, readonly, etc). These are |
373 | only valid in the property context. */ |
374 | if (parser->objc_property_attr_context) |
375 | { |
376 | token->type = CPP_KEYWORD; |
377 | token->keyword = rid_code; |
378 | break; |
379 | } |
380 | /* Else they are not special keywords. |
381 | */ |
382 | } |
383 | else if (c_dialect_objc ()((c_language & clk_objc) != 0) |
384 | && (OBJC_IS_AT_KEYWORD (rid_code)((unsigned int) (rid_code) >= (unsigned int) RID_FIRST_AT && (unsigned int) (rid_code) <= (unsigned int) RID_LAST_AT) |
385 | || OBJC_IS_CXX_KEYWORD (rid_code)(rid_code == RID_CLASS || rid_code == RID_SYNCHRONIZED || rid_code == RID_PUBLIC || rid_code == RID_PROTECTED || rid_code == RID_PRIVATE || rid_code == RID_TRY || rid_code == RID_THROW || rid_code == RID_CATCH))) |
386 | { |
387 | /* We found one of the Objective-C "@" keywords (defs, |
388 | selector, synchronized, etc) or one of the |
389 | Objective-C "cxx" keywords (class, private, |
390 | protected, public, try, catch, throw) without a |
391 | preceding '@' sign. Do nothing and fall through to |
392 | the code for normal tokens (in C++ we would still |
393 | consider the CXX ones keywords, but not in C). */ |
394 | ; |
395 | } |
396 | else |
397 | { |
398 | token->type = CPP_KEYWORD; |
399 | token->keyword = rid_code; |
400 | break; |
401 | } |
402 | } |
403 | |
404 | decl = lookup_name (token->value); |
405 | if (decl) |
406 | { |
407 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL) |
408 | { |
409 | token->id_kind = C_ID_TYPENAME; |
410 | break; |
411 | } |
412 | } |
413 | else if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
414 | { |
415 | tree objc_interface_decl = objc_is_class_name (token->value); |
416 | /* Objective-C class names are in the same namespace as |
417 | variables and typedefs, and hence are shadowed by local |
418 | declarations. */ |
419 | if (objc_interface_decl |
420 | && (!objc_force_identifier || global_bindings_p ())) |
421 | { |
422 | token->value = objc_interface_decl; |
423 | token->id_kind = C_ID_CLASSNAME; |
424 | break; |
425 | } |
426 | } |
427 | token->id_kind = C_ID_ID; |
428 | } |
429 | break; |
430 | case CPP_AT_NAME: |
431 | /* This only happens in Objective-C; it must be a keyword. */ |
432 | token->type = CPP_KEYWORD; |
433 | switch (C_RID_CODE (token->value)((enum rid) (((struct c_common_identifier *) (token->value ))->node.rid_code))) |
434 | { |
435 | /* Replace 'class' with '@class', 'private' with '@private', |
436 | etc. This prevents confusion with the C++ keyword |
437 | 'class', and makes the tokens consistent with other |
438 | Objective-C 'AT' keywords. For example '@class' is |
439 | reported as RID_AT_CLASS which is consistent with |
440 | '@synchronized', which is reported as |
441 | RID_AT_SYNCHRONIZED. |
442 | */ |
443 | case RID_CLASS: token->keyword = RID_AT_CLASS; break; |
444 | case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break; |
445 | case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break; |
446 | case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break; |
447 | case RID_THROW: token->keyword = RID_AT_THROW; break; |
448 | case RID_TRY: token->keyword = RID_AT_TRY; break; |
449 | case RID_CATCH: token->keyword = RID_AT_CATCH; break; |
450 | case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break; |
451 | default: token->keyword = C_RID_CODE (token->value)((enum rid) (((struct c_common_identifier *) (token->value ))->node.rid_code)); |
452 | } |
453 | break; |
454 | case CPP_COLON: |
455 | case CPP_COMMA: |
456 | case CPP_CLOSE_PAREN: |
457 | case CPP_SEMICOLON: |
458 | /* These tokens may affect the interpretation of any identifiers |
459 | following, if doing Objective-C. */ |
460 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
461 | parser->objc_need_raw_identifier = false; |
462 | break; |
463 | case CPP_PRAGMA: |
464 | /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ |
465 | token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value)((unsigned long) (*tree_int_cst_elt_check ((token->value), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 465, __FUNCTION__))); |
466 | token->value = NULL__null; |
467 | break; |
468 | default: |
469 | break; |
470 | } |
471 | out: |
472 | timevar_pop (TV_LEX); |
473 | } |
474 | |
475 | /* Return a pointer to the next token from PARSER, reading it in if |
476 | necessary. */ |
477 | |
478 | c_token * |
479 | c_parser_peek_token (c_parser *parser) |
480 | { |
481 | if (parser->tokens_avail == 0) |
482 | { |
483 | c_lex_one_token (parser, &parser->tokens[0]); |
484 | parser->tokens_avail = 1; |
485 | } |
486 | return &parser->tokens[0]; |
487 | } |
488 | |
489 | /* Return a pointer to the next-but-one token from PARSER, reading it |
490 | in if necessary. The next token is already read in. */ |
491 | |
492 | c_token * |
493 | c_parser_peek_2nd_token (c_parser *parser) |
494 | { |
495 | if (parser->tokens_avail >= 2) |
496 | return &parser->tokens[1]; |
497 | gcc_assert (parser->tokens_avail == 1)((void)(!(parser->tokens_avail == 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 497, __FUNCTION__), 0 : 0)); |
498 | gcc_assert (parser->tokens[0].type != CPP_EOF)((void)(!(parser->tokens[0].type != CPP_EOF) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 498, __FUNCTION__), 0 : 0)); |
499 | gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL)((void)(!(parser->tokens[0].type != CPP_PRAGMA_EOL) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 499, __FUNCTION__), 0 : 0)); |
500 | c_lex_one_token (parser, &parser->tokens[1]); |
501 | parser->tokens_avail = 2; |
502 | return &parser->tokens[1]; |
503 | } |
504 | |
505 | /* Return a pointer to the Nth token from PARSER, reading it |
506 | in if necessary. The N-1th token is already read in. */ |
507 | |
508 | c_token * |
509 | c_parser_peek_nth_token (c_parser *parser, unsigned int n) |
510 | { |
511 | /* N is 1-based, not zero-based. */ |
512 | gcc_assert (n > 0)((void)(!(n > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 512, __FUNCTION__), 0 : 0)); |
513 | |
514 | if (parser->tokens_avail >= n) |
515 | return &parser->tokens[n - 1]; |
516 | gcc_assert (parser->tokens_avail == n - 1)((void)(!(parser->tokens_avail == n - 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 516, __FUNCTION__), 0 : 0)); |
517 | c_lex_one_token (parser, &parser->tokens[n - 1]); |
518 | parser->tokens_avail = n; |
519 | return &parser->tokens[n - 1]; |
520 | } |
521 | |
522 | /* Return a pointer to the Nth token from PARSER, reading it in as a |
523 | raw look-ahead token if necessary. The N-1th token is already read |
524 | in. Raw look-ahead tokens remain available for when the non-raw |
525 | functions above are called. */ |
526 | |
527 | c_token * |
528 | c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n) |
529 | { |
530 | /* N is 1-based, not zero-based. */ |
531 | gcc_assert (n > 0)((void)(!(n > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 531, __FUNCTION__), 0 : 0)); |
532 | |
533 | if (parser->tokens_avail >= n) |
534 | return &parser->tokens[n - 1]; |
535 | unsigned int raw_len = vec_safe_length (parser->raw_tokens); |
536 | unsigned int raw_avail |
537 | = parser->tokens_avail + raw_len - parser->raw_tokens_used; |
538 | gcc_assert (raw_avail >= n - 1)((void)(!(raw_avail >= n - 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 538, __FUNCTION__), 0 : 0)); |
539 | if (raw_avail >= n) |
540 | return &(*parser->raw_tokens)[parser->raw_tokens_used |
541 | + n - 1 - parser->tokens_avail]; |
542 | vec_safe_reserve (parser->raw_tokens, 1); |
543 | parser->raw_tokens->quick_grow (raw_len + 1); |
544 | c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true); |
545 | return &(*parser->raw_tokens)[raw_len]; |
546 | } |
547 | |
548 | bool |
549 | c_keyword_starts_typename (enum rid keyword) |
550 | { |
551 | switch (keyword) |
552 | { |
553 | case RID_UNSIGNED: |
554 | case RID_LONG: |
555 | case RID_SHORT: |
556 | case RID_SIGNED: |
557 | case RID_COMPLEX: |
558 | case RID_INT: |
559 | case RID_CHAR: |
560 | case RID_FLOAT: |
561 | case RID_DOUBLE: |
562 | case RID_VOID: |
563 | case RID_DFLOAT32: |
564 | case RID_DFLOAT64: |
565 | case RID_DFLOAT128: |
566 | CASE_RID_FLOATN_NXcase RID_FLOAT16: case RID_FLOAT32: case RID_FLOAT64: case RID_FLOAT128 : case RID_FLOAT32X: case RID_FLOAT64X: case RID_FLOAT128X: |
567 | case RID_BOOL: |
568 | case RID_ENUM: |
569 | case RID_STRUCT: |
570 | case RID_UNION: |
571 | case RID_TYPEOF: |
572 | case RID_CONST: |
573 | case RID_ATOMIC: |
574 | case RID_VOLATILE: |
575 | case RID_RESTRICT: |
576 | case RID_ATTRIBUTE: |
577 | case RID_FRACT: |
578 | case RID_ACCUM: |
579 | case RID_SAT: |
580 | case RID_AUTO_TYPE: |
581 | case RID_ALIGNAS: |
582 | return true; |
583 | default: |
584 | if (keyword >= RID_FIRST_INT_N |
585 | && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS1 |
586 | && int_n_enabled_p[keyword - RID_FIRST_INT_N]) |
587 | return true; |
588 | return false; |
589 | } |
590 | } |
591 | |
592 | /* Return true if TOKEN can start a type name, |
593 | false otherwise. */ |
594 | bool |
595 | c_token_starts_typename (c_token *token) |
596 | { |
597 | switch (token->type) |
598 | { |
599 | case CPP_NAME: |
600 | switch (token->id_kind) |
601 | { |
602 | case C_ID_ID: |
603 | return false; |
604 | case C_ID_ADDRSPACE: |
605 | return true; |
606 | case C_ID_TYPENAME: |
607 | return true; |
608 | case C_ID_CLASSNAME: |
609 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 609, __FUNCTION__), 0 : 0)); |
610 | return true; |
611 | default: |
612 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 612, __FUNCTION__)); |
613 | } |
614 | case CPP_KEYWORD: |
615 | return c_keyword_starts_typename (token->keyword); |
616 | case CPP_LESS: |
617 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
618 | return true; |
619 | return false; |
620 | default: |
621 | return false; |
622 | } |
623 | } |
624 | |
625 | /* Return true if the next token from PARSER can start a type name, |
626 | false otherwise. LA specifies how to do lookahead in order to |
627 | detect unknown type names. If unsure, pick CLA_PREFER_ID. */ |
628 | |
629 | static inline bool |
630 | c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la) |
631 | { |
632 | c_token *token = c_parser_peek_token (parser); |
633 | if (c_token_starts_typename (token)) |
634 | return true; |
635 | |
636 | /* Try a bit harder to detect an unknown typename. */ |
637 | if (la != cla_prefer_id |
638 | && token->type == CPP_NAME |
639 | && token->id_kind == C_ID_ID |
640 | |
641 | /* Do not try too hard when we could have "object in array". */ |
642 | && !parser->objc_could_be_foreach_context |
643 | |
644 | && (la == cla_prefer_type |
645 | || c_parser_peek_2nd_token (parser)->type == CPP_NAME |
646 | || c_parser_peek_2nd_token (parser)->type == CPP_MULT) |
647 | |
648 | /* Only unknown identifiers. */ |
649 | && !lookup_name (token->value)) |
650 | return true; |
651 | |
652 | return false; |
653 | } |
654 | |
655 | /* Return true if TOKEN is a type qualifier, false otherwise. */ |
656 | static bool |
657 | c_token_is_qualifier (c_token *token) |
658 | { |
659 | switch (token->type) |
660 | { |
661 | case CPP_NAME: |
662 | switch (token->id_kind) |
663 | { |
664 | case C_ID_ADDRSPACE: |
665 | return true; |
666 | default: |
667 | return false; |
668 | } |
669 | case CPP_KEYWORD: |
670 | switch (token->keyword) |
671 | { |
672 | case RID_CONST: |
673 | case RID_VOLATILE: |
674 | case RID_RESTRICT: |
675 | case RID_ATTRIBUTE: |
676 | case RID_ATOMIC: |
677 | return true; |
678 | default: |
679 | return false; |
680 | } |
681 | case CPP_LESS: |
682 | return false; |
683 | default: |
684 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 684, __FUNCTION__)); |
685 | } |
686 | } |
687 | |
688 | /* Return true if the next token from PARSER is a type qualifier, |
689 | false otherwise. */ |
690 | static inline bool |
691 | c_parser_next_token_is_qualifier (c_parser *parser) |
692 | { |
693 | c_token *token = c_parser_peek_token (parser); |
694 | return c_token_is_qualifier (token); |
695 | } |
696 | |
697 | /* Return true if TOKEN can start declaration specifiers (not |
698 | including standard attributes), false otherwise. */ |
699 | static bool |
700 | c_token_starts_declspecs (c_token *token) |
701 | { |
702 | switch (token->type) |
703 | { |
704 | case CPP_NAME: |
705 | switch (token->id_kind) |
706 | { |
707 | case C_ID_ID: |
708 | return false; |
709 | case C_ID_ADDRSPACE: |
710 | return true; |
711 | case C_ID_TYPENAME: |
712 | return true; |
713 | case C_ID_CLASSNAME: |
714 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 714, __FUNCTION__), 0 : 0)); |
715 | return true; |
716 | default: |
717 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 717, __FUNCTION__)); |
718 | } |
719 | case CPP_KEYWORD: |
720 | switch (token->keyword) |
721 | { |
722 | case RID_STATIC: |
723 | case RID_EXTERN: |
724 | case RID_REGISTER: |
725 | case RID_TYPEDEF: |
726 | case RID_INLINE: |
727 | case RID_NORETURN: |
728 | case RID_AUTO: |
729 | case RID_THREAD: |
730 | case RID_UNSIGNED: |
731 | case RID_LONG: |
732 | case RID_SHORT: |
733 | case RID_SIGNED: |
734 | case RID_COMPLEX: |
735 | case RID_INT: |
736 | case RID_CHAR: |
737 | case RID_FLOAT: |
738 | case RID_DOUBLE: |
739 | case RID_VOID: |
740 | case RID_DFLOAT32: |
741 | case RID_DFLOAT64: |
742 | case RID_DFLOAT128: |
743 | CASE_RID_FLOATN_NXcase RID_FLOAT16: case RID_FLOAT32: case RID_FLOAT64: case RID_FLOAT128 : case RID_FLOAT32X: case RID_FLOAT64X: case RID_FLOAT128X: |
744 | case RID_BOOL: |
745 | case RID_ENUM: |
746 | case RID_STRUCT: |
747 | case RID_UNION: |
748 | case RID_TYPEOF: |
749 | case RID_CONST: |
750 | case RID_VOLATILE: |
751 | case RID_RESTRICT: |
752 | case RID_ATTRIBUTE: |
753 | case RID_FRACT: |
754 | case RID_ACCUM: |
755 | case RID_SAT: |
756 | case RID_ALIGNAS: |
757 | case RID_ATOMIC: |
758 | case RID_AUTO_TYPE: |
759 | return true; |
760 | default: |
761 | if (token->keyword >= RID_FIRST_INT_N |
762 | && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS1 |
763 | && int_n_enabled_p[token->keyword - RID_FIRST_INT_N]) |
764 | return true; |
765 | return false; |
766 | } |
767 | case CPP_LESS: |
768 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
769 | return true; |
770 | return false; |
771 | default: |
772 | return false; |
773 | } |
774 | } |
775 | |
776 | |
777 | /* Return true if TOKEN can start declaration specifiers (not |
778 | including standard attributes) or a static assertion, false |
779 | otherwise. */ |
780 | static bool |
781 | c_token_starts_declaration (c_token *token) |
782 | { |
783 | if (c_token_starts_declspecs (token) |
784 | || token->keyword == RID_STATIC_ASSERT) |
785 | return true; |
786 | else |
787 | return false; |
788 | } |
789 | |
790 | /* Return true if the next token from PARSER can start declaration |
791 | specifiers (not including standard attributes), false |
792 | otherwise. */ |
793 | bool |
794 | c_parser_next_token_starts_declspecs (c_parser *parser) |
795 | { |
796 | c_token *token = c_parser_peek_token (parser); |
797 | |
798 | /* In Objective-C, a classname normally starts a declspecs unless it |
799 | is immediately followed by a dot. In that case, it is the |
800 | Objective-C 2.0 "dot-syntax" for class objects, ie, calls the |
801 | setter/getter on the class. c_token_starts_declspecs() can't |
802 | differentiate between the two cases because it only checks the |
803 | current token, so we have a special check here. */ |
804 | if (c_dialect_objc ()((c_language & clk_objc) != 0) |
805 | && token->type == CPP_NAME |
806 | && token->id_kind == C_ID_CLASSNAME |
807 | && c_parser_peek_2nd_token (parser)->type == CPP_DOT) |
808 | return false; |
809 | |
810 | return c_token_starts_declspecs (token); |
811 | } |
812 | |
813 | /* Return true if the next tokens from PARSER can start declaration |
814 | specifiers (not including standard attributes) or a static |
815 | assertion, false otherwise. */ |
816 | bool |
817 | c_parser_next_tokens_start_declaration (c_parser *parser) |
818 | { |
819 | c_token *token = c_parser_peek_token (parser); |
820 | |
821 | /* Same as above. */ |
822 | if (c_dialect_objc ()((c_language & clk_objc) != 0) |
823 | && token->type == CPP_NAME |
824 | && token->id_kind == C_ID_CLASSNAME |
825 | && c_parser_peek_2nd_token (parser)->type == CPP_DOT) |
826 | return false; |
827 | |
828 | /* Labels do not start declarations. */ |
829 | if (token->type == CPP_NAME |
830 | && c_parser_peek_2nd_token (parser)->type == CPP_COLON) |
831 | return false; |
832 | |
833 | if (c_token_starts_declaration (token)) |
834 | return true; |
835 | |
836 | if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl)) |
837 | return true; |
838 | |
839 | return false; |
840 | } |
841 | |
842 | /* Consume the next token from PARSER. */ |
843 | |
844 | void |
845 | c_parser_consume_token (c_parser *parser) |
846 | { |
847 | gcc_assert (parser->tokens_avail >= 1)((void)(!(parser->tokens_avail >= 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 847, __FUNCTION__), 0 : 0)); |
848 | gcc_assert (parser->tokens[0].type != CPP_EOF)((void)(!(parser->tokens[0].type != CPP_EOF) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 848, __FUNCTION__), 0 : 0)); |
849 | gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL)((void)(!(!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 849, __FUNCTION__), 0 : 0)); |
850 | gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA)((void)(!(parser->error || parser->tokens[0].type != CPP_PRAGMA ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 850, __FUNCTION__), 0 : 0)); |
851 | parser->last_token_location = parser->tokens[0].location; |
852 | if (parser->tokens != &parser->tokens_buf[0]) |
853 | parser->tokens++; |
854 | else if (parser->tokens_avail >= 2) |
855 | { |
856 | parser->tokens[0] = parser->tokens[1]; |
857 | if (parser->tokens_avail >= 3) |
858 | { |
859 | parser->tokens[1] = parser->tokens[2]; |
860 | if (parser->tokens_avail >= 4) |
861 | parser->tokens[2] = parser->tokens[3]; |
862 | } |
863 | } |
864 | parser->tokens_avail--; |
865 | parser->seen_string_literal = false; |
866 | } |
867 | |
868 | /* Expect the current token to be a #pragma. Consume it and remember |
869 | that we've begun parsing a pragma. */ |
870 | |
871 | static void |
872 | c_parser_consume_pragma (c_parser *parser) |
873 | { |
874 | gcc_assert (!parser->in_pragma)((void)(!(!parser->in_pragma) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 874, __FUNCTION__), 0 : 0)); |
875 | gcc_assert (parser->tokens_avail >= 1)((void)(!(parser->tokens_avail >= 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 875, __FUNCTION__), 0 : 0)); |
876 | gcc_assert (parser->tokens[0].type == CPP_PRAGMA)((void)(!(parser->tokens[0].type == CPP_PRAGMA) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 876, __FUNCTION__), 0 : 0)); |
877 | if (parser->tokens != &parser->tokens_buf[0]) |
878 | parser->tokens++; |
879 | else if (parser->tokens_avail >= 2) |
880 | { |
881 | parser->tokens[0] = parser->tokens[1]; |
882 | if (parser->tokens_avail >= 3) |
883 | parser->tokens[1] = parser->tokens[2]; |
884 | } |
885 | parser->tokens_avail--; |
886 | parser->in_pragma = true; |
887 | } |
888 | |
889 | /* Update the global input_location from TOKEN. */ |
890 | static inline void |
891 | c_parser_set_source_position_from_token (c_token *token) |
892 | { |
893 | if (token->type != CPP_EOF) |
894 | { |
895 | input_location = token->location; |
896 | } |
897 | } |
898 | |
899 | /* Helper function for c_parser_error. |
900 | Having peeked a token of kind TOK1_KIND that might signify |
901 | a conflict marker, peek successor tokens to determine |
902 | if we actually do have a conflict marker. |
903 | Specifically, we consider a run of 7 '<', '=' or '>' characters |
904 | at the start of a line as a conflict marker. |
905 | These come through the lexer as three pairs and a single, |
906 | e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<'). |
907 | If it returns true, *OUT_LOC is written to with the location/range |
908 | of the marker. */ |
909 | |
910 | static bool |
911 | c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind, |
912 | location_t *out_loc) |
913 | { |
914 | c_token *token2 = c_parser_peek_2nd_token (parser); |
915 | if (token2->type != tok1_kind) |
916 | return false; |
917 | c_token *token3 = c_parser_peek_nth_token (parser, 3); |
918 | if (token3->type != tok1_kind) |
919 | return false; |
920 | c_token *token4 = c_parser_peek_nth_token (parser, 4); |
921 | if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind)) |
922 | return false; |
923 | |
924 | /* It must be at the start of the line. */ |
925 | location_t start_loc = c_parser_peek_token (parser)->location; |
926 | if (LOCATION_COLUMN (start_loc)((expand_location (start_loc)).column) != 1) |
927 | return false; |
928 | |
929 | /* We have a conflict marker. Construct a location of the form: |
930 | <<<<<<< |
931 | ^~~~~~~ |
932 | with start == caret, finishing at the end of the marker. */ |
933 | location_t finish_loc = get_finish (token4->location); |
934 | *out_loc = make_location (start_loc, start_loc, finish_loc); |
935 | |
936 | return true; |
937 | } |
938 | |
939 | /* Issue a diagnostic of the form |
940 | FILE:LINE: MESSAGE before TOKEN |
941 | where TOKEN is the next token in the input stream of PARSER. |
942 | MESSAGE (specified by the caller) is usually of the form "expected |
943 | OTHER-TOKEN". |
944 | |
945 | Use RICHLOC as the location of the diagnostic. |
946 | |
947 | Do not issue a diagnostic if still recovering from an error. |
948 | |
949 | Return true iff an error was actually emitted. |
950 | |
951 | ??? This is taken from the C++ parser, but building up messages in |
952 | this way is not i18n-friendly and some other approach should be |
953 | used. */ |
954 | |
955 | static bool |
956 | c_parser_error_richloc (c_parser *parser, const char *gmsgid, |
957 | rich_location *richloc) |
958 | { |
959 | c_token *token = c_parser_peek_token (parser); |
960 | if (parser->error) |
961 | return false; |
962 | parser->error = true; |
963 | if (!gmsgid) |
964 | return false; |
965 | |
966 | /* If this is actually a conflict marker, report it as such. */ |
967 | if (token->type == CPP_LSHIFT |
968 | || token->type == CPP_RSHIFT |
969 | || token->type == CPP_EQ_EQ) |
970 | { |
971 | location_t loc; |
972 | if (c_parser_peek_conflict_marker (parser, token->type, &loc)) |
973 | { |
974 | error_at (loc, "version control conflict marker in file"); |
975 | return true; |
976 | } |
977 | } |
978 | |
979 | /* If we were parsing a string-literal and there is an unknown name |
980 | token right after, then check to see if that could also have been |
981 | a literal string by checking the name against a list of known |
982 | standard string literal constants defined in header files. If |
983 | there is one, then add that as an hint to the error message. */ |
984 | auto_diagnostic_group d; |
985 | name_hint h; |
986 | if (parser->seen_string_literal && token->type == CPP_NAME) |
987 | { |
988 | tree name = token->value; |
989 | const char *token_name = IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 989, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
990 | const char *header_hint |
991 | = get_c_stdlib_header_for_string_macro_name (token_name); |
992 | if (header_hint != NULL__null) |
993 | h = name_hint (NULL__null, new suggest_missing_header (token->location, |
994 | token_name, |
995 | header_hint)); |
996 | } |
997 | |
998 | c_parse_error (gmsgid, |
999 | /* Because c_parse_error does not understand |
1000 | CPP_KEYWORD, keywords are treated like |
1001 | identifiers. */ |
1002 | (token->type == CPP_KEYWORD ? CPP_NAME : token->type), |
1003 | /* ??? The C parser does not save the cpp flags of a |
1004 | token, we need to pass 0 here and we will not get |
1005 | the source spelling of some tokens but rather the |
1006 | canonical spelling. */ |
1007 | token->value, /*flags=*/0, richloc); |
1008 | return true; |
1009 | } |
1010 | |
1011 | /* As c_parser_error_richloc, but issue the message at the |
1012 | location of PARSER's next token, or at input_location |
1013 | if the next token is EOF. */ |
1014 | |
1015 | bool |
1016 | c_parser_error (c_parser *parser, const char *gmsgid) |
1017 | { |
1018 | c_token *token = c_parser_peek_token (parser); |
1019 | c_parser_set_source_position_from_token (token); |
1020 | rich_location richloc (line_table, input_location); |
1021 | return c_parser_error_richloc (parser, gmsgid, &richloc); |
1022 | } |
1023 | |
1024 | /* Some tokens naturally come in pairs e.g.'(' and ')'. |
1025 | This class is for tracking such a matching pair of symbols. |
1026 | In particular, it tracks the location of the first token, |
1027 | so that if the second token is missing, we can highlight the |
1028 | location of the first token when notifying the user about the |
1029 | problem. */ |
1030 | |
1031 | template <typename traits_t> |
1032 | class token_pair |
1033 | { |
1034 | public: |
1035 | /* token_pair's ctor. */ |
1036 | token_pair () : m_open_loc (UNKNOWN_LOCATION((location_t) 0)) {} |
1037 | |
1038 | /* If the next token is the opening symbol for this pair, consume it and |
1039 | return true. |
1040 | Otherwise, issue an error and return false. |
1041 | In either case, record the location of the opening token. */ |
1042 | |
1043 | bool require_open (c_parser *parser) |
1044 | { |
1045 | c_token *token = c_parser_peek_token (parser); |
1046 | if (token) |
1047 | m_open_loc = token->location; |
1048 | |
1049 | return c_parser_require (parser, traits_t::open_token_type, |
1050 | traits_t::open_gmsgid); |
1051 | } |
1052 | |
1053 | /* Consume the next token from PARSER, recording its location as |
1054 | that of the opening token within the pair. */ |
1055 | |
1056 | void consume_open (c_parser *parser) |
1057 | { |
1058 | c_token *token = c_parser_peek_token (parser); |
1059 | gcc_assert (token->type == traits_t::open_token_type)((void)(!(token->type == traits_t::open_token_type) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1059, __FUNCTION__), 0 : 0)); |
1060 | m_open_loc = token->location; |
1061 | c_parser_consume_token (parser); |
1062 | } |
1063 | |
1064 | /* If the next token is the closing symbol for this pair, consume it |
1065 | and return true. |
1066 | Otherwise, issue an error, highlighting the location of the |
1067 | corresponding opening token, and return false. */ |
1068 | |
1069 | bool require_close (c_parser *parser) const |
1070 | { |
1071 | return c_parser_require (parser, traits_t::close_token_type, |
1072 | traits_t::close_gmsgid, m_open_loc); |
1073 | } |
1074 | |
1075 | /* Like token_pair::require_close, except that tokens will be skipped |
1076 | until the desired token is found. An error message is still produced |
1077 | if the next token is not as expected. */ |
1078 | |
1079 | void skip_until_found_close (c_parser *parser) const |
1080 | { |
1081 | c_parser_skip_until_found (parser, traits_t::close_token_type, |
1082 | traits_t::close_gmsgid, m_open_loc); |
1083 | } |
1084 | |
1085 | private: |
1086 | location_t m_open_loc; |
1087 | }; |
1088 | |
1089 | /* Traits for token_pair<T> for tracking matching pairs of parentheses. */ |
1090 | |
1091 | struct matching_paren_traits |
1092 | { |
1093 | static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN; |
1094 | static const char * const open_gmsgid; |
1095 | static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN; |
1096 | static const char * const close_gmsgid; |
1097 | }; |
1098 | |
1099 | const char * const matching_paren_traits::open_gmsgid = "expected %<(%>"; |
1100 | const char * const matching_paren_traits::close_gmsgid = "expected %<)%>"; |
1101 | |
1102 | /* "matching_parens" is a token_pair<T> class for tracking matching |
1103 | pairs of parentheses. */ |
1104 | |
1105 | typedef token_pair<matching_paren_traits> matching_parens; |
1106 | |
1107 | /* Traits for token_pair<T> for tracking matching pairs of braces. */ |
1108 | |
1109 | struct matching_brace_traits |
1110 | { |
1111 | static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE; |
1112 | static const char * const open_gmsgid; |
1113 | static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE; |
1114 | static const char * const close_gmsgid; |
1115 | }; |
1116 | |
1117 | const char * const matching_brace_traits::open_gmsgid = "expected %<{%>"; |
1118 | const char * const matching_brace_traits::close_gmsgid = "expected %<}%>"; |
1119 | |
1120 | /* "matching_braces" is a token_pair<T> class for tracking matching |
1121 | pairs of braces. */ |
1122 | |
1123 | typedef token_pair<matching_brace_traits> matching_braces; |
1124 | |
1125 | /* Get a description of the matching symbol to TYPE e.g. "(" for |
1126 | CPP_CLOSE_PAREN. */ |
1127 | |
1128 | static const char * |
1129 | get_matching_symbol (enum cpp_ttype type) |
1130 | { |
1131 | switch (type) |
1132 | { |
1133 | default: |
1134 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1134, __FUNCTION__)); |
1135 | return ""; |
1136 | case CPP_CLOSE_PAREN: |
1137 | return "("; |
1138 | case CPP_CLOSE_BRACE: |
1139 | return "{"; |
1140 | } |
1141 | } |
1142 | |
1143 | /* If the next token is of the indicated TYPE, consume it. Otherwise, |
1144 | issue the error MSGID. If MSGID is NULL then a message has already |
1145 | been produced and no message will be produced this time. Returns |
1146 | true if found, false otherwise. |
1147 | |
1148 | If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it |
1149 | within any error as the location of an "opening" token matching |
1150 | the close token TYPE (e.g. the location of the '(' when TYPE is |
1151 | CPP_CLOSE_PAREN). |
1152 | |
1153 | If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly |
1154 | one type (e.g. "expected %<)%>") and thus it may be reasonable to |
1155 | attempt to generate a fix-it hint for the problem. |
1156 | Otherwise msgid describes multiple token types (e.g. |
1157 | "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to |
1158 | generate a fix-it hint. */ |
1159 | |
1160 | bool |
1161 | c_parser_require (c_parser *parser, |
1162 | enum cpp_ttype type, |
1163 | const char *msgid, |
1164 | location_t matching_location, |
1165 | bool type_is_unique) |
1166 | { |
1167 | if (c_parser_next_token_is (parser, type)) |
1168 | { |
1169 | c_parser_consume_token (parser); |
1170 | return true; |
1171 | } |
1172 | else |
1173 | { |
1174 | location_t next_token_loc = c_parser_peek_token (parser)->location; |
1175 | gcc_rich_location richloc (next_token_loc); |
1176 | |
1177 | /* Potentially supply a fix-it hint, suggesting to add the |
1178 | missing token immediately after the *previous* token. |
1179 | This may move the primary location within richloc. */ |
1180 | if (!parser->error && type_is_unique) |
1181 | maybe_suggest_missing_token_insertion (&richloc, type, |
1182 | parser->last_token_location); |
1183 | |
1184 | /* If matching_location != UNKNOWN_LOCATION, highlight it. |
1185 | Attempt to consolidate diagnostics by printing it as a |
1186 | secondary range within the main diagnostic. */ |
1187 | bool added_matching_location = false; |
1188 | if (matching_location != UNKNOWN_LOCATION((location_t) 0)) |
1189 | added_matching_location |
1190 | = richloc.add_location_if_nearby (matching_location); |
1191 | |
1192 | if (c_parser_error_richloc (parser, msgid, &richloc)) |
1193 | /* If we weren't able to consolidate matching_location, then |
1194 | print it as a secondary diagnostic. */ |
1195 | if (matching_location != UNKNOWN_LOCATION((location_t) 0) && !added_matching_location) |
1196 | inform (matching_location, "to match this %qs", |
1197 | get_matching_symbol (type)); |
1198 | |
1199 | return false; |
1200 | } |
1201 | } |
1202 | |
1203 | /* If the next token is the indicated keyword, consume it. Otherwise, |
1204 | issue the error MSGID. Returns true if found, false otherwise. */ |
1205 | |
1206 | static bool |
1207 | c_parser_require_keyword (c_parser *parser, |
1208 | enum rid keyword, |
1209 | const char *msgid) |
1210 | { |
1211 | if (c_parser_next_token_is_keyword (parser, keyword)) |
1212 | { |
1213 | c_parser_consume_token (parser); |
1214 | return true; |
1215 | } |
1216 | else |
1217 | { |
1218 | c_parser_error (parser, msgid); |
1219 | return false; |
1220 | } |
1221 | } |
1222 | |
1223 | /* Like c_parser_require, except that tokens will be skipped until the |
1224 | desired token is found. An error message is still produced if the |
1225 | next token is not as expected. If MSGID is NULL then a message has |
1226 | already been produced and no message will be produced this |
1227 | time. |
1228 | |
1229 | If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it |
1230 | within any error as the location of an "opening" token matching |
1231 | the close token TYPE (e.g. the location of the '(' when TYPE is |
1232 | CPP_CLOSE_PAREN). */ |
1233 | |
1234 | void |
1235 | c_parser_skip_until_found (c_parser *parser, |
1236 | enum cpp_ttype type, |
1237 | const char *msgid, |
1238 | location_t matching_location) |
1239 | { |
1240 | unsigned nesting_depth = 0; |
1241 | |
1242 | if (c_parser_require (parser, type, msgid, matching_location)) |
1243 | return; |
1244 | |
1245 | /* Skip tokens until the desired token is found. */ |
1246 | while (true) |
1247 | { |
1248 | /* Peek at the next token. */ |
1249 | c_token *token = c_parser_peek_token (parser); |
1250 | /* If we've reached the token we want, consume it and stop. */ |
1251 | if (token->type == type && !nesting_depth) |
1252 | { |
1253 | c_parser_consume_token (parser); |
1254 | break; |
1255 | } |
1256 | |
1257 | /* If we've run out of tokens, stop. */ |
1258 | if (token->type == CPP_EOF) |
1259 | return; |
1260 | if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) |
1261 | return; |
1262 | if (token->type == CPP_OPEN_BRACE |
1263 | || token->type == CPP_OPEN_PAREN |
1264 | || token->type == CPP_OPEN_SQUARE) |
1265 | ++nesting_depth; |
1266 | else if (token->type == CPP_CLOSE_BRACE |
1267 | || token->type == CPP_CLOSE_PAREN |
1268 | || token->type == CPP_CLOSE_SQUARE) |
1269 | { |
1270 | if (nesting_depth-- == 0) |
1271 | break; |
1272 | } |
1273 | /* Consume this token. */ |
1274 | c_parser_consume_token (parser); |
1275 | } |
1276 | parser->error = false; |
1277 | } |
1278 | |
1279 | /* Skip tokens until the end of a parameter is found, but do not |
1280 | consume the comma, semicolon or closing delimiter. */ |
1281 | |
1282 | static void |
1283 | c_parser_skip_to_end_of_parameter (c_parser *parser) |
1284 | { |
1285 | unsigned nesting_depth = 0; |
1286 | |
1287 | while (true) |
1288 | { |
1289 | c_token *token = c_parser_peek_token (parser); |
1290 | if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON) |
1291 | && !nesting_depth) |
1292 | break; |
1293 | /* If we've run out of tokens, stop. */ |
1294 | if (token->type == CPP_EOF) |
1295 | return; |
1296 | if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) |
1297 | return; |
1298 | if (token->type == CPP_OPEN_BRACE |
1299 | || token->type == CPP_OPEN_PAREN |
1300 | || token->type == CPP_OPEN_SQUARE) |
1301 | ++nesting_depth; |
1302 | else if (token->type == CPP_CLOSE_BRACE |
1303 | || token->type == CPP_CLOSE_PAREN |
1304 | || token->type == CPP_CLOSE_SQUARE) |
1305 | { |
1306 | if (nesting_depth-- == 0) |
1307 | break; |
1308 | } |
1309 | /* Consume this token. */ |
1310 | c_parser_consume_token (parser); |
1311 | } |
1312 | parser->error = false; |
1313 | } |
1314 | |
1315 | /* Expect to be at the end of the pragma directive and consume an |
1316 | end of line marker. */ |
1317 | |
1318 | static void |
1319 | c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true) |
1320 | { |
1321 | gcc_assert (parser->in_pragma)((void)(!(parser->in_pragma) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1321, __FUNCTION__), 0 : 0)); |
1322 | parser->in_pragma = false; |
1323 | |
1324 | if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL) |
1325 | c_parser_error (parser, "expected end of line"); |
1326 | |
1327 | cpp_ttype token_type; |
1328 | do |
1329 | { |
1330 | c_token *token = c_parser_peek_token (parser); |
1331 | token_type = token->type; |
1332 | if (token_type == CPP_EOF) |
1333 | break; |
1334 | c_parser_consume_token (parser); |
1335 | } |
1336 | while (token_type != CPP_PRAGMA_EOL); |
1337 | |
1338 | parser->error = false; |
1339 | } |
1340 | |
1341 | /* Skip tokens until we have consumed an entire block, or until we |
1342 | have consumed a non-nested ';'. */ |
1343 | |
1344 | static void |
1345 | c_parser_skip_to_end_of_block_or_statement (c_parser *parser) |
1346 | { |
1347 | unsigned nesting_depth = 0; |
1348 | bool save_error = parser->error; |
1349 | |
1350 | while (true) |
1351 | { |
1352 | c_token *token; |
1353 | |
1354 | /* Peek at the next token. */ |
1355 | token = c_parser_peek_token (parser); |
1356 | |
1357 | switch (token->type) |
1358 | { |
1359 | case CPP_EOF: |
1360 | return; |
1361 | |
1362 | case CPP_PRAGMA_EOL: |
1363 | if (parser->in_pragma) |
1364 | return; |
1365 | break; |
1366 | |
1367 | case CPP_SEMICOLON: |
1368 | /* If the next token is a ';', we have reached the |
1369 | end of the statement. */ |
1370 | if (!nesting_depth) |
1371 | { |
1372 | /* Consume the ';'. */ |
1373 | c_parser_consume_token (parser); |
1374 | goto finished; |
1375 | } |
1376 | break; |
1377 | |
1378 | case CPP_CLOSE_BRACE: |
1379 | /* If the next token is a non-nested '}', then we have |
1380 | reached the end of the current block. */ |
1381 | if (nesting_depth == 0 || --nesting_depth == 0) |
1382 | { |
1383 | c_parser_consume_token (parser); |
1384 | goto finished; |
1385 | } |
1386 | break; |
1387 | |
1388 | case CPP_OPEN_BRACE: |
1389 | /* If it the next token is a '{', then we are entering a new |
1390 | block. Consume the entire block. */ |
1391 | ++nesting_depth; |
1392 | break; |
1393 | |
1394 | case CPP_PRAGMA: |
1395 | /* If we see a pragma, consume the whole thing at once. We |
1396 | have some safeguards against consuming pragmas willy-nilly. |
1397 | Normally, we'd expect to be here with parser->error set, |
1398 | which disables these safeguards. But it's possible to get |
1399 | here for secondary error recovery, after parser->error has |
1400 | been cleared. */ |
1401 | c_parser_consume_pragma (parser); |
1402 | c_parser_skip_to_pragma_eol (parser); |
1403 | parser->error = save_error; |
1404 | continue; |
1405 | |
1406 | default: |
1407 | break; |
1408 | } |
1409 | |
1410 | c_parser_consume_token (parser); |
1411 | } |
1412 | |
1413 | finished: |
1414 | parser->error = false; |
1415 | } |
1416 | |
1417 | /* CPP's options (initialized by c-opts.c). */ |
1418 | extern cpp_options *cpp_opts; |
1419 | |
1420 | /* Save the warning flags which are controlled by __extension__. */ |
1421 | |
1422 | static inline int |
1423 | disable_extension_diagnostics (void) |
1424 | { |
1425 | int ret = (pedanticglobal_options.x_pedantic |
1426 | | (warn_pointer_arithglobal_options.x_warn_pointer_arith << 1) |
1427 | | (warn_traditionalglobal_options.x_warn_traditional << 2) |
1428 | | (flag_iso << 3) |
1429 | | (warn_long_longglobal_options.x_warn_long_long << 4) |
1430 | | (warn_cxx_compatglobal_options.x_warn_cxx_compat << 5) |
1431 | | (warn_overlength_stringsglobal_options.x_warn_overlength_strings << 6) |
1432 | /* warn_c90_c99_compat has three states: -1/0/1, so we must |
1433 | play tricks to properly restore it. */ |
1434 | | ((warn_c90_c99_compatglobal_options.x_warn_c90_c99_compat == 1) << 7) |
1435 | | ((warn_c90_c99_compatglobal_options.x_warn_c90_c99_compat == -1) << 8) |
1436 | /* Similarly for warn_c99_c11_compat. */ |
1437 | | ((warn_c99_c11_compatglobal_options.x_warn_c99_c11_compat == 1) << 9) |
1438 | | ((warn_c99_c11_compatglobal_options.x_warn_c99_c11_compat == -1) << 10) |
1439 | /* Similarly for warn_c11_c2x_compat. */ |
1440 | | ((warn_c11_c2x_compatglobal_options.x_warn_c11_c2x_compat == 1) << 11) |
1441 | | ((warn_c11_c2x_compatglobal_options.x_warn_c11_c2x_compat == -1) << 12) |
1442 | ); |
1443 | cpp_opts->cpp_pedantic = pedanticglobal_options.x_pedantic = 0; |
1444 | warn_pointer_arithglobal_options.x_warn_pointer_arith = 0; |
1445 | cpp_opts->cpp_warn_traditional = warn_traditionalglobal_options.x_warn_traditional = 0; |
1446 | flag_iso = 0; |
1447 | cpp_opts->cpp_warn_long_long = warn_long_longglobal_options.x_warn_long_long = 0; |
1448 | warn_cxx_compatglobal_options.x_warn_cxx_compat = 0; |
1449 | warn_overlength_stringsglobal_options.x_warn_overlength_strings = 0; |
1450 | warn_c90_c99_compatglobal_options.x_warn_c90_c99_compat = 0; |
1451 | warn_c99_c11_compatglobal_options.x_warn_c99_c11_compat = 0; |
1452 | warn_c11_c2x_compatglobal_options.x_warn_c11_c2x_compat = 0; |
1453 | return ret; |
1454 | } |
1455 | |
1456 | /* Restore the warning flags which are controlled by __extension__. |
1457 | FLAGS is the return value from disable_extension_diagnostics. */ |
1458 | |
1459 | static inline void |
1460 | restore_extension_diagnostics (int flags) |
1461 | { |
1462 | cpp_opts->cpp_pedantic = pedanticglobal_options.x_pedantic = flags & 1; |
1463 | warn_pointer_arithglobal_options.x_warn_pointer_arith = (flags >> 1) & 1; |
1464 | cpp_opts->cpp_warn_traditional = warn_traditionalglobal_options.x_warn_traditional = (flags >> 2) & 1; |
1465 | flag_iso = (flags >> 3) & 1; |
1466 | cpp_opts->cpp_warn_long_long = warn_long_longglobal_options.x_warn_long_long = (flags >> 4) & 1; |
1467 | warn_cxx_compatglobal_options.x_warn_cxx_compat = (flags >> 5) & 1; |
1468 | warn_overlength_stringsglobal_options.x_warn_overlength_strings = (flags >> 6) & 1; |
1469 | /* See above for why is this needed. */ |
1470 | warn_c90_c99_compatglobal_options.x_warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0); |
1471 | warn_c99_c11_compatglobal_options.x_warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0); |
1472 | warn_c11_c2x_compatglobal_options.x_warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0); |
1473 | } |
1474 | |
1475 | /* Helper data structure for parsing #pragma acc routine. */ |
1476 | struct oacc_routine_data { |
1477 | bool error_seen; /* Set if error has been reported. */ |
1478 | bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */ |
1479 | tree clauses; |
1480 | location_t loc; |
1481 | }; |
1482 | |
1483 | /* Used for parsing objc foreach statements. */ |
1484 | static tree objc_foreach_break_label, objc_foreach_continue_label; |
1485 | |
1486 | static bool c_parser_nth_token_starts_std_attributes (c_parser *, |
1487 | unsigned int); |
1488 | static tree c_parser_std_attribute_specifier_sequence (c_parser *); |
1489 | static void c_parser_external_declaration (c_parser *); |
1490 | static void c_parser_asm_definition (c_parser *); |
1491 | static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, |
1492 | bool, bool, tree *, vec<c_token>, |
1493 | bool have_attrs = false, |
1494 | tree attrs = NULL__null, |
1495 | struct oacc_routine_data * = NULL__null, |
1496 | bool * = NULL__null); |
1497 | static void c_parser_static_assert_declaration_no_semi (c_parser *); |
1498 | static void c_parser_static_assert_declaration (c_parser *); |
1499 | static struct c_typespec c_parser_enum_specifier (c_parser *); |
1500 | static struct c_typespec c_parser_struct_or_union_specifier (c_parser *); |
1501 | static tree c_parser_struct_declaration (c_parser *); |
1502 | static struct c_typespec c_parser_typeof_specifier (c_parser *); |
1503 | static tree c_parser_alignas_specifier (c_parser *); |
1504 | static struct c_declarator *c_parser_direct_declarator (c_parser *, bool, |
1505 | c_dtr_syn, bool *); |
1506 | static struct c_declarator *c_parser_direct_declarator_inner (c_parser *, |
1507 | bool, |
1508 | struct c_declarator *); |
1509 | static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree, |
1510 | bool); |
1511 | static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree, |
1512 | tree, bool); |
1513 | static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool); |
1514 | static tree c_parser_simple_asm_expr (c_parser *); |
1515 | static tree c_parser_gnu_attributes (c_parser *); |
1516 | static struct c_expr c_parser_initializer (c_parser *); |
1517 | static struct c_expr c_parser_braced_init (c_parser *, tree, bool, |
1518 | struct obstack *); |
1519 | static void c_parser_initelt (c_parser *, struct obstack *); |
1520 | static void c_parser_initval (c_parser *, struct c_expr *, |
1521 | struct obstack *); |
1522 | static tree c_parser_compound_statement (c_parser *, location_t * = NULL__null); |
1523 | static location_t c_parser_compound_statement_nostart (c_parser *); |
1524 | static void c_parser_label (c_parser *, tree); |
1525 | static void c_parser_statement (c_parser *, bool *, location_t * = NULL__null); |
1526 | static void c_parser_statement_after_labels (c_parser *, bool *, |
1527 | vec<tree> * = NULL__null); |
1528 | static tree c_parser_c99_block_statement (c_parser *, bool *, |
1529 | location_t * = NULL__null); |
1530 | static void c_parser_if_statement (c_parser *, bool *, vec<tree> *); |
1531 | static void c_parser_switch_statement (c_parser *, bool *); |
1532 | static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *); |
1533 | static void c_parser_do_statement (c_parser *, bool, unsigned short); |
1534 | static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *); |
1535 | static tree c_parser_asm_statement (c_parser *); |
1536 | static tree c_parser_asm_operands (c_parser *); |
1537 | static tree c_parser_asm_goto_operands (c_parser *); |
1538 | static tree c_parser_asm_clobbers (c_parser *); |
1539 | static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *, |
1540 | tree = NULL_TREE(tree) __null); |
1541 | static struct c_expr c_parser_conditional_expression (c_parser *, |
1542 | struct c_expr *, tree); |
1543 | static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *, |
1544 | tree); |
1545 | static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *); |
1546 | static struct c_expr c_parser_unary_expression (c_parser *); |
1547 | static struct c_expr c_parser_sizeof_expression (c_parser *); |
1548 | static struct c_expr c_parser_alignof_expression (c_parser *); |
1549 | static struct c_expr c_parser_postfix_expression (c_parser *); |
1550 | static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, |
1551 | struct c_type_name *, |
1552 | location_t); |
1553 | static struct c_expr c_parser_postfix_expression_after_primary (c_parser *, |
1554 | location_t loc, |
1555 | struct c_expr); |
1556 | static tree c_parser_transaction (c_parser *, enum rid); |
1557 | static struct c_expr c_parser_transaction_expression (c_parser *, enum rid); |
1558 | static tree c_parser_transaction_cancel (c_parser *); |
1559 | static struct c_expr c_parser_expression (c_parser *); |
1560 | static struct c_expr c_parser_expression_conv (c_parser *); |
1561 | static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool, |
1562 | vec<tree, va_gc> **, location_t *, |
1563 | tree *, vec<location_t> *, |
1564 | unsigned int * = NULL__null); |
1565 | static struct c_expr c_parser_has_attribute_expression (c_parser *); |
1566 | |
1567 | static void c_parser_oacc_declare (c_parser *); |
1568 | static void c_parser_oacc_enter_exit_data (c_parser *, bool); |
1569 | static void c_parser_oacc_update (c_parser *); |
1570 | static void c_parser_omp_construct (c_parser *, bool *); |
1571 | static void c_parser_omp_threadprivate (c_parser *); |
1572 | static void c_parser_omp_barrier (c_parser *); |
1573 | static void c_parser_omp_depobj (c_parser *); |
1574 | static void c_parser_omp_flush (c_parser *); |
1575 | static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code, |
1576 | tree, tree *, bool *); |
1577 | static void c_parser_omp_taskwait (c_parser *); |
1578 | static void c_parser_omp_taskyield (c_parser *); |
1579 | static void c_parser_omp_cancel (c_parser *); |
1580 | |
1581 | enum pragma_context { pragma_external, pragma_struct, pragma_param, |
1582 | pragma_stmt, pragma_compound }; |
1583 | static bool c_parser_pragma (c_parser *, enum pragma_context, bool *); |
1584 | static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context); |
1585 | static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *); |
1586 | static void c_parser_omp_end_declare_target (c_parser *); |
1587 | static void c_parser_omp_declare (c_parser *, enum pragma_context); |
1588 | static void c_parser_omp_requires (c_parser *); |
1589 | static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *); |
1590 | static void c_parser_oacc_routine (c_parser *, enum pragma_context); |
1591 | |
1592 | /* These Objective-C parser functions are only ever called when |
1593 | compiling Objective-C. */ |
1594 | static void c_parser_objc_class_definition (c_parser *, tree); |
1595 | static void c_parser_objc_class_instance_variables (c_parser *); |
1596 | static void c_parser_objc_class_declaration (c_parser *); |
1597 | static void c_parser_objc_alias_declaration (c_parser *); |
1598 | static void c_parser_objc_protocol_definition (c_parser *, tree); |
1599 | static bool c_parser_objc_method_type (c_parser *); |
1600 | static void c_parser_objc_method_definition (c_parser *); |
1601 | static void c_parser_objc_methodprotolist (c_parser *); |
1602 | static void c_parser_objc_methodproto (c_parser *); |
1603 | static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *); |
1604 | static tree c_parser_objc_type_name (c_parser *); |
1605 | static tree c_parser_objc_protocol_refs (c_parser *); |
1606 | static void c_parser_objc_try_catch_finally_statement (c_parser *); |
1607 | static void c_parser_objc_synchronized_statement (c_parser *); |
1608 | static tree c_parser_objc_selector (c_parser *); |
1609 | static tree c_parser_objc_selector_arg (c_parser *); |
1610 | static tree c_parser_objc_receiver (c_parser *); |
1611 | static tree c_parser_objc_message_args (c_parser *); |
1612 | static tree c_parser_objc_keywordexpr (c_parser *); |
1613 | static void c_parser_objc_at_property_declaration (c_parser *); |
1614 | static void c_parser_objc_at_synthesize_declaration (c_parser *); |
1615 | static void c_parser_objc_at_dynamic_declaration (c_parser *); |
1616 | static bool c_parser_objc_diagnose_bad_element_prefix |
1617 | (c_parser *, struct c_declspecs *); |
1618 | static location_t c_parser_parse_rtl_body (c_parser *, char *); |
1619 | |
1620 | /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9). |
1621 | |
1622 | translation-unit: |
1623 | external-declarations |
1624 | |
1625 | external-declarations: |
1626 | external-declaration |
1627 | external-declarations external-declaration |
1628 | |
1629 | GNU extensions: |
1630 | |
1631 | translation-unit: |
1632 | empty |
1633 | */ |
1634 | |
1635 | static void |
1636 | c_parser_translation_unit (c_parser *parser) |
1637 | { |
1638 | if (c_parser_next_token_is (parser, CPP_EOF)) |
1639 | { |
1640 | pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, |
1641 | "ISO C forbids an empty translation unit"); |
1642 | } |
1643 | else |
1644 | { |
1645 | void *obstack_position = obstack_alloc (&parser_obstack, 0)__extension__ ({ struct obstack *__h = (&parser_obstack); __extension__ ({ struct obstack *__o = (__h); size_t __len = ((0)); if (__extension__ ({ struct obstack const *__o1 = (__o ); (size_t) (__o1->chunk_limit - __o1->next_free); }) < __len) _obstack_newchunk (__o, __len); ((void) ((__o)->next_free += (__len))); }); __extension__ ({ struct obstack *__o1 = (__h ); void *__value = (void *) __o1->object_base; if (__o1-> next_free == __value) __o1->maybe_empty_object = 1; __o1-> next_free = ((sizeof (ptrdiff_t) < sizeof (void *) ? (__o1 ->object_base) : (char *) 0) + (((__o1->next_free) - (sizeof (ptrdiff_t) < sizeof (void *) ? (__o1->object_base) : ( char *) 0) + (__o1->alignment_mask)) & ~(__o1->alignment_mask ))); if ((size_t) (__o1->next_free - (char *) __o1->chunk ) > (size_t) (__o1->chunk_limit - (char *) __o1->chunk )) __o1->next_free = __o1->chunk_limit; __o1->object_base = __o1->next_free; __value; }); }); |
1646 | mark_valid_location_for_stdc_pragma (false); |
1647 | do |
1648 | { |
1649 | ggc_collect (); |
1650 | c_parser_external_declaration (parser); |
1651 | obstack_free (&parser_obstack, obstack_position)__extension__ ({ struct obstack *__o = (&parser_obstack); void *__obj = (void *) (obstack_position); if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit ) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o, __obj); }); |
1652 | } |
1653 | while (c_parser_next_token_is_not (parser, CPP_EOF)); |
1654 | } |
1655 | |
1656 | unsigned int i; |
1657 | tree decl; |
1658 | FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)for (i = 0; (incomplete_record_decls).iterate ((i), &(decl )); ++(i)) |
1659 | if (DECL_SIZE (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1659, __FUNCTION__))->decl_common.size) == NULL_TREE(tree) __null && TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1659, __FUNCTION__))->typed.type) != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
1660 | error ("storage size of %q+D isn%'t known", decl); |
1661 | |
1662 | if (current_omp_declare_target_attribute) |
1663 | { |
1664 | if (!errorcount(global_dc)->diagnostic_count[(int) (DK_ERROR)]) |
1665 | error ("%<#pragma omp declare target%> without corresponding " |
1666 | "%<#pragma omp end declare target%>"); |
1667 | current_omp_declare_target_attribute = 0; |
1668 | } |
1669 | } |
1670 | |
1671 | /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9). |
1672 | |
1673 | external-declaration: |
1674 | function-definition |
1675 | declaration |
1676 | |
1677 | GNU extensions: |
1678 | |
1679 | external-declaration: |
1680 | asm-definition |
1681 | ; |
1682 | __extension__ external-declaration |
1683 | |
1684 | Objective-C: |
1685 | |
1686 | external-declaration: |
1687 | objc-class-definition |
1688 | objc-class-declaration |
1689 | objc-alias-declaration |
1690 | objc-protocol-definition |
1691 | objc-method-definition |
1692 | @end |
1693 | */ |
1694 | |
1695 | static void |
1696 | c_parser_external_declaration (c_parser *parser) |
1697 | { |
1698 | int ext; |
1699 | switch (c_parser_peek_token (parser)->type) |
1700 | { |
1701 | case CPP_KEYWORD: |
1702 | switch (c_parser_peek_token (parser)->keyword) |
1703 | { |
1704 | case RID_EXTENSION: |
1705 | ext = disable_extension_diagnostics (); |
1706 | c_parser_consume_token (parser); |
1707 | c_parser_external_declaration (parser); |
1708 | restore_extension_diagnostics (ext); |
1709 | break; |
1710 | case RID_ASM: |
1711 | c_parser_asm_definition (parser); |
1712 | break; |
1713 | case RID_AT_INTERFACE: |
1714 | case RID_AT_IMPLEMENTATION: |
1715 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1715, __FUNCTION__), 0 : 0)); |
1716 | c_parser_objc_class_definition (parser, NULL_TREE(tree) __null); |
1717 | break; |
1718 | case RID_AT_CLASS: |
1719 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1719, __FUNCTION__), 0 : 0)); |
1720 | c_parser_objc_class_declaration (parser); |
1721 | break; |
1722 | case RID_AT_ALIAS: |
1723 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1723, __FUNCTION__), 0 : 0)); |
1724 | c_parser_objc_alias_declaration (parser); |
1725 | break; |
1726 | case RID_AT_PROTOCOL: |
1727 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1727, __FUNCTION__), 0 : 0)); |
1728 | c_parser_objc_protocol_definition (parser, NULL_TREE(tree) __null); |
1729 | break; |
1730 | case RID_AT_PROPERTY: |
1731 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1731, __FUNCTION__), 0 : 0)); |
1732 | c_parser_objc_at_property_declaration (parser); |
1733 | break; |
1734 | case RID_AT_SYNTHESIZE: |
1735 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1735, __FUNCTION__), 0 : 0)); |
1736 | c_parser_objc_at_synthesize_declaration (parser); |
1737 | break; |
1738 | case RID_AT_DYNAMIC: |
1739 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1739, __FUNCTION__), 0 : 0)); |
1740 | c_parser_objc_at_dynamic_declaration (parser); |
1741 | break; |
1742 | case RID_AT_END: |
1743 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1743, __FUNCTION__), 0 : 0)); |
1744 | c_parser_consume_token (parser); |
1745 | objc_finish_implementation (); |
1746 | break; |
1747 | default: |
1748 | goto decl_or_fndef; |
1749 | } |
1750 | break; |
1751 | case CPP_SEMICOLON: |
1752 | pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, |
1753 | "ISO C does not allow extra %<;%> outside of a function"); |
1754 | c_parser_consume_token (parser); |
1755 | break; |
1756 | case CPP_PRAGMA: |
1757 | mark_valid_location_for_stdc_pragma (true); |
1758 | c_parser_pragma (parser, pragma_external, NULL__null); |
1759 | mark_valid_location_for_stdc_pragma (false); |
1760 | break; |
1761 | case CPP_PLUS: |
1762 | case CPP_MINUS: |
1763 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
1764 | { |
1765 | c_parser_objc_method_definition (parser); |
1766 | break; |
1767 | } |
1768 | /* Else fall through, and yield a syntax error trying to parse |
1769 | as a declaration or function definition. */ |
1770 | /* FALLTHRU */ |
1771 | default: |
1772 | decl_or_fndef: |
1773 | /* A declaration or a function definition (or, in Objective-C, |
1774 | an @interface or @protocol with prefix attributes). We can |
1775 | only tell which after parsing the declaration specifiers, if |
1776 | any, and the first declarator. */ |
1777 | c_parser_declaration_or_fndef (parser, true, true, true, false, true, |
1778 | NULL__null, vNULL); |
1779 | break; |
1780 | } |
1781 | } |
1782 | |
1783 | static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>); |
1784 | static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool); |
1785 | |
1786 | /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */ |
1787 | |
1788 | static void |
1789 | add_debug_begin_stmt (location_t loc) |
1790 | { |
1791 | /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */ |
1792 | if (!MAY_HAVE_DEBUG_MARKER_STMTSglobal_options.x_debug_nonbind_markers_p || !building_stmt_list_p ()((current_stmt_tree ()->x_cur_stmt_list) && !(current_stmt_tree ()->x_cur_stmt_list)->is_empty())) |
1793 | return; |
1794 | |
1795 | tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_nodeglobal_trees[TI_VOID_TYPE]); |
1796 | SET_EXPR_LOCATION (stmt, loc)(expr_check (((stmt)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 1796, __FUNCTION__))->exp.locus = (loc); |
1797 | add_stmt (stmt); |
1798 | } |
1799 | |
1800 | /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 |
1801 | 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition |
1802 | is accepted; otherwise (old-style parameter declarations) only other |
1803 | declarations are accepted. If STATIC_ASSERT_OK is true, a static |
1804 | assertion is accepted; otherwise (old-style parameter declarations) |
1805 | it is not. If NESTED is true, we are inside a function or parsing |
1806 | old-style parameter declarations; any functions encountered are |
1807 | nested functions and declaration specifiers are required; otherwise |
1808 | we are at top level and functions are normal functions and |
1809 | declaration specifiers may be optional. If EMPTY_OK is true, empty |
1810 | declarations are OK (subject to all other constraints); otherwise |
1811 | (old-style parameter declarations) they are diagnosed. If |
1812 | START_ATTR_OK is true, the declaration specifiers may start with |
1813 | attributes (GNU or standard); otherwise they may not. |
1814 | OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed |
1815 | declaration when parsing an Objective-C foreach statement. |
1816 | FALLTHRU_ATTR_P is used to signal whether this function parsed |
1817 | "__attribute__((fallthrough));". ATTRS are any standard attributes |
1818 | parsed in the caller (in contexts where such attributes had to be |
1819 | parsed to determine whether what follows is a declaration or a |
1820 | statement); HAVE_ATTRS says whether there were any such attributes |
1821 | (even empty). |
1822 | |
1823 | declaration: |
1824 | declaration-specifiers init-declarator-list[opt] ; |
1825 | static_assert-declaration |
1826 | |
1827 | function-definition: |
1828 | declaration-specifiers[opt] declarator declaration-list[opt] |
1829 | compound-statement |
1830 | |
1831 | declaration-list: |
1832 | declaration |
1833 | declaration-list declaration |
1834 | |
1835 | init-declarator-list: |
1836 | init-declarator |
1837 | init-declarator-list , init-declarator |
1838 | |
1839 | init-declarator: |
1840 | declarator simple-asm-expr[opt] gnu-attributes[opt] |
1841 | declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer |
1842 | |
1843 | GNU extensions: |
1844 | |
1845 | nested-function-definition: |
1846 | declaration-specifiers declarator declaration-list[opt] |
1847 | compound-statement |
1848 | |
1849 | attribute ; |
1850 | |
1851 | Objective-C: |
1852 | gnu-attributes objc-class-definition |
1853 | gnu-attributes objc-category-definition |
1854 | gnu-attributes objc-protocol-definition |
1855 | |
1856 | The simple-asm-expr and gnu-attributes are GNU extensions. |
1857 | |
1858 | This function does not handle __extension__; that is handled in its |
1859 | callers. ??? Following the old parser, __extension__ may start |
1860 | external declarations, declarations in functions and declarations |
1861 | at the start of "for" loops, but not old-style parameter |
1862 | declarations. |
1863 | |
1864 | C99 requires declaration specifiers in a function definition; the |
1865 | absence is diagnosed through the diagnosis of implicit int. In GNU |
1866 | C we also allow but diagnose declarations without declaration |
1867 | specifiers, but only at top level (elsewhere they conflict with |
1868 | other syntax). |
1869 | |
1870 | In Objective-C, declarations of the looping variable in a foreach |
1871 | statement are exceptionally terminated by 'in' (for example, 'for |
1872 | (NSObject *object in array) { ... }'). |
1873 | |
1874 | OpenMP: |
1875 | |
1876 | declaration: |
1877 | threadprivate-directive |
1878 | |
1879 | GIMPLE: |
1880 | |
1881 | gimple-function-definition: |
1882 | declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator |
1883 | declaration-list[opt] compound-statement |
1884 | |
1885 | rtl-function-definition: |
1886 | declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator |
1887 | declaration-list[opt] compound-statement */ |
1888 | |
1889 | static void |
1890 | c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, |
1891 | bool static_assert_ok, bool empty_ok, |
1892 | bool nested, bool start_attr_ok, |
1893 | tree *objc_foreach_object_declaration, |
1894 | vec<c_token> omp_declare_simd_clauses, |
1895 | bool have_attrs, tree attrs, |
1896 | struct oacc_routine_data *oacc_routine_data, |
1897 | bool *fallthru_attr_p) |
1898 | { |
1899 | struct c_declspecs *specs; |
1900 | tree prefix_attrs; |
1901 | tree all_prefix_attrs; |
1902 | bool diagnosed_no_specs = false; |
1903 | location_t here = c_parser_peek_token (parser)->location; |
1904 | |
1905 | add_debug_begin_stmt (c_parser_peek_token (parser)->location); |
1906 | |
1907 | if (static_assert_ok |
1908 | && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) |
1909 | { |
1910 | c_parser_static_assert_declaration (parser); |
1911 | return; |
1912 | } |
1913 | specs = build_null_declspecs (); |
1914 | |
1915 | /* Handle any standard attributes parsed in the caller. */ |
1916 | if (have_attrs) |
1917 | { |
1918 | declspecs_add_attrs (here, specs, attrs); |
1919 | specs->non_std_attrs_seen_p = false; |
1920 | } |
1921 | |
1922 | /* Try to detect an unknown type name when we have "A B" or "A *B". */ |
1923 | if (c_parser_peek_token (parser)->type == CPP_NAME |
1924 | && c_parser_peek_token (parser)->id_kind == C_ID_ID |
1925 | && (c_parser_peek_2nd_token (parser)->type == CPP_NAME |
1926 | || c_parser_peek_2nd_token (parser)->type == CPP_MULT) |
1927 | && (!nested || !lookup_name (c_parser_peek_token (parser)->value))) |
1928 | { |
1929 | tree name = c_parser_peek_token (parser)->value; |
1930 | |
1931 | /* Issue a warning about NAME being an unknown type name, perhaps |
1932 | with some kind of hint. |
1933 | If the user forgot a "struct" etc, suggest inserting |
1934 | it. Otherwise, attempt to look for misspellings. */ |
1935 | gcc_rich_location richloc (here); |
1936 | if (tag_exists_p (RECORD_TYPE, name)) |
1937 | { |
1938 | /* This is not C++ with its implicit typedef. */ |
1939 | richloc.add_fixit_insert_before ("struct "); |
1940 | error_at (&richloc, |
1941 | "unknown type name %qE;" |
1942 | " use %<struct%> keyword to refer to the type", |
1943 | name); |
1944 | } |
1945 | else if (tag_exists_p (UNION_TYPE, name)) |
1946 | { |
1947 | richloc.add_fixit_insert_before ("union "); |
1948 | error_at (&richloc, |
1949 | "unknown type name %qE;" |
1950 | " use %<union%> keyword to refer to the type", |
1951 | name); |
1952 | } |
1953 | else if (tag_exists_p (ENUMERAL_TYPE, name)) |
1954 | { |
1955 | richloc.add_fixit_insert_before ("enum "); |
1956 | error_at (&richloc, |
1957 | "unknown type name %qE;" |
1958 | " use %<enum%> keyword to refer to the type", |
1959 | name); |
1960 | } |
1961 | else |
1962 | { |
1963 | auto_diagnostic_group d; |
1964 | name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME, |
1965 | here); |
1966 | if (const char *suggestion = hint.suggestion ()) |
1967 | { |
1968 | richloc.add_fixit_replace (suggestion); |
1969 | error_at (&richloc, |
1970 | "unknown type name %qE; did you mean %qs?", |
1971 | name, suggestion); |
1972 | } |
1973 | else |
1974 | error_at (here, "unknown type name %qE", name); |
1975 | } |
1976 | |
1977 | /* Parse declspecs normally to get a correct pointer type, but avoid |
1978 | a further "fails to be a type name" error. Refuse nested functions |
1979 | since it is not how the user likely wants us to recover. */ |
1980 | c_parser_peek_token (parser)->type = CPP_KEYWORD; |
1981 | c_parser_peek_token (parser)->keyword = RID_VOID; |
1982 | c_parser_peek_token (parser)->value = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
1983 | fndef_ok = !nested; |
1984 | } |
1985 | |
1986 | /* When there are standard attributes at the start of the |
1987 | declaration (to apply to the entity being declared), an |
1988 | init-declarator-list or function definition must be present. */ |
1989 | if (c_parser_nth_token_starts_std_attributes (parser, 1)) |
1990 | have_attrs = true; |
1991 | |
1992 | c_parser_declspecs (parser, specs, true, true, start_attr_ok, |
1993 | true, true, start_attr_ok, true, cla_nonabstract_decl); |
1994 | if (parser->error) |
1995 | { |
1996 | c_parser_skip_to_end_of_block_or_statement (parser); |
1997 | return; |
1998 | } |
1999 | if (nested && !specs->declspecs_seen_p) |
2000 | { |
2001 | c_parser_error (parser, "expected declaration specifiers"); |
2002 | c_parser_skip_to_end_of_block_or_statement (parser); |
2003 | return; |
2004 | } |
2005 | |
2006 | finish_declspecs (specs); |
2007 | bool auto_type_p = specs->typespec_word == cts_auto_type; |
2008 | if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
2009 | { |
2010 | if (auto_type_p) |
2011 | error_at (here, "%<__auto_type%> in empty declaration"); |
2012 | else if (specs->typespec_kind == ctsk_none |
2013 | && attribute_fallthrough_p (specs->attrs)) |
2014 | { |
2015 | if (fallthru_attr_p != NULL__null) |
2016 | *fallthru_attr_p = true; |
2017 | if (nested) |
2018 | { |
2019 | tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH, |
2020 | void_type_nodeglobal_trees[TI_VOID_TYPE], 0); |
2021 | add_stmt (fn); |
2022 | } |
2023 | else |
2024 | pedwarn (here, OPT_Wattributes, |
2025 | "%<fallthrough%> attribute at top level"); |
2026 | } |
2027 | else if (empty_ok && !(have_attrs |
2028 | && specs->non_std_attrs_seen_p)) |
2029 | shadow_tag (specs); |
2030 | else |
2031 | { |
2032 | shadow_tag_warned (specs, 1); |
2033 | pedwarn (here, 0, "empty declaration"); |
2034 | } |
2035 | c_parser_consume_token (parser); |
2036 | if (oacc_routine_data) |
2037 | c_finish_oacc_routine (oacc_routine_data, NULL_TREE(tree) __null, false); |
2038 | return; |
2039 | } |
2040 | |
2041 | /* Provide better error recovery. Note that a type name here is usually |
2042 | better diagnosed as a redeclaration. */ |
2043 | if (empty_ok |
2044 | && specs->typespec_kind == ctsk_tagdef |
2045 | && c_parser_next_token_starts_declspecs (parser) |
2046 | && !c_parser_next_token_is (parser, CPP_NAME)) |
2047 | { |
2048 | c_parser_error (parser, "expected %<;%>, identifier or %<(%>"); |
2049 | parser->error = false; |
2050 | shadow_tag_warned (specs, 1); |
2051 | return; |
2052 | } |
2053 | else if (c_dialect_objc ()((c_language & clk_objc) != 0) && !auto_type_p) |
2054 | { |
2055 | /* Prefix attributes are an error on method decls. */ |
2056 | switch (c_parser_peek_token (parser)->type) |
2057 | { |
2058 | case CPP_PLUS: |
2059 | case CPP_MINUS: |
2060 | if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) |
2061 | return; |
2062 | if (specs->attrs) |
2063 | { |
2064 | warning_at (c_parser_peek_token (parser)->location, |
2065 | OPT_Wattributes, |
2066 | "prefix attributes are ignored for methods"); |
2067 | specs->attrs = NULL_TREE(tree) __null; |
2068 | } |
2069 | if (fndef_ok) |
2070 | c_parser_objc_method_definition (parser); |
2071 | else |
2072 | c_parser_objc_methodproto (parser); |
2073 | return; |
2074 | break; |
2075 | default: |
2076 | break; |
2077 | } |
2078 | /* This is where we parse 'attributes @interface ...', |
2079 | 'attributes @implementation ...', 'attributes @protocol ...' |
2080 | (where attributes could be, for example, __attribute__ |
2081 | ((deprecated)). |
2082 | */ |
2083 | switch (c_parser_peek_token (parser)->keyword) |
2084 | { |
2085 | case RID_AT_INTERFACE: |
2086 | { |
2087 | if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) |
2088 | return; |
2089 | c_parser_objc_class_definition (parser, specs->attrs); |
2090 | return; |
2091 | } |
2092 | break; |
2093 | case RID_AT_IMPLEMENTATION: |
2094 | { |
2095 | if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) |
2096 | return; |
2097 | if (specs->attrs) |
2098 | { |
2099 | warning_at (c_parser_peek_token (parser)->location, |
2100 | OPT_Wattributes, |
2101 | "prefix attributes are ignored for implementations"); |
2102 | specs->attrs = NULL_TREE(tree) __null; |
2103 | } |
2104 | c_parser_objc_class_definition (parser, NULL_TREE(tree) __null); |
2105 | return; |
2106 | } |
2107 | break; |
2108 | case RID_AT_PROTOCOL: |
2109 | { |
2110 | if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) |
2111 | return; |
2112 | c_parser_objc_protocol_definition (parser, specs->attrs); |
2113 | return; |
2114 | } |
2115 | break; |
2116 | case RID_AT_ALIAS: |
2117 | case RID_AT_CLASS: |
2118 | case RID_AT_END: |
2119 | case RID_AT_PROPERTY: |
2120 | if (specs->attrs) |
2121 | { |
2122 | c_parser_error (parser, "unexpected attribute"); |
2123 | specs->attrs = NULL__null; |
2124 | } |
2125 | break; |
2126 | default: |
2127 | break; |
2128 | } |
2129 | } |
2130 | else if (attribute_fallthrough_p (specs->attrs)) |
2131 | warning_at (here, OPT_Wattributes, |
2132 | "%<fallthrough%> attribute not followed by %<;%>"); |
2133 | |
2134 | pending_xref_error (); |
2135 | prefix_attrs = specs->attrs; |
2136 | all_prefix_attrs = prefix_attrs; |
2137 | specs->attrs = NULL_TREE(tree) __null; |
2138 | while (true) |
2139 | { |
2140 | struct c_declarator *declarator; |
2141 | bool dummy = false; |
2142 | timevar_id_t tv; |
2143 | tree fnbody = NULL_TREE(tree) __null; |
2144 | /* Declaring either one or more declarators (in which case we |
2145 | should diagnose if there were no declaration specifiers) or a |
2146 | function definition (in which case the diagnostic for |
2147 | implicit int suffices). */ |
2148 | declarator = c_parser_declarator (parser, |
2149 | specs->typespec_kind != ctsk_none, |
2150 | C_DTR_NORMAL, &dummy); |
2151 | if (declarator == NULL__null) |
2152 | { |
2153 | if (omp_declare_simd_clauses.exists ()) |
2154 | c_finish_omp_declare_simd (parser, NULL_TREE(tree) __null, NULL_TREE(tree) __null, |
2155 | omp_declare_simd_clauses); |
2156 | if (oacc_routine_data) |
2157 | c_finish_oacc_routine (oacc_routine_data, NULL_TREE(tree) __null, false); |
2158 | c_parser_skip_to_end_of_block_or_statement (parser); |
2159 | return; |
2160 | } |
2161 | if (auto_type_p && declarator->kind != cdk_id) |
2162 | { |
2163 | error_at (here, |
2164 | "%<__auto_type%> requires a plain identifier" |
2165 | " as declarator"); |
2166 | c_parser_skip_to_end_of_block_or_statement (parser); |
2167 | return; |
2168 | } |
2169 | if (c_parser_next_token_is (parser, CPP_EQ) |
2170 | || c_parser_next_token_is (parser, CPP_COMMA) |
2171 | || c_parser_next_token_is (parser, CPP_SEMICOLON) |
2172 | || c_parser_next_token_is_keyword (parser, RID_ASM) |
2173 | || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE) |
2174 | || c_parser_next_token_is_keyword (parser, RID_IN)) |
2175 | { |
2176 | tree asm_name = NULL_TREE(tree) __null; |
2177 | tree postfix_attrs = NULL_TREE(tree) __null; |
2178 | if (!diagnosed_no_specs && !specs->declspecs_seen_p) |
2179 | { |
2180 | diagnosed_no_specs = true; |
2181 | pedwarn (here, 0, "data definition has no type or storage class"); |
2182 | } |
2183 | /* Having seen a data definition, there cannot now be a |
2184 | function definition. */ |
2185 | fndef_ok = false; |
2186 | if (c_parser_next_token_is_keyword (parser, RID_ASM)) |
2187 | asm_name = c_parser_simple_asm_expr (parser); |
2188 | if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
2189 | { |
2190 | postfix_attrs = c_parser_gnu_attributes (parser); |
2191 | if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) |
2192 | { |
2193 | /* This means there is an attribute specifier after |
2194 | the declarator in a function definition. Provide |
2195 | some more information for the user. */ |
2196 | error_at (here, "attributes should be specified before the " |
2197 | "declarator in a function definition"); |
2198 | c_parser_skip_to_end_of_block_or_statement (parser); |
2199 | return; |
2200 | } |
2201 | } |
2202 | if (c_parser_next_token_is (parser, CPP_EQ)) |
2203 | { |
2204 | tree d; |
2205 | struct c_expr init; |
2206 | location_t init_loc; |
2207 | c_parser_consume_token (parser); |
2208 | if (auto_type_p) |
2209 | { |
2210 | init_loc = c_parser_peek_token (parser)->location; |
2211 | rich_location richloc (line_table, init_loc); |
2212 | start_init (NULL_TREE(tree) __null, asm_name, global_bindings_p (), &richloc); |
2213 | /* A parameter is initialized, which is invalid. Don't |
2214 | attempt to instrument the initializer. */ |
2215 | int flag_sanitize_save = flag_sanitizeglobal_options.x_flag_sanitize; |
2216 | if (nested && !empty_ok) |
2217 | flag_sanitizeglobal_options.x_flag_sanitize = 0; |
2218 | init = c_parser_expr_no_commas (parser, NULL__null); |
2219 | flag_sanitizeglobal_options.x_flag_sanitize = flag_sanitize_save; |
2220 | if (TREE_CODE (init.value)((enum tree_code) (init.value)->base.code) == COMPONENT_REF |
2221 | && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1))(((contains_struct_check (((tree_check (((*((const_cast<tree *> (tree_operand_check ((init.value), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2221, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2221, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2221, __FUNCTION__))->decl_common.lang_flag_4) == 1)) |
2222 | error_at (here, |
2223 | "%<__auto_type%> used with a bit-field" |
2224 | " initializer"); |
2225 | init = convert_lvalue_to_rvalue (init_loc, init, true, true); |
2226 | tree init_type = TREE_TYPE (init.value)((contains_struct_check ((init.value), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2226, __FUNCTION__))->typed.type); |
2227 | bool vm_type = variably_modified_type_p (init_type, |
2228 | NULL_TREE(tree) __null); |
2229 | if (vm_type) |
2230 | init.value = save_expr (init.value); |
2231 | finish_init (); |
2232 | specs->typespec_kind = ctsk_typeof; |
2233 | specs->locations[cdw_typedef] = init_loc; |
2234 | specs->typedef_p = true; |
2235 | specs->type = init_type; |
2236 | if (vm_type) |
2237 | { |
2238 | bool maybe_const = true; |
2239 | tree type_expr = c_fully_fold (init.value, false, |
2240 | &maybe_const); |
2241 | specs->expr_const_operands &= maybe_const; |
2242 | if (specs->expr) |
2243 | specs->expr = build2 (COMPOUND_EXPR, |
2244 | TREE_TYPE (type_expr)((contains_struct_check ((type_expr), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2244, __FUNCTION__))->typed.type), |
2245 | specs->expr, type_expr); |
2246 | else |
2247 | specs->expr = type_expr; |
2248 | } |
2249 | d = start_decl (declarator, specs, true, |
2250 | chainon (postfix_attrs, all_prefix_attrs)); |
2251 | if (!d) |
2252 | d = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2253 | if (omp_declare_simd_clauses.exists ()) |
2254 | c_finish_omp_declare_simd (parser, d, NULL_TREE(tree) __null, |
2255 | omp_declare_simd_clauses); |
2256 | } |
2257 | else |
2258 | { |
2259 | /* The declaration of the variable is in effect while |
2260 | its initializer is parsed. */ |
2261 | d = start_decl (declarator, specs, true, |
2262 | chainon (postfix_attrs, all_prefix_attrs)); |
2263 | if (!d) |
2264 | d = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2265 | if (omp_declare_simd_clauses.exists ()) |
2266 | c_finish_omp_declare_simd (parser, d, NULL_TREE(tree) __null, |
2267 | omp_declare_simd_clauses); |
2268 | init_loc = c_parser_peek_token (parser)->location; |
2269 | rich_location richloc (line_table, init_loc); |
2270 | start_init (d, asm_name, global_bindings_p (), &richloc); |
2271 | /* A parameter is initialized, which is invalid. Don't |
2272 | attempt to instrument the initializer. */ |
2273 | int flag_sanitize_save = flag_sanitizeglobal_options.x_flag_sanitize; |
2274 | if (TREE_CODE (d)((enum tree_code) (d)->base.code) == PARM_DECL) |
2275 | flag_sanitizeglobal_options.x_flag_sanitize = 0; |
2276 | init = c_parser_initializer (parser); |
2277 | flag_sanitizeglobal_options.x_flag_sanitize = flag_sanitize_save; |
2278 | finish_init (); |
2279 | } |
2280 | if (oacc_routine_data) |
2281 | c_finish_oacc_routine (oacc_routine_data, d, false); |
2282 | if (d != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
2283 | { |
2284 | maybe_warn_string_init (init_loc, TREE_TYPE (d)((contains_struct_check ((d), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2284, __FUNCTION__))->typed.type), init); |
2285 | finish_decl (d, init_loc, init.value, |
2286 | init.original_type, asm_name); |
2287 | } |
2288 | } |
2289 | else |
2290 | { |
2291 | if (auto_type_p) |
2292 | { |
2293 | error_at (here, |
2294 | "%<__auto_type%> requires an initialized " |
2295 | "data declaration"); |
2296 | c_parser_skip_to_end_of_block_or_statement (parser); |
2297 | return; |
2298 | } |
2299 | |
2300 | location_t lastloc = UNKNOWN_LOCATION((location_t) 0); |
2301 | tree attrs = chainon (postfix_attrs, all_prefix_attrs); |
2302 | tree d = start_decl (declarator, specs, false, attrs, &lastloc); |
2303 | if (d && TREE_CODE (d)((enum tree_code) (d)->base.code) == FUNCTION_DECL) |
2304 | { |
2305 | /* Find the innermost declarator that is neither cdk_id |
2306 | nor cdk_attrs. */ |
2307 | const struct c_declarator *decl = declarator; |
2308 | const struct c_declarator *last_non_id_attrs = NULL__null; |
2309 | |
2310 | while (decl) |
2311 | switch (decl->kind) |
2312 | { |
2313 | case cdk_array: |
2314 | case cdk_function: |
2315 | case cdk_pointer: |
2316 | last_non_id_attrs = decl; |
2317 | decl = decl->declarator; |
2318 | break; |
2319 | |
2320 | case cdk_attrs: |
2321 | decl = decl->declarator; |
2322 | break; |
2323 | |
2324 | case cdk_id: |
2325 | decl = 0; |
2326 | break; |
2327 | |
2328 | default: |
2329 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2329, __FUNCTION__)); |
2330 | } |
2331 | |
2332 | /* If it exists and is cdk_function declaration whose |
2333 | arguments have not been set yet, use its arguments. */ |
2334 | if (last_non_id_attrs |
2335 | && last_non_id_attrs->kind == cdk_function) |
2336 | { |
2337 | tree parms = last_non_id_attrs->u.arg_info->parms; |
2338 | if (DECL_ARGUMENTS (d)((tree_check ((d), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2338, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) == NULL_TREE(tree) __null |
2339 | && DECL_INITIAL (d)((contains_struct_check ((d), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2339, __FUNCTION__))->decl_common.initial) == NULL_TREE(tree) __null) |
2340 | DECL_ARGUMENTS (d)((tree_check ((d), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2340, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) = parms; |
2341 | |
2342 | warn_parm_array_mismatch (lastloc, d, parms); |
2343 | } |
2344 | } |
2345 | if (omp_declare_simd_clauses.exists ()) |
2346 | { |
2347 | tree parms = NULL_TREE(tree) __null; |
2348 | if (d && TREE_CODE (d)((enum tree_code) (d)->base.code) == FUNCTION_DECL) |
2349 | { |
2350 | struct c_declarator *ce = declarator; |
2351 | while (ce != NULL__null) |
2352 | if (ce->kind == cdk_function) |
2353 | { |
2354 | parms = ce->u.arg_info->parms; |
2355 | break; |
2356 | } |
2357 | else |
2358 | ce = ce->declarator; |
2359 | } |
2360 | if (parms) |
2361 | temp_store_parm_decls (d, parms); |
2362 | c_finish_omp_declare_simd (parser, d, parms, |
2363 | omp_declare_simd_clauses); |
2364 | if (parms) |
2365 | temp_pop_parm_decls (); |
2366 | } |
2367 | if (oacc_routine_data) |
2368 | c_finish_oacc_routine (oacc_routine_data, d, false); |
2369 | if (d) |
2370 | finish_decl (d, UNKNOWN_LOCATION((location_t) 0), NULL_TREE(tree) __null, |
2371 | NULL_TREE(tree) __null, asm_name); |
2372 | |
2373 | if (c_parser_next_token_is_keyword (parser, RID_IN)) |
2374 | { |
2375 | if (d) |
2376 | *objc_foreach_object_declaration = d; |
2377 | else |
2378 | *objc_foreach_object_declaration = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2379 | } |
2380 | } |
2381 | if (c_parser_next_token_is (parser, CPP_COMMA)) |
2382 | { |
2383 | if (auto_type_p) |
2384 | { |
2385 | error_at (here, |
2386 | "%<__auto_type%> may only be used with" |
2387 | " a single declarator"); |
2388 | c_parser_skip_to_end_of_block_or_statement (parser); |
2389 | return; |
2390 | } |
2391 | c_parser_consume_token (parser); |
2392 | if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
2393 | all_prefix_attrs = chainon (c_parser_gnu_attributes (parser), |
2394 | prefix_attrs); |
2395 | else |
2396 | all_prefix_attrs = prefix_attrs; |
2397 | continue; |
2398 | } |
2399 | else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
2400 | { |
2401 | c_parser_consume_token (parser); |
2402 | return; |
2403 | } |
2404 | else if (c_parser_next_token_is_keyword (parser, RID_IN)) |
2405 | { |
2406 | /* This can only happen in Objective-C: we found the |
2407 | 'in' that terminates the declaration inside an |
2408 | Objective-C foreach statement. Do not consume the |
2409 | token, so that the caller can use it to determine |
2410 | that this indeed is a foreach context. */ |
2411 | return; |
2412 | } |
2413 | else |
2414 | { |
2415 | c_parser_error (parser, "expected %<,%> or %<;%>"); |
2416 | c_parser_skip_to_end_of_block_or_statement (parser); |
2417 | return; |
2418 | } |
2419 | } |
2420 | else if (auto_type_p) |
2421 | { |
2422 | error_at (here, |
2423 | "%<__auto_type%> requires an initialized data declaration"); |
2424 | c_parser_skip_to_end_of_block_or_statement (parser); |
2425 | return; |
2426 | } |
2427 | else if (!fndef_ok) |
2428 | { |
2429 | c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, " |
2430 | "%<asm%> or %<__attribute__%>"); |
2431 | c_parser_skip_to_end_of_block_or_statement (parser); |
2432 | return; |
2433 | } |
2434 | /* Function definition (nested or otherwise). */ |
2435 | if (nested) |
2436 | { |
2437 | pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions"); |
2438 | c_push_function_context (); |
2439 | } |
2440 | if (!start_function (specs, declarator, all_prefix_attrs)) |
2441 | { |
2442 | /* At this point we've consumed: |
2443 | declaration-specifiers declarator |
2444 | and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON, |
2445 | RID_ASM, RID_ATTRIBUTE, or RID_IN, |
2446 | but the |
2447 | declaration-specifiers declarator |
2448 | aren't grokkable as a function definition, so we have |
2449 | an error. */ |
2450 | gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON))((void)(!(!c_parser_next_token_is (parser, CPP_SEMICOLON)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2450, __FUNCTION__), 0 : 0)); |
2451 | if (c_parser_next_token_starts_declspecs (parser)) |
2452 | { |
2453 | /* If we have |
2454 | declaration-specifiers declarator decl-specs |
2455 | then assume we have a missing semicolon, which would |
2456 | give us: |
2457 | declaration-specifiers declarator decl-specs |
2458 | ^ |
2459 | ; |
2460 | <~~~~~~~~~ declaration ~~~~~~~~~~> |
2461 | Use c_parser_require to get an error with a fix-it hint. */ |
2462 | c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"); |
2463 | parser->error = false; |
2464 | } |
2465 | else |
2466 | { |
2467 | /* This can appear in many cases looking nothing like a |
2468 | function definition, so we don't give a more specific |
2469 | error suggesting there was one. */ |
2470 | c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> " |
2471 | "or %<__attribute__%>"); |
2472 | } |
2473 | if (nested) |
2474 | c_pop_function_context (); |
2475 | break; |
2476 | } |
2477 | |
2478 | if (DECL_DECLARED_INLINE_P (current_function_decl)((tree_check ((current_function_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2478, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag )) |
2479 | tv = TV_PARSE_INLINE; |
2480 | else |
2481 | tv = TV_PARSE_FUNC; |
2482 | auto_timevar at (g_timer, tv); |
2483 | |
2484 | /* Parse old-style parameter declarations. ??? Attributes are |
2485 | not allowed to start declaration specifiers here because of a |
2486 | syntax conflict between a function declaration with attribute |
2487 | suffix and a function definition with an attribute prefix on |
2488 | first old-style parameter declaration. Following the old |
2489 | parser, they are not accepted on subsequent old-style |
2490 | parameter declarations either. However, there is no |
2491 | ambiguity after the first declaration, nor indeed on the |
2492 | first as long as we don't allow postfix attributes after a |
2493 | declarator with a nonempty identifier list in a definition; |
2494 | and postfix attributes have never been accepted here in |
2495 | function definitions either. */ |
2496 | while (c_parser_next_token_is_not (parser, CPP_EOF) |
2497 | && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) |
2498 | c_parser_declaration_or_fndef (parser, false, false, false, |
2499 | true, false, NULL__null, vNULL); |
2500 | store_parm_decls (); |
2501 | if (omp_declare_simd_clauses.exists ()) |
2502 | c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE(tree) __null, |
2503 | omp_declare_simd_clauses); |
2504 | if (oacc_routine_data) |
2505 | c_finish_oacc_routine (oacc_routine_data, current_function_decl, true); |
2506 | location_t startloc = c_parser_peek_token (parser)->location; |
2507 | DECL_STRUCT_FUNCTION (current_function_decl)((tree_check ((current_function_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2507, __FUNCTION__, (FUNCTION_DECL)))->function_decl.f)->function_start_locus |
2508 | = startloc; |
2509 | location_t endloc = startloc; |
2510 | |
2511 | /* If the definition was marked with __RTL, use the RTL parser now, |
2512 | consuming the function body. */ |
2513 | if (specs->declspec_il == cdil_rtl) |
2514 | { |
2515 | endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); |
2516 | |
2517 | /* Normally, store_parm_decls sets next_is_function_body, |
2518 | anticipating a function body. We need a push_scope/pop_scope |
2519 | pair to flush out this state, or subsequent function parsing |
2520 | will go wrong. */ |
2521 | push_scope (); |
2522 | pop_scope (); |
2523 | |
2524 | finish_function (endloc); |
2525 | return; |
2526 | } |
2527 | /* If the definition was marked with __GIMPLE then parse the |
2528 | function body as GIMPLE. */ |
2529 | else if (specs->declspec_il != cdil_none) |
2530 | { |
2531 | bool saved = in_late_binary_op; |
2532 | in_late_binary_op = true; |
2533 | c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass, |
2534 | specs->declspec_il, |
2535 | specs->entry_bb_count); |
2536 | in_late_binary_op = saved; |
2537 | } |
2538 | else |
2539 | fnbody = c_parser_compound_statement (parser, &endloc); |
2540 | tree fndecl = current_function_decl; |
2541 | if (nested) |
2542 | { |
2543 | tree decl = current_function_decl; |
2544 | /* Mark nested functions as needing static-chain initially. |
2545 | lower_nested_functions will recompute it but the |
2546 | DECL_STATIC_CHAIN flag is also used before that happens, |
2547 | by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ |
2548 | DECL_STATIC_CHAIN (decl)((tree_check ((decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2548, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.regdecl_flag ) = 1; |
2549 | add_stmt (fnbody); |
2550 | finish_function (endloc); |
2551 | c_pop_function_context (); |
2552 | add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2552, __FUNCTION__))->decl_minimal.locus), DECL_EXPR, decl)); |
2553 | } |
2554 | else |
2555 | { |
2556 | if (fnbody) |
2557 | add_stmt (fnbody); |
2558 | finish_function (endloc); |
2559 | } |
2560 | /* Get rid of the empty stmt list for GIMPLE/RTL. */ |
2561 | if (specs->declspec_il != cdil_none) |
2562 | DECL_SAVED_TREE (fndecl)((tree_check ((fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2562, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ) = NULL_TREE(tree) __null; |
2563 | |
2564 | break; |
2565 | } |
2566 | } |
2567 | |
2568 | /* Parse an asm-definition (asm() outside a function body). This is a |
2569 | GNU extension. |
2570 | |
2571 | asm-definition: |
2572 | simple-asm-expr ; |
2573 | */ |
2574 | |
2575 | static void |
2576 | c_parser_asm_definition (c_parser *parser) |
2577 | { |
2578 | tree asm_str = c_parser_simple_asm_expr (parser); |
2579 | if (asm_str) |
2580 | symtab->finalize_toplevel_asm (asm_str); |
2581 | c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); |
2582 | } |
2583 | |
2584 | /* Parse a static assertion (C11 6.7.10). |
2585 | |
2586 | static_assert-declaration: |
2587 | static_assert-declaration-no-semi ; |
2588 | */ |
2589 | |
2590 | static void |
2591 | c_parser_static_assert_declaration (c_parser *parser) |
2592 | { |
2593 | c_parser_static_assert_declaration_no_semi (parser); |
2594 | if (parser->error |
2595 | || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) |
2596 | c_parser_skip_to_end_of_block_or_statement (parser); |
2597 | } |
2598 | |
2599 | /* Parse a static assertion (C11 6.7.10), without the trailing |
2600 | semicolon. |
2601 | |
2602 | static_assert-declaration-no-semi: |
2603 | _Static_assert ( constant-expression , string-literal ) |
2604 | |
2605 | C2X: |
2606 | static_assert-declaration-no-semi: |
2607 | _Static_assert ( constant-expression ) |
2608 | */ |
2609 | |
2610 | static void |
2611 | c_parser_static_assert_declaration_no_semi (c_parser *parser) |
2612 | { |
2613 | location_t assert_loc, value_loc; |
2614 | tree value; |
2615 | tree string = NULL_TREE(tree) __null; |
2616 | |
2617 | gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))((void)(!(c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT )) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2617, __FUNCTION__), 0 : 0)); |
2618 | assert_loc = c_parser_peek_token (parser)->location; |
2619 | if (flag_isoc99) |
2620 | pedwarn_c99 (assert_loc, OPT_Wpedantic, |
2621 | "ISO C99 does not support %<_Static_assert%>"); |
2622 | else |
2623 | pedwarn_c99 (assert_loc, OPT_Wpedantic, |
2624 | "ISO C90 does not support %<_Static_assert%>"); |
2625 | c_parser_consume_token (parser); |
2626 | matching_parens parens; |
2627 | if (!parens.require_open (parser)) |
2628 | return; |
2629 | location_t value_tok_loc = c_parser_peek_token (parser)->location; |
2630 | value = c_parser_expr_no_commas (parser, NULL__null).value; |
2631 | value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc)((((IS_ADHOC_LOC (((((value)) && ((tree_code_type[(int ) (((enum tree_code) ((value))->base.code))]) >= tcc_reference && (tree_code_type[(int) (((enum tree_code) ((value) )->base.code))]) <= tcc_expression)) ? (value)->exp. locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((value)) && ((tree_code_type[(int) (((enum tree_code ) ((value))->base.code))]) >= tcc_reference && ( tree_code_type[(int) (((enum tree_code) ((value))->base.code ))]) <= tcc_expression)) ? (value)->exp.locus : ((location_t ) 0))) : (((((value)) && ((tree_code_type[(int) (((enum tree_code) ((value))->base.code))]) >= tcc_reference && (tree_code_type[(int) (((enum tree_code) ((value))->base. code))]) <= tcc_expression)) ? (value)->exp.locus : ((location_t ) 0)))) != ((location_t) 0)) ? (value)->exp.locus : (value_tok_loc )); |
2632 | if (c_parser_next_token_is (parser, CPP_COMMA)) |
2633 | { |
2634 | c_parser_consume_token (parser); |
2635 | switch (c_parser_peek_token (parser)->type) |
2636 | { |
2637 | case CPP_STRING: |
2638 | case CPP_STRING16: |
2639 | case CPP_STRING32: |
2640 | case CPP_WSTRING: |
2641 | case CPP_UTF8STRING: |
2642 | string = c_parser_string_literal (parser, false, true).value; |
2643 | break; |
2644 | default: |
2645 | c_parser_error (parser, "expected string literal"); |
2646 | return; |
2647 | } |
2648 | } |
2649 | else if (flag_isoc11) |
2650 | /* If pedantic for pre-C11, the use of _Static_assert itself will |
2651 | have been diagnosed, so do not also diagnose the use of this |
2652 | new C2X feature of _Static_assert. */ |
2653 | pedwarn_c11 (assert_loc, OPT_Wpedantic, |
2654 | "ISO C11 does not support omitting the string in " |
2655 | "%<_Static_assert%>"); |
2656 | parens.require_close (parser); |
2657 | |
2658 | if (!INTEGRAL_TYPE_P (TREE_TYPE (value))(((enum tree_code) (((contains_struct_check ((value), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2658, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((value), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2658, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((value), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2658, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE )) |
2659 | { |
2660 | error_at (value_loc, "expression in static assertion is not an integer"); |
2661 | return; |
2662 | } |
2663 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) != INTEGER_CST) |
2664 | { |
2665 | value = c_fully_fold (value, false, NULL__null); |
2666 | /* Strip no-op conversions. */ |
2667 | STRIP_TYPE_NOPS (value)while ((((((enum tree_code) (value)->base.code)) == NOP_EXPR || (((enum tree_code) (value)->base.code)) == CONVERT_EXPR ) || ((enum tree_code) (value)->base.code) == NON_LVALUE_EXPR ) && (*((const_cast<tree*> (tree_operand_check ( (value), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2667, __FUNCTION__))))) != global_trees[TI_ERROR_MARK] && (((contains_struct_check ((value), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2667, __FUNCTION__))->typed.type) == ((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((value), ( 0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2667, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2667, __FUNCTION__))->typed.type))) (value) = (*((const_cast <tree*> (tree_operand_check ((value), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2667, __FUNCTION__))))); |
2668 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) == INTEGER_CST) |
2669 | pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion " |
2670 | "is not an integer constant expression"); |
2671 | } |
2672 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) != INTEGER_CST) |
2673 | { |
2674 | error_at (value_loc, "expression in static assertion is not constant"); |
2675 | return; |
2676 | } |
2677 | constant_expression_warning (value); |
2678 | if (integer_zerop (value)) |
2679 | { |
2680 | if (string) |
2681 | error_at (assert_loc, "static assertion failed: %E", string); |
2682 | else |
2683 | error_at (assert_loc, "static assertion failed"); |
2684 | } |
2685 | } |
2686 | |
2687 | /* Parse some declaration specifiers (possibly none) (C90 6.5, C99 |
2688 | 6.7, C11 6.7), adding them to SPECS (which may already include some). |
2689 | Storage class specifiers are accepted iff SCSPEC_OK; type |
2690 | specifiers are accepted iff TYPESPEC_OK; alignment specifiers are |
2691 | accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start |
2692 | iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In |
2693 | addition to the syntax shown, standard attributes are accepted at |
2694 | the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK; |
2695 | unlike gnu-attributes, they are not accepted in the middle of the |
2696 | list. (This combines various different syntax productions in the C |
2697 | standard, and in some cases gnu-attributes and standard attributes |
2698 | at the start may already have been parsed before this function is |
2699 | called.) |
2700 | |
2701 | declaration-specifiers: |
2702 | storage-class-specifier declaration-specifiers[opt] |
2703 | type-specifier declaration-specifiers[opt] |
2704 | type-qualifier declaration-specifiers[opt] |
2705 | function-specifier declaration-specifiers[opt] |
2706 | alignment-specifier declaration-specifiers[opt] |
2707 | |
2708 | Function specifiers (inline) are from C99, and are currently |
2709 | handled as storage class specifiers, as is __thread. Alignment |
2710 | specifiers are from C11. |
2711 | |
2712 | C90 6.5.1, C99 6.7.1, C11 6.7.1: |
2713 | storage-class-specifier: |
2714 | typedef |
2715 | extern |
2716 | static |
2717 | auto |
2718 | register |
2719 | _Thread_local |
2720 | |
2721 | (_Thread_local is new in C11.) |
2722 | |
2723 | C99 6.7.4, C11 6.7.4: |
2724 | function-specifier: |
2725 | inline |
2726 | _Noreturn |
2727 | |
2728 | (_Noreturn is new in C11.) |
2729 | |
2730 | C90 6.5.2, C99 6.7.2, C11 6.7.2: |
2731 | type-specifier: |
2732 | void |
2733 | char |
2734 | short |
2735 | int |
2736 | long |
2737 | float |
2738 | double |
2739 | signed |
2740 | unsigned |
2741 | _Bool |
2742 | _Complex |
2743 | [_Imaginary removed in C99 TC2] |
2744 | struct-or-union-specifier |
2745 | enum-specifier |
2746 | typedef-name |
2747 | atomic-type-specifier |
2748 | |
2749 | (_Bool and _Complex are new in C99.) |
2750 | (atomic-type-specifier is new in C11.) |
2751 | |
2752 | C90 6.5.3, C99 6.7.3, C11 6.7.3: |
2753 | |
2754 | type-qualifier: |
2755 | const |
2756 | restrict |
2757 | volatile |
2758 | address-space-qualifier |
2759 | _Atomic |
2760 | |
2761 | (restrict is new in C99.) |
2762 | (_Atomic is new in C11.) |
2763 | |
2764 | GNU extensions: |
2765 | |
2766 | declaration-specifiers: |
2767 | gnu-attributes declaration-specifiers[opt] |
2768 | |
2769 | type-qualifier: |
2770 | address-space |
2771 | |
2772 | address-space: |
2773 | identifier recognized by the target |
2774 | |
2775 | storage-class-specifier: |
2776 | __thread |
2777 | |
2778 | type-specifier: |
2779 | typeof-specifier |
2780 | __auto_type |
2781 | __intN |
2782 | _Decimal32 |
2783 | _Decimal64 |
2784 | _Decimal128 |
2785 | _Fract |
2786 | _Accum |
2787 | _Sat |
2788 | |
2789 | (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037: |
2790 | http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf) |
2791 | |
2792 | atomic-type-specifier |
2793 | _Atomic ( type-name ) |
2794 | |
2795 | Objective-C: |
2796 | |
2797 | type-specifier: |
2798 | class-name objc-protocol-refs[opt] |
2799 | typedef-name objc-protocol-refs |
2800 | objc-protocol-refs |
2801 | */ |
2802 | |
2803 | void |
2804 | c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, |
2805 | bool scspec_ok, bool typespec_ok, bool start_attr_ok, |
2806 | bool alignspec_ok, bool auto_type_ok, |
2807 | bool start_std_attr_ok, bool end_std_attr_ok, |
2808 | enum c_lookahead_kind la) |
2809 | { |
2810 | bool attrs_ok = start_attr_ok; |
2811 | bool seen_type = specs->typespec_kind != ctsk_none; |
2812 | |
2813 | if (!typespec_ok) |
2814 | gcc_assert (la == cla_prefer_id)((void)(!(la == cla_prefer_id) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2814, __FUNCTION__), 0 : 0)); |
2815 | |
2816 | if (start_std_attr_ok |
2817 | && c_parser_nth_token_starts_std_attributes (parser, 1)) |
2818 | { |
2819 | gcc_assert (!specs->non_std_attrs_seen_p)((void)(!(!specs->non_std_attrs_seen_p) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2819, __FUNCTION__), 0 : 0)); |
2820 | location_t loc = c_parser_peek_token (parser)->location; |
2821 | tree attrs = c_parser_std_attribute_specifier_sequence (parser); |
2822 | declspecs_add_attrs (loc, specs, attrs); |
2823 | specs->non_std_attrs_seen_p = false; |
2824 | } |
2825 | |
2826 | while (c_parser_next_token_is (parser, CPP_NAME) |
2827 | || c_parser_next_token_is (parser, CPP_KEYWORD) |
2828 | || (c_dialect_objc ()((c_language & clk_objc) != 0) && c_parser_next_token_is (parser, CPP_LESS))) |
2829 | { |
2830 | struct c_typespec t; |
2831 | tree attrs; |
2832 | tree align; |
2833 | location_t loc = c_parser_peek_token (parser)->location; |
2834 | |
2835 | /* If we cannot accept a type, exit if the next token must start |
2836 | one. Also, if we already have seen a tagged definition, |
2837 | a typename would be an error anyway and likely the user |
2838 | has simply forgotten a semicolon, so we exit. */ |
2839 | if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef) |
2840 | && c_parser_next_tokens_start_typename (parser, la) |
2841 | && !c_parser_next_token_is_qualifier (parser) |
2842 | && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS)) |
2843 | break; |
2844 | |
2845 | if (c_parser_next_token_is (parser, CPP_NAME)) |
2846 | { |
2847 | c_token *name_token = c_parser_peek_token (parser); |
2848 | tree value = name_token->value; |
2849 | c_id_kind kind = name_token->id_kind; |
2850 | |
2851 | if (kind == C_ID_ADDRSPACE) |
2852 | { |
2853 | addr_space_t as |
2854 | = name_token->keyword - RID_FIRST_ADDR_SPACE; |
2855 | declspecs_add_addrspace (name_token->location, specs, as); |
2856 | c_parser_consume_token (parser); |
2857 | attrs_ok = true; |
2858 | continue; |
2859 | } |
2860 | |
2861 | gcc_assert (!c_parser_next_token_is_qualifier (parser))((void)(!(!c_parser_next_token_is_qualifier (parser)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2861, __FUNCTION__), 0 : 0)); |
2862 | |
2863 | /* If we cannot accept a type, and the next token must start one, |
2864 | exit. Do the same if we already have seen a tagged definition, |
2865 | since it would be an error anyway and likely the user has simply |
2866 | forgotten a semicolon. */ |
2867 | if (seen_type || !c_parser_next_tokens_start_typename (parser, la)) |
2868 | break; |
2869 | |
2870 | /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or |
2871 | a C_ID_CLASSNAME. */ |
2872 | c_parser_consume_token (parser); |
2873 | seen_type = true; |
2874 | attrs_ok = true; |
2875 | if (kind == C_ID_ID) |
2876 | { |
2877 | error_at (loc, "unknown type name %qE", value); |
2878 | t.kind = ctsk_typedef; |
2879 | t.spec = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2880 | } |
2881 | else if (kind == C_ID_TYPENAME |
2882 | && (!c_dialect_objc ()((c_language & clk_objc) != 0) |
2883 | || c_parser_next_token_is_not (parser, CPP_LESS))) |
2884 | { |
2885 | t.kind = ctsk_typedef; |
2886 | /* For a typedef name, record the meaning, not the name. |
2887 | In case of 'foo foo, bar;'. */ |
2888 | t.spec = lookup_name (value); |
2889 | } |
2890 | else |
2891 | { |
2892 | tree proto = NULL_TREE(tree) __null; |
2893 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2893, __FUNCTION__), 0 : 0)); |
2894 | t.kind = ctsk_objc; |
2895 | if (c_parser_next_token_is (parser, CPP_LESS)) |
2896 | proto = c_parser_objc_protocol_refs (parser); |
2897 | t.spec = objc_get_protocol_qualified_type (value, proto); |
2898 | } |
2899 | t.expr = NULL_TREE(tree) __null; |
2900 | t.expr_const_operands = true; |
2901 | declspecs_add_type (name_token->location, specs, t); |
2902 | continue; |
2903 | } |
2904 | if (c_parser_next_token_is (parser, CPP_LESS)) |
2905 | { |
2906 | /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" - |
2907 | nisse@lysator.liu.se. */ |
2908 | tree proto; |
2909 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2909, __FUNCTION__), 0 : 0)); |
2910 | if (!typespec_ok || seen_type) |
2911 | break; |
2912 | proto = c_parser_objc_protocol_refs (parser); |
2913 | t.kind = ctsk_objc; |
2914 | t.spec = objc_get_protocol_qualified_type (NULL_TREE(tree) __null, proto); |
2915 | t.expr = NULL_TREE(tree) __null; |
2916 | t.expr_const_operands = true; |
2917 | declspecs_add_type (loc, specs, t); |
2918 | continue; |
2919 | } |
2920 | gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD))((void)(!(c_parser_next_token_is (parser, CPP_KEYWORD)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 2920, __FUNCTION__), 0 : 0)); |
2921 | switch (c_parser_peek_token (parser)->keyword) |
2922 | { |
2923 | case RID_STATIC: |
2924 | case RID_EXTERN: |
2925 | case RID_REGISTER: |
2926 | case RID_TYPEDEF: |
2927 | case RID_INLINE: |
2928 | case RID_NORETURN: |
2929 | case RID_AUTO: |
2930 | case RID_THREAD: |
2931 | if (!scspec_ok) |
2932 | goto out; |
2933 | attrs_ok = true; |
2934 | /* TODO: Distinguish between function specifiers (inline, noreturn) |
2935 | and storage class specifiers, either here or in |
2936 | declspecs_add_scspec. */ |
2937 | declspecs_add_scspec (loc, specs, |
2938 | c_parser_peek_token (parser)->value); |
2939 | c_parser_consume_token (parser); |
2940 | break; |
2941 | case RID_AUTO_TYPE: |
2942 | if (!auto_type_ok) |
2943 | goto out; |
2944 | /* Fall through. */ |
2945 | case RID_UNSIGNED: |
2946 | case RID_LONG: |
2947 | case RID_SHORT: |
2948 | case RID_SIGNED: |
2949 | case RID_COMPLEX: |
2950 | case RID_INT: |
2951 | case RID_CHAR: |
2952 | case RID_FLOAT: |
2953 | case RID_DOUBLE: |
2954 | case RID_VOID: |
2955 | case RID_DFLOAT32: |
2956 | case RID_DFLOAT64: |
2957 | case RID_DFLOAT128: |
2958 | CASE_RID_FLOATN_NXcase RID_FLOAT16: case RID_FLOAT32: case RID_FLOAT64: case RID_FLOAT128 : case RID_FLOAT32X: case RID_FLOAT64X: case RID_FLOAT128X: |
2959 | case RID_BOOL: |
2960 | case RID_FRACT: |
2961 | case RID_ACCUM: |
2962 | case RID_SAT: |
2963 | case RID_INT_N_0: |
2964 | case RID_INT_N_1: |
2965 | case RID_INT_N_2: |
2966 | case RID_INT_N_3: |
2967 | if (!typespec_ok) |
2968 | goto out; |
2969 | attrs_ok = true; |
2970 | seen_type = true; |
2971 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
2972 | parser->objc_need_raw_identifier = true; |
2973 | t.kind = ctsk_resword; |
2974 | t.spec = c_parser_peek_token (parser)->value; |
2975 | t.expr = NULL_TREE(tree) __null; |
2976 | t.expr_const_operands = true; |
2977 | declspecs_add_type (loc, specs, t); |
2978 | c_parser_consume_token (parser); |
2979 | break; |
2980 | case RID_ENUM: |
2981 | if (!typespec_ok) |
2982 | goto out; |
2983 | attrs_ok = true; |
2984 | seen_type = true; |
2985 | t = c_parser_enum_specifier (parser); |
2986 | invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); |
2987 | declspecs_add_type (loc, specs, t); |
2988 | break; |
2989 | case RID_STRUCT: |
2990 | case RID_UNION: |
2991 | if (!typespec_ok) |
2992 | goto out; |
2993 | attrs_ok = true; |
2994 | seen_type = true; |
2995 | t = c_parser_struct_or_union_specifier (parser); |
2996 | invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); |
2997 | declspecs_add_type (loc, specs, t); |
2998 | break; |
2999 | case RID_TYPEOF: |
3000 | /* ??? The old parser rejected typeof after other type |
3001 | specifiers, but is a syntax error the best way of |
3002 | handling this? */ |
3003 | if (!typespec_ok || seen_type) |
3004 | goto out; |
3005 | attrs_ok = true; |
3006 | seen_type = true; |
3007 | t = c_parser_typeof_specifier (parser); |
3008 | declspecs_add_type (loc, specs, t); |
3009 | break; |
3010 | case RID_ATOMIC: |
3011 | /* C parser handling of Objective-C constructs needs |
3012 | checking for correct lvalue-to-rvalue conversions, and |
3013 | the code in build_modify_expr handling various |
3014 | Objective-C cases, and that in build_unary_op handling |
3015 | Objective-C cases for increment / decrement, also needs |
3016 | updating; uses of TYPE_MAIN_VARIANT in objc_compare_types |
3017 | and objc_types_are_equivalent may also need updates. */ |
3018 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
3019 | sorry ("%<_Atomic%> in Objective-C"); |
3020 | if (flag_isoc99) |
3021 | pedwarn_c99 (loc, OPT_Wpedantic, |
3022 | "ISO C99 does not support the %<_Atomic%> qualifier"); |
3023 | else |
3024 | pedwarn_c99 (loc, OPT_Wpedantic, |
3025 | "ISO C90 does not support the %<_Atomic%> qualifier"); |
3026 | attrs_ok = true; |
3027 | tree value; |
3028 | value = c_parser_peek_token (parser)->value; |
3029 | c_parser_consume_token (parser); |
3030 | if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN)) |
3031 | { |
3032 | /* _Atomic ( type-name ). */ |
3033 | seen_type = true; |
3034 | c_parser_consume_token (parser); |
3035 | struct c_type_name *type = c_parser_type_name (parser); |
3036 | t.kind = ctsk_typeof; |
3037 | t.spec = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3038 | t.expr = NULL_TREE(tree) __null; |
3039 | t.expr_const_operands = true; |
3040 | if (type != NULL__null) |
3041 | t.spec = groktypename (type, &t.expr, |
3042 | &t.expr_const_operands); |
3043 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
3044 | "expected %<)%>"); |
3045 | if (t.spec != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3046 | { |
3047 | if (TREE_CODE (t.spec)((enum tree_code) (t.spec)->base.code) == ARRAY_TYPE) |
3048 | error_at (loc, "%<_Atomic%>-qualified array type"); |
3049 | else if (TREE_CODE (t.spec)((enum tree_code) (t.spec)->base.code) == FUNCTION_TYPE) |
3050 | error_at (loc, "%<_Atomic%>-qualified function type"); |
3051 | else if (TYPE_QUALS (t.spec)((int) ((((tree_class_check ((t.spec), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3051, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((t.spec), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3051, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((t.spec), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3051, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((t.spec), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3051, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((t.spec), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3051, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))) != TYPE_UNQUALIFIED) |
3052 | error_at (loc, "%<_Atomic%> applied to a qualified type"); |
3053 | else |
3054 | t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC); |
3055 | } |
3056 | declspecs_add_type (loc, specs, t); |
3057 | } |
3058 | else |
3059 | declspecs_add_qual (loc, specs, value); |
3060 | break; |
3061 | case RID_CONST: |
3062 | case RID_VOLATILE: |
3063 | case RID_RESTRICT: |
3064 | attrs_ok = true; |
3065 | declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value); |
3066 | c_parser_consume_token (parser); |
3067 | break; |
3068 | case RID_ATTRIBUTE: |
3069 | if (!attrs_ok) |
3070 | goto out; |
3071 | attrs = c_parser_gnu_attributes (parser); |
3072 | declspecs_add_attrs (loc, specs, attrs); |
3073 | break; |
3074 | case RID_ALIGNAS: |
3075 | if (!alignspec_ok) |
3076 | goto out; |
3077 | align = c_parser_alignas_specifier (parser); |
3078 | declspecs_add_alignas (loc, specs, align); |
3079 | break; |
3080 | case RID_GIMPLE: |
3081 | if (! flag_gimpleglobal_options.x_flag_gimple) |
3082 | error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>"); |
3083 | c_parser_consume_token (parser); |
3084 | specs->declspec_il = cdil_gimple; |
3085 | specs->locations[cdw_gimple] = loc; |
3086 | c_parser_gimple_or_rtl_pass_list (parser, specs); |
3087 | break; |
3088 | case RID_RTL: |
3089 | c_parser_consume_token (parser); |
3090 | specs->declspec_il = cdil_rtl; |
3091 | specs->locations[cdw_rtl] = loc; |
3092 | c_parser_gimple_or_rtl_pass_list (parser, specs); |
3093 | break; |
3094 | default: |
3095 | goto out; |
3096 | } |
3097 | } |
3098 | out: |
3099 | if (end_std_attr_ok |
3100 | && c_parser_nth_token_starts_std_attributes (parser, 1)) |
3101 | specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser); |
3102 | } |
3103 | |
3104 | /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2). |
3105 | |
3106 | enum-specifier: |
3107 | enum gnu-attributes[opt] identifier[opt] { enumerator-list } |
3108 | gnu-attributes[opt] |
3109 | enum gnu-attributes[opt] identifier[opt] { enumerator-list , } |
3110 | gnu-attributes[opt] |
3111 | enum gnu-attributes[opt] identifier |
3112 | |
3113 | The form with trailing comma is new in C99. The forms with |
3114 | gnu-attributes are GNU extensions. In GNU C, we accept any expression |
3115 | without commas in the syntax (assignment expressions, not just |
3116 | conditional expressions); assignment expressions will be diagnosed |
3117 | as non-constant. |
3118 | |
3119 | enumerator-list: |
3120 | enumerator |
3121 | enumerator-list , enumerator |
3122 | |
3123 | enumerator: |
3124 | enumeration-constant attribute-specifier-sequence[opt] |
3125 | enumeration-constant attribute-specifier-sequence[opt] |
3126 | = constant-expression |
3127 | |
3128 | GNU Extensions: |
3129 | |
3130 | enumerator: |
3131 | enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt] |
3132 | enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt] |
3133 | = constant-expression |
3134 | |
3135 | */ |
3136 | |
3137 | static struct c_typespec |
3138 | c_parser_enum_specifier (c_parser *parser) |
3139 | { |
3140 | struct c_typespec ret; |
3141 | bool have_std_attrs; |
3142 | tree std_attrs = NULL_TREE(tree) __null; |
3143 | tree attrs; |
3144 | tree ident = NULL_TREE(tree) __null; |
3145 | location_t enum_loc; |
3146 | location_t ident_loc = UNKNOWN_LOCATION((location_t) 0); /* Quiet warning. */ |
3147 | gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM))((void)(!(c_parser_next_token_is_keyword (parser, RID_ENUM)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3147, __FUNCTION__), 0 : 0)); |
3148 | c_parser_consume_token (parser); |
3149 | have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1); |
3150 | if (have_std_attrs) |
3151 | std_attrs = c_parser_std_attribute_specifier_sequence (parser); |
3152 | attrs = c_parser_gnu_attributes (parser); |
3153 | enum_loc = c_parser_peek_token (parser)->location; |
3154 | /* Set the location in case we create a decl now. */ |
3155 | c_parser_set_source_position_from_token (c_parser_peek_token (parser)); |
3156 | if (c_parser_next_token_is (parser, CPP_NAME)) |
3157 | { |
3158 | ident = c_parser_peek_token (parser)->value; |
3159 | ident_loc = c_parser_peek_token (parser)->location; |
3160 | enum_loc = ident_loc; |
3161 | c_parser_consume_token (parser); |
3162 | } |
3163 | if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) |
3164 | { |
3165 | /* Parse an enum definition. */ |
3166 | struct c_enum_contents the_enum; |
3167 | tree type; |
3168 | tree postfix_attrs; |
3169 | /* We chain the enumerators in reverse order, then put them in |
3170 | forward order at the end. */ |
3171 | tree values; |
3172 | timevar_push (TV_PARSE_ENUM); |
3173 | type = start_enum (enum_loc, &the_enum, ident); |
3174 | values = NULL_TREE(tree) __null; |
3175 | c_parser_consume_token (parser); |
3176 | while (true) |
3177 | { |
3178 | tree enum_id; |
3179 | tree enum_value; |
3180 | tree enum_decl; |
3181 | bool seen_comma; |
3182 | c_token *token; |
3183 | location_t comma_loc = UNKNOWN_LOCATION((location_t) 0); /* Quiet warning. */ |
3184 | location_t decl_loc, value_loc; |
3185 | if (c_parser_next_token_is_not (parser, CPP_NAME)) |
3186 | { |
3187 | /* Give a nicer error for "enum {}". */ |
3188 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE) |
3189 | && !parser->error) |
3190 | { |
3191 | error_at (c_parser_peek_token (parser)->location, |
3192 | "empty enum is invalid"); |
3193 | parser->error = true; |
3194 | } |
3195 | else |
3196 | c_parser_error (parser, "expected identifier"); |
3197 | c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL__null); |
3198 | values = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3199 | break; |
3200 | } |
3201 | token = c_parser_peek_token (parser); |
3202 | enum_id = token->value; |
3203 | /* Set the location in case we create a decl now. */ |
3204 | c_parser_set_source_position_from_token (token); |
3205 | decl_loc = value_loc = token->location; |
3206 | c_parser_consume_token (parser); |
3207 | /* Parse any specified attributes. */ |
3208 | tree std_attrs = NULL_TREE(tree) __null; |
3209 | if (c_parser_nth_token_starts_std_attributes (parser, 1)) |
3210 | std_attrs = c_parser_std_attribute_specifier_sequence (parser); |
3211 | tree enum_attrs = chainon (std_attrs, |
3212 | c_parser_gnu_attributes (parser)); |
3213 | if (c_parser_next_token_is (parser, CPP_EQ)) |
3214 | { |
3215 | c_parser_consume_token (parser); |
3216 | value_loc = c_parser_peek_token (parser)->location; |
3217 | enum_value = c_parser_expr_no_commas (parser, NULL__null).value; |
3218 | } |
3219 | else |
3220 | enum_value = NULL_TREE(tree) __null; |
3221 | enum_decl = build_enumerator (decl_loc, value_loc, |
3222 | &the_enum, enum_id, enum_value); |
3223 | if (enum_attrs) |
3224 | decl_attributes (&TREE_PURPOSE (enum_decl)((tree_check ((enum_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3224, __FUNCTION__, (TREE_LIST)))->list.purpose), enum_attrs, 0); |
3225 | TREE_CHAIN (enum_decl)((contains_struct_check ((enum_decl), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3225, __FUNCTION__))->common.chain) = values; |
3226 | values = enum_decl; |
3227 | seen_comma = false; |
3228 | if (c_parser_next_token_is (parser, CPP_COMMA)) |
3229 | { |
3230 | comma_loc = c_parser_peek_token (parser)->location; |
3231 | seen_comma = true; |
3232 | c_parser_consume_token (parser); |
3233 | } |
3234 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
3235 | { |
3236 | if (seen_comma) |
3237 | pedwarn_c90 (comma_loc, OPT_Wpedantic, |
3238 | "comma at end of enumerator list"); |
3239 | c_parser_consume_token (parser); |
3240 | break; |
3241 | } |
3242 | if (!seen_comma) |
3243 | { |
3244 | c_parser_error (parser, "expected %<,%> or %<}%>"); |
3245 | c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL__null); |
3246 | values = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3247 | break; |
3248 | } |
3249 | } |
3250 | postfix_attrs = c_parser_gnu_attributes (parser); |
3251 | ret.spec = finish_enum (type, nreverse (values), |
3252 | chainon (std_attrs, |
3253 | chainon (attrs, postfix_attrs))); |
3254 | ret.kind = ctsk_tagdef; |
3255 | ret.expr = NULL_TREE(tree) __null; |
3256 | ret.expr_const_operands = true; |
3257 | timevar_pop (TV_PARSE_ENUM); |
3258 | return ret; |
3259 | } |
3260 | else if (!ident) |
3261 | { |
3262 | c_parser_error (parser, "expected %<{%>"); |
3263 | ret.spec = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3264 | ret.kind = ctsk_tagref; |
3265 | ret.expr = NULL_TREE(tree) __null; |
3266 | ret.expr_const_operands = true; |
3267 | return ret; |
3268 | } |
3269 | /* Attributes may only appear when the members are defined or in |
3270 | certain forward declarations (treat enum forward declarations in |
3271 | GNU C analogously to struct and union forward declarations in |
3272 | standard C). */ |
3273 | if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON)) |
3274 | c_parser_error (parser, "expected %<;%>"); |
3275 | ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs, |
3276 | std_attrs); |
3277 | /* In ISO C, enumerated types can be referred to only if already |
3278 | defined. */ |
3279 | if (pedanticglobal_options.x_pedantic && !COMPLETE_TYPE_P (ret.spec)(((tree_class_check ((ret.spec), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3279, __FUNCTION__))->type_common.size) != (tree) __null )) |
3280 | { |
3281 | gcc_assert (ident)((void)(!(ident) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3281, __FUNCTION__), 0 : 0)); |
3282 | pedwarn (enum_loc, OPT_Wpedantic, |
3283 | "ISO C forbids forward references to %<enum%> types"); |
3284 | } |
3285 | return ret; |
3286 | } |
3287 | |
3288 | /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1). |
3289 | |
3290 | struct-or-union-specifier: |
3291 | struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt] |
3292 | identifier[opt] { struct-contents } gnu-attributes[opt] |
3293 | struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt] |
3294 | identifier |
3295 | |
3296 | struct-contents: |
3297 | struct-declaration-list |
3298 | |
3299 | struct-declaration-list: |
3300 | struct-declaration ; |
3301 | struct-declaration-list struct-declaration ; |
3302 | |
3303 | GNU extensions: |
3304 | |
3305 | struct-contents: |
3306 | empty |
3307 | struct-declaration |
3308 | struct-declaration-list struct-declaration |
3309 | |
3310 | struct-declaration-list: |
3311 | struct-declaration-list ; |
3312 | ; |
3313 | |
3314 | (Note that in the syntax here, unlike that in ISO C, the semicolons |
3315 | are included here rather than in struct-declaration, in order to |
3316 | describe the syntax with extra semicolons and missing semicolon at |
3317 | end.) |
3318 | |
3319 | Objective-C: |
3320 | |
3321 | struct-declaration-list: |
3322 | @defs ( class-name ) |
3323 | |
3324 | (Note this does not include a trailing semicolon, but can be |
3325 | followed by further declarations, and gets a pedwarn-if-pedantic |
3326 | when followed by a semicolon.) */ |
3327 | |
3328 | static struct c_typespec |
3329 | c_parser_struct_or_union_specifier (c_parser *parser) |
3330 | { |
3331 | struct c_typespec ret; |
3332 | bool have_std_attrs; |
3333 | tree std_attrs = NULL_TREE(tree) __null; |
3334 | tree attrs; |
3335 | tree ident = NULL_TREE(tree) __null; |
3336 | location_t struct_loc; |
3337 | location_t ident_loc = UNKNOWN_LOCATION((location_t) 0); |
3338 | enum tree_code code; |
3339 | switch (c_parser_peek_token (parser)->keyword) |
3340 | { |
3341 | case RID_STRUCT: |
3342 | code = RECORD_TYPE; |
3343 | break; |
3344 | case RID_UNION: |
3345 | code = UNION_TYPE; |
3346 | break; |
3347 | default: |
3348 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3348, __FUNCTION__)); |
3349 | } |
3350 | struct_loc = c_parser_peek_token (parser)->location; |
3351 | c_parser_consume_token (parser); |
3352 | have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1); |
3353 | if (have_std_attrs) |
3354 | std_attrs = c_parser_std_attribute_specifier_sequence (parser); |
3355 | attrs = c_parser_gnu_attributes (parser); |
3356 | |
3357 | /* Set the location in case we create a decl now. */ |
3358 | c_parser_set_source_position_from_token (c_parser_peek_token (parser)); |
3359 | |
3360 | if (c_parser_next_token_is (parser, CPP_NAME)) |
3361 | { |
3362 | ident = c_parser_peek_token (parser)->value; |
3363 | ident_loc = c_parser_peek_token (parser)->location; |
3364 | struct_loc = ident_loc; |
3365 | c_parser_consume_token (parser); |
3366 | } |
3367 | if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) |
3368 | { |
3369 | /* Parse a struct or union definition. Start the scope of the |
3370 | tag before parsing components. */ |
3371 | class c_struct_parse_info *struct_info; |
3372 | tree type = start_struct (struct_loc, code, ident, &struct_info); |
3373 | tree postfix_attrs; |
3374 | /* We chain the components in reverse order, then put them in |
3375 | forward order at the end. Each struct-declaration may |
3376 | declare multiple components (comma-separated), so we must use |
3377 | chainon to join them, although when parsing each |
3378 | struct-declaration we can use TREE_CHAIN directly. |
3379 | |
3380 | The theory behind all this is that there will be more |
3381 | semicolon separated fields than comma separated fields, and |
3382 | so we'll be minimizing the number of node traversals required |
3383 | by chainon. */ |
3384 | tree contents; |
3385 | timevar_push (TV_PARSE_STRUCT); |
3386 | contents = NULL_TREE(tree) __null; |
3387 | c_parser_consume_token (parser); |
3388 | /* Handle the Objective-C @defs construct, |
3389 | e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ |
3390 | if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS)) |
3391 | { |
3392 | tree name; |
3393 | gcc_assert (c_dialect_objc ())((void)(!(((c_language & clk_objc) != 0)) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3393, __FUNCTION__), 0 : 0)); |
3394 | c_parser_consume_token (parser); |
3395 | matching_parens parens; |
3396 | if (!parens.require_open (parser)) |
3397 | goto end_at_defs; |
3398 | if (c_parser_next_token_is (parser, CPP_NAME) |
3399 | && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) |
3400 | { |
3401 | name = c_parser_peek_token (parser)->value; |
3402 | c_parser_consume_token (parser); |
3403 | } |
3404 | else |
3405 | { |
3406 | c_parser_error (parser, "expected class name"); |
3407 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL__null); |
3408 | goto end_at_defs; |
3409 | } |
3410 | parens.skip_until_found_close (parser); |
3411 | contents = nreverse (objc_get_class_ivars (name)); |
3412 | } |
3413 | end_at_defs: |
3414 | /* Parse the struct-declarations and semicolons. Problems with |
3415 | semicolons are diagnosed here; empty structures are diagnosed |
3416 | elsewhere. */ |
3417 | while (true) |
3418 | { |
3419 | tree decls; |
3420 | /* Parse any stray semicolon. */ |
3421 | if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
3422 | { |
3423 | location_t semicolon_loc |
3424 | = c_parser_peek_token (parser)->location; |
3425 | gcc_rich_location richloc (semicolon_loc); |
3426 | richloc.add_fixit_remove (); |
3427 | pedwarn (&richloc, OPT_Wpedantic, |
3428 | "extra semicolon in struct or union specified"); |
3429 | c_parser_consume_token (parser); |
3430 | continue; |
3431 | } |
3432 | /* Stop if at the end of the struct or union contents. */ |
3433 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
3434 | { |
3435 | c_parser_consume_token (parser); |
3436 | break; |
3437 | } |
3438 | /* Accept #pragmas at struct scope. */ |
3439 | if (c_parser_next_token_is (parser, CPP_PRAGMA)) |
3440 | { |
3441 | c_parser_pragma (parser, pragma_struct, NULL__null); |
3442 | continue; |
3443 | } |
3444 | /* Parse some comma-separated declarations, but not the |
3445 | trailing semicolon if any. */ |
3446 | decls = c_parser_struct_declaration (parser); |
3447 | contents = chainon (decls, contents); |
3448 | /* If no semicolon follows, either we have a parse error or |
3449 | are at the end of the struct or union and should |
3450 | pedwarn. */ |
3451 | if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
3452 | c_parser_consume_token (parser); |
3453 | else |
3454 | { |
3455 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
3456 | pedwarn (c_parser_peek_token (parser)->location, 0, |
3457 | "no semicolon at end of struct or union"); |
3458 | else if (parser->error |
3459 | || !c_parser_next_token_starts_declspecs (parser)) |
3460 | { |
3461 | c_parser_error (parser, "expected %<;%>"); |
3462 | c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL__null); |
3463 | break; |
3464 | } |
3465 | |
3466 | /* If we come here, we have already emitted an error |
3467 | for an expected `;', identifier or `(', and we also |
3468 | recovered already. Go on with the next field. */ |
3469 | } |
3470 | } |
3471 | postfix_attrs = c_parser_gnu_attributes (parser); |
3472 | ret.spec = finish_struct (struct_loc, type, nreverse (contents), |
3473 | chainon (std_attrs, |
3474 | chainon (attrs, postfix_attrs)), |
3475 | struct_info); |
3476 | ret.kind = ctsk_tagdef; |
3477 | ret.expr = NULL_TREE(tree) __null; |
3478 | ret.expr_const_operands = true; |
3479 | timevar_pop (TV_PARSE_STRUCT); |
3480 | return ret; |
3481 | } |
3482 | else if (!ident) |
3483 | { |
3484 | c_parser_error (parser, "expected %<{%>"); |
3485 | ret.spec = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3486 | ret.kind = ctsk_tagref; |
3487 | ret.expr = NULL_TREE(tree) __null; |
3488 | ret.expr_const_operands = true; |
3489 | return ret; |
3490 | } |
3491 | /* Attributes may only appear when the members are defined or in |
3492 | certain forward declarations. */ |
3493 | if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON)) |
3494 | c_parser_error (parser, "expected %<;%>"); |
3495 | /* ??? Existing practice is that GNU attributes are ignored after |
3496 | the struct or union keyword when not defining the members. */ |
3497 | ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs); |
3498 | return ret; |
3499 | } |
3500 | |
3501 | /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1), |
3502 | *without* the trailing semicolon. |
3503 | |
3504 | struct-declaration: |
3505 | attribute-specifier-sequence[opt] specifier-qualifier-list |
3506 | attribute-specifier-sequence[opt] struct-declarator-list |
3507 | static_assert-declaration-no-semi |
3508 | |
3509 | specifier-qualifier-list: |
3510 | type-specifier specifier-qualifier-list[opt] |
3511 | type-qualifier specifier-qualifier-list[opt] |
3512 | alignment-specifier specifier-qualifier-list[opt] |
3513 | gnu-attributes specifier-qualifier-list[opt] |
3514 | |
3515 | struct-declarator-list: |
3516 | struct-declarator |
3517 | struct-declarator-list , gnu-attributes[opt] struct-declarator |
3518 | |
3519 | struct-declarator: |
3520 | declarator gnu-attributes[opt] |
3521 | declarator[opt] : constant-expression gnu-attributes[opt] |
3522 | |
3523 | GNU extensions: |
3524 | |
3525 | struct-declaration: |
3526 | __extension__ struct-declaration |
3527 | specifier-qualifier-list |
3528 | |
3529 | Unlike the ISO C syntax, semicolons are handled elsewhere. The use |
3530 | of gnu-attributes where shown is a GNU extension. In GNU C, we accept |
3531 | any expression without commas in the syntax (assignment |
3532 | expressions, not just conditional expressions); assignment |
3533 | expressions will be diagnosed as non-constant. */ |
3534 | |
3535 | static tree |
3536 | c_parser_struct_declaration (c_parser *parser) |
3537 | { |
3538 | struct c_declspecs *specs; |
3539 | tree prefix_attrs; |
3540 | tree all_prefix_attrs; |
3541 | tree decls; |
3542 | location_t decl_loc; |
3543 | if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) |
3544 | { |
3545 | int ext; |
3546 | tree decl; |
3547 | ext = disable_extension_diagnostics (); |
3548 | c_parser_consume_token (parser); |
3549 | decl = c_parser_struct_declaration (parser); |
3550 | restore_extension_diagnostics (ext); |
3551 | return decl; |
3552 | } |
3553 | if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) |
3554 | { |
3555 | c_parser_static_assert_declaration_no_semi (parser); |
3556 | return NULL_TREE(tree) __null; |
3557 | } |
3558 | specs = build_null_declspecs (); |
3559 | decl_loc = c_parser_peek_token (parser)->location; |
3560 | /* Strictly by the standard, we shouldn't allow _Alignas here, |
3561 | but it appears to have been intended to allow it there, so |
3562 | we're keeping it as it is until WG14 reaches a conclusion |
3563 | of N1731. |
3564 | <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */ |
3565 | c_parser_declspecs (parser, specs, false, true, true, |
3566 | true, false, true, true, cla_nonabstract_decl); |
3567 | if (parser->error) |
3568 | return NULL_TREE(tree) __null; |
3569 | if (!specs->declspecs_seen_p) |
3570 | { |
3571 | c_parser_error (parser, "expected specifier-qualifier-list"); |
3572 | return NULL_TREE(tree) __null; |
3573 | } |
3574 | finish_declspecs (specs); |
3575 | if (c_parser_next_token_is (parser, CPP_SEMICOLON) |
3576 | || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
3577 | { |
3578 | tree ret; |
3579 | if (specs->typespec_kind == ctsk_none) |
3580 | { |
3581 | pedwarn (decl_loc, OPT_Wpedantic, |
3582 | "ISO C forbids member declarations with no members"); |
3583 | shadow_tag_warned (specs, pedanticglobal_options.x_pedantic); |
3584 | ret = NULL_TREE(tree) __null; |
3585 | } |
3586 | else |
3587 | { |
3588 | /* Support for unnamed structs or unions as members of |
3589 | structs or unions (which is [a] useful and [b] supports |
3590 | MS P-SDK). */ |
3591 | tree attrs = NULL__null; |
3592 | |
3593 | ret = grokfield (c_parser_peek_token (parser)->location, |
3594 | build_id_declarator (NULL_TREE(tree) __null), specs, |
3595 | NULL_TREE(tree) __null, &attrs); |
3596 | if (ret) |
3597 | decl_attributes (&ret, attrs, 0); |
3598 | } |
3599 | return ret; |
3600 | } |
3601 | |
3602 | /* Provide better error recovery. Note that a type name here is valid, |
3603 | and will be treated as a field name. */ |
3604 | if (specs->typespec_kind == ctsk_tagdef |
3605 | && TREE_CODE (specs->type)((enum tree_code) (specs->type)->base.code) != ENUMERAL_TYPE |
3606 | && c_parser_next_token_starts_declspecs (parser) |
3607 | && !c_parser_next_token_is (parser, CPP_NAME)) |
3608 | { |
3609 | c_parser_error (parser, "expected %<;%>, identifier or %<(%>"); |
3610 | parser->error = false; |
3611 | return NULL_TREE(tree) __null; |
3612 | } |
3613 | |
3614 | pending_xref_error (); |
3615 | prefix_attrs = specs->attrs; |
3616 | all_prefix_attrs = prefix_attrs; |
3617 | specs->attrs = NULL_TREE(tree) __null; |
3618 | decls = NULL_TREE(tree) __null; |
3619 | while (true) |
3620 | { |
3621 | /* Declaring one or more declarators or un-named bit-fields. */ |
3622 | struct c_declarator *declarator; |
3623 | bool dummy = false; |
3624 | if (c_parser_next_token_is (parser, CPP_COLON)) |
3625 | declarator = build_id_declarator (NULL_TREE(tree) __null); |
3626 | else |
3627 | declarator = c_parser_declarator (parser, |
3628 | specs->typespec_kind != ctsk_none, |
3629 | C_DTR_NORMAL, &dummy); |
3630 | if (declarator == NULL__null) |
3631 | { |
3632 | c_parser_skip_to_end_of_block_or_statement (parser); |
3633 | break; |
3634 | } |
3635 | if (c_parser_next_token_is (parser, CPP_COLON) |
3636 | || c_parser_next_token_is (parser, CPP_COMMA) |
3637 | || c_parser_next_token_is (parser, CPP_SEMICOLON) |
3638 | || c_parser_next_token_is (parser, CPP_CLOSE_BRACE) |
3639 | || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
3640 | { |
3641 | tree postfix_attrs = NULL_TREE(tree) __null; |
3642 | tree width = NULL_TREE(tree) __null; |
3643 | tree d; |
3644 | if (c_parser_next_token_is (parser, CPP_COLON)) |
3645 | { |
3646 | c_parser_consume_token (parser); |
3647 | width = c_parser_expr_no_commas (parser, NULL__null).value; |
3648 | } |
3649 | if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
3650 | postfix_attrs = c_parser_gnu_attributes (parser); |
3651 | d = grokfield (c_parser_peek_token (parser)->location, |
3652 | declarator, specs, width, &all_prefix_attrs); |
3653 | decl_attributes (&d, chainon (postfix_attrs, |
3654 | all_prefix_attrs), 0); |
3655 | DECL_CHAIN (d)(((contains_struct_check (((contains_struct_check ((d), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3655, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3655, __FUNCTION__))->common.chain)) = decls; |
3656 | decls = d; |
3657 | if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
3658 | all_prefix_attrs = chainon (c_parser_gnu_attributes (parser), |
3659 | prefix_attrs); |
3660 | else |
3661 | all_prefix_attrs = prefix_attrs; |
3662 | if (c_parser_next_token_is (parser, CPP_COMMA)) |
3663 | c_parser_consume_token (parser); |
3664 | else if (c_parser_next_token_is (parser, CPP_SEMICOLON) |
3665 | || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
3666 | { |
3667 | /* Semicolon consumed in caller. */ |
3668 | break; |
3669 | } |
3670 | else |
3671 | { |
3672 | c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>"); |
3673 | break; |
3674 | } |
3675 | } |
3676 | else |
3677 | { |
3678 | c_parser_error (parser, |
3679 | "expected %<:%>, %<,%>, %<;%>, %<}%> or " |
3680 | "%<__attribute__%>"); |
3681 | break; |
3682 | } |
3683 | } |
3684 | return decls; |
3685 | } |
3686 | |
3687 | /* Parse a typeof specifier (a GNU extension). |
3688 | |
3689 | typeof-specifier: |
3690 | typeof ( expression ) |
3691 | typeof ( type-name ) |
3692 | */ |
3693 | |
3694 | static struct c_typespec |
3695 | c_parser_typeof_specifier (c_parser *parser) |
3696 | { |
3697 | struct c_typespec ret; |
3698 | ret.kind = ctsk_typeof; |
3699 | ret.spec = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3700 | ret.expr = NULL_TREE(tree) __null; |
3701 | ret.expr_const_operands = true; |
3702 | gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF))((void)(!(c_parser_next_token_is_keyword (parser, RID_TYPEOF) ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3702, __FUNCTION__), 0 : 0)); |
3703 | c_parser_consume_token (parser); |
3704 | c_inhibit_evaluation_warnings++; |
3705 | in_typeof++; |
3706 | matching_parens parens; |
3707 | if (!parens.require_open (parser)) |
3708 | { |
3709 | c_inhibit_evaluation_warnings--; |
3710 | in_typeof--; |
3711 | return ret; |
3712 | } |
3713 | if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) |
3714 | { |
3715 | struct c_type_name *type = c_parser_type_name (parser); |
3716 | c_inhibit_evaluation_warnings--; |
3717 | in_typeof--; |
3718 | if (type != NULL__null) |
3719 | { |
3720 | ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands); |
3721 | pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE(tree) __null)); |
3722 | } |
3723 | } |
3724 | else |
3725 | { |
3726 | bool was_vm; |
3727 | location_t here = c_parser_peek_token (parser)->location; |
3728 | struct c_expr expr = c_parser_expression (parser); |
3729 | c_inhibit_evaluation_warnings--; |
3730 | in_typeof--; |
3731 | if (TREE_CODE (expr.value)((enum tree_code) (expr.value)->base.code) == COMPONENT_REF |
3732 | && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))(((contains_struct_check (((tree_check (((*((const_cast<tree *> (tree_operand_check ((expr.value), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3732, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3732, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3732, __FUNCTION__))->decl_common.lang_flag_4) == 1)) |
3733 | error_at (here, "%<typeof%> applied to a bit-field"); |
3734 | mark_exp_read (expr.value); |
3735 | ret.spec = TREE_TYPE (expr.value)((contains_struct_check ((expr.value), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3735, __FUNCTION__))->typed.type); |
3736 | was_vm = variably_modified_type_p (ret.spec, NULL_TREE(tree) __null); |
3737 | /* This is returned with the type so that when the type is |
3738 | evaluated, this can be evaluated. */ |
3739 | if (was_vm) |
3740 | ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands); |
3741 | pop_maybe_used (was_vm); |
3742 | } |
3743 | parens.skip_until_found_close (parser); |
3744 | return ret; |
3745 | } |
3746 | |
3747 | /* Parse an alignment-specifier. |
3748 | |
3749 | C11 6.7.5: |
3750 | |
3751 | alignment-specifier: |
3752 | _Alignas ( type-name ) |
3753 | _Alignas ( constant-expression ) |
3754 | */ |
3755 | |
3756 | static tree |
3757 | c_parser_alignas_specifier (c_parser * parser) |
3758 | { |
3759 | tree ret = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3760 | location_t loc = c_parser_peek_token (parser)->location; |
3761 | gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS))((void)(!(c_parser_next_token_is_keyword (parser, RID_ALIGNAS )) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3761, __FUNCTION__), 0 : 0)); |
3762 | c_parser_consume_token (parser); |
3763 | if (flag_isoc99) |
3764 | pedwarn_c99 (loc, OPT_Wpedantic, |
3765 | "ISO C99 does not support %<_Alignas%>"); |
3766 | else |
3767 | pedwarn_c99 (loc, OPT_Wpedantic, |
3768 | "ISO C90 does not support %<_Alignas%>"); |
3769 | matching_parens parens; |
3770 | if (!parens.require_open (parser)) |
3771 | return ret; |
3772 | if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) |
3773 | { |
3774 | struct c_type_name *type = c_parser_type_name (parser); |
3775 | if (type != NULL__null) |
3776 | ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL__null, NULL__null), |
3777 | false, true, 1); |
3778 | } |
3779 | else |
3780 | ret = c_parser_expr_no_commas (parser, NULL__null).value; |
3781 | parens.skip_until_found_close (parser); |
3782 | return ret; |
3783 | } |
3784 | |
3785 | /* Parse a declarator, possibly an abstract declarator (C90 6.5.4, |
3786 | 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then |
3787 | a typedef name may be redeclared; otherwise it may not. KIND |
3788 | indicates which kind of declarator is wanted. Returns a valid |
3789 | declarator except in the case of a syntax error in which case NULL is |
3790 | returned. *SEEN_ID is set to true if an identifier being declared is |
3791 | seen; this is used to diagnose bad forms of abstract array declarators |
3792 | and to determine whether an identifier list is syntactically permitted. |
3793 | |
3794 | declarator: |
3795 | pointer[opt] direct-declarator |
3796 | |
3797 | direct-declarator: |
3798 | identifier |
3799 | ( gnu-attributes[opt] declarator ) |
3800 | direct-declarator array-declarator |
3801 | direct-declarator ( parameter-type-list ) |
3802 | direct-declarator ( identifier-list[opt] ) |
3803 | |
3804 | pointer: |
3805 | * type-qualifier-list[opt] |
3806 | * type-qualifier-list[opt] pointer |
3807 | |
3808 | type-qualifier-list: |
3809 | type-qualifier |
3810 | gnu-attributes |
3811 | type-qualifier-list type-qualifier |
3812 | type-qualifier-list gnu-attributes |
3813 | |
3814 | array-declarator: |
3815 | [ type-qualifier-list[opt] assignment-expression[opt] ] |
3816 | [ static type-qualifier-list[opt] assignment-expression ] |
3817 | [ type-qualifier-list static assignment-expression ] |
3818 | [ type-qualifier-list[opt] * ] |
3819 | |
3820 | parameter-type-list: |
3821 | parameter-list |
3822 | parameter-list , ... |
3823 | |
3824 | parameter-list: |
3825 | parameter-declaration |
3826 | parameter-list , parameter-declaration |
3827 | |
3828 | parameter-declaration: |
3829 | declaration-specifiers declarator gnu-attributes[opt] |
3830 | declaration-specifiers abstract-declarator[opt] gnu-attributes[opt] |
3831 | |
3832 | identifier-list: |
3833 | identifier |
3834 | identifier-list , identifier |
3835 | |
3836 | abstract-declarator: |
3837 | pointer |
3838 | pointer[opt] direct-abstract-declarator |
3839 | |
3840 | direct-abstract-declarator: |
3841 | ( gnu-attributes[opt] abstract-declarator ) |
3842 | direct-abstract-declarator[opt] array-declarator |
3843 | direct-abstract-declarator[opt] ( parameter-type-list[opt] ) |
3844 | |
3845 | GNU extensions: |
3846 | |
3847 | direct-declarator: |
3848 | direct-declarator ( parameter-forward-declarations |
3849 | parameter-type-list[opt] ) |
3850 | |
3851 | direct-abstract-declarator: |
3852 | direct-abstract-declarator[opt] ( parameter-forward-declarations |
3853 | parameter-type-list[opt] ) |
3854 | |
3855 | parameter-forward-declarations: |
3856 | parameter-list ; |
3857 | parameter-forward-declarations parameter-list ; |
3858 | |
3859 | The uses of gnu-attributes shown above are GNU extensions. |
3860 | |
3861 | Some forms of array declarator are not included in C99 in the |
3862 | syntax for abstract declarators; these are disallowed elsewhere. |
3863 | This may be a defect (DR#289). |
3864 | |
3865 | This function also accepts an omitted abstract declarator as being |
3866 | an abstract declarator, although not part of the formal syntax. */ |
3867 | |
3868 | struct c_declarator * |
3869 | c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, |
3870 | bool *seen_id) |
3871 | { |
3872 | /* Parse any initial pointer part. */ |
3873 | if (c_parser_next_token_is (parser, CPP_MULT)) |
3874 | { |
3875 | struct c_declspecs *quals_attrs = build_null_declspecs (); |
3876 | struct c_declarator *inner; |
3877 | c_parser_consume_token (parser); |
3878 | c_parser_declspecs (parser, quals_attrs, false, false, true, |
3879 | false, false, true, false, cla_prefer_id); |
3880 | inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); |
3881 | if (inner == NULL__null) |
3882 | return NULL__null; |
3883 | else |
3884 | return make_pointer_declarator (quals_attrs, inner); |
3885 | } |
3886 | /* Now we have a direct declarator, direct abstract declarator or |
3887 | nothing (which counts as a direct abstract declarator here). */ |
3888 | return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id); |
3889 | } |
3890 | |
3891 | /* Parse a direct declarator or direct abstract declarator; arguments |
3892 | as c_parser_declarator. */ |
3893 | |
3894 | static struct c_declarator * |
3895 | c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, |
3896 | bool *seen_id) |
3897 | { |
3898 | /* The direct declarator must start with an identifier (possibly |
3899 | omitted) or a parenthesized declarator (possibly abstract). In |
3900 | an ordinary declarator, initial parentheses must start a |
3901 | parenthesized declarator. In an abstract declarator or parameter |
3902 | declarator, they could start a parenthesized declarator or a |
3903 | parameter list. To tell which, the open parenthesis and any |
3904 | following gnu-attributes must be read. If a declaration |
3905 | specifier or standard attributes follow, then it is a parameter |
3906 | list; if the specifier is a typedef name, there might be an |
3907 | ambiguity about redeclaring it, which is resolved in the |
3908 | direction of treating it as a typedef name. If a close |
3909 | parenthesis follows, it is also an empty parameter list, as the |
3910 | syntax does not permit empty abstract declarators. Otherwise, it |
3911 | is a parenthesized declarator (in which case the analysis may be |
3912 | repeated inside it, recursively). |
3913 | |
3914 | ??? There is an ambiguity in a parameter declaration "int |
3915 | (__attribute__((foo)) x)", where x is not a typedef name: it |
3916 | could be an abstract declarator for a function, or declare x with |
3917 | parentheses. The proper resolution of this ambiguity needs |
3918 | documenting. At present we follow an accident of the old |
3919 | parser's implementation, whereby the first parameter must have |
3920 | some declaration specifiers other than just gnu-attributes. Thus as |
3921 | a parameter declaration it is treated as a parenthesized |
3922 | parameter named x, and as an abstract declarator it is |
3923 | rejected. |
3924 | |
3925 | ??? Also following the old parser, gnu-attributes inside an empty |
3926 | parameter list are ignored, making it a list not yielding a |
3927 | prototype, rather than giving an error or making it have one |
3928 | parameter with implicit type int. |
3929 | |
3930 | ??? Also following the old parser, typedef names may be |
3931 | redeclared in declarators, but not Objective-C class names. */ |
3932 | |
3933 | if (kind != C_DTR_ABSTRACT |
3934 | && c_parser_next_token_is (parser, CPP_NAME) |
3935 | && ((type_seen_p |
3936 | && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME |
3937 | || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) |
3938 | || c_parser_peek_token (parser)->id_kind == C_ID_ID)) |
3939 | { |
3940 | struct c_declarator *inner |
3941 | = build_id_declarator (c_parser_peek_token (parser)->value); |
3942 | *seen_id = true; |
3943 | inner->id_loc = c_parser_peek_token (parser)->location; |
3944 | c_parser_consume_token (parser); |
3945 | if (c_parser_nth_token_starts_std_attributes (parser, 1)) |
3946 | inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser); |
3947 | return c_parser_direct_declarator_inner (parser, *seen_id, inner); |
3948 | } |
3949 | |
3950 | if (kind != C_DTR_NORMAL |
3951 | && c_parser_next_token_is (parser, CPP_OPEN_SQUARE) |
3952 | && !c_parser_nth_token_starts_std_attributes (parser, 1)) |
3953 | { |
3954 | struct c_declarator *inner = build_id_declarator (NULL_TREE(tree) __null); |
3955 | inner->id_loc = c_parser_peek_token (parser)->location; |
3956 | return c_parser_direct_declarator_inner (parser, *seen_id, inner); |
3957 | } |
3958 | |
3959 | /* Either we are at the end of an abstract declarator, or we have |
3960 | parentheses. */ |
3961 | |
3962 | if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) |
3963 | { |
3964 | tree attrs; |
3965 | struct c_declarator *inner; |
3966 | c_parser_consume_token (parser); |
3967 | bool have_gnu_attrs = c_parser_next_token_is_keyword (parser, |
3968 | RID_ATTRIBUTE); |
3969 | attrs = c_parser_gnu_attributes (parser); |
3970 | if (kind != C_DTR_NORMAL |
3971 | && (c_parser_next_token_starts_declspecs (parser) |
3972 | || (!have_gnu_attrs |
3973 | && c_parser_nth_token_starts_std_attributes (parser, 1)) |
3974 | || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) |
3975 | { |
3976 | struct c_arg_info *args |
3977 | = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL, |
3978 | attrs, have_gnu_attrs); |
3979 | if (args == NULL__null) |
3980 | return NULL__null; |
3981 | else |
3982 | { |
3983 | inner = build_id_declarator (NULL_TREE(tree) __null); |
3984 | if (!(args->types |
3985 | && args->types != error_mark_nodeglobal_trees[TI_ERROR_MARK] |
3986 | && TREE_CODE (TREE_VALUE (args->types))((enum tree_code) (((tree_check ((args->types), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 3986, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == IDENTIFIER_NODE) |
3987 | && c_parser_nth_token_starts_std_attributes (parser, 1)) |
3988 | { |
3989 | tree std_attrs |
3990 | = c_parser_std_attribute_specifier_sequence (parser); |
3991 | if (std_attrs) |
3992 | inner = build_attrs_declarator (std_attrs, inner); |
3993 | } |
3994 | inner = build_function_declarator (args, inner); |
3995 | return c_parser_direct_declarator_inner (parser, *seen_id, |
3996 | inner); |
3997 | } |
3998 | } |
3999 | /* A parenthesized declarator. */ |
4000 | inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); |
4001 | if (inner != NULL__null && attrs != NULL__null) |
4002 | inner = build_attrs_declarator (attrs, inner); |
4003 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4004 | { |
4005 | c_parser_consume_token (parser); |
4006 | if (inner == NULL__null) |
4007 | return NULL__null; |
4008 | else |
4009 | return c_parser_direct_declarator_inner (parser, *seen_id, inner); |
4010 | } |
4011 | else |
4012 | { |
4013 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4014 | "expected %<)%>"); |
4015 | return NULL__null; |
4016 | } |
4017 | } |
4018 | else |
4019 | { |
4020 | if (kind == C_DTR_NORMAL) |
4021 | { |
4022 | c_parser_error (parser, "expected identifier or %<(%>"); |
4023 | return NULL__null; |
4024 | } |
4025 | else |
4026 | return build_id_declarator (NULL_TREE(tree) __null); |
4027 | } |
4028 | } |
4029 | |
4030 | /* Parse part of a direct declarator or direct abstract declarator, |
4031 | given that some (in INNER) has already been parsed; ID_PRESENT is |
4032 | true if an identifier is present, false for an abstract |
4033 | declarator. */ |
4034 | |
4035 | static struct c_declarator * |
4036 | c_parser_direct_declarator_inner (c_parser *parser, bool id_present, |
4037 | struct c_declarator *inner) |
4038 | { |
4039 | /* Parse a sequence of array declarators and parameter lists. */ |
4040 | if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) |
4041 | && !c_parser_nth_token_starts_std_attributes (parser, 1)) |
4042 | { |
4043 | location_t brace_loc = c_parser_peek_token (parser)->location; |
4044 | struct c_declarator *declarator; |
4045 | struct c_declspecs *quals_attrs = build_null_declspecs (); |
4046 | bool static_seen; |
4047 | bool star_seen; |
4048 | struct c_expr dimen; |
4049 | dimen.value = NULL_TREE(tree) __null; |
4050 | dimen.original_code = ERROR_MARK; |
4051 | dimen.original_type = NULL_TREE(tree) __null; |
4052 | c_parser_consume_token (parser); |
4053 | c_parser_declspecs (parser, quals_attrs, false, false, true, |
4054 | false, false, false, false, cla_prefer_id); |
4055 | static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC); |
4056 | if (static_seen) |
4057 | c_parser_consume_token (parser); |
4058 | if (static_seen && !quals_attrs->declspecs_seen_p) |
4059 | c_parser_declspecs (parser, quals_attrs, false, false, true, |
4060 | false, false, false, false, cla_prefer_id); |
4061 | if (!quals_attrs->declspecs_seen_p) |
4062 | quals_attrs = NULL__null; |
4063 | /* If "static" is present, there must be an array dimension. |
4064 | Otherwise, there may be a dimension, "*", or no |
4065 | dimension. */ |
4066 | if (static_seen) |
4067 | { |
4068 | star_seen = false; |
4069 | dimen = c_parser_expr_no_commas (parser, NULL__null); |
4070 | } |
4071 | else |
4072 | { |
4073 | if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) |
4074 | { |
4075 | dimen.value = NULL_TREE(tree) __null; |
4076 | star_seen = false; |
4077 | } |
4078 | else if (c_parser_next_token_is (parser, CPP_MULT)) |
4079 | { |
4080 | if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE) |
4081 | { |
4082 | dimen.value = NULL_TREE(tree) __null; |
4083 | star_seen = true; |
4084 | c_parser_consume_token (parser); |
4085 | } |
4086 | else |
4087 | { |
4088 | star_seen = false; |
4089 | dimen = c_parser_expr_no_commas (parser, NULL__null); |
4090 | } |
4091 | } |
4092 | else |
4093 | { |
4094 | star_seen = false; |
4095 | dimen = c_parser_expr_no_commas (parser, NULL__null); |
4096 | } |
4097 | } |
4098 | if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) |
4099 | c_parser_consume_token (parser); |
4100 | else |
4101 | { |
4102 | c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, |
4103 | "expected %<]%>"); |
4104 | return NULL__null; |
4105 | } |
4106 | if (dimen.value) |
4107 | dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true); |
4108 | declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs, |
4109 | static_seen, star_seen); |
4110 | if (declarator == NULL__null) |
4111 | return NULL__null; |
4112 | if (c_parser_nth_token_starts_std_attributes (parser, 1)) |
4113 | { |
4114 | tree std_attrs |
4115 | = c_parser_std_attribute_specifier_sequence (parser); |
4116 | if (std_attrs) |
4117 | inner = build_attrs_declarator (std_attrs, inner); |
4118 | } |
4119 | inner = set_array_declarator_inner (declarator, inner); |
4120 | return c_parser_direct_declarator_inner (parser, id_present, inner); |
4121 | } |
4122 | else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) |
4123 | { |
4124 | tree attrs; |
4125 | struct c_arg_info *args; |
4126 | c_parser_consume_token (parser); |
4127 | bool have_gnu_attrs = c_parser_next_token_is_keyword (parser, |
4128 | RID_ATTRIBUTE); |
4129 | attrs = c_parser_gnu_attributes (parser); |
4130 | args = c_parser_parms_declarator (parser, id_present, attrs, |
4131 | have_gnu_attrs); |
4132 | if (args == NULL__null) |
4133 | return NULL__null; |
4134 | else |
4135 | { |
4136 | if (!(args->types |
4137 | && args->types != error_mark_nodeglobal_trees[TI_ERROR_MARK] |
4138 | && TREE_CODE (TREE_VALUE (args->types))((enum tree_code) (((tree_check ((args->types), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4138, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == IDENTIFIER_NODE) |
4139 | && c_parser_nth_token_starts_std_attributes (parser, 1)) |
4140 | { |
4141 | tree std_attrs |
4142 | = c_parser_std_attribute_specifier_sequence (parser); |
4143 | if (std_attrs) |
4144 | inner = build_attrs_declarator (std_attrs, inner); |
4145 | } |
4146 | inner = build_function_declarator (args, inner); |
4147 | return c_parser_direct_declarator_inner (parser, id_present, inner); |
4148 | } |
4149 | } |
4150 | return inner; |
4151 | } |
4152 | |
4153 | /* Parse a parameter list or identifier list, including the closing |
4154 | parenthesis but not the opening one. ATTRS are the gnu-attributes |
4155 | at the start of the list. ID_LIST_OK is true if an identifier list |
4156 | is acceptable; such a list must not have attributes at the start. |
4157 | HAVE_GNU_ATTRS says whether any gnu-attributes (including empty |
4158 | attributes) were present (in which case standard attributes cannot |
4159 | occur). */ |
4160 | |
4161 | static struct c_arg_info * |
4162 | c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs, |
4163 | bool have_gnu_attrs) |
4164 | { |
4165 | push_scope (); |
4166 | declare_parm_level (); |
4167 | /* If the list starts with an identifier, it is an identifier list. |
4168 | Otherwise, it is either a prototype list or an empty list. */ |
4169 | if (id_list_ok |
4170 | && !attrs |
4171 | && c_parser_next_token_is (parser, CPP_NAME) |
4172 | && c_parser_peek_token (parser)->id_kind == C_ID_ID |
4173 | |
4174 | /* Look ahead to detect typos in type names. */ |
4175 | && c_parser_peek_2nd_token (parser)->type != CPP_NAME |
4176 | && c_parser_peek_2nd_token (parser)->type != CPP_MULT |
4177 | && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN |
4178 | && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE |
4179 | && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD) |
4180 | { |
4181 | tree list = NULL_TREE(tree) __null, *nextp = &list; |
4182 | while (c_parser_next_token_is (parser, CPP_NAME) |
4183 | && c_parser_peek_token (parser)->id_kind == C_ID_ID) |
4184 | { |
4185 | *nextp = build_tree_list (NULL_TREE(tree) __null, |
4186 | c_parser_peek_token (parser)->value); |
4187 | nextp = & TREE_CHAIN (*nextp)((contains_struct_check ((*nextp), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4187, __FUNCTION__))->common.chain); |
4188 | c_parser_consume_token (parser); |
4189 | if (c_parser_next_token_is_not (parser, CPP_COMMA)) |
4190 | break; |
4191 | c_parser_consume_token (parser); |
4192 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4193 | { |
4194 | c_parser_error (parser, "expected identifier"); |
4195 | break; |
4196 | } |
4197 | } |
4198 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4199 | { |
4200 | struct c_arg_info *ret = build_arg_info (); |
4201 | ret->types = list; |
4202 | c_parser_consume_token (parser); |
4203 | pop_scope (); |
4204 | return ret; |
4205 | } |
4206 | else |
4207 | { |
4208 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4209 | "expected %<)%>"); |
4210 | pop_scope (); |
4211 | return NULL__null; |
4212 | } |
4213 | } |
4214 | else |
4215 | { |
4216 | struct c_arg_info *ret |
4217 | = c_parser_parms_list_declarator (parser, attrs, NULL__null, have_gnu_attrs); |
4218 | pop_scope (); |
4219 | return ret; |
4220 | } |
4221 | } |
4222 | |
4223 | /* Parse a parameter list (possibly empty), including the closing |
4224 | parenthesis but not the opening one. ATTRS are the gnu-attributes |
4225 | at the start of the list; if HAVE_GNU_ATTRS, there were some such |
4226 | attributes (possibly empty, in which case ATTRS is NULL_TREE), |
4227 | which means standard attributes cannot start the list. EXPR is |
4228 | NULL or an expression that needs to be evaluated for the side |
4229 | effects of array size expressions in the parameters. */ |
4230 | |
4231 | static struct c_arg_info * |
4232 | c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr, |
4233 | bool have_gnu_attrs) |
4234 | { |
4235 | bool bad_parm = false; |
4236 | |
4237 | /* ??? Following the old parser, forward parameter declarations may |
4238 | use abstract declarators, and if no real parameter declarations |
4239 | follow the forward declarations then this is not diagnosed. Also |
4240 | note as above that gnu-attributes are ignored as the only contents of |
4241 | the parentheses, or as the only contents after forward |
4242 | declarations. */ |
4243 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4244 | { |
4245 | struct c_arg_info *ret = build_arg_info (); |
4246 | c_parser_consume_token (parser); |
4247 | return ret; |
4248 | } |
4249 | if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) |
4250 | { |
4251 | struct c_arg_info *ret = build_arg_info (); |
4252 | |
4253 | if (flag_allow_parameterless_variadic_functionsglobal_options.x_flag_allow_parameterless_variadic_functions) |
4254 | { |
4255 | /* F (...) is allowed. */ |
4256 | ret->types = NULL_TREE(tree) __null; |
4257 | } |
4258 | else |
4259 | { |
4260 | /* Suppress -Wold-style-definition for this case. */ |
4261 | ret->types = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4262 | error_at (c_parser_peek_token (parser)->location, |
4263 | "ISO C requires a named argument before %<...%>"); |
4264 | } |
4265 | c_parser_consume_token (parser); |
4266 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4267 | { |
4268 | c_parser_consume_token (parser); |
4269 | return ret; |
4270 | } |
4271 | else |
4272 | { |
4273 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4274 | "expected %<)%>"); |
4275 | return NULL__null; |
4276 | } |
4277 | } |
4278 | /* Nonempty list of parameters, either terminated with semicolon |
4279 | (forward declarations; recurse) or with close parenthesis (normal |
4280 | function) or with ", ... )" (variadic function). */ |
4281 | while (true) |
4282 | { |
4283 | /* Parse a parameter. */ |
4284 | struct c_parm *parm = c_parser_parameter_declaration (parser, attrs, |
4285 | have_gnu_attrs); |
4286 | attrs = NULL_TREE(tree) __null; |
4287 | have_gnu_attrs = false; |
4288 | if (parm == NULL__null) |
4289 | bad_parm = true; |
4290 | else |
4291 | push_parm_decl (parm, &expr); |
4292 | if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
4293 | { |
4294 | tree new_attrs; |
4295 | c_parser_consume_token (parser); |
4296 | mark_forward_parm_decls (); |
4297 | bool new_have_gnu_attrs |
4298 | = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE); |
4299 | new_attrs = c_parser_gnu_attributes (parser); |
4300 | return c_parser_parms_list_declarator (parser, new_attrs, expr, |
4301 | new_have_gnu_attrs); |
4302 | } |
4303 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4304 | { |
4305 | c_parser_consume_token (parser); |
4306 | if (bad_parm) |
4307 | return NULL__null; |
4308 | else |
4309 | return get_parm_info (false, expr); |
4310 | } |
4311 | if (!c_parser_require (parser, CPP_COMMA, |
4312 | "expected %<;%>, %<,%> or %<)%>", |
4313 | UNKNOWN_LOCATION((location_t) 0), false)) |
4314 | { |
4315 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL__null); |
4316 | return NULL__null; |
4317 | } |
4318 | if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) |
4319 | { |
4320 | c_parser_consume_token (parser); |
4321 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4322 | { |
4323 | c_parser_consume_token (parser); |
4324 | if (bad_parm) |
4325 | return NULL__null; |
4326 | else |
4327 | return get_parm_info (true, expr); |
4328 | } |
4329 | else |
4330 | { |
4331 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4332 | "expected %<)%>"); |
4333 | return NULL__null; |
4334 | } |
4335 | } |
4336 | } |
4337 | } |
4338 | |
4339 | /* Parse a parameter declaration. ATTRS are the gnu-attributes at the |
4340 | start of the declaration if it is the first parameter; |
4341 | HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even |
4342 | empty) there. */ |
4343 | |
4344 | static struct c_parm * |
4345 | c_parser_parameter_declaration (c_parser *parser, tree attrs, |
4346 | bool have_gnu_attrs) |
4347 | { |
4348 | struct c_declspecs *specs; |
4349 | struct c_declarator *declarator; |
4350 | tree prefix_attrs; |
4351 | tree postfix_attrs = NULL_TREE(tree) __null; |
4352 | bool dummy = false; |
4353 | |
4354 | /* Accept #pragmas between parameter declarations. */ |
4355 | while (c_parser_next_token_is (parser, CPP_PRAGMA)) |
4356 | c_parser_pragma (parser, pragma_param, NULL__null); |
4357 | |
4358 | if (!c_parser_next_token_starts_declspecs (parser) |
4359 | && !c_parser_nth_token_starts_std_attributes (parser, 1)) |
4360 | { |
4361 | c_token *token = c_parser_peek_token (parser); |
4362 | if (parser->error) |
4363 | return NULL__null; |
4364 | c_parser_set_source_position_from_token (token); |
4365 | if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) |
4366 | { |
4367 | auto_diagnostic_group d; |
4368 | name_hint hint = lookup_name_fuzzy (token->value, |
4369 | FUZZY_LOOKUP_TYPENAME, |
4370 | token->location); |
4371 | if (const char *suggestion = hint.suggestion ()) |
4372 | { |
4373 | gcc_rich_location richloc (token->location); |
4374 | richloc.add_fixit_replace (suggestion); |
4375 | error_at (&richloc, |
4376 | "unknown type name %qE; did you mean %qs?", |
4377 | token->value, suggestion); |
4378 | } |
4379 | else |
4380 | error_at (token->location, "unknown type name %qE", token->value); |
4381 | parser->error = true; |
4382 | } |
4383 | /* ??? In some Objective-C cases '...' isn't applicable so there |
4384 | should be a different message. */ |
4385 | else |
4386 | c_parser_error (parser, |
4387 | "expected declaration specifiers or %<...%>"); |
4388 | c_parser_skip_to_end_of_parameter (parser); |
4389 | return NULL__null; |
4390 | } |
4391 | |
4392 | location_t start_loc = c_parser_peek_token (parser)->location; |
4393 | |
4394 | specs = build_null_declspecs (); |
4395 | if (attrs) |
4396 | { |
4397 | declspecs_add_attrs (input_location, specs, attrs); |
4398 | attrs = NULL_TREE(tree) __null; |
4399 | } |
4400 | c_parser_declspecs (parser, specs, true, true, true, true, false, |
4401 | !have_gnu_attrs, true, cla_nonabstract_decl); |
4402 | finish_declspecs (specs); |
4403 | pending_xref_error (); |
4404 | prefix_attrs = specs->attrs; |
4405 | specs->attrs = NULL_TREE(tree) __null; |
4406 | declarator = c_parser_declarator (parser, |
4407 | specs->typespec_kind != ctsk_none, |
4408 | C_DTR_PARM, &dummy); |
4409 | if (declarator == NULL__null) |
4410 | { |
4411 | c_parser_skip_until_found (parser, CPP_COMMA, NULL__null); |
4412 | return NULL__null; |
4413 | } |
4414 | if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
4415 | postfix_attrs = c_parser_gnu_attributes (parser); |
4416 | |
4417 | /* Generate a location for the parameter, ranging from the start of the |
4418 | initial token to the end of the final token. |
4419 | |
4420 | If we have a identifier, then use it for the caret location, e.g. |
4421 | |
4422 | extern int callee (int one, int (*two)(int, int), float three); |
4423 | ~~~~~~^~~~~~~~~~~~~~ |
4424 | |
4425 | otherwise, reuse the start location for the caret location e.g.: |
4426 | |
4427 | extern int callee (int one, int (*)(int, int), float three); |
4428 | ^~~~~~~~~~~~~~~~~ |
4429 | */ |
4430 | location_t end_loc = parser->last_token_location; |
4431 | |
4432 | /* Find any cdk_id declarator; determine if we have an identifier. */ |
4433 | c_declarator *id_declarator = declarator; |
4434 | while (id_declarator && id_declarator->kind != cdk_id) |
4435 | id_declarator = id_declarator->declarator; |
4436 | location_t caret_loc = (id_declarator->u.id.id |
4437 | ? id_declarator->id_loc |
4438 | : start_loc); |
4439 | location_t param_loc = make_location (caret_loc, start_loc, end_loc); |
4440 | |
4441 | return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs), |
4442 | declarator, param_loc); |
4443 | } |
4444 | |
4445 | /* Parse a string literal in an asm expression. It should not be |
4446 | translated, and wide string literals are an error although |
4447 | permitted by the syntax. This is a GNU extension. |
4448 | |
4449 | asm-string-literal: |
4450 | string-literal |
4451 | */ |
4452 | |
4453 | static tree |
4454 | c_parser_asm_string_literal (c_parser *parser) |
4455 | { |
4456 | tree str; |
4457 | int save_flag = warn_overlength_stringsglobal_options.x_warn_overlength_strings; |
4458 | warn_overlength_stringsglobal_options.x_warn_overlength_strings = 0; |
4459 | str = c_parser_string_literal (parser, false, false).value; |
4460 | warn_overlength_stringsglobal_options.x_warn_overlength_strings = save_flag; |
4461 | return str; |
4462 | } |
4463 | |
4464 | /* Parse a simple asm expression. This is used in restricted |
4465 | contexts, where a full expression with inputs and outputs does not |
4466 | make sense. This is a GNU extension. |
4467 | |
4468 | simple-asm-expr: |
4469 | asm ( asm-string-literal ) |
4470 | */ |
4471 | |
4472 | static tree |
4473 | c_parser_simple_asm_expr (c_parser *parser) |
4474 | { |
4475 | tree str; |
4476 | gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM))((void)(!(c_parser_next_token_is_keyword (parser, RID_ASM)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4476, __FUNCTION__), 0 : 0)); |
4477 | c_parser_consume_token (parser); |
4478 | matching_parens parens; |
4479 | if (!parens.require_open (parser)) |
4480 | return NULL_TREE(tree) __null; |
4481 | str = c_parser_asm_string_literal (parser); |
4482 | if (!parens.require_close (parser)) |
4483 | { |
4484 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL__null); |
4485 | return NULL_TREE(tree) __null; |
4486 | } |
4487 | return str; |
4488 | } |
4489 | |
4490 | static tree |
4491 | c_parser_gnu_attribute_any_word (c_parser *parser) |
4492 | { |
4493 | tree attr_name = NULL_TREE(tree) __null; |
4494 | |
4495 | if (c_parser_next_token_is (parser, CPP_KEYWORD)) |
4496 | { |
4497 | /* ??? See comment above about what keywords are accepted here. */ |
4498 | bool ok; |
4499 | switch (c_parser_peek_token (parser)->keyword) |
4500 | { |
4501 | case RID_STATIC: |
4502 | case RID_UNSIGNED: |
4503 | case RID_LONG: |
4504 | case RID_CONST: |
4505 | case RID_EXTERN: |
4506 | case RID_REGISTER: |
4507 | case RID_TYPEDEF: |
4508 | case RID_SHORT: |
4509 | case RID_INLINE: |
4510 | case RID_NORETURN: |
4511 | case RID_VOLATILE: |
4512 | case RID_SIGNED: |
4513 | case RID_AUTO: |
4514 | case RID_RESTRICT: |
4515 | case RID_COMPLEX: |
4516 | case RID_THREAD: |
4517 | case RID_INT: |
4518 | case RID_CHAR: |
4519 | case RID_FLOAT: |
4520 | case RID_DOUBLE: |
4521 | case RID_VOID: |
4522 | case RID_DFLOAT32: |
4523 | case RID_DFLOAT64: |
4524 | case RID_DFLOAT128: |
4525 | CASE_RID_FLOATN_NXcase RID_FLOAT16: case RID_FLOAT32: case RID_FLOAT64: case RID_FLOAT128 : case RID_FLOAT32X: case RID_FLOAT64X: case RID_FLOAT128X: |
4526 | case RID_BOOL: |
4527 | case RID_FRACT: |
4528 | case RID_ACCUM: |
4529 | case RID_SAT: |
4530 | case RID_TRANSACTION_ATOMIC: |
4531 | case RID_TRANSACTION_CANCEL: |
4532 | case RID_ATOMIC: |
4533 | case RID_AUTO_TYPE: |
4534 | case RID_INT_N_0: |
4535 | case RID_INT_N_1: |
4536 | case RID_INT_N_2: |
4537 | case RID_INT_N_3: |
4538 | ok = true; |
4539 | break; |
4540 | default: |
4541 | ok = false; |
4542 | break; |
4543 | } |
4544 | if (!ok) |
4545 | return NULL_TREE(tree) __null; |
4546 | |
4547 | /* Accept __attribute__((__const)) as __attribute__((const)) etc. */ |
4548 | attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword]; |
4549 | } |
4550 | else if (c_parser_next_token_is (parser, CPP_NAME)) |
4551 | attr_name = c_parser_peek_token (parser)->value; |
4552 | |
4553 | return attr_name; |
4554 | } |
4555 | |
4556 | /* Parse attribute arguments. This is a common form of syntax |
4557 | covering all currently valid GNU and standard attributes. |
4558 | |
4559 | gnu-attribute-arguments: |
4560 | identifier |
4561 | identifier , nonempty-expr-list |
4562 | expr-list |
4563 | |
4564 | where the "identifier" must not be declared as a type. ??? Why not |
4565 | allow identifiers declared as types to start the arguments? */ |
4566 | |
4567 | static tree |
4568 | c_parser_attribute_arguments (c_parser *parser, bool takes_identifier, |
4569 | bool require_string, bool allow_empty_args) |
4570 | { |
4571 | vec<tree, va_gc> *expr_list; |
4572 | tree attr_args; |
4573 | /* Parse the attribute contents. If they start with an |
4574 | identifier which is followed by a comma or close |
4575 | parenthesis, then the arguments start with that |
4576 | identifier; otherwise they are an expression list. |
4577 | In objective-c the identifier may be a classname. */ |
4578 | if (c_parser_next_token_is (parser, CPP_NAME) |
4579 | && (c_parser_peek_token (parser)->id_kind == C_ID_ID |
4580 | || (c_dialect_objc ()((c_language & clk_objc) != 0) |
4581 | && c_parser_peek_token (parser)->id_kind |
4582 | == C_ID_CLASSNAME)) |
4583 | && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA) |
4584 | || (c_parser_peek_2nd_token (parser)->type |
4585 | == CPP_CLOSE_PAREN)) |
4586 | && (takes_identifier |
4587 | || (c_dialect_objc ()((c_language & clk_objc) != 0) |
4588 | && c_parser_peek_token (parser)->id_kind |
4589 | == C_ID_CLASSNAME))) |
4590 | { |
4591 | tree arg1 = c_parser_peek_token (parser)->value; |
4592 | c_parser_consume_token (parser); |
4593 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4594 | attr_args = build_tree_list (NULL_TREE(tree) __null, arg1); |
4595 | else |
4596 | { |
4597 | tree tree_list; |
4598 | c_parser_consume_token (parser); |
4599 | expr_list = c_parser_expr_list (parser, false, true, |
4600 | NULL__null, NULL__null, NULL__null, NULL__null); |
4601 | tree_list = build_tree_list_vec (expr_list); |
4602 | attr_args = tree_cons (NULL_TREE(tree) __null, arg1, tree_list); |
4603 | release_tree_vector (expr_list); |
4604 | } |
4605 | } |
4606 | else |
4607 | { |
4608 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4609 | { |
4610 | if (!allow_empty_args) |
4611 | error_at (c_parser_peek_token (parser)->location, |
4612 | "parentheses must be omitted if " |
4613 | "attribute argument list is empty"); |
4614 | attr_args = NULL_TREE(tree) __null; |
4615 | } |
4616 | else if (require_string) |
4617 | { |
4618 | /* The only valid argument for this attribute is a string |
4619 | literal. Handle this specially here to avoid accepting |
4620 | string literals with excess parentheses. */ |
4621 | tree string = c_parser_string_literal (parser, false, true).value; |
4622 | attr_args = build_tree_list (NULL_TREE(tree) __null, string); |
4623 | } |
4624 | else |
4625 | { |
4626 | expr_list = c_parser_expr_list (parser, false, true, |
4627 | NULL__null, NULL__null, NULL__null, NULL__null); |
4628 | attr_args = build_tree_list_vec (expr_list); |
4629 | release_tree_vector (expr_list); |
4630 | } |
4631 | } |
4632 | return attr_args; |
4633 | } |
4634 | |
4635 | /* Parse (possibly empty) gnu-attributes. This is a GNU extension. |
4636 | |
4637 | gnu-attributes: |
4638 | empty |
4639 | gnu-attributes gnu-attribute |
4640 | |
4641 | gnu-attribute: |
4642 | __attribute__ ( ( gnu-attribute-list ) ) |
4643 | |
4644 | gnu-attribute-list: |
4645 | gnu-attrib |
4646 | gnu-attribute_list , gnu-attrib |
4647 | |
4648 | gnu-attrib: |
4649 | empty |
4650 | any-word |
4651 | any-word ( gnu-attribute-arguments ) |
4652 | |
4653 | where "any-word" may be any identifier (including one declared as a |
4654 | type), a reserved word storage class specifier, type specifier or |
4655 | type qualifier. ??? This still leaves out most reserved keywords |
4656 | (following the old parser), shouldn't we include them? |
4657 | When EXPECT_COMMA is true, expect the attribute to be preceded |
4658 | by a comma and fail if it isn't. |
4659 | When EMPTY_OK is true, allow and consume any number of consecutive |
4660 | commas with no attributes in between. */ |
4661 | |
4662 | static tree |
4663 | c_parser_gnu_attribute (c_parser *parser, tree attrs, |
4664 | bool expect_comma = false, bool empty_ok = true) |
4665 | { |
4666 | bool comma_first = c_parser_next_token_is (parser, CPP_COMMA); |
4667 | if (!comma_first |
4668 | && !c_parser_next_token_is (parser, CPP_NAME) |
4669 | && !c_parser_next_token_is (parser, CPP_KEYWORD)) |
4670 | return NULL_TREE(tree) __null; |
4671 | |
4672 | while (c_parser_next_token_is (parser, CPP_COMMA)) |
4673 | { |
4674 | c_parser_consume_token (parser); |
4675 | if (!empty_ok) |
4676 | return attrs; |
4677 | } |
4678 | |
4679 | tree attr_name = c_parser_gnu_attribute_any_word (parser); |
4680 | if (attr_name == NULL_TREE(tree) __null) |
4681 | return NULL_TREE(tree) __null; |
4682 | |
4683 | attr_name = canonicalize_attr_name (attr_name); |
4684 | c_parser_consume_token (parser); |
4685 | |
4686 | tree attr; |
4687 | if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) |
4688 | { |
4689 | if (expect_comma && !comma_first) |
4690 | { |
4691 | /* A comma is missing between the last attribute on the chain |
4692 | and this one. */ |
4693 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4694 | "expected %<)%>"); |
4695 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4696 | } |
4697 | attr = build_tree_list (attr_name, NULL_TREE(tree) __null); |
4698 | /* Add this attribute to the list. */ |
4699 | attrs = chainon (attrs, attr); |
4700 | return attrs; |
4701 | } |
4702 | c_parser_consume_token (parser); |
4703 | |
4704 | tree attr_args |
4705 | = c_parser_attribute_arguments (parser, |
4706 | attribute_takes_identifier_p (attr_name), |
4707 | false, true); |
4708 | |
4709 | attr = build_tree_list (attr_name, attr_args); |
4710 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4711 | c_parser_consume_token (parser); |
4712 | else |
4713 | { |
4714 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4715 | "expected %<)%>"); |
4716 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4717 | } |
4718 | |
4719 | if (expect_comma && !comma_first) |
4720 | { |
4721 | /* A comma is missing between the last attribute on the chain |
4722 | and this one. */ |
4723 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4724 | "expected %<)%>"); |
4725 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4726 | } |
4727 | |
4728 | /* Add this attribute to the list. */ |
4729 | attrs = chainon (attrs, attr); |
4730 | return attrs; |
4731 | } |
4732 | |
4733 | static tree |
4734 | c_parser_gnu_attributes (c_parser *parser) |
4735 | { |
4736 | tree attrs = NULL_TREE(tree) __null; |
4737 | while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) |
4738 | { |
4739 | bool save_translate_strings_p = parser->translate_strings_p; |
4740 | parser->translate_strings_p = false; |
4741 | /* Consume the `__attribute__' keyword. */ |
4742 | c_parser_consume_token (parser); |
4743 | /* Look for the two `(' tokens. */ |
4744 | if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) |
4745 | { |
4746 | parser->translate_strings_p = save_translate_strings_p; |
4747 | return attrs; |
4748 | } |
4749 | if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) |
4750 | { |
4751 | parser->translate_strings_p = save_translate_strings_p; |
4752 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL__null); |
4753 | return attrs; |
4754 | } |
4755 | /* Parse the attribute list. Require a comma between successive |
4756 | (possibly empty) attributes. */ |
4757 | for (bool expect_comma = false; ; expect_comma = true) |
4758 | { |
4759 | /* Parse a single attribute. */ |
4760 | tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma); |
4761 | if (attr == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4762 | return attrs; |
4763 | if (!attr) |
4764 | break; |
4765 | attrs = attr; |
4766 | } |
4767 | |
4768 | /* Look for the two `)' tokens. */ |
4769 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4770 | c_parser_consume_token (parser); |
4771 | else |
4772 | { |
4773 | parser->translate_strings_p = save_translate_strings_p; |
4774 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4775 | "expected %<)%>"); |
4776 | return attrs; |
4777 | } |
4778 | if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) |
4779 | c_parser_consume_token (parser); |
4780 | else |
4781 | { |
4782 | parser->translate_strings_p = save_translate_strings_p; |
4783 | c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, |
4784 | "expected %<)%>"); |
4785 | return attrs; |
4786 | } |
4787 | parser->translate_strings_p = save_translate_strings_p; |
4788 | } |
4789 | |
4790 | return attrs; |
4791 | } |
4792 | |
4793 | /* Parse an optional balanced token sequence. |
4794 | |
4795 | balanced-token-sequence: |
4796 | balanced-token |
4797 | balanced-token-sequence balanced-token |
4798 | |
4799 | balanced-token: |
4800 | ( balanced-token-sequence[opt] ) |
4801 | [ balanced-token-sequence[opt] ] |
4802 | { balanced-token-sequence[opt] } |
4803 | any token other than ()[]{} |
4804 | */ |
4805 | |
4806 | static void |
4807 | c_parser_balanced_token_sequence (c_parser *parser) |
4808 | { |
4809 | while (true) |
4810 | { |
4811 | c_token *token = c_parser_peek_token (parser); |
4812 | switch (token->type) |
4813 | { |
4814 | case CPP_OPEN_BRACE: |
4815 | { |
4816 | matching_braces braces; |
4817 | braces.consume_open (parser); |
4818 | c_parser_balanced_token_sequence (parser); |
4819 | braces.require_close (parser); |
4820 | break; |
4821 | } |
4822 | |
4823 | case CPP_OPEN_PAREN: |
4824 | { |
4825 | matching_parens parens; |
4826 | parens.consume_open (parser); |
4827 | c_parser_balanced_token_sequence (parser); |
4828 | parens.require_close (parser); |
4829 | break; |
4830 | } |
4831 | |
4832 | case CPP_OPEN_SQUARE: |
4833 | c_parser_consume_token (parser); |
4834 | c_parser_balanced_token_sequence (parser); |
4835 | c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); |
4836 | break; |
4837 | |
4838 | case CPP_CLOSE_BRACE: |
4839 | case CPP_CLOSE_PAREN: |
4840 | case CPP_CLOSE_SQUARE: |
4841 | case CPP_EOF: |
4842 | return; |
4843 | |
4844 | default: |
4845 | c_parser_consume_token (parser); |
4846 | break; |
4847 | } |
4848 | } |
4849 | } |
4850 | |
4851 | /* Parse standard (C2X) attributes (including GNU attributes in the |
4852 | gnu:: namespace). |
4853 | |
4854 | attribute-specifier-sequence: |
4855 | attribute-specifier-sequence[opt] attribute-specifier |
4856 | |
4857 | attribute-specifier: |
4858 | [ [ attribute-list ] ] |
4859 | |
4860 | attribute-list: |
4861 | attribute[opt] |
4862 | attribute-list, attribute[opt] |
4863 | |
4864 | attribute: |
4865 | attribute-token attribute-argument-clause[opt] |
4866 | |
4867 | attribute-token: |
4868 | standard-attribute |
4869 | attribute-prefixed-token |
4870 | |
4871 | standard-attribute: |
4872 | identifier |
4873 | |
4874 | attribute-prefixed-token: |
4875 | attribute-prefix :: identifier |
4876 | |
4877 | attribute-prefix: |
4878 | identifier |
4879 | |
4880 | attribute-argument-clause: |
4881 | ( balanced-token-sequence[opt] ) |
4882 | |
4883 | Keywords are accepted as identifiers for this purpose. |
4884 | */ |
4885 | |
4886 | static tree |
4887 | c_parser_std_attribute (c_parser *parser, bool for_tm) |
4888 | { |
4889 | c_token *token = c_parser_peek_token (parser); |
4890 | tree ns, name, attribute; |
4891 | |
4892 | /* Parse the attribute-token. */ |
4893 | if (token->type != CPP_NAME && token->type != CPP_KEYWORD) |
4894 | { |
4895 | c_parser_error (parser, "expected identifier"); |
4896 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4897 | } |
4898 | name = canonicalize_attr_name (token->value); |
4899 | c_parser_consume_token (parser); |
4900 | if (c_parser_next_token_is (parser, CPP_SCOPE)) |
4901 | { |
4902 | ns = name; |
4903 | c_parser_consume_token (parser); |
4904 | token = c_parser_peek_token (parser); |
4905 | if (token->type != CPP_NAME && token->type != CPP_KEYWORD) |
4906 | { |
4907 | c_parser_error (parser, "expected identifier"); |
4908 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4909 | } |
4910 | name = canonicalize_attr_name (token->value); |
4911 | c_parser_consume_token (parser); |
4912 | } |
4913 | else |
4914 | ns = NULL_TREE(tree) __null; |
4915 | attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE(tree) __null); |
4916 | |
4917 | /* Parse the arguments, if any. */ |
4918 | const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute)((tree_check ((attribute), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4918, __FUNCTION__, (TREE_LIST)))->list.purpose)); |
4919 | if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) |
4920 | goto out; |
4921 | { |
4922 | location_t open_loc = c_parser_peek_token (parser)->location; |
4923 | matching_parens parens; |
4924 | parens.consume_open (parser); |
4925 | if ((as && as->max_length == 0) |
4926 | /* Special-case the transactional-memory attribute "outer", |
4927 | which is specially handled but not registered as an |
4928 | attribute, to avoid allowing arbitrary balanced token |
4929 | sequences as arguments. */ |
4930 | || is_attribute_p ("outer", name)) |
4931 | { |
4932 | error_at (open_loc, "%qE attribute does not take any arguments", name); |
4933 | parens.skip_until_found_close (parser); |
4934 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4935 | } |
4936 | if (as) |
4937 | { |
4938 | bool takes_identifier |
4939 | = (ns != NULL_TREE(tree) __null |
4940 | && strcmp (IDENTIFIER_POINTER (ns)((const char *) (tree_check ((ns), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4940, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "gnu") == 0 |
4941 | && attribute_takes_identifier_p (name)); |
4942 | bool require_string |
4943 | = (ns == NULL_TREE(tree) __null |
4944 | && (strcmp (IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4944, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "deprecated") == 0 |
4945 | || strcmp (IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4945, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "nodiscard") == 0)); |
4946 | TREE_VALUE (attribute)((tree_check ((attribute), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4946, __FUNCTION__, (TREE_LIST)))->list.value) |
4947 | = c_parser_attribute_arguments (parser, takes_identifier, |
4948 | require_string, false); |
4949 | } |
4950 | else |
4951 | c_parser_balanced_token_sequence (parser); |
4952 | parens.require_close (parser); |
4953 | } |
4954 | out: |
4955 | if (ns == NULL_TREE(tree) __null && !for_tm && !as) |
4956 | { |
4957 | /* An attribute with standard syntax and no namespace specified |
4958 | is a constraint violation if it is not one of the known |
4959 | standard attributes. Diagnose it here with a pedwarn and |
4960 | then discard it to prevent a duplicate warning later. */ |
4961 | pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", |
4962 | name); |
4963 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4964 | } |
4965 | return attribute; |
4966 | } |
4967 | |
4968 | static tree |
4969 | c_parser_std_attribute_specifier (c_parser *parser, bool for_tm) |
4970 | { |
4971 | location_t loc = c_parser_peek_token (parser)->location; |
4972 | if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>")) |
4973 | return NULL_TREE(tree) __null; |
4974 | if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>")) |
4975 | { |
4976 | c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); |
4977 | return NULL_TREE(tree) __null; |
4978 | } |
4979 | if (!for_tm) |
4980 | pedwarn_c11 (loc, OPT_Wpedantic, |
4981 | "ISO C does not support %<[[]]%> attributes before C2X"); |
4982 | tree attributes = NULL_TREE(tree) __null; |
4983 | while (true) |
4984 | { |
4985 | c_token *token = c_parser_peek_token (parser); |
4986 | if (token->type == CPP_CLOSE_SQUARE) |
4987 | break; |
4988 | if (token->type == CPP_COMMA) |
4989 | { |
4990 | c_parser_consume_token (parser); |
4991 | continue; |
4992 | } |
4993 | tree attribute = c_parser_std_attribute (parser, for_tm); |
4994 | if (attribute != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4995 | { |
4996 | TREE_CHAIN (attribute)((contains_struct_check ((attribute), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 4996, __FUNCTION__))->common.chain) = attributes; |
4997 | attributes = attribute; |
4998 | } |
4999 | if (c_parser_next_token_is_not (parser, CPP_COMMA)) |
5000 | break; |
5001 | } |
5002 | c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); |
5003 | c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); |
5004 | return nreverse (attributes); |
5005 | } |
5006 | |
5007 | /* Look past an optional balanced token sequence of raw look-ahead |
5008 | tokens starting with the *Nth token. *N is updated to point to the |
5009 | following token. Return true if such a sequence was found, false |
5010 | if the tokens parsed were not balanced. */ |
5011 | |
5012 | static bool |
5013 | c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n) |
5014 | { |
5015 | while (true) |
5016 | { |
5017 | c_token *token = c_parser_peek_nth_token_raw (parser, *n); |
5018 | switch (token->type) |
5019 | { |
5020 | case CPP_OPEN_BRACE: |
5021 | { |
5022 | ++*n; |
5023 | if (c_parser_check_balanced_raw_token_sequence (parser, n)) |
5024 | { |
5025 | token = c_parser_peek_nth_token_raw (parser, *n); |
5026 | if (token->type == CPP_CLOSE_BRACE) |
5027 | ++*n; |
5028 | else |
5029 | return false; |
5030 | } |
5031 | else |
5032 | return false; |
5033 | break; |
5034 | } |
5035 | |
5036 | case CPP_OPEN_PAREN: |
5037 | { |
5038 | ++*n; |
5039 | if (c_parser_check_balanced_raw_token_sequence (parser, n)) |
5040 | { |
5041 | token = c_parser_peek_nth_token_raw (parser, *n); |
5042 | if (token->type == CPP_CLOSE_PAREN) |
5043 | ++*n; |
5044 | else |
5045 | return false; |
5046 | } |
5047 | else |
5048 | return false; |
5049 | break; |
5050 | } |
5051 | |
5052 | case CPP_OPEN_SQUARE: |
5053 | { |
5054 | ++*n; |
5055 | if (c_parser_check_balanced_raw_token_sequence (parser, n)) |
5056 | { |
5057 | token = c_parser_peek_nth_token_raw (parser, *n); |
5058 | if (token->type == CPP_CLOSE_SQUARE) |
5059 | ++*n; |
5060 | else |
5061 | return false; |
5062 | } |
5063 | else |
5064 | return false; |
5065 | break; |
5066 | } |
5067 | |
5068 | case CPP_CLOSE_BRACE: |
5069 | case CPP_CLOSE_PAREN: |
5070 | case CPP_CLOSE_SQUARE: |
5071 | case CPP_EOF: |
5072 | return true; |
5073 | |
5074 | default: |
5075 | ++*n; |
5076 | break; |
5077 | } |
5078 | } |
5079 | } |
5080 | |
5081 | /* Return whether standard attributes start with the Nth token. */ |
5082 | |
5083 | static bool |
5084 | c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n) |
5085 | { |
5086 | if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE |
5087 | && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE)) |
5088 | return false; |
5089 | /* In C, '[[' must start attributes. In Objective-C, we need to |
5090 | check whether '[[' is matched by ']]'. */ |
5091 | if (!c_dialect_objc ()((c_language & clk_objc) != 0)) |
5092 | return true; |
5093 | n += 2; |
5094 | if (!c_parser_check_balanced_raw_token_sequence (parser, &n)) |
5095 | return false; |
5096 | c_token *token = c_parser_peek_nth_token_raw (parser, n); |
5097 | if (token->type != CPP_CLOSE_SQUARE) |
5098 | return false; |
5099 | token = c_parser_peek_nth_token_raw (parser, n + 1); |
5100 | return token->type == CPP_CLOSE_SQUARE; |
5101 | } |
5102 | |
5103 | static tree |
5104 | c_parser_std_attribute_specifier_sequence (c_parser *parser) |
5105 | { |
5106 | tree attributes = NULL_TREE(tree) __null; |
5107 | do |
5108 | { |
5109 | tree attrs = c_parser_std_attribute_specifier (parser, false); |
5110 | attributes = chainon (attributes, attrs); |
5111 | } |
5112 | while (c_parser_nth_token_starts_std_attributes (parser, 1)); |
5113 | return attributes; |
5114 | } |
5115 | |
5116 | /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK |
5117 | says whether alignment specifiers are OK (only in cases that might |
5118 | be the type name of a compound literal). |
5119 | |
5120 | type-name: |
5121 | specifier-qualifier-list abstract-declarator[opt] |
5122 | */ |
5123 | |
5124 | struct c_type_name * |
5125 | c_parser_type_name (c_parser *parser, bool alignas_ok) |
5126 | { |
5127 | struct c_declspecs *specs = build_null_declspecs (); |
5128 | struct c_declarator *declarator; |
5129 | struct c_type_name *ret; |
5130 | bool dummy = false; |
5131 | c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false, |
5132 | false, true, cla_prefer_type); |
5133 | if (!specs->declspecs_seen_p) |
5134 | { |
5135 | c_parser_error (parser, "expected specifier-qualifier-list"); |
5136 | return NULL__null; |
5137 | } |
5138 | if (specs->type != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
5139 | { |
5140 | pending_xref_error (); |
5141 | finish_declspecs (specs); |
5142 | } |
5143 | declarator = c_parser_declarator (parser, |
5144 | specs->typespec_kind != ctsk_none, |
5145 | C_DTR_ABSTRACT, &dummy); |
5146 | if (declarator == NULL__null) |
5147 | return NULL__null; |
5148 | ret = XOBNEW (&parser_obstack, struct c_type_name)((struct c_type_name *) __extension__ ({ struct obstack *__h = ((&parser_obstack)); __extension__ ({ struct obstack *__o = (__h); size_t __len = ((sizeof (struct c_type_name))); if ( __extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->next_free); }) < __len) _obstack_newchunk (__o, __len); ((void) ((__o)->next_free += (__len))); }); __extension__ ({ struct obstack *__o1 = (__h); void *__value = (void *) __o1->object_base; if (__o1->next_free == __value ) __o1->maybe_empty_object = 1; __o1->next_free = ((sizeof (ptrdiff_t) < sizeof (void *) ? (__o1->object_base) : ( char *) 0) + (((__o1->next_free) - (sizeof (ptrdiff_t) < sizeof (void *) ? (__o1->object_base) : (char *) 0) + (__o1 ->alignment_mask)) & ~(__o1->alignment_mask))); if ( (size_t) (__o1->next_free - (char *) __o1->chunk) > ( size_t) (__o1->chunk_limit - (char *) __o1->chunk)) __o1 ->next_free = __o1->chunk_limit; __o1->object_base = __o1->next_free; __value; }); })); |
5149 | ret->specs = specs; |
5150 | ret->declarator = declarator; |
5151 | return ret; |
5152 | } |
5153 | |
5154 | /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9). |
5155 | |
5156 | initializer: |
5157 | assignment-expression |
5158 | { initializer-list } |
5159 | { initializer-list , } |
5160 | |
5161 | initializer-list: |
5162 | designation[opt] initializer |
5163 | initializer-list , designation[opt] initializer |
5164 | |
5165 | designation: |
5166 | designator-list = |
5167 | |
5168 | designator-list: |
5169 | designator |
5170 | designator-list designator |
5171 | |
5172 | designator: |
5173 | array-designator |
5174 | . identifier |
5175 | |
5176 | array-designator: |
5177 | [ constant-expression ] |
5178 | |
5179 | GNU extensions: |
5180 | |
5181 | initializer: |
5182 | { } |
5183 | |
5184 | designation: |
5185 | array-designator |
5186 | identifier : |
5187 | |
5188 | array-designator: |
5189 | [ constant-expression ... constant-expression ] |
5190 | |
5191 | Any expression without commas is accepted in the syntax for the |
5192 | constant-expressions, with non-constant expressions rejected later. |
5193 | |
5194 | This function is only used for top-level initializers; for nested |
5195 | ones, see c_parser_initval. */ |
5196 | |
5197 | static struct c_expr |
5198 | c_parser_initializer (c_parser *parser) |
5199 | { |
5200 | if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) |
5201 | return c_parser_braced_init (parser, NULL_TREE(tree) __null, false, NULL__null); |
5202 | else |
5203 | { |
5204 | struct c_expr ret; |
5205 | location_t loc = c_parser_peek_token (parser)->location; |
5206 | ret = c_parser_expr_no_commas (parser, NULL__null); |
5207 | if (TREE_CODE (ret.value)((enum tree_code) (ret.value)->base.code) != STRING_CST |
5208 | && TREE_CODE (ret.value)((enum tree_code) (ret.value)->base.code) != COMPOUND_LITERAL_EXPR) |
5209 | ret = convert_lvalue_to_rvalue (loc, ret, true, true); |
5210 | return ret; |
5211 | } |
5212 | } |
5213 | |
5214 | /* The location of the last comma within the current initializer list, |
5215 | or UNKNOWN_LOCATION if not within one. */ |
5216 | |
5217 | location_t last_init_list_comma; |
5218 | |
5219 | /* Parse a braced initializer list. TYPE is the type specified for a |
5220 | compound literal, and NULL_TREE for other initializers and for |
5221 | nested braced lists. NESTED_P is true for nested braced lists, |
5222 | false for the list of a compound literal or the list that is the |
5223 | top-level initializer in a declaration. */ |
5224 | |
5225 | static struct c_expr |
5226 | c_parser_braced_init (c_parser *parser, tree type, bool nested_p, |
5227 | struct obstack *outer_obstack) |
5228 | { |
5229 | struct c_expr ret; |
5230 | struct obstack braced_init_obstack; |
5231 | location_t brace_loc = c_parser_peek_token (parser)->location; |
5232 | gcc_obstack_init (&braced_init_obstack)_obstack_begin (((&braced_init_obstack)), (memory_block_pool ::block_size), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free )); |
5233 | gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE))((void)(!(c_parser_next_token_is (parser, CPP_OPEN_BRACE)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5233, __FUNCTION__), 0 : 0)); |
5234 | matching_braces braces; |
5235 | braces.consume_open (parser); |
5236 | if (nested_p) |
5237 | { |
5238 | finish_implicit_inits (brace_loc, outer_obstack); |
5239 | push_init_level (brace_loc, 0, &braced_init_obstack); |
5240 | } |
5241 | else |
5242 | really_start_incremental_init (type); |
5243 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
5244 | { |
5245 | pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces"); |
5246 | } |
5247 | else |
5248 | { |
5249 | /* Parse a non-empty initializer list, possibly with a trailing |
5250 | comma. */ |
5251 | while (true) |
5252 | { |
5253 | c_parser_initelt (parser, &braced_init_obstack); |
5254 | if (parser->error) |
5255 | break; |
5256 | if (c_parser_next_token_is (parser, CPP_COMMA)) |
5257 | { |
5258 | last_init_list_comma = c_parser_peek_token (parser)->location; |
5259 | c_parser_consume_token (parser); |
5260 | } |
5261 | else |
5262 | break; |
5263 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
5264 | break; |
5265 | } |
5266 | } |
5267 | c_token *next_tok = c_parser_peek_token (parser); |
5268 | if (next_tok->type != CPP_CLOSE_BRACE) |
5269 | { |
5270 | ret.set_error (); |
5271 | ret.original_code = ERROR_MARK; |
5272 | ret.original_type = NULL__null; |
5273 | braces.skip_until_found_close (parser); |
5274 | pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma); |
5275 | obstack_free (&braced_init_obstack, NULL)__extension__ ({ struct obstack *__o = (&braced_init_obstack ); void *__obj = (void *) (__null); if (__obj > (void *) __o ->chunk && __obj < (void *) __o->chunk_limit ) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o, __obj); }); |
5276 | return ret; |
5277 | } |
5278 | location_t close_loc = next_tok->location; |
5279 | c_parser_consume_token (parser); |
5280 | ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc); |
5281 | obstack_free (&braced_init_obstack, NULL)__extension__ ({ struct obstack *__o = (&braced_init_obstack ); void *__obj = (void *) (__null); if (__obj > (void *) __o ->chunk && __obj < (void *) __o->chunk_limit ) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o, __obj); }); |
5282 | set_c_expr_source_range (&ret, brace_loc, close_loc); |
5283 | return ret; |
5284 | } |
5285 | |
5286 | /* Parse a nested initializer, including designators. */ |
5287 | |
5288 | static void |
5289 | c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) |
5290 | { |
5291 | /* Parse any designator or designator list. A single array |
5292 | designator may have the subsequent "=" omitted in GNU C, but a |
5293 | longer list or a structure member designator may not. */ |
5294 | if (c_parser_next_token_is (parser, CPP_NAME) |
5295 | && c_parser_peek_2nd_token (parser)->type == CPP_COLON) |
5296 | { |
5297 | /* Old-style structure member designator. */ |
5298 | set_init_label (c_parser_peek_token (parser)->location, |
5299 | c_parser_peek_token (parser)->value, |
5300 | c_parser_peek_token (parser)->location, |
5301 | braced_init_obstack); |
5302 | /* Use the colon as the error location. */ |
5303 | pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic, |
5304 | "obsolete use of designated initializer with %<:%>"); |
5305 | c_parser_consume_token (parser); |
5306 | c_parser_consume_token (parser); |
5307 | } |
5308 | else |
5309 | { |
5310 | /* des_seen is 0 if there have been no designators, 1 if there |
5311 | has been a single array designator and 2 otherwise. */ |
5312 | int des_seen = 0; |
5313 | /* Location of a designator. */ |
5314 | location_t des_loc = UNKNOWN_LOCATION((location_t) 0); /* Quiet warning. */ |
5315 | while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) |
5316 | || c_parser_next_token_is (parser, CPP_DOT)) |
5317 | { |
5318 | int des_prev = des_seen; |
5319 | if (!des_seen) |
5320 | des_loc = c_parser_peek_token (parser)->location; |
5321 | if (des_seen < 2) |
5322 | des_seen++; |
5323 | if (c_parser_next_token_is (parser, CPP_DOT)) |
5324 | { |
5325 | des_seen = 2; |
5326 | c_parser_consume_token (parser); |
5327 | if (c_parser_next_token_is (parser, CPP_NAME)) |
5328 | { |
5329 | set_init_label (des_loc, c_parser_peek_token (parser)->value, |
5330 | c_parser_peek_token (parser)->location, |
5331 | braced_init_obstack); |
5332 | c_parser_consume_token (parser); |
5333 | } |
5334 | else |
5335 | { |
5336 | struct c_expr init; |
5337 | init.set_error (); |
5338 | init.original_code = ERROR_MARK; |
5339 | init.original_type = NULL__null; |
5340 | c_parser_error (parser, "expected identifier"); |
5341 | c_parser_skip_until_found (parser, CPP_COMMA, NULL__null); |
5342 | process_init_element (input_location, init, false, |
5343 | braced_init_obstack); |
5344 | return; |
5345 | } |
5346 | } |
5347 | else |
5348 | { |
5349 | tree first, second; |
5350 | location_t ellipsis_loc = UNKNOWN_LOCATION((location_t) 0); /* Quiet warning. */ |
5351 | location_t array_index_loc = UNKNOWN_LOCATION((location_t) 0); |
5352 | /* ??? Following the old parser, [ objc-receiver |
5353 | objc-message-args ] is accepted as an initializer, |
5354 | being distinguished from a designator by what follows |
5355 | the first assignment expression inside the square |
5356 | brackets, but after a first array designator a |
5357 | subsequent square bracket is for Objective-C taken to |
5358 | start an expression, using the obsolete form of |
5359 | designated initializer without '=', rather than |
5360 | possibly being a second level of designation: in LALR |
5361 | terms, the '[' is shifted rather than reducing |
5362 | designator to designator-list. */ |
5363 | if (des_prev == 1 && c_dialect_objc ()((c_language & clk_objc) != 0)) |
5364 | { |
5365 | des_seen = des_prev; |
5366 | break; |
5367 | } |
5368 | if (des_prev == 0 && c_dialect_objc ()((c_language & clk_objc) != 0)) |
5369 | { |
5370 | /* This might be an array designator or an |
5371 | Objective-C message expression. If the former, |
5372 | continue parsing here; if the latter, parse the |
5373 | remainder of the initializer given the starting |
5374 | primary-expression. ??? It might make sense to |
5375 | distinguish when des_prev == 1 as well; see |
5376 | previous comment. */ |
5377 | tree rec, args; |
5378 | struct c_expr mexpr; |
5379 | c_parser_consume_token (parser); |
5380 | if (c_parser_peek_token (parser)->type == CPP_NAME |
5381 | && ((c_parser_peek_token (parser)->id_kind |
5382 | == C_ID_TYPENAME) |
5383 | || (c_parser_peek_token (parser)->id_kind |
5384 | == C_ID_CLASSNAME))) |
5385 | { |
5386 | /* Type name receiver. */ |
5387 | tree id = c_parser_peek_token (parser)->value; |
5388 | c_parser_consume_token (parser); |
5389 | rec = objc_get_class_reference (id); |
5390 | goto parse_message_args; |
5391 | } |
5392 | first = c_parser_expr_no_commas (parser, NULL__null).value; |
5393 | mark_exp_read (first); |
5394 | if (c_parser_next_token_is (parser, CPP_ELLIPSIS) |
5395 | || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) |
5396 | goto array_desig_after_first; |
5397 | /* Expression receiver. So far only one part |
5398 | without commas has been parsed; there might be |
5399 | more of the expression. */ |
5400 | rec = first; |
5401 | while (c_parser_next_token_is (parser, CPP_COMMA)) |
5402 | { |
5403 | struct c_expr next; |
5404 | location_t comma_loc, exp_loc; |
5405 | comma_loc = c_parser_peek_token (parser)->location; |
5406 | c_parser_consume_token (parser); |
5407 | exp_loc = c_parser_peek_token (parser)->location; |
5408 | next = c_parser_expr_no_commas (parser, NULL__null); |
5409 | next = convert_lvalue_to_rvalue (exp_loc, next, |
5410 | true, true); |
5411 | rec = build_compound_expr (comma_loc, rec, next.value); |
5412 | } |
5413 | parse_message_args: |
5414 | /* Now parse the objc-message-args. */ |
5415 | args = c_parser_objc_message_args (parser); |
5416 | c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, |
5417 | "expected %<]%>"); |
5418 | mexpr.value |
5419 | = objc_build_message_expr (rec, args); |
5420 | mexpr.original_code = ERROR_MARK; |
5421 | mexpr.original_type = NULL__null; |
5422 | /* Now parse and process the remainder of the |
5423 | initializer, starting with this message |
5424 | expression as a primary-expression. */ |
5425 | c_parser_initval (parser, &mexpr, braced_init_obstack); |
5426 | return; |
5427 | } |
5428 | c_parser_consume_token (parser); |
5429 | array_index_loc = c_parser_peek_token (parser)->location; |
5430 | first = c_parser_expr_no_commas (parser, NULL__null).value; |
5431 | mark_exp_read (first); |
5432 | array_desig_after_first: |
5433 | if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) |
5434 | { |
5435 | ellipsis_loc = c_parser_peek_token (parser)->location; |
5436 | c_parser_consume_token (parser); |
5437 | second = c_parser_expr_no_commas (parser, NULL__null).value; |
5438 | mark_exp_read (second); |
5439 | } |
5440 | else |
5441 | second = NULL_TREE(tree) __null; |
5442 | if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) |
5443 | { |
5444 | c_parser_consume_token (parser); |
5445 | set_init_index (array_index_loc, first, second, |
5446 | braced_init_obstack); |
5447 | if (second) |
5448 | pedwarn (ellipsis_loc, OPT_Wpedantic, |
5449 | "ISO C forbids specifying range of elements to initialize"); |
5450 | } |
5451 | else |
5452 | c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, |
5453 | "expected %<]%>"); |
5454 | } |
5455 | } |
5456 | if (des_seen >= 1) |
5457 | { |
5458 | if (c_parser_next_token_is (parser, CPP_EQ)) |
5459 | { |
5460 | pedwarn_c90 (des_loc, OPT_Wpedantic, |
5461 | "ISO C90 forbids specifying subobject " |
5462 | "to initialize"); |
5463 | c_parser_consume_token (parser); |
5464 | } |
5465 | else |
5466 | { |
5467 | if (des_seen == 1) |
5468 | pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, |
5469 | "obsolete use of designated initializer without %<=%>"); |
5470 | else |
5471 | { |
5472 | struct c_expr init; |
5473 | init.set_error (); |
5474 | init.original_code = ERROR_MARK; |
5475 | init.original_type = NULL__null; |
5476 | c_parser_error (parser, "expected %<=%>"); |
5477 | c_parser_skip_until_found (parser, CPP_COMMA, NULL__null); |
5478 | process_init_element (input_location, init, false, |
5479 | braced_init_obstack); |
5480 | return; |
5481 | } |
5482 | } |
5483 | } |
5484 | } |
5485 | c_parser_initval (parser, NULL__null, braced_init_obstack); |
5486 | } |
5487 | |
5488 | /* Parse a nested initializer; as c_parser_initializer but parses |
5489 | initializers within braced lists, after any designators have been |
5490 | applied. If AFTER is not NULL then it is an Objective-C message |
5491 | expression which is the primary-expression starting the |
5492 | initializer. */ |
5493 | |
5494 | static void |
5495 | c_parser_initval (c_parser *parser, struct c_expr *after, |
5496 | struct obstack * braced_init_obstack) |
5497 | { |
5498 | struct c_expr init; |
5499 | gcc_assert (!after || c_dialect_objc ())((void)(!(!after || ((c_language & clk_objc) != 0)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5499, __FUNCTION__), 0 : 0)); |
5500 | location_t loc = c_parser_peek_token (parser)->location; |
5501 | |
5502 | if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after) |
5503 | init = c_parser_braced_init (parser, NULL_TREE(tree) __null, true, |
5504 | braced_init_obstack); |
5505 | else |
5506 | { |
5507 | init = c_parser_expr_no_commas (parser, after); |
5508 | if (init.value != NULL_TREE(tree) __null |
5509 | && TREE_CODE (init.value)((enum tree_code) (init.value)->base.code) != STRING_CST |
5510 | && TREE_CODE (init.value)((enum tree_code) (init.value)->base.code) != COMPOUND_LITERAL_EXPR) |
5511 | init = convert_lvalue_to_rvalue (loc, init, true, true); |
5512 | } |
5513 | process_init_element (loc, init, false, braced_init_obstack); |
5514 | } |
5515 | |
5516 | /* Parse a compound statement (possibly a function body) (C90 6.6.2, |
5517 | C99 6.8.2, C11 6.8.2, C2X 6.8.2). |
5518 | |
5519 | compound-statement: |
5520 | { block-item-list[opt] } |
5521 | { label-declarations block-item-list } |
5522 | |
5523 | block-item-list: |
5524 | block-item |
5525 | block-item-list block-item |
5526 | |
5527 | block-item: |
5528 | label |
5529 | nested-declaration |
5530 | statement |
5531 | |
5532 | nested-declaration: |
5533 | declaration |
5534 | |
5535 | GNU extensions: |
5536 | |
5537 | compound-statement: |
5538 | { label-declarations block-item-list } |
5539 | |
5540 | nested-declaration: |
5541 | __extension__ nested-declaration |
5542 | nested-function-definition |
5543 | |
5544 | label-declarations: |
5545 | label-declaration |
5546 | label-declarations label-declaration |
5547 | |
5548 | label-declaration: |
5549 | __label__ identifier-list ; |
5550 | |
5551 | Allowing the mixing of declarations and code is new in C99. The |
5552 | GNU syntax also permits (not shown above) labels at the end of |
5553 | compound statements, which yield an error. We don't allow labels |
5554 | on declarations; this might seem like a natural extension, but |
5555 | there would be a conflict between gnu-attributes on the label and |
5556 | prefix gnu-attributes on the declaration. ??? The syntax follows the |
5557 | old parser in requiring something after label declarations. |
5558 | Although they are erroneous if the labels declared aren't defined, |
5559 | is it useful for the syntax to be this way? |
5560 | |
5561 | OpenACC: |
5562 | |
5563 | block-item: |
5564 | openacc-directive |
5565 | |
5566 | openacc-directive: |
5567 | update-directive |
5568 | |
5569 | OpenMP: |
5570 | |
5571 | block-item: |
5572 | openmp-directive |
5573 | |
5574 | openmp-directive: |
5575 | barrier-directive |
5576 | flush-directive |
5577 | taskwait-directive |
5578 | taskyield-directive |
5579 | cancel-directive |
5580 | cancellation-point-directive */ |
5581 | |
5582 | static tree |
5583 | c_parser_compound_statement (c_parser *parser, location_t *endlocp) |
5584 | { |
5585 | tree stmt; |
5586 | location_t brace_loc; |
5587 | brace_loc = c_parser_peek_token (parser)->location; |
5588 | if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) |
5589 | { |
5590 | /* Ensure a scope is entered and left anyway to avoid confusion |
5591 | if we have just prepared to enter a function body. */ |
5592 | stmt = c_begin_compound_stmt (true); |
5593 | c_end_compound_stmt (brace_loc, stmt, true); |
5594 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5595 | } |
5596 | stmt = c_begin_compound_stmt (true); |
5597 | location_t end_loc = c_parser_compound_statement_nostart (parser); |
5598 | if (endlocp) |
5599 | *endlocp = end_loc; |
5600 | |
5601 | return c_end_compound_stmt (brace_loc, stmt, true); |
5602 | } |
5603 | |
5604 | /* Parse a compound statement except for the opening brace. This is |
5605 | used for parsing both compound statements and statement expressions |
5606 | (which follow different paths to handling the opening). */ |
5607 | |
5608 | static location_t |
5609 | c_parser_compound_statement_nostart (c_parser *parser) |
5610 | { |
5611 | bool last_stmt = false; |
5612 | bool last_label = false; |
5613 | bool save_valid_for_pragma = valid_location_for_stdc_pragma_p (); |
5614 | location_t label_loc = UNKNOWN_LOCATION((location_t) 0); /* Quiet warning. */ |
5615 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
5616 | { |
5617 | location_t endloc = c_parser_peek_token (parser)->location; |
5618 | add_debug_begin_stmt (endloc); |
5619 | c_parser_consume_token (parser); |
5620 | return endloc; |
5621 | } |
5622 | mark_valid_location_for_stdc_pragma (true); |
5623 | if (c_parser_next_token_is_keyword (parser, RID_LABEL)) |
5624 | { |
5625 | /* Read zero or more forward-declarations for labels that nested |
5626 | functions can jump to. */ |
5627 | mark_valid_location_for_stdc_pragma (false); |
5628 | while (c_parser_next_token_is_keyword (parser, RID_LABEL)) |
5629 | { |
5630 | label_loc = c_parser_peek_token (parser)->location; |
5631 | c_parser_consume_token (parser); |
5632 | /* Any identifiers, including those declared as type names, |
5633 | are OK here. */ |
5634 | while (true) |
5635 | { |
5636 | tree label; |
5637 | if (c_parser_next_token_is_not (parser, CPP_NAME)) |
5638 | { |
5639 | c_parser_error (parser, "expected identifier"); |
5640 | break; |
5641 | } |
5642 | label |
5643 | = declare_label (c_parser_peek_token (parser)->value); |
5644 | C_DECLARED_LABEL_FLAG (label)((tree_not_check2 ((label), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5644, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1) = 1; |
5645 | add_stmt (build_stmt (label_loc, DECL_EXPR, label)); |
5646 | c_parser_consume_token (parser); |
5647 | if (c_parser_next_token_is (parser, CPP_COMMA)) |
5648 | c_parser_consume_token (parser); |
5649 | else |
5650 | break; |
5651 | } |
5652 | c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); |
5653 | } |
5654 | pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations"); |
5655 | } |
5656 | /* We must now have at least one statement, label or declaration. */ |
5657 | if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) |
5658 | { |
5659 | mark_valid_location_for_stdc_pragma (save_valid_for_pragma); |
5660 | c_parser_error (parser, "expected declaration or statement"); |
5661 | location_t endloc = c_parser_peek_token (parser)->location; |
5662 | c_parser_consume_token (parser); |
5663 | return endloc; |
5664 | } |
5665 | while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) |
5666 | { |
5667 | location_t loc = c_parser_peek_token (parser)->location; |
5668 | loc = expansion_point_location_if_in_system_header (loc); |
5669 | /* Standard attributes may start a label, statement or declaration. */ |
5670 | bool have_std_attrs |
5671 | = c_parser_nth_token_starts_std_attributes (parser, 1); |
5672 | tree std_attrs = NULL_TREE(tree) __null; |
5673 | if (have_std_attrs) |
5674 | std_attrs = c_parser_std_attribute_specifier_sequence (parser); |
5675 | if (c_parser_next_token_is_keyword (parser, RID_CASE) |
5676 | || c_parser_next_token_is_keyword (parser, RID_DEFAULT) |
5677 | || (c_parser_next_token_is (parser, CPP_NAME) |
5678 | && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) |
5679 | { |
5680 | if (c_parser_next_token_is_keyword (parser, RID_CASE)) |
5681 | label_loc = c_parser_peek_2nd_token (parser)->location; |
5682 | else |
5683 | label_loc = c_parser_peek_token (parser)->location; |
5684 | last_label = true; |
5685 | last_stmt = false; |
5686 | mark_valid_location_for_stdc_pragma (false); |
5687 | c_parser_label (parser, std_attrs); |
5688 | } |
5689 | else if (c_parser_next_tokens_start_declaration (parser) |
5690 | || (have_std_attrs |
5691 | && c_parser_next_token_is (parser, CPP_SEMICOLON))) |
5692 | { |
5693 | if (last_label) |
5694 | pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic, |
5695 | "a label can only be part of a statement and " |
5696 | "a declaration is not a statement"); |
5697 | |
5698 | mark_valid_location_for_stdc_pragma (false); |
5699 | bool fallthru_attr_p = false; |
5700 | c_parser_declaration_or_fndef (parser, true, !have_std_attrs, |
5701 | true, true, true, NULL__null, |
5702 | vNULL, have_std_attrs, std_attrs, |
5703 | NULL__null, &fallthru_attr_p); |
5704 | |
5705 | if (last_stmt && !fallthru_attr_p) |
5706 | pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, |
5707 | "ISO C90 forbids mixed declarations and code"); |
5708 | last_stmt = fallthru_attr_p; |
5709 | last_label = false; |
5710 | } |
5711 | else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) |
5712 | { |
5713 | /* __extension__ can start a declaration, but is also an |
5714 | unary operator that can start an expression. Consume all |
5715 | but the last of a possible series of __extension__ to |
5716 | determine which. If standard attributes have already |
5717 | been seen, it must start a statement, not a declaration, |
5718 | but standard attributes starting a declaration may appear |
5719 | after __extension__. */ |
5720 | while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD |
5721 | && (c_parser_peek_2nd_token (parser)->keyword |
5722 | == RID_EXTENSION)) |
5723 | c_parser_consume_token (parser); |
5724 | if (!have_std_attrs |
5725 | && (c_token_starts_declaration (c_parser_peek_2nd_token (parser)) |
5726 | || c_parser_nth_token_starts_std_attributes (parser, 2))) |
5727 | { |
5728 | int ext; |
5729 | ext = disable_extension_diagnostics (); |
5730 | c_parser_consume_token (parser); |
5731 | last_label = false; |
5732 | mark_valid_location_for_stdc_pragma (false); |
5733 | c_parser_declaration_or_fndef (parser, true, true, true, true, |
5734 | true, NULL__null, vNULL); |
5735 | /* Following the old parser, __extension__ does not |
5736 | disable this diagnostic. */ |
5737 | restore_extension_diagnostics (ext); |
5738 | if (last_stmt) |
5739 | pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, |
5740 | "ISO C90 forbids mixed declarations and code"); |
5741 | last_stmt = false; |
5742 | } |
5743 | else |
5744 | goto statement; |
5745 | } |
5746 | else if (c_parser_next_token_is (parser, CPP_PRAGMA)) |
5747 | { |
5748 | if (have_std_attrs) |
5749 | c_parser_error (parser, "expected declaration or statement"); |
5750 | /* External pragmas, and some omp pragmas, are not associated |
5751 | with regular c code, and so are not to be considered statements |
5752 | syntactically. This ensures that the user doesn't put them |
5753 | places that would turn into syntax errors if the directive |
5754 | were ignored. */ |
5755 | if (c_parser_pragma (parser, |
5756 | last_label ? pragma_stmt : pragma_compound, |
5757 | NULL__null)) |
5758 | last_label = false, last_stmt = true; |
5759 | } |
5760 | else if (c_parser_next_token_is (parser, CPP_EOF)) |
5761 | { |
5762 | mark_valid_location_for_stdc_pragma (save_valid_for_pragma); |
5763 | c_parser_error (parser, "expected declaration or statement"); |
5764 | return c_parser_peek_token (parser)->location; |
5765 | } |
5766 | else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) |
5767 | { |
5768 | if (parser->in_if_block) |
5769 | { |
5770 | mark_valid_location_for_stdc_pragma (save_valid_for_pragma); |
5771 | error_at (loc, "expected %<}%> before %<else%>"); |
5772 | return c_parser_peek_token (parser)->location; |
5773 | } |
5774 | else |
5775 | { |
5776 | error_at (loc, "%<else%> without a previous %<if%>"); |
5777 | c_parser_consume_token (parser); |
5778 | continue; |
5779 | } |
5780 | } |
5781 | else |
5782 | { |
5783 | statement: |
5784 | c_warn_unused_attributes (std_attrs); |
5785 | last_label = false; |
5786 | last_stmt = true; |
5787 | mark_valid_location_for_stdc_pragma (false); |
5788 | c_parser_statement_after_labels (parser, NULL__null); |
5789 | } |
5790 | |
5791 | parser->error = false; |
5792 | } |
5793 | if (last_label) |
5794 | pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement"); |
5795 | location_t endloc = c_parser_peek_token (parser)->location; |
5796 | c_parser_consume_token (parser); |
5797 | /* Restore the value we started with. */ |
5798 | mark_valid_location_for_stdc_pragma (save_valid_for_pragma); |
5799 | return endloc; |
5800 | } |
5801 | |
5802 | /* Parse all consecutive labels, possibly preceded by standard |
5803 | attributes. In this context, a statement is required, not a |
5804 | declaration, so attributes must be followed by a statement that is |
5805 | not just a semicolon. */ |
5806 | |
5807 | static void |
5808 | c_parser_all_labels (c_parser *parser) |
5809 | { |
5810 | tree std_attrs = NULL__null; |
5811 | if (c_parser_nth_token_starts_std_attributes (parser, 1)) |
5812 | { |
5813 | std_attrs = c_parser_std_attribute_specifier_sequence (parser); |
5814 | if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
5815 | c_parser_error (parser, "expected statement"); |
5816 | } |
5817 | while (c_parser_next_token_is_keyword (parser, RID_CASE) |
5818 | || c_parser_next_token_is_keyword (parser, RID_DEFAULT) |
5819 | || (c_parser_next_token_is (parser, CPP_NAME) |
5820 | && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) |
5821 | { |
5822 | c_parser_label (parser, std_attrs); |
5823 | std_attrs = NULL__null; |
5824 | if (c_parser_nth_token_starts_std_attributes (parser, 1)) |
5825 | { |
5826 | std_attrs = c_parser_std_attribute_specifier_sequence (parser); |
5827 | if (c_parser_next_token_is (parser, CPP_SEMICOLON)) |
5828 | c_parser_error (parser, "expected statement"); |
5829 | } |
5830 | } |
5831 | if (std_attrs) |
5832 | c_warn_unused_attributes (std_attrs); |
5833 | } |
5834 | |
5835 | /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1). |
5836 | |
5837 | label: |
5838 | identifier : gnu-attributes[opt] |
5839 | case constant-expression : |
5840 | default : |
5841 | |
5842 | GNU extensions: |
5843 | |
5844 | label: |
5845 | case constant-expression ... constant-expression : |
5846 | |
5847 | The use of gnu-attributes on labels is a GNU extension. The syntax in |
5848 | GNU C accepts any expressions without commas, non-constant |
5849 | expressions being rejected later. Any standard |
5850 | attribute-specifier-sequence before the first label has been parsed |
5851 | in the caller, to distinguish statements from declarations. Any |
5852 | attribute-specifier-sequence after the label is parsed in this |
5853 | function. */ |
5854 | static void |
5855 | c_parser_label (c_parser *parser, tree std_attrs) |
5856 | { |
5857 | location_t loc1 = c_parser_peek_token (parser)->location; |
5858 | tree label = NULL_TREE(tree) __null; |
5859 | |
5860 | /* Remember whether this case or a user-defined label is allowed to fall |
5861 | through to. */ |
5862 | bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH(1 << 5); |
5863 | |
5864 | if (c_parser_next_token_is_keyword (parser, RID_CASE)) |
5865 | { |
5866 | tree exp1, exp2; |
5867 | c_parser_consume_token (parser); |
5868 | exp1 = c_parser_expr_no_commas (parser, NULL__null).value; |
5869 | if (c_parser_next_token_is (parser, CPP_COLON)) |
5870 | { |
5871 | c_parser_consume_token (parser); |
5872 | label = do_case (loc1, exp1, NULL_TREE(tree) __null); |
5873 | } |
5874 | else if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) |
5875 | { |
5876 | c_parser_consume_token (parser); |
5877 | exp2 = c_parser_expr_no_commas (parser, NULL__null).value; |
5878 | if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) |
5879 | label = do_case (loc1, exp1, exp2); |
5880 | } |
5881 | else |
5882 | c_parser_error (parser, "expected %<:%> or %<...%>"); |
5883 | } |
5884 | else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) |
5885 | { |
5886 | c_parser_consume_token (parser); |
5887 | if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) |
5888 | label = do_case (loc1, NULL_TREE(tree) __null, NULL_TREE(tree) __null); |
5889 | } |
5890 | else |
5891 | { |
5892 | tree name = c_parser_peek_token (parser)->value; |
5893 | tree tlab; |
5894 | tree attrs; |
5895 | location_t loc2 = c_parser_peek_token (parser)->location; |
5896 | gcc_assert (c_parser_next_token_is (parser, CPP_NAME))((void)(!(c_parser_next_token_is (parser, CPP_NAME)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5896, __FUNCTION__), 0 : 0)); |
5897 | c_parser_consume_token (parser); |
5898 | gcc_assert (c_parser_next_token_is (parser, CPP_COLON))((void)(!(c_parser_next_token_is (parser, CPP_COLON)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5898, __FUNCTION__), 0 : 0)); |
5899 | c_parser_consume_token (parser); |
5900 | attrs = c_parser_gnu_attributes (parser); |
5901 | tlab = define_label (loc2, name); |
5902 | if (tlab) |
5903 | { |
5904 | decl_attributes (&tlab, attrs, 0); |
5905 | decl_attributes (&tlab, std_attrs, 0); |
5906 | label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab)); |
5907 | } |
5908 | if (attrs |
5909 | && c_parser_next_tokens_start_declaration (parser)) |
5910 | warning_at (loc2, OPT_Wattributes, "GNU-style attribute between" |
5911 | " label and declaration appertains to the label"); |
5912 | } |
5913 | if (label) |
5914 | { |
5915 | if (TREE_CODE (label)((enum tree_code) (label)->base.code) == LABEL_EXPR) |
5916 | FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label))((tree_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((label), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5916, __FUNCTION__, (LABEL_EXPR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5916, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5916, __FUNCTION__, (LABEL_DECL)))->base.private_flag) = fallthrough_p; |
5917 | else |
5918 | FALLTHROUGH_LABEL_P (CASE_LABEL (label))((tree_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((label), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5918, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5918, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c/c-parser.c" , 5918, __FUNCTION__, (LABEL_DECL)))->base.private_flag) = fallthrough_p; |
5919 | } |
5920 | } |
5921 | |
5922 | /* Parse a statement (C90 6.6, C99 6.8, C11 6.8). |
5923 | |
5924 | statement: |
5925 | labeled-statement |
5926 | attribute-specifier-sequence[opt] compound-statement |
5927 | expression-statement |
5928 | attribute-specifier-sequence[opt] selection-statement |
5929 | attribute-specifier-sequence[opt] iteration-statement |
5930 | attribute-specifier-sequence[opt] jump-statement |
5931 | |
5932 | labeled-statement: |
5933 | attribute-specifier-sequence[opt] label statement |
5934 | |
5935 | expression-statement: |
5936 | expression[opt] ; |
5937 | attribute-specifier-sequence expression ; |
5938 | |
5939 | selection-statement: |
5940 | if-statement |
5941 | switch-statement |
5942 | |
5943 | iteration-statement: |
5944 | while-statement |
5945 | do-statement |
5946 | for-statement |
5947 | |
5948 | jump-statement: |
5949 | goto identifier ; |
5950 | continue ; |
5951 | break ; |
5952 | return expression[opt] ; |
5953 | |
5954 | GNU extensions: |
5955 | |
5956 | statement: |
5957 | attribute-specifier-sequence[opt] asm-statement |
5958 | |
5959 | jump-statement: |
5960 | goto * expression ; |
5961 | |
5962 | expression-statement: |
5963 | gnu-attributes ; |
5964 | |
5965 | Objective-C: |
5966 | |
5967 | statement: |
5968 | attribute-specifier-sequence[opt] objc-throw-statement |
5969 | attribute-specifier-sequence[opt] objc-try-catch-statement |
5970 | attribute-specifier-sequence[opt] objc-synchronized-statement |
5971 | |
5972 | objc-throw-statement: |
5973 | @throw expression ; |
5974 | @throw ; |
5975 | |
5976 | OpenACC: |
5977 | |
5978 | statement: |
5979 | attribute-specifier-sequence[opt] openacc-construct |
5980 | |
5981 | openacc-construct: |
5982 | parallel-construct |
5983 | kernels-construct |
5984 | data-construct |
5985 | loop-construct |
5986 | |
5987 | parallel-construct: |
5988 | parallel-directive structured-block |
5989 | |
5990 | kernels-construct: |
5991 | kernels-directive structured-block |
5992 | |
5993 | data-construct: |
5994 | data-directive structured-block |
5995 | |
5996 | loop-construct: |
5997 | loop-directive structured-block |
5998 | |
5999 | OpenMP: |
6000 | |
6001 | statement: |
6002 | attribute-specifier-sequence[opt] openmp-construct |
6003 | |
6004 | openmp-construct: |
6005 | parallel-construct |
6006 | for-construct |
6007 | simd-construct |
6008 | for-simd-construct |
6009 | sections-construct |
6010 | single-construct |
6011 | parallel-for-construct |
6012 | parallel-for-simd-construct |
6013 | parallel-sections-construct |
6014 | master-construct |
6015 | critical-construct |
6016 | atomic-construct |
6017 | ordered-construct |
6018 | |
6019 | parallel-construct: |
6020 | parallel-directive structured-block |
6021 | |
6022 | for-construct: |
6023 | for-directive iteration-statement |
6024 | |
6025 | simd-construct: |
6026 | simd-directive iteration-statements |
6027 | |
6028 | for-simd-construct: |
6029 | for-simd-directive iteration-statements |
6030 | |
6031 | sections-construct: |
6032 | sections-directive section-scope |
6033 | |
6034 | single-construct: |
6035 | single-directive structured-block |
6036 | |
6037 | parallel-for-construct: |
6038 | parallel-for-directive iteration-statement |
6039 | |
6040 | parallel-for-simd-construct: |
6041 | parallel-for-simd-directive iteration-statement |
6042 | |
6043 | parallel-sections-construct: |
6044 | parallel-sections-directive section-scope |
6045 | |
6046 | master-construct: |
6047 | master-directive structured-block |
6048 | |
6049 | critical-construct: |
6050 | critical-directive structured-block |
6051 | |
6052 | atomic-construct: |
6053 | atomic-directive expression-statement |
6054 | |
6055 | ordered-construct: |
6056 | ordered-directive structured-block |
6057 | |
6058 | Transactional Memory: |
6059 | |
6060 | statement: |
6061 | attribute-specifier-sequence[opt] transaction-statement |
6062 | attribute-specifier-sequence[opt] transaction-cancel-statement |
6063 | |
6064 | IF_P is used to track whether there's a (possibly labeled) if statement |
6065 | which is not enclosed in braces and has an else clause. This is used to |
6066 | implement -Wparentheses. */ |
6067 | |
6068 | static void |
6069 | c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels) |
6070 | { |
6071 | c_parser_all_labels (parser); |
6072 | if (loc_after_labels) |
6073 | *loc_after_labels = c_parser_peek_token (parser)->location; |
6074 | c_parser_statement_after_labels (parser, if_p, NULL__null); |
6075 | } |
6076 | |
6077 | /* Parse a statement, other than a labeled statement. CHAIN is a vector |
6078 | of if-else-if conditions. All labels and standard attributes have |
6079 | been parsed in the caller. |
6080 | |
6081 | IF_P is used to track whether there's a (possibly labeled) if statement |
6082 | which is not enclosed in braces and has an else clause. This is used to |
6083 | implement -Wparentheses. */ |
6084 | |
6085 | static void |
6086 | c_parser_statement_after_labels (c_parser *parser, bool *if_p, |
6087 | vec<tree> *chain) |
6088 | { |
6089 | location_t loc = c_parser_peek_token (parser)->location; |
6090 | tree stmt = NULL_TREE(tree) __null; |
6091 | bool in_if_block = parser->in_if_block; |
6092 | parser->in_if_block = false; |
6093 | if (if_p != NULL__null) |
6094 | *if_p = false; |
6095 | |
6096 | if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE) |
6097 | add_debug_begin_stmt (loc); |
6098 | |
6099 | switch (c_parser_peek_token (parser)->type) |
6100 | { |
6101 | case CPP_OPEN_BRACE: |
6102 | add_stmt (c_parser_compound_statement (parser)); |
6103 | break; |
6104 | case CPP_KEYWORD: |
6105 | switch (c_parser_peek_token (parser)->keyword) |
6106 | { |
6107 | case RID_IF: |
6108 | c_parser_if_statement (parser, if_p, chain); |
6109 | break; |
6110 | case RID_SWITCH: |
6111 | c_parser_switch_statement (parser, if_p); |
6112 | break; |
6113 | case RID_WHILE: |
6114 | c_parser_while_statement (parser, false, 0, if_p); |
6115 | break; |
6116 | case RID_DO: |
6117 | c_parser_do_statement (parser, false, 0); |
6118 | break; |
6119 | case RID_FOR: |
6120 | c_parser_for_statement (parser, false, 0, if_p); |
6121 | break; |
6122 | case RID_GOTO: |
6123 | c_parser_consume_token (parser); |
6124 | if (c_parser_next_token_is (parser, CPP_NAME)) |
6125 | { |
6126 | stmt = c_finish_goto_label (loc, |
6127 | c_parser_peek_token (parser)->value); |
6128 | c_parser_consume_token (parser); |
6129 | } |
6130 | else if (c_parser_next_token_is (parser, CPP_MULT)) |
6131 | { |