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