PIPS
splitc.y
Go to the documentation of this file.
1 /* $Id: splitc.y 23035 2016-01-06 16:30:14Z irigoin $ */
2 
3 /******************** SYNTAX ANALYZER ************************************
4 
5  Here are the parsing rules, based on the work of people from
6  Open Source Quality projects (http://osq.cs.berkeley.edu/), used
7  by the CCured source-to-source translator for C
8 
9 *****************************************************************/
10 
11 /*(*
12  *
13  * Copyright (c) 2001-2003,
14  * George C. Necula <necula@cs.berkeley.edu>
15  * Scott McPeak <smcpeak@cs.berkeley.edu>
16  * Wes Weimer <weimer@cs.berkeley.edu>
17  * Ben Liblit <liblit@cs.berkeley.edu>
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions are
22  * met:
23  *
24  * 1. Redistributions of source code must retain the above copyright
25  * notice, this list of conditions and the following disclaimer.
26  *
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  *
31  * 3. The names of the contributors may not be used to endorse or promote
32  * products derived from this software without specific prior written
33  * permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
36  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
37  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
38  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
39  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46  *
47  **)/
48 /*(* NOTE: This parser is based on a parser written by Hugues Casse. Since
49  * then I have changed it in numerous ways to the point where it probably
50  * does not resemble Hugues's original one at all *)*/
51 
52 %{
53 #ifdef HAVE_CONFIG_H
54  #include "pips_config.h"
55 #endif
56  /* C declarations */
57 #include <stdio.h>
58 #include <string.h>
59 #include <stdlib.h>
60 
61 #include "genC.h"
62 #include "linear.h"
63 #include "ri-util.h"
64 #include "misc.h"
65 #include "properties.h"
66 
67 #include "preprocessor.h"
68 
69 #define C_ERROR_VERBOSE 1 /* much clearer error messages with bison */
70 
71 /* Increase the parser stack to have SPEC2006/445.gobmk/owl_defendpat.c
72  going through without a:
73 
74  user warning in splitc_error: C memory exhausted near "0" at preprocessed line 13459 (user line 8732)
75 */
76 #define YYMAXDEPTH 1000000
77 
78 /* The following global variables are used to store the information such as
79  the scope, type and storage of an entity, given by the decl_spec_list,
80  which are used later by direct_decl to create the entity.
81 
82  For the moment, block scope is not considered. CurrentScope can be File,
83  Module, File'FILE_SEP_STRING'Module or TOP-LEVEL*/
84 
85 /* static string CurrentScope = NULL; */
86 /*
87 static type CurrentType = type_undefined;
88 static storage CurrentStorage = storage_undefined;
89 static list CurrentQualifiers = NIL; */
90 /* static string CurrentDerivedName = NULL; */ /* to remember the name of a struct and add it to the member prefix name*/
91 /* static int CurrentMode = 0; */ /* to know the mode of the formal parameter : by value or by reference*/
92 
93 int csplit_is_external = 0; /* to know if the variable is declared inside or outside a function */
94 int csplit_is_function = 0; /* to know if this is the declaration of a function or not, to distinguish between
95  a static variable and a static function */
96 /* Shared with the lexical analyzer */
97 string csplit_current_function_name = string_undefined;
98 string csplit_current_function_name2 = string_undefined;
99 string csplit_definite_function_name = string_undefined;
100 string csplit_definite_function_signature = string_undefined;
101 
102 
103 static void reset_csplit_current_function_name()
104 {
105  if(!string_undefined_p(csplit_current_function_name)) {
106  free(csplit_current_function_name);
107  csplit_current_function_name =
108  csplit_current_function_name2;
109  }
110  if(!string_undefined_p(csplit_current_function_name2)) {
111  csplit_current_function_name2 = string_undefined;
112  }
113 }
114 /* static int enum_counter = 0; */
115 
116 /* Shared with the lexical analyzer */
117 bool csplit_is_static_p = false;
118 static bool current_function_is_static_p = false;
119 
120 static void csplit_parser_warning_alist(
121  const char * pips_func,
122  const char * pips_file,
123  const int pips_line,
124  const string format,
125  va_list * args)
126 {
127  if (get_bool_property("NO_USER_WARNING"))
128  return;
129 
130  string cpn = get_pips_current_pass_name();
131  if (cpn==NULL)
132  cpn = "unknown";
133 
134  string uifn = preprocessor_current_initial_file_name;
135  // note: this is the line number in the preprocessed file, which changes
136  // from cpp to cpp because of inserted preprocessor junk...
137  int ln = csplit_line_number;
138  string s = safe_read_nth_line(preprocessor_current_split_file_name, ln);
139 
140  pips_log_alist(warning_log, cpn, get_pips_current_module(),
141  (const string) pips_func, (const string) pips_file, pips_line,
142  NULL, (const string) uifn, ln, -1,
143  s, "see stderr for exact file and line number",
144  (const string) format, args);
145  free(s);
146 }
147 
148 void csplit_parser_warning_func(
149  const char * pips_func,
150  const char * pips_file,
151  const int pips_line,
152  const string format,
153  ...)
154 {
155  va_list args;
156  va_start(args, format);
157  csplit_parser_warning_alist(pips_func, pips_file, pips_line, format, &args);
158  va_end(args);
159 }
160 
161 /* Redundant with splitc_error()? */
162 void csplit_parser_error(const string msg)
163 {
164  /* Should add the current line number of the lexer */
165 
166  /* csplit_parser_warning("Corrupted or non-supported C constructs.\n" */
167  /* "Make sure your code is compiled by gcc -stc=c99 first, " */
168  /* "and/or set proper PIPS option, " */
169  /* "CHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPS or " */
170  /* "CHECK_C_SYNTAX_BEFORE_RUNNING_PIPS.\n"); */
171 
172  csplit_parser_warning(msg);
173 
174  //pips_internal_error("Not implemented yet\n."
175  // " Should reset all static variables.\n");
176  /* Reset all static variables */
177  /* Close all open files: at least three... */
178  extern string current_file_name;
179  csplit_close_files(current_file_name);
180  csplit_error_handler();
181 
182  // See syn_reset_lex() -> syn_restart(syn_in); as in ParserError,
183  // the error routine for the Fortran parser, but its lexer is
184  // made of two passes, a Fortran-specific first pass and a lex second pass
185  // syn_restart(splitc_in);
186  // yy_flush_buffer(); //YY_FLUSH_BUFFER;
187  splitc_lex_destroy(); // trial and error
188  // BEGIN(0); we might have to reset the state of lex
189 
190  //pips_user_error(s);
191  pips_user_error("Corrupted or non-supported C constructs.\n"
192  "Make sure your code is compiled by gcc -stc=c99 first, "
193  "and/or set proper PIPS option, "
194  "CHECK_FORTRAN_SYNTAX_BEFORE_RUNNING_PIPS or "
195  "CHECK_C_SYNTAX_BEFORE_RUNNING_PIPS.\n");
196 }
197 
198 /* All the following global variables must be replaced by functions, once we have the preprocessor for C */
199 
200 static int csplit_is_typedef = false; /* to know if this is a typedef name or not */
201 static stack TypedefStack = stack_undefined;
202 
203  static void PushTypedef()
204  {
205  pips_debug(8, "csplit_is_typedef = %s\n", bool_to_string(csplit_is_typedef));
206  stack_push((void *) (_int)csplit_is_typedef, TypedefStack);
207  csplit_is_typedef = false;
208  pips_debug(8, "csplit_is_typedef = %s\n", bool_to_string(csplit_is_typedef));
209  }
210 
211  static void PopTypedef()
212  {
213  csplit_is_typedef = (_int) stack_pop(TypedefStack);
214  pips_debug(8, "csplit_is_typedef = %s\n", bool_to_string(csplit_is_typedef));
215  }
216 
217  void MakeTypedefStack()
218  {
219  pips_assert("TypedefStack is undefined", stack_undefined_p(TypedefStack));
220  TypedefStack = stack_make(int_domain, 0, 0);
221 }
222 
223  void ResetTypedefStack()
224  {
225  if(stack_empty_p(TypedefStack)) {
226  stack_free(&TypedefStack);
227  TypedefStack = stack_undefined;
228  }
229  else
230  pips_internal_error("TypedefStack is not empty");
231  }
232 
233 void ForceResetTypedefStack()
234 {
235  stack_free(&TypedefStack);
236  TypedefStack = stack_undefined;
237 }
238 ␌
239  /* Each scope in the compilation unit has its own number
240  *
241  * The scope management in the C preprocessor is different from the
242  * scope management in the C parser.
243  */
244 #define SCOPE_UNDEFINED (-1)
245  static int c_preprocessor_scope_number = SCOPE_UNDEFINED;
246  static stack c_preprocessor_scope_stack = stack_undefined;
247 
248  void init_preprocessor_scope_stack()
249  {
250  c_preprocessor_scope_number = 0;
251  c_preprocessor_scope_stack = stack_make(string_domain, 0, 0);
252  }
253 
254  void reset_preprocessor_scope_stack()
255  {
256  if(c_preprocessor_scope_stack != stack_undefined) {
257  if(stack_empty_p(c_preprocessor_scope_stack)) {
258  stack_free(&c_preprocessor_scope_stack);
259  c_preprocessor_scope_stack = stack_undefined;
260  }
261  else {
262  // pips_internal_error? Could be a bad input C file...
263  pips_user_warning("Preprocessor scope stack is not empty.\n");
264  }
265  }
266  c_preprocessor_scope_number = SCOPE_UNDEFINED;
267  return;
268  }
269 
270  /* To be used by an error handler */
271  void force_reset_preprocessor_scope_stack()
272  {
273  if(c_preprocessor_scope_stack != stack_undefined) {
274  stack_free(&c_preprocessor_scope_stack);
275  c_preprocessor_scope_stack = stack_undefined;
276  }
277  c_preprocessor_scope_number = SCOPE_UNDEFINED;
278  return;
279  }
280 
281  void push_new_preprocessor_scope()
282  {
283  c_preprocessor_scope_number++;
284  string sn = string_undefined;
285  (void) asprintf(&sn, "%d", c_preprocessor_scope_number);
286  stack_push((void *) sn, c_preprocessor_scope_stack);
287  return;
288  }
289 
290  void pop_preprocessor_scope()
291  {
292  stack_pop(c_preprocessor_scope_stack);
293  return;
294  }
295 
296 bool preprocessor_scope_stack_empty_p()
297 {
298  return stack_empty_p(c_preprocessor_scope_stack);
299 }
300 
301 string get_preprocessor_current_scope()
302  {
303  string sn = string_undefined;
304  if(preprocessor_scope_stack_empty_p()) {
305  // We are at the global level: no scope has been entered yet
306  sn = "";
307  }
308  else
309  sn = (string) stack_head(c_preprocessor_scope_stack);
310  return sn;
311  }
312 
313 string get_preprocessor_nth_scope(int n)
314  {
315  string sn = (string) stack_nth(c_preprocessor_scope_stack, n);
316  return sn;
317  }
318 
319 int preprocessor_scope_number()
320  {
321  int n = stack_size(c_preprocessor_scope_stack);
322  return n;
323  }
324 ␌
325 /* If any of the strings is undefined, we are in trouble. If not,
326  concatenate them with separator into a new string and free all input
327  strings. No more than six arguments. */
328 
329  static int number_of_signatures_built = 0;
330  static int number_of_signatures_freed = 0;
331 
332 static string new_signature(const string s)
333  {
334  string new_s = strdup(s);
335  number_of_signatures_built++;
336  return new_s;
337  }
338 
339 static void free_partial_signature(string s)
340  {
341  number_of_signatures_freed++;
342  if(!string_undefined_p(s))
343  free(s);
344  }
345 
346 static string general_build_signature(bool arguments_are_defined_p,
347  string s1,
348  va_list * p_some_arguments)
349  {
350  /* va_list some_arguments; */
351  int count = 0;
352  string s = NULL;
353  string sa[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
354  string r = string_undefined;
355  int i;
356  bool some_argument_undefined_p = false;
357 
358  /* va_start(*some_arguments, s1); */
359  s = s1;
360  while(s) {
361  if(string_undefined_p(s)) {
362  /* We are in trouble */
363  if(arguments_are_defined_p)
364  pips_internal_error("Unexpected undefined argument %d", count+1);
365  else
366  some_argument_undefined_p = true;
367  }
368  else if(s==NULL) {
369  /* We are in trouble too */
370  pips_internal_error("Unexpected NULL argument");
371  }
372  else if(strcmp(s, "")==0) {
373  free(s);
374  }
375  else {
376  pips_debug(9, "s%d = \"%s\"\n", count, s);
377  sa[count++] = s;
378  }
379  s = va_arg(*p_some_arguments, string);
380  }
381 
382  pips_assert("No more than 6 effective arguments (check grammar rules).",
383  count<=6);
384 
385  if(some_argument_undefined_p)
386  r = string_undefined;
387  else {
388  r = strdup(concatenate("", sa[0], " ", sa[1], " ", sa[2], " ",
389  sa[3], " ", sa[4], " ", sa[5], "", NULL));
390 
391  number_of_signatures_built++;
392  }
393 
394  pips_debug(9, "%d arguments:\n", count);
395 
396  for(i=0; i<count; i++) {
397  int j;
398  for(j=0; i<count; i++) {
399  if(sa[i]==sa[j]&&i!=j) pips_internal_error("Unexpected common arguments\n");
400  }
401  }
402 
403  for(i=0; i<count; i++) {
404  /* pips_debug(9, "s%d = \"%s\"\n", i, sa[i]); */
405  number_of_signatures_freed++;
406  free(sa[i]);
407  }
408 
409  pips_assert("An argument may be really undefined only if"
410  " arguments are not guaranteed to be defined",
411  !(some_argument_undefined_p && arguments_are_defined_p));
412  pips_assert("If all arguments are defined, the result is defined",
413  some_argument_undefined_p || !string_undefined_p(r));
414 
415  pips_debug(8, "Returns: \"%s\"\n", string_undefined_p(r)? "STRING_UNDEFINED" : r);
416 
417  return r;
418  }
419 
420 /* All arguments must be defined. The result is always defined. */
421 static string build_signature(string s1, ...)
422  {
423  va_list some_arguments;
424 
425  va_start(some_arguments, s1);
426  return general_build_signature(true, s1, &some_arguments);
427  }
428 
429 /* Arguments may be defined or not, but as soon as one is undefined, an
430  undefined_string is returned.*/
431 static string safe_build_signature(string s1, ...)
432  {
433  va_list some_arguments;
434 
435  va_start(some_arguments, s1);
436  return general_build_signature(false, s1, &some_arguments);
437  }
438 
439 /* Get rid of useless spaces: multiple contiguous spaces, spaces next to a
440  separator,... Some look ahead required to get rid of spaces before a
441  separator. Could be moved into build_signature but it seemed easier to
442  separate concerns. */
443  static string simplify_signature(string s)
444  {
445  string new_s = strdup(s); /* Make sure to allocate enough space... */
446  string source = s+1;
447  string destination = new_s;
448 
449  pips_debug(8, "Begin with signature \"%s\"\n", s);
450 
451  pips_assert("The signature is not empty", *s);
452 
453  /* source points to the next character to copy and destination to the
454  last character copied. The first character is already copied. */
455  while(*source) {
456  if(*destination==' ') {
457  if(*source==' ') {
458  /* Do not copy a second space */
459  source++;
460  }
461  else if (*source==',' || *source=='(' || *source==')' || *source==';') {
462  /* Overwrite the space in the destination */
463  *destination = *source++;
464  }
465  else {
466  /* Normal copy */
467  *++destination = *source++;
468  }
469  }
470  else if(*destination=='(' || *destination=='*') {
471  if(*source==' ') {
472  /* Do not copy a space after some separators */
473  source++;
474  }
475  else {
476  /* Normal copy */
477  *++destination = *source++;
478  }
479  }
480  else {
481  /* Normal copy */
482  *++destination = *source++;
483  }
484  }
485 
486  /* Get rid of a trailing SPACE. */
487  if(*destination==' ')
488  *(destination) = '\000';
489  else
490  *(destination+1) = '\000';
491 
492  pips_debug(8, "End with signature \"%s\"\n", new_s);
493 
494  free_partial_signature(s);
495  return new_s;
496  }
497 
498  int check_signature_balance()
499  {
500  int imbalance = number_of_signatures_built - number_of_signatures_freed;
501  if(imbalance<0) {
502  /* pips_internal_error("More signatures freed than allocated: %d\n", imbalance); */
503  pips_debug(5, "More signatures freed than allocated: %d\n", imbalance);
504  }
505  return imbalance;
506  }
507 ␌
508 /* Beware of the free: no constant strings in signature! */
509 static string new_empty()
510  {
511  return new_signature("");
512  }
513 static string new_comma()
514  {
515  return new_signature(",");
516  }
517 static string new_eq()
518  {
519  return new_signature("=");
520  }
521 static string new_star()
522  {
523  return new_signature("*");
524  }
525 static string new_semicolon()
526  {
527  return new_signature(";");
528  }
529 static string new_colon()
530  {
531  return new_signature(":");
532  }
533 
534 static string new_lbrace()
535  {
536  return new_signature("{");
537  }
538 static string new_rbrace()
539  {
540  return new_signature("}");
541  }
542 static string new_lparen()
543  {
544  return new_signature("(");
545  }
546 static string new_rparen()
547  {
548  return new_signature(")");
549  }
550 static string new_lbracket()
551  {
552  return new_signature("[");
553  }
554 static string new_rbracket()
555  {
556  return new_signature("]");
557  }
558 static string new_ellipsis()
559  {
560  return new_signature("...");
561  }
562 %}
563 
564 /* Bison declarations */
565 
566 %union {
567  basic basic;
568  char character;
569  cons * liste;
570  dimension dimension;
571  entity entity;
572  expression expression;
573  statement statement;
574  int integer;
575  string string;
576  syntax syntax;
577  tag tag;
578  type type;
579  value value;
580  parameter parameter;
581 }
582 
583 %token <string> TK_IDENT
584 %token <string> TK_CHARCON
585 %token <string> TK_INTCON
586 %token <string> TK_FLOATCON
587 %token <string> TK_NAMED_TYPE
588 
589 %token <string> TK_STRINGCON
590 %token <string> TK_WSTRINGCON
591 
592 %token TK_EOF
593 %token TK_CHAR TK_INT TK_INT128 TK_UINT128 TK_DOUBLE TK_FLOAT TK_VOID TK_COMPLEX
594 %token TK_ENUM TK_STRUCT TK_TYPEDEF TK_UNION
595 %token TK_SIGNED TK_UNSIGNED TK_LONG TK_SHORT
596 %token TK_VOLATILE TK_EXTERN TK_STATIC TK_CONST TK_RESTRICT TK_AUTO TK_REGISTER TK_THREAD TK_STATIC_DIMENSION
597 
598 %token TK_SIZEOF TK_ALIGNOF
599 
600 %token TK_EQ TK_PLUS_EQ TK_MINUS_EQ TK_STAR_EQ TK_SLASH_EQ TK_PERCENT_EQ
601 %token TK_AND_EQ TK_PIPE_EQ TK_CIRC_EQ TK_INF_INF_EQ TK_SUP_SUP_EQ
602 %token TK_ARROW TK_DOT
603 
604 %token TK_EQ_EQ TK_EXCLAM_EQ TK_INF TK_SUP TK_INF_EQ TK_SUP_EQ
605 %token TK_PLUS TK_MINUS TK_STAR
606 %token TK_SLASH TK_PERCENT
607 %token TK_TILDE TK_AND
608 %token TK_PIPE TK_CIRC
609 %token TK_EXCLAM TK_AND_AND
610 %token TK_PIPE_PIPE
611 %token TK_INF_INF TK_SUP_SUP
612 %token TK_PLUS_PLUS TK_MINUS_MINUS
613 
614 %token TK_RPAREN
615 %token TK_LPAREN TK_RBRACE
616 %token TK_LBRACE
617 %token TK_LBRACKET TK_RBRACKET
618 %token TK_COLON
619 %token TK_SEMICOLON
620 %token TK_COMMA TK_ELLIPSIS TK_QUEST
621 
622 %token TK_BREAK TK_CONTINUE TK_GOTO TK_RETURN
623 %token TK_SWITCH TK_CASE TK_DEFAULT
624 %token TK_WHILE TK_DO TK_FOR
625 %token TK_IF
626 %token TK_ELSE
627 
628 %token TK_ATTRIBUTE TK_INLINE TK_ASM TK_TYPEOF TK_FUNCTION__ TK_PRETTY_FUNCTION__
629 %token TK_LABEL__
630 %token TK_BUILTIN_VA_ARG
631 %token TK_BUILTIN_VA_LIST
632 %token TK_BLOCKATTRIBUTE
633 %token TK_DECLSPEC
634 %token TK_MSASM TK_MSATTR
635 %token TK_PRAGMA
636 
637 /* sm: cabs tree transformation specification keywords */
638 %token TK_AT_TRANSFORM TK_AT_TRANSFORMEXPR TK_AT_SPECIFIER TK_AT_EXPR
639 %token TK_AT_NAME
640 
641 /* Added here because the token numbering seems to be fragile */
642 %token <string> TK_COMPLEXCON
643 
644 /* operator precedence */
645 %nonassoc TK_IF
646 %nonassoc TK_ELSE
647 %left TK_COMMA
648 %right TK_EQ TK_PLUS_EQ TK_MINUS_EQ TK_STAR_EQ TK_SLASH_EQ TK_PERCENT_EQ TK_AND_EQ TK_PIPE_EQ TK_CIRC_EQ TK_INF_INF_EQ TK_SUP_SUP_EQ
649 %right TK_QUEST TK_COLON
650 %left TK_PIPE_PIPE
651 %left TK_AND_AND
652 %left TK_PIPE
653 %left TK_CIRC
654 %left TK_AND
655 %left TK_EQ_EQ TK_EXCLAM_EQ
656 %left TK_INF TK_SUP TK_INF_EQ TK_SUP_EQ
657 %left TK_INF_INF TK_SUP_SUP
658 %left TK_PLUS TK_MINUS
659 %left TK_STAR TK_SLASH TK_PERCENT TK_CONST TK_RESTRICT TK_VOLATILE TK_STATIC_DIMENSION
660 %right TK_EXCLAM TK_TILDE TK_PLUS_PLUS TK_MINUS_MINUS TK_CAST TK_RPAREN TK_ADDROF TK_SIZEOF TK_ALIGNOF
661 %left TK_LBRACKET
662 %left TK_DOT TK_ARROW TK_LPAREN TK_LBRACE
663 %right TK_NAMED_TYPE
664 %left TK_IDENT
665 
666 /* Non-terminals informations */
667 %start interpret
668 
669 %type <void> interpret
670 %type <void> file globals
671 %type <void> global
672 %type <string> attributes
673 %type <string> attributes_with_asm
674 %type <void> asmattr
675 %type <string> attribute
676 %type <void> statement
677 %type <string> constant
678 %type <void> string_constant
679 %type <string> expression /* Required for bit fields, and maybe for enumerators. */
680 %type <string> opt_expression /* required to initialize enumerator members via conditional expressions */
681 %type <void> init_expression
682 %type <string> comma_expression
683 %type <string> paren_comma_expression
684 %type <void> arguments
685 %type <void> bracket_comma_expression
686 %type <void> string_list
687 %type <void> wstring_list
688 
689 %type <void> initializer
690 %type <void> initializer_list
691 %type <void> init_designators init_designators_opt
692 
693 %type <string> type_spec
694 %type <string> struct_decl_list
695 
696 
697 %type <string> old_proto_decl direct_old_proto_decl
698 %type <string> parameter_decl
699 %type <string> enumerator
700 %type <string> enum_list
701 %type <string> declaration
702 %type <void> function_def
703 %type <void> function_def_start
704 %type <string> type_name
705 %type <void> block
706 %type <void> local_labels local_label_names
707 %type <string> old_parameter_list_ne
708 
709 %type <string> init_declarator
710 %type <string> init_declarator_list
711 %type <string> declarator
712 %type <string> field_decl
713 %type <string> field_decl_list
714 %type <string> direct_decl
715 %type <string> abs_direct_decl
716 %type <string> abs_direct_decl_opt
717 %type <string> abstract_decl
718 %type <string> pointer pointer_opt
719 %type <void> location
720 
721 %type <string> id_or_typename
722 %type <string> comma_expression_opt
723 %type <void> initializer_list_opt
724 %type <string> one_string_constant
725 %type <string> one_string
726 
727 %type <string> rest_par_list rest_par_list1
728 %type <void> declaration_list
729 %type <void> statement_list
730 %type <void> for_clause
731 %type <string> decl_spec_list
732 %type <string> decl_spec_list_opt_no_named
733 %type <string> decl_spec_list_opt
734 
735 %type <string> maybecomma
736 %type <string> parameter_list_startscope
737 %type <string> paren_attr_list_ne
738 %type <string> old_pardef_list
739 %type <string> old_pardef
740 %%
741 
742 interpret: file TK_EOF
743  { YYACCEPT; };
744 file: globals /* do nothing */
745 ;
746 globals:
747  /* empty */ {} /* do nothing */
748 | global globals {} /* do nothing */
749 | TK_SEMICOLON globals{} /* do nothing */
750 ;
751 
752 location:
753  /* empty */ {} %prec TK_IDENT
754 
755 
756 /*** Global Definition ***/
757 global:
758  declaration
759  {
760  pips_debug(5, "declaration->global\n");
761  csplit_is_external = 1; /* the variable is declared outside of any function */
762  /* csplit_is_typedef = 0; */
763  pips_debug(1, "Declaration is located between line %d and line %d\n", get_csplit_current_beginning(), csplit_line_number);
764  /* Useless since it is dealt by csplit_copy()
765  later */
766  //csplit_append_to_compilation_unit(csplit_line_number, get_current_csplit_file_offset());
767  if(!string_undefined_p($1)) {
768  pips_debug(1, "Definition: \"%s\"\n", $1);
769  free_partial_signature($1);
770  }
771  reset_csplit_current_beginning();
772  }
773 | function_def
774  {
775 
776  /*SG: mechanism to prevent the generation of module for functions defined in standard header files
777  it should never be the case, but it sometimes happen with inline functions */
778  pips_debug(5, "function_def->global\n");
779  csplit_is_external = 0; /* the variable is declared inside a function */
780  pips_debug(1, "Function \"%s\" declaration and body are located between line %d and line %d\n",
781  csplit_definite_function_name,
782  get_csplit_current_beginning(),
783  csplit_line_number);
784  /* Hmm... It happens to early to gather
785  following comments to its module... */
786  csplit_copy(csplit_definite_function_name,
787  csplit_definite_function_signature,
788  get_csplit_current_beginning(),
789  csplit_line_number,
790  get_csplit_file_offset_beginning(),
791  get_current_csplit_file_offset(),
792  get_user_current_beginning(),
793  current_function_is_static_p);
794  reset_csplit_current_beginning();
795  }
796 | TK_ASM TK_LPAREN string_constant TK_RPAREN TK_SEMICOLON
797  {
798  reset_csplit_current_beginning();
799  }
800 | TK_PRAGMA attr
801  {
802  reset_csplit_current_beginning();
803  }
804 /* Old-style function prototype. This should be somewhere else, like in
805  "declaration". For now we keep it at global scope only because in local
806  scope it looks too much like a function call */
807 | TK_IDENT TK_LPAREN old_parameter_list_ne TK_RPAREN old_pardef_list TK_SEMICOLON
808  {
809  pips_internal_error("Not implemented yet\n");
810  }
811 /* Old style function prototype, but without any arguments */
812 | TK_IDENT TK_LPAREN TK_RPAREN TK_SEMICOLON
813  {
814  pips_internal_error("Not implemented yet\n");
815  }
816 /* transformer for a toplevel construct */
817 | TK_AT_TRANSFORM TK_LBRACE global TK_RBRACE TK_IDENT /*to*/ TK_LBRACE globals TK_RBRACE
818  {
819  pips_internal_error("Not implemented yet\n");
820  }
821 /* transformer for an expression */
822 | TK_AT_TRANSFORMEXPR TK_LBRACE expression TK_RBRACE TK_IDENT /*to*/ TK_LBRACE expression TK_RBRACE
823  {
824  pips_internal_error("Not implemented yet\n");
825  }
826 | location error TK_SEMICOLON
827  {
828  pips_user_error("Parse error: location error TK_SEMICOLON \n");
829  }
830 ;
831 
832 id_or_typename:
833  TK_IDENT
834  {
835  $$=new_signature(splitc_text);
836  }
837 | TK_NAMED_TYPE
838  { $$=new_signature(splitc_text);}
839 | TK_AT_NAME TK_LPAREN TK_IDENT TK_RPAREN
840  {
841  csplit_parser_warning("CIL AT not implemented\n");
842  $$ = build_signature(new_signature("at_name"), new_lparen(), new_signature($3),
843  new_rparen(), NULL);
844  }
845 ;
846 
847 maybecomma:
848 /* empty */ { $$ =new_signature("");}
849 | TK_COMMA { $$ = new_comma();}
850 ;
851 
852 /* *** Expressions *** */
853 
854 /* They may be only needed in declarations to specify bit fields. */
855 
856 expression:
857  constant
858  {
859  $$ = $1;
860  }
861 | TK_IDENT
862  {
863  /* Elements in enum are symbolic constant which
864  may appear in an array declaration. */
865  $$ = new_signature($1);
866  }
867 | TK_SIZEOF expression
868  {
869  /* Can be used to dimemsion an argument */
870  $$ = safe_build_signature(new_signature("sizeof"),
871  $2, NULL);
872  }
873 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
874  {
875  $$ = safe_build_signature(new_signature("sizeof"),
876  new_lparen(), $3, new_rparen(),
877  NULL);
878  }
879 | TK_ALIGNOF expression
880  {
881  free_partial_signature($2);
882  $$ = string_undefined;
883  }
884 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
885  {
886  free_partial_signature($3);
887  $$ = string_undefined;
888  }
889 | TK_PLUS expression
890  {
891  $$ = safe_build_signature(new_signature("+"), $2, NULL);
892  }
893 | TK_MINUS expression
894  {
895  $$ = safe_build_signature(new_signature("-"), $2, NULL);
896  }
897 | TK_STAR expression
898  {
899  $$ = safe_build_signature(new_signature("*"), $2, NULL);
900  }
901 | TK_AND expression %prec TK_ADDROF
902  {
903  $$ = safe_build_signature(new_signature("&"), $2, NULL);
904  }
905 | TK_EXCLAM expression
906  {
907  $$ = safe_build_signature(new_signature("!"), $2, NULL);
908  }
909 | TK_TILDE expression
910  {
911  $$ = safe_build_signature(new_signature("~"), $2, NULL);
912  }
913 | TK_PLUS_PLUS expression %prec TK_CAST
914  {
915  $$ = safe_build_signature(new_signature("++"), $2, NULL);
916  }
917 | expression TK_PLUS_PLUS
918  {
919  $$ = safe_build_signature($1, new_signature("++"), NULL);
920  }
921 | TK_MINUS_MINUS expression %prec TK_CAST
922  {
923  $$ = safe_build_signature(new_signature("--"), $2, NULL);
924  }
925 | expression TK_MINUS_MINUS
926  {
927  $$ = safe_build_signature($1, new_signature("--"), NULL);
928  }
929 | expression TK_ARROW id_or_typename
930  {
931  $$ = safe_build_signature($1, new_signature("->"), $3, NULL);
932  }
933 | expression TK_DOT id_or_typename
934  {
935  $$ = safe_build_signature($1, new_signature("."), $3, NULL);
936  }
937 | TK_LPAREN block TK_RPAREN
938  {
939  $$ = string_undefined;
940  /* $$ = new_signature("block"); */
941  }
942 | paren_comma_expression
943  {
944  $$ = $1;
945  }
946 | expression TK_LPAREN arguments TK_RPAREN
947  {
948  free_partial_signature($1);
949  /* arguments does not return anything. */
950  $$ = string_undefined;
951  }
952 | TK_BUILTIN_VA_ARG TK_LPAREN expression TK_COMMA type_name TK_RPAREN
953  {
954  free_partial_signature($3);
955  free_partial_signature($5);
956  $$ = string_undefined;
957  }
958 | expression bracket_comma_expression
959  {
960  free_partial_signature($1);
961  /* bracket_comma_expression does not return anything. */
962  $$ = string_undefined;
963  }
964 | expression TK_QUEST opt_expression TK_COLON expression
965  {
966  //free_partial_signature($1);
967  /* opt_expression does not return anything. */
968  //free_partial_signature($5);
969  //$$ = string_undefined;
970  $$ = safe_build_signature($1,
971  new_signature("?"),
972  $3,
973  new_signature(":"),
974  $5, NULL);
975  }
976 | expression TK_PLUS expression
977  {
978  $$ = safe_build_signature($1, new_signature("+"), $3, NULL);
979  }
980 | expression TK_MINUS expression
981  {
982  $$ = safe_build_signature($1, new_signature("-"), $3, NULL);
983  }
984 | expression TK_STAR expression
985  {
986  $$ = safe_build_signature($1, new_signature("*"), $3, NULL);
987  }
988 | expression TK_SLASH expression
989  {
990  $$ = safe_build_signature($1, new_signature("/"), $3, NULL);
991  }
992 | expression TK_PERCENT expression
993  {
994  $$ = safe_build_signature($1, new_signature("%"), $3, NULL);
995  }
996 | expression TK_AND_AND expression
997  {
998  $$ = safe_build_signature($1, new_signature("&&"), $3, NULL);
999  }
1000 | expression TK_PIPE_PIPE expression
1001  {
1002  $$ = safe_build_signature($1, new_signature("||"), $3, NULL);
1003  }
1004 | expression TK_AND expression
1005  {
1006  $$ = safe_build_signature($1, new_signature("&"), $3, NULL);
1007  }
1008 | expression TK_PIPE expression
1009  {
1010  $$ = safe_build_signature($1, new_signature("|"), $3, NULL);
1011  }
1012 | expression TK_CIRC expression
1013  {
1014  $$ = safe_build_signature($1, new_signature("^"), $3, NULL);
1015  }
1016 | expression TK_EQ_EQ expression
1017  {
1018  //free_partial_signature($1);
1019  //free_partial_signature($3);
1020  //$$ = string_undefined;
1021  $$ = safe_build_signature($1, new_signature("=="), $3, NULL);
1022  }
1023 | expression TK_EXCLAM_EQ expression
1024  {
1025  //free_partial_signature($1);
1026  //free_partial_signature($3);
1027  //$$ = string_undefined;
1028  $$ = safe_build_signature($1, new_signature("!="), $3, NULL);
1029  }
1030 | expression TK_INF expression
1031  {
1032  //free_partial_signature($1);
1033  //free_partial_signature($3);
1034  //$$ = string_undefined;
1035  $$ = safe_build_signature($1, new_signature("<"), $3, NULL);
1036  }
1037 | expression TK_SUP expression
1038  {
1039  //free_partial_signature($1);
1040  //free_partial_signature($3);
1041  //$$ = string_undefined;
1042  $$ = safe_build_signature($1, new_signature(">"), $3, NULL);
1043  }
1044 | expression TK_INF_EQ expression
1045  {
1046  //free_partial_signature($1);
1047  //free_partial_signature($3);
1048  //$$ = string_undefined;
1049  $$ = safe_build_signature($1, new_signature("<="), $3, NULL);
1050  }
1051 | expression TK_SUP_EQ expression
1052  {
1053  //free_partial_signature($1);
1054  //free_partial_signature($3);
1055  //$$ = string_undefined;
1056  $$ = safe_build_signature($1, new_signature(">="), $3, NULL);
1057  }
1058 | expression TK_INF_INF expression
1059  {
1060  //free_partial_signature($1);
1061  //free_partial_signature($3);
1062  //$$ = string_undefined;
1063  $$ = safe_build_signature($1, new_signature("<<"), $3, NULL);
1064  }
1065 | expression TK_SUP_SUP expression
1066  {
1067  //free_partial_signature($1);
1068  //free_partial_signature($3);
1069  //$$ = string_undefined;
1070  $$ = safe_build_signature($1, new_signature(">>"), $3, NULL);
1071  }
1072 | expression TK_EQ expression
1073  {
1074  free_partial_signature($1);
1075  free_partial_signature($3);
1076  $$ = string_undefined;
1077  }
1078 | expression TK_PLUS_EQ expression
1079  {
1080  free_partial_signature($1);
1081  free_partial_signature($3);
1082  $$ = string_undefined;
1083  }
1084 | expression TK_MINUS_EQ expression
1085  {
1086  free_partial_signature($1);
1087  free_partial_signature($3);
1088  $$ = string_undefined;
1089  }
1090 | expression TK_STAR_EQ expression
1091  {
1092  free_partial_signature($1);
1093  free_partial_signature($3);
1094  $$ = string_undefined;
1095  }
1096 | expression TK_SLASH_EQ expression
1097  {
1098  free_partial_signature($1);
1099  free_partial_signature($3);
1100  $$ = string_undefined;
1101  }
1102 | expression TK_PERCENT_EQ expression
1103  {
1104  free_partial_signature($1);
1105  free_partial_signature($3);
1106  $$ = string_undefined;
1107  }
1108 | expression TK_AND_EQ expression
1109  {
1110  free_partial_signature($1);
1111  free_partial_signature($3);
1112  $$ = string_undefined;
1113  }
1114 | expression TK_PIPE_EQ expression
1115  {
1116  free_partial_signature($1);
1117  free_partial_signature($3);
1118  $$ = string_undefined;
1119  }
1120 | expression TK_CIRC_EQ expression
1121  {
1122  free_partial_signature($1);
1123  free_partial_signature($3);
1124  $$ = string_undefined;
1125  }
1126 | expression TK_INF_INF_EQ expression
1127  {
1128  free_partial_signature($1);
1129  free_partial_signature($3);
1130  $$ = string_undefined;
1131  }
1132 | expression TK_SUP_SUP_EQ expression
1133  {
1134  free_partial_signature($1);
1135  free_partial_signature($3);
1136  $$ = string_undefined;
1137  }
1138 | TK_LPAREN type_name TK_RPAREN expression
1139  {
1140  free_partial_signature($2);
1141  free_partial_signature($4);
1142  $$ = string_undefined;
1143  }
1144 /* (* We handle GCC constructor expressions *) */
1145 | TK_LPAREN type_name TK_RPAREN TK_LBRACE initializer_list_opt TK_RBRACE
1146  {
1147  free_partial_signature($2);
1148  /* initializer_list_opt does not return anything. */
1149  $$ = string_undefined;
1150  }
1151 /* (* GCC's address of labels *) */
1152 | TK_AND_AND TK_IDENT
1153  {
1154  $$ = string_undefined;
1155  }
1156 | TK_AT_EXPR TK_LPAREN TK_IDENT TK_RPAREN /* expression pattern variable */
1157  {
1158  $$ = string_undefined;
1159  }
1160 ;
1161 
1162 /* FI: I assume that only integer constant are useful in declarations. */
1163 
1164 constant:
1165  TK_INTCON
1166  {
1167  $$ = new_signature($1);
1168  }
1169 | TK_FLOATCON
1170  {
1171  $$ = string_undefined;
1172  }
1173 | TK_COMPLEXCON
1174  {
1175  $$ = string_undefined;
1176  }
1177 | TK_CHARCON
1178  {
1179  $$ = string_undefined;
1180  }
1181 | string_constant
1182  {
1183  $$ = string_undefined;
1184  }
1185 /*add a nul to strings. We do this here (rather than in the lexer) to make
1186  concatenation easy below.*/
1187 | wstring_list
1188  {
1189  $$ = string_undefined;
1190  }
1191 ;
1192 
1193 string_constant:
1194 /* Now that we know this constant isn't part of a wstring, convert it
1195  back to a string for easy viewing. */
1196  string_list
1197  {
1198  }
1199 ;
1200 one_string_constant:
1201 /* Don't concat multiple strings. For asm templates. */
1202  TK_STRINGCON
1203  {}
1204 ;
1205 string_list:
1206  one_string
1207  {
1208  }
1209 | string_list one_string
1210  {
1211  }
1212 ;
1213 
1214 wstring_list:
1215  TK_WSTRINGCON
1216  {
1217  }
1218 | wstring_list one_string
1219  {
1220  }
1221 | wstring_list TK_WSTRINGCON
1222  {
1223  }
1224 /* Only the first string in the list needs an L, so L"a" "b" is the same
1225  * as L"ab" or L"a" L"b". */
1226 
1227 one_string:
1228  TK_STRINGCON { }
1229 | TK_FUNCTION__
1230  { }
1231 | TK_PRETTY_FUNCTION__
1232  { }
1233 ;
1234 
1235 init_expression:
1236  expression { free_partial_signature($1);}
1237 | TK_LBRACE initializer_list_opt TK_RBRACE
1238  { }
1239 
1240 initializer_list: /* ISO 6.7.8. Allow a trailing COMMA */
1241  initializer
1242  {
1243  }
1244 | initializer TK_COMMA initializer_list_opt
1245  {
1246  }
1247 ;
1248 initializer_list_opt:
1249  /* empty */ { }
1250 | initializer_list { }
1251 ;
1252 initializer:
1253  init_designators eq_opt init_expression
1254  {
1255  }
1256 | gcc_init_designators init_expression
1257  {
1258  }
1259 | init_expression { }
1260 ;
1261 eq_opt:
1262  TK_EQ
1263  { }
1264  /*(* GCC allows missing = *)*/
1265 | /*(* empty *)*/
1266  {
1267  }
1268 ;
1269 init_designators:
1270  TK_DOT id_or_typename init_designators_opt
1271  { }
1272 | TK_LBRACKET expression TK_RBRACKET init_designators_opt
1273  { free_partial_signature($2); }
1274 | TK_LBRACKET expression TK_ELLIPSIS expression TK_RBRACKET
1275  { free_partial_signature($2); free_partial_signature($4); }
1276 ;
1277 init_designators_opt:
1278  /* empty */ { }
1279 | init_designators {}
1280 ;
1281 
1282 gcc_init_designators: /*(* GCC supports these strange things *)*/
1283  id_or_typename TK_COLON
1284  {
1285  }
1286 ;
1287 
1288 arguments:
1289  /* empty */ { }
1290 | comma_expression { free_partial_signature($1); }
1291 ;
1292 
1293 opt_expression:
1294  /* empty */
1295  { $$=strdup(" ");}
1296 | comma_expression
1297  {
1298  //free_partial_signature($1);
1299  $$ = $1;
1300  }
1301 ;
1302 
1303 comma_expression:
1304  expression
1305  {
1306  $$ = $1;
1307  }
1308 | expression TK_COMMA comma_expression
1309  {
1310  $$ = safe_build_signature($1, new_comma(), $3, NULL);
1311  }
1312 | error TK_COMMA comma_expression
1313  {
1314  csplit_parser_error("within expression list.\n");
1315  $$ = string_undefined;
1316  }
1317 ;
1318 
1319 comma_expression_opt:
1320  /* empty */ { $$ = new_empty(); }
1321 | comma_expression { $$ = $1; }
1322 ;
1323 
1324 paren_comma_expression:
1325  TK_LPAREN comma_expression TK_RPAREN
1326  {
1327  $$ = safe_build_signature(new_lparen(), $2,
1328  new_rparen(), NULL);
1329  }
1330 | TK_LPAREN error TK_RPAREN
1331  {
1332  csplit_parser_error("Error within parenthesized expression.\n");
1333  $$ = string_undefined;
1334  }
1335 ;
1336 
1337 bracket_comma_expression:
1338  TK_LBRACKET comma_expression TK_RBRACKET
1339  {
1340  free_partial_signature($2);
1341  }
1342 | TK_LBRACKET error TK_RBRACKET
1343  {
1344  }
1345 ;
1346 
1347 /*** statements ***/
1348 block: /* ISO 6.8.2 */
1349 TK_LBRACE {push_new_preprocessor_scope();} local_labels block_attrs declaration_list statement_list {pop_preprocessor_scope();} TK_RBRACE
1350  {
1351  pips_debug(5, "block found at line %d\n",
1352  csplit_line_number);
1353  }
1354 | error location TK_RBRACE
1355  { }
1356 ;
1357 
1358 block_attrs:
1359  /* empty */ {}
1360 | TK_BLOCKATTRIBUTE paren_attr_list_ne
1361  { }
1362 ;
1363 
1364 declaration_list:
1365  /* empty */ { }
1366 | declaration declaration_list
1367  {
1368  }
1369 
1370 ;
1371 statement_list:
1372  /* empty */ { }
1373 | statement statement_list
1374  {
1375  }
1376 /*(* GCC accepts a label at the end of a block *)*/
1377 | TK_IDENT TK_COLON { }
1378 ;
1379 
1380 local_labels:
1381  /* empty */ {}
1382 | TK_LABEL__ local_label_names TK_SEMICOLON local_labels
1383  { }
1384 ;
1385 
1386 local_label_names:
1387  TK_IDENT {}
1388 | TK_IDENT TK_COMMA local_label_names {}
1389 ;
1390 
1391 statement:
1392  TK_SEMICOLON
1393  {
1394  }
1395 | comma_expression TK_SEMICOLON
1396  {
1397  free_partial_signature($1);
1398  }
1399 | block { }
1400 | TK_IF paren_comma_expression statement %prec TK_IF
1401  {
1402  free_partial_signature($2);
1403  }
1404 | TK_IF paren_comma_expression statement TK_ELSE statement
1405  {
1406  free_partial_signature($2);
1407  }
1408 | TK_SWITCH
1409  {
1410  }
1411  paren_comma_expression
1412  {
1413  /* free_partial_signature($1); */
1414  }
1415  statement
1416  {
1417  }
1418 | TK_WHILE
1419  {
1420  }
1421  paren_comma_expression statement
1422  {
1423  /* free_partial_signature($1); */
1424  }
1425 | TK_DO
1426  {
1427  }
1428  statement TK_WHILE paren_comma_expression TK_SEMICOLON
1429  {
1430  /* free_partial_signature($3); */
1431  }
1432 | TK_FOR
1433  {
1434  }
1435  TK_LPAREN for_clause
1436  {
1437  }
1438 | TK_IDENT TK_COLON statement
1439  {
1440  }
1441 | TK_CASE expression TK_COLON
1442  {
1443  free_partial_signature($2);
1444  }
1445 | TK_CASE expression TK_ELLIPSIS expression TK_COLON
1446  {
1447  free_partial_signature($2);
1448  free_partial_signature($4);
1449  }
1450 | TK_DEFAULT TK_COLON
1451  {
1452  }
1453 | TK_RETURN TK_SEMICOLON
1454  {
1455  }
1456 | TK_RETURN comma_expression TK_SEMICOLON
1457  {
1458  free_partial_signature($2);
1459  }
1460 | TK_BREAK TK_SEMICOLON
1461  {
1462  }
1463 | TK_CONTINUE TK_SEMICOLON
1464  {
1465  }
1466 | TK_GOTO TK_IDENT TK_SEMICOLON
1467  {
1468  }
1469 | TK_GOTO TK_STAR comma_expression TK_SEMICOLON
1470  {
1471  free_partial_signature($3);
1472  }
1473 | TK_ASM asmattr TK_LPAREN asmtemplate asmoutputs TK_RPAREN TK_SEMICOLON
1474  { }
1475 | TK_MSASM
1476  { }
1477 | declaration
1478  { /* In C99 we can have declarations everywhere... */ }
1479 | error location TK_SEMICOLON
1480  {
1481  }
1482 ;
1483 
1484 for_clause:
1485  opt_expression TK_SEMICOLON opt_expression TK_SEMICOLON opt_expression TK_RPAREN statement
1486  {
1487  }
1488 | declaration opt_expression TK_SEMICOLON opt_expression TK_RPAREN statement
1489  {
1490  }
1491 ;
1492 
1493 declaration: /* ISO 6.7.*/
1494  decl_spec_list init_declarator_list TK_SEMICOLON
1495  {
1496  pips_debug(5, "decl_spec_list init_declarator_list TK_SEMICOLON -> declaration\n");
1497  pips_debug(5, "decl_spec_list=\"%s\", init_declarator_list=\"%s\"\n",
1498  $1, string_undefined_p($2) ? "UNDEFINED" : $2);
1499  csplit_is_function = 0; /* not function's declaration */
1500  //pips_assert("TypedefStack is empty", stack_empty_p(TypedefStack));
1501  csplit_is_typedef = false;
1502  free_partial_signature($1);
1503  free_partial_signature($2);
1504  $$ = string_undefined;
1505  PopTypedef();
1506  }
1507 | decl_spec_list TK_SEMICOLON
1508  {
1509  pips_debug(5, "decl_spec_list TK_SEMICOLON -> declaration\n");
1510  pips_debug(5, "decl_spec_list=\"%s\"\n", $1);
1511  csplit_is_function = 0; /* not function's declaration */
1512  //pips_assert("TypedefStack is empty", stack_empty_p(TypedefStack));
1513  csplit_is_typedef = false;
1514  free_partial_signature($1);
1515  $$ = string_undefined;
1516  PopTypedef();
1517  }
1518 ;
1519 
1520 init_declarator_list: /* ISO 6.7 */
1521  init_declarator
1522  {
1523  $$ = string_undefined;
1524  }
1525 | init_declarator TK_COMMA init_declarator_list
1526  {
1527  $$ = string_undefined;
1528  }
1529 
1530 ;
1531 init_declarator: /* ISO 6.7 */
1532  declarator {
1533  $$ = string_undefined;
1534  }
1535 | declarator TK_EQ init_expression
1536  {
1537  $$ = string_undefined;
1538  }
1539 ;
1540 
1541 /* Design choice: I can either build signatures unconditionnally to use
1542  all declarations to validate this grammar, or I can build them
1543  conditionnally ot a potential interest. In the later case, I do not
1544  lose much in computation time because of the parser structure which is
1545  going to build part of useless declarations anyway before I realize
1546  they are useless, but I lose a lot in robustness since anything will go
1547  as soon as an undefined_string crops up. */
1548 decl_spec_list: /* ISO 6.7 */
1549  /* ISO 6.7.1 */
1550  TK_TYPEDEF decl_spec_list_opt
1551  {
1552  pips_debug(5, "TK_TYPEDEF decl_spec_list_opt->decl_spec_list\n");
1553  csplit_is_typedef = true;
1554  pips_debug(8, "csplit_is_typedef=%s\n", bool_to_string(csplit_is_typedef));
1555  /* I would have liked not to build them when unnecessary. */
1556  /*
1557  free_partial_signature($2);
1558  $$ = string_undefined;
1559  */
1560  $$ = build_signature(new_signature("typedef"), $2, NULL);
1561  }
1562 | TK_EXTERN decl_spec_list_opt
1563  {
1564  pips_debug(5, "TK_EXTERN decl_spec_list_opt->decl_spec_list\n");
1565  /*
1566  free_partial_signature($2);
1567  $$ = string_undefined;
1568  */
1569  $$ = build_signature(new_signature("extern"), $2, NULL);
1570  }
1571 | TK_STATIC decl_spec_list_opt
1572  {
1573  /* There are 3 cases: static function, external and internal static variable*/
1574  pips_debug(5, "TK_STATIC decl_spec_list_opt->decl_spec_list\n");
1575  csplit_is_static_p = true;
1576  if (!csplit_is_function) {
1577  pips_debug(5, "We are not within a function, so this STATIC may be related to a function: %s.\n", $2);
1578  }
1579  $$ = build_signature(new_signature("static"), $2, NULL);
1580  }
1581 | TK_AUTO decl_spec_list_opt
1582  {
1583  pips_debug(5, "TK_AUTO decl_spec_list_opt->decl_spec_list\n");
1584  /*
1585  free_partial_signature($2);
1586  $$ = string_undefined;
1587  */
1588  $$ = build_signature(new_signature("auto"), $2, NULL);
1589  }
1590 | TK_REGISTER decl_spec_list_opt
1591  {
1592  pips_debug(5, "TK_REGISTER decl_spec_list_opt->decl_spec_list\n");
1593  /*
1594  free_partial_signature($2);
1595  $$ = string_undefined;
1596  */
1597  $$ = build_signature(new_signature("register"), $2, NULL);
1598  }
1599 | TK_THREAD decl_spec_list_opt
1600  {
1601  pips_debug(5, "TK_THREAD decl_spec_list_opt->decl_spec_list\n");
1602  /*
1603  free_partial_signature($2);
1604  $$ = string_undefined;
1605  */
1606  $$ = build_signature(new_signature("thread"), $2, NULL);
1607  }
1608  /* ISO 6.7.2 */
1609 | type_spec decl_spec_list_opt_no_named
1610  {
1611  pips_debug(5, "type_spec and decl_spec_list_opt_no_named -> decl_spec_list\n");
1612  if(string_undefined_p($1)) {
1613  pips_debug(5, "type_spec is undefined\n");
1614  if(!string_undefined_p($2)) {
1615  pips_debug(5, "Useless partial signature $2: %s\n", $2);
1616  free($2);
1617  }
1618  else
1619  pips_debug(5, "$1 and $2 undefined\n");
1620  $$ = string_undefined;
1621  }
1622  else {
1623  pips_debug(5, "Type spec: \"%s\"\n", $1);
1624  $$ = build_signature($1, $2, NULL);
1625  pips_debug(5, "Partial signature: \"%s\"\n", $$);
1626  /* FI: might need a call to reset_csplit_current_function_name
1627  if(!string_undefined_p(csplit_current_function_name)
1628  && strcmp($2, csplit_current_function_name)==0) {
1629  csplit_current_function_name
1630  = csplit_current_function_name2;
1631  csplit_current_function_name2 = string_undefined;
1632  }
1633  */
1634  }
1635  }
1636  /* ISO 6.7.4 */
1637 | TK_INLINE decl_spec_list_opt
1638  {
1639  pips_debug(5, "TK_INLINE decl_spec_list_opt->decl_spec_list\n");
1640  /*
1641  free_partial_signature($2);
1642  $$ = string_undefined;
1643  */
1644  $$ = build_signature(new_signature("inline"), $2, NULL);
1645  }
1646 | attribute decl_spec_list_opt
1647  {
1648  pips_debug(5, "attribute decl_spec_list_opt->decl_spec_list\n");
1649  /*
1650  free_partial_signature($1);
1651  free_partial_signature($2);
1652  $$ = string_undefined;
1653  */
1654  $$ = build_signature($1, $2, NULL);
1655  }
1656 /* specifier pattern variable (must be last in spec list) */
1657 | TK_AT_SPECIFIER TK_LPAREN TK_IDENT TK_RPAREN
1658  {
1659  pips_debug(5, "TK_AT_SPECIFIER TK_LPAREN TK_IDENT TK_RPAREN->decl_spec_list\n");
1660  /* $$ = string_undefined; */
1661  $$ = build_signature(new_signature("at specifier"),
1662  new_lparen(), new_signature($3),
1663  new_rparen(), NULL);
1664  }
1665 ;
1666 
1667 /* (* In most cases if we see a NAMED_TYPE we must shift it. Thus we declare
1668  * NAMED_TYPE to have right associativity *) */
1669 decl_spec_list_opt:
1670 /* empty */ { $$=new_empty(); PushTypedef();} %prec TK_NAMED_TYPE
1671 | decl_spec_list { $$=$1;}
1672 ;
1673 
1674 /* (* We add this separate rule to handle the special case when an appearance
1675  * of NAMED_TYPE should not be considered as part of the specifiers but as
1676  * part of the declarator. IDENT has higher precedence than NAMED_TYPE *)
1677  */
1678 decl_spec_list_opt_no_named: /* empty */
1679  {
1680  /* Cf "Actions in Mid-Rule" in the Bison doc. */
1681  $<string>$ = new_empty();
1682  PushTypedef();
1683  free($<string>$);
1684  }
1685  %prec TK_IDENT
1686  {
1687  pips_debug(8, "empty TK_IDENT->decl_spec_list_opt_no_named\n");
1688  /* pips_debug(8, "TK_IDENT %s is discarded\n", $1); */
1689  /* free($1); */
1690  /* FI: I do not feel safe about this. */
1691  /* $$=strdup(splitc_text); */ /* FI: why not $1?*/
1692  /* $$ = strdup("IAmNotSure"); */
1693  $$ = new_empty();
1694  }
1695 | decl_spec_list {
1696  pips_debug(8,
1697  "decl_spec_slit->decl_spec_list_opt_no_named\n");
1698  $$=$1;
1699  }
1700 ;
1701 
1702 /* To generate the function signature, we need the keywords. */
1703 
1704 type_spec: /* ISO 6.7.2 */
1705  TK_VOID
1706  {
1707  pips_debug(8, "TK_VOID->type_spec\n");
1708  $$ = new_signature(splitc_text);
1709  }
1710 | TK_CHAR
1711  {
1712  pips_debug(8, "TK_CHAR->type_spec\n");
1713  $$ = new_signature(splitc_text);
1714  }
1715 | TK_SHORT
1716  {
1717  pips_debug(8, "TK_SHORT->type_spec\n");
1718  $$ = new_signature(splitc_text);
1719  }
1720 | TK_INT
1721  {
1722  pips_debug(8, "TK_INT->type_spec\n");
1723  $$ = new_signature(splitc_text);
1724  }
1725 | TK_INT128
1726  {
1727  pips_debug(8, "TK_INT128->type_spec\n");
1728  $$ = new_signature(splitc_text);
1729  }
1730 | TK_UINT128
1731  {
1732  pips_debug(8, "TK_UINT128->type_spec\n");
1733  $$ = new_signature(splitc_text);
1734  }
1735 | TK_COMPLEX
1736  {
1737  pips_debug(8, "TK_COMPLEX->type_spec\n");
1738  $$ = new_signature(splitc_text);
1739  }
1740 | TK_LONG
1741  {
1742  pips_debug(8, "TK_LONG->type_spec\n");
1743  $$ = new_signature(splitc_text);
1744  }
1745 | TK_FLOAT
1746  {
1747  pips_debug(8, "TK_FLOAT->type_spec\n");
1748  $$ = new_signature(splitc_text);
1749  }
1750 | TK_DOUBLE
1751  {
1752  pips_debug(8, "TK_DOUBLE->type_spec\n");
1753  $$ = new_signature(splitc_text);
1754  }
1755 | TK_SIGNED
1756  {
1757  pips_debug(8, "TK_SIGNED->type_spec\n");
1758  $$ = new_signature(splitc_text);
1759  }
1760 | TK_UNSIGNED
1761  {
1762  pips_debug(8, "TK_UNSIGNED->type_spec\n");
1763  $$ = new_signature(splitc_text);
1764  }
1765 | TK_STRUCT id_or_typename
1766  {
1767  pips_debug(8, "TK_STRUCT id_or_typename->type_spec\n");
1768  /* FI: not clean, but the parser
1769  distinguishes between different kinds of
1770  ident and do not process them the same
1771  way. */
1772  if(!string_undefined_p(csplit_current_function_name)
1773  && strcmp(csplit_current_function_name, $2)==0) {
1774  reset_csplit_current_function_name();
1775  }
1776  $$ = build_signature(new_signature("struct"), $2, NULL);
1777  /* see reset_csplit_current_function_name()
1778  if(!string_undefined_p(csplit_current_function_name)
1779  && strcmp($2, csplit_current_function_name)==0) {
1780  csplit_current_function_name
1781  = csplit_current_function_name2;
1782  csplit_current_function_name2 = string_undefined;
1783  }
1784  */
1785  }
1786 | TK_STRUCT id_or_typename TK_LBRACE /* { } */ struct_decl_list TK_RBRACE
1787  {
1788  pips_debug(8, "TK_STRUCT id_or_typename TK_LBRACE struct_decl_list"
1789  " TK_RBRACE->type_spec\n");
1790  /* FI: I do not understand the reset. I copy
1791  the guard from previous rule */
1792  if(!string_undefined_p(csplit_current_function_name)
1793  && strcmp(csplit_current_function_name, $2)==0) {
1794  reset_csplit_current_function_name();
1795  }
1796  $$ = build_signature(new_signature("bstruct"), $2, new_lbrace(), $4,
1797  new_rbrace(), NULL);
1798  }
1799 | TK_STRUCT TK_LBRACE /* { } */
1800  struct_decl_list TK_RBRACE
1801  {
1802  pips_debug(8, "TK_STRUCT TK_LBRACE struct_decl_list TK_RBRACE->type_spec\n");
1803  $$ = build_signature(new_signature("struct"), new_lbrace(), $3,
1804  new_rbrace(), NULL);
1805  }
1806 | TK_UNION id_or_typename
1807  {
1808  pips_debug(8, "TK_UNION id_or_typename->type_spec\n");
1809  if(strcmp(csplit_current_function_name, $2)==0) {
1810  reset_csplit_current_function_name();
1811  }
1812  $$ = build_signature(new_signature("union"), $2, NULL);
1813  }
1814 | TK_UNION id_or_typename TK_LBRACE /* { } */ struct_decl_list TK_RBRACE
1815  {
1816  pips_debug(8, "TK_UNION id_or_typename TK_LBRACE struct_decl_list TK_RBRACE->type_spec\n");
1817  if(strcmp(csplit_current_function_name, $2)==0) {
1818  reset_csplit_current_function_name();
1819  }
1820  $$ = build_signature(new_signature("union"), $2, new_lbrace(), $4,
1821  new_rbrace(), NULL);
1822  }
1823 | TK_UNION TK_LBRACE /* { } */ struct_decl_list TK_RBRACE
1824  {
1825  pips_debug(8, "TK_UNION TK_LBRACE->type_spec\n");
1826  $$ = build_signature(new_signature("union"), new_lbrace(), $3,
1827  new_rbrace(), NULL);
1828  }
1829 | TK_ENUM id_or_typename
1830  {
1831  pips_debug(8, "TK_ENUM id_or_typename->type_spec\n");
1832  if(strcmp(csplit_current_function_name, $2)==0) {
1833  reset_csplit_current_function_name();
1834  }
1835  $$ = build_signature(new_signature("enum"), $2, NULL);
1836  }
1837 | TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE
1838  {
1839  pips_debug(8, "TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE->type_spec\n");
1840  if(strcmp(csplit_current_function_name, $2)==0) {
1841  reset_csplit_current_function_name();
1842  }
1843  $$ = build_signature(new_signature("enum"), $2, new_lbrace(), $4, $5, new_rbrace(), NULL);
1844  }
1845 | TK_ENUM TK_LBRACE enum_list maybecomma TK_RBRACE
1846  {
1847  pips_debug(8, "TK_ENUM TK_LBRACE enum_list maybecomma TK_RBRACE->type_spec\n");
1848  $$ = build_signature(new_signature("enum"), new_lbrace(), $3, $4, new_rbrace(), NULL);
1849  }
1850 | TK_NAMED_TYPE
1851  {
1852  pips_debug(8, "TK_NAMED_TYPE->type_spec\n");
1853  $$ = new_signature($1);
1854  }
1855 | TK_TYPEOF TK_LPAREN expression TK_RPAREN
1856  {
1857  pips_debug(8, "TK_TYPEOF TK_LPAREN expression TK_RPAREN->type_spec\n");
1858  $$ = build_signature(new_signature("typeof"), new_lparen(), new_signature("IDoNotWantToDealWithExpressions"), new_rparen(), NULL);
1859  }
1860 | TK_TYPEOF TK_LPAREN type_name TK_RPAREN
1861  {
1862  pips_debug(8, "TK_TYPEOF TK_LPAREN type_name TK_RPAREN->type_spec\n");
1863  $$ = build_signature(new_signature("typeof"), new_lparen(), $3, new_rparen(), NULL);;
1864  }
1865 ;
1866 
1867 struct_decl_list: /* (* ISO 6.7.2. Except that we allow empty structs. We
1868  * also allow missing field names. *)
1869  */
1870  /* empty */ { $$ = new_empty(); }
1871 | decl_spec_list TK_SEMICOLON struct_decl_list
1872  {
1873  PopTypedef();
1874  $$ = build_signature($1, new_semicolon(), $3, NULL);
1875  }
1876 | decl_spec_list /* { } */
1877  field_decl_list TK_SEMICOLON struct_decl_list
1878  {
1879  PopTypedef();
1880  $$ = build_signature($1, $2, new_semicolon(), $4, NULL);
1881  }
1882 | error TK_SEMICOLON struct_decl_list
1883  {
1884  csplit_parser_error("in struct declaration.");
1885  $$ = string_undefined;
1886  }
1887 ;
1888 
1889 field_decl_list: /* (* ISO 6.7.2 *) */
1890  field_decl
1891  {
1892  $$ = $1;
1893  }
1894 | field_decl TK_COMMA field_decl_list
1895  {
1896  $$ = build_signature($1, new_comma(), $3, NULL);
1897  }
1898 ;
1899 
1900 field_decl: /* (* ISO 6.7.2. Except that we allow unnamed fields. *) */
1901  declarator { $$ = $1; }
1902 | declarator TK_COLON expression
1903  {
1904  $$ = build_signature($1, new_colon(), $3, NULL);
1905  }
1906 | TK_COLON expression
1907  {
1908  $$ = build_signature(new_colon(), $2, NULL);
1909  }
1910 ;
1911 
1912 enum_list: /* (* ISO 6.7.2.2 *) */
1913  enumerator
1914  {
1915  $$ = $1;
1916  }
1917 | enum_list TK_COMMA enumerator
1918  {
1919  $$ = build_signature($1, new_comma(), $3, NULL);
1920  }
1921 | enum_list TK_COMMA error
1922  {
1923  csplit_parser_error("in enum list");
1924  $$ = string_undefined;
1925  }
1926 ;
1927 
1928 enumerator:
1929  TK_IDENT
1930  {
1931  pips_debug(5, "TK_IDENT->enumerator\n");
1932  pips_debug(9, "TK_IDENT=%s\n", $1);
1933  $$ = new_signature($1);
1934  }
1935 | TK_IDENT TK_EQ expression
1936  {
1937  pips_debug(5, "TK_IDENT TK_EQ expression->enumerator\n");
1938  pips_debug(9, "TK_IDENT=%s\n", $1);
1939  $$ = build_signature(new_signature($1), new_eq(), $3, NULL);
1940  }
1941 ;
1942 
1943 declarator: /* (* ISO 6.7.5. Plus Microsoft declarators.*) */
1944  pointer_opt direct_decl attributes_with_asm
1945  {
1946  pips_debug(5, "pointer_opt direct_decl attributes_with_asm -> declarator\n");
1947  pips_debug(5, "pointer_opt=\"%s\", direct_decl=\"%s\", attributes_with_asm=\"%s\"\n", $1, $2, $3);
1948  /* Type and identifier information are mixed
1949  here. Instead of trying to retrieve the type
1950  only, it might be easier to postprocess the
1951  signature for Rule 2. */
1952  if(!string_undefined_p($3) && strlen($3)>0) {
1953  pips_user_warning("attributes_with_asm=", $3);
1954  csplit_parser_warning("attributes_with_asm not supported\n");
1955  free_partial_signature($3);
1956  }
1957  if(true) /* Keep parameter names in signatures. */
1958  $$ = build_signature($1, $2, NULL);
1959  else {
1960  /* This does not work! Do not try it anymore... */
1961  free_partial_signature($2);
1962  $$ = $1;
1963  }
1964  }
1965 ;
1966 
1967 direct_decl: /* (* ISO 6.7.5 *) */
1968  /* (* We want to be able to redefine named
1969  * types as variable names *) */
1970  id_or_typename
1971  {
1972  pips_debug(5, "id_or_typename -> direct_decl\n");
1973  pips_debug(5,"id_or_typename=\"%s\", csplit_is_typedef=%s\n", $1, bool_to_string(csplit_is_typedef));
1974  /* FI: I declare many too many types! I should look at Nga's grammar. */
1975  if (csplit_is_typedef) {
1976  /* Tell the lexer about the new type names : add to keyword_typedef_table */
1977  /*
1978  hash_put(keyword_typedef_table,new_signature($1),(void *) TK_NAMED_TYPE);
1979  */
1980  keep_track_of_typedef(new_signature($1));
1981  /* Too early to reset: one typedef can be used
1982  to declare several named types... but I do
1983  not know how to use it. */
1984  //csplit_is_typedef = false;
1985  $$ = $1;
1986  }
1987  else if(true) { /* Keep identifiers in signatures */
1988  $$ = $1;
1989  }
1990  else { /* You are going to loose the function
1991  identifier. You may also loose enum
1992  member names... */
1993  $$ = new_empty();
1994  }
1995  }
1996 | TK_LPAREN attributes declarator TK_RPAREN
1997  {
1998  $$ = build_signature(new_lparen(), $2, $3, new_rparen(), NULL);
1999  }
2000 | direct_decl TK_LBRACKET attributes comma_expression_opt TK_RBRACKET
2001  {
2002  string s1 = $1;
2003  string s3 = $3;
2004  string s4 = $4;
2005  /* FI: quick fix for
2006  summary_preconditions02.c which uses a
2007  function call to size an array... */
2008  if(string_undefined_p(s4))
2009  s4 = new_empty();
2010  $$ = build_signature(s1, new_lbracket(), s3, s4, new_rbracket(), NULL);
2011  }
2012 | direct_decl TK_LBRACKET attributes error TK_RBRACKET
2013  {
2014  $$ = build_signature($1, new_lbracket(), $3, new_rbracket(), NULL);
2015  }
2016 | direct_decl parameter_list_startscope rest_par_list TK_RPAREN
2017  {
2018  $$ = build_signature($1, $2, $3, new_rparen(), NULL);
2019  }
2020 ;
2021 
2022 parameter_list_startscope:
2023  TK_LPAREN { $$ = new_lparen();}
2024 ;
2025 
2026 rest_par_list:
2027  /* empty */ { $$ = new_empty();}
2028 | parameter_decl rest_par_list1
2029  {
2030  /* If such a test is really useful, it might be
2031  better located in another version of
2032  build_signature() which would check its
2033  arguments and decide to return
2034  string_undefined as soon as one of its
2035  arguments is undefined. */
2036  if(string_undefined_p($1)) {
2037  free_partial_signature($2);
2038  $$ = string_undefined;
2039  }
2040  else
2041  $$ = build_signature($1, $2, NULL);
2042  }
2043 ;
2044 rest_par_list1:
2045  /* empty */ { $$ = new_empty(); }
2046 | TK_COMMA TK_ELLIPSIS
2047  {
2048  $$ = build_signature(new_comma(), new_ellipsis(), NULL);
2049  }
2050 | TK_COMMA parameter_decl rest_par_list1
2051  {
2052  $$ = build_signature(new_comma(), $2, $3, NULL);
2053  }
2054 ;
2055 
2056 parameter_decl: /* (* ISO 6.7.5 *) */
2057  decl_spec_list declarator
2058  {
2059  PopTypedef();
2060  $$ = build_signature($1, $2, NULL);
2061  }
2062 | decl_spec_list abstract_decl
2063  {
2064  pips_debug(5, "decl_spec_list abstract_decl->parameter_decl\n");
2065  /*
2066  $$ = build_signature($1, $2, NULL);
2067  $$ = build_signature($1,
2068  $2,
2069  NULL);
2070  */
2071  /* pips_internal_error("FI: C syntax problem...\n"); */
2072  /* To avoid building to much useless stuff,
2073  although it foes not gain much because of
2074  parser structure: $2 is built before you
2075  realize it's useless because of $1. */
2076  if(string_undefined_p($1)) {
2077  free_partial_signature($2);
2078  $$ = string_undefined;
2079  }
2080  else
2081  $$ = build_signature($1, $2, NULL);
2082  PopTypedef();
2083  }
2084 | decl_spec_list
2085  {
2086  PopTypedef();
2087  $$ = $1;
2088  }
2089 | TK_LPAREN parameter_decl TK_RPAREN
2090  {
2091  //PopTypedef();
2092  $$ = build_signature(new_lparen(), $2, new_rparen(), NULL);
2093  }
2094 ;
2095 
2096 /* (* Old style prototypes. Like a declarator *) */
2097 old_proto_decl:
2098  pointer_opt direct_old_proto_decl
2099  {
2100  $$ = build_signature($1, $2, NULL);
2101  }
2102 ;
2103 direct_old_proto_decl:
2104  direct_decl TK_LPAREN old_parameter_list_ne TK_RPAREN old_pardef_list
2105  {
2106  /* You do not need the formal parameter list */
2107  /*
2108  $$ = build_signature($1, new_lparen(), $3, new_rparen(),
2109  $5, NULL);
2110  */
2111  free_partial_signature($3);
2112  free_partial_signature($5);
2113  /* $$ = build_signature($1, new_lparen(), new_rparen(), $5, NULL); */
2114  $$ = build_signature($1, new_lparen(), new_rparen(), NULL);
2115  }
2116 | direct_decl TK_LPAREN TK_RPAREN
2117  {
2118  $$ = build_signature($1, new_lparen(), new_rparen(), NULL);
2119  }
2120 ;
2121 
2122 old_parameter_list_ne:
2123  TK_IDENT
2124  {
2125  $$ = new_signature($1);
2126  }
2127 | TK_IDENT TK_COMMA old_parameter_list_ne
2128  {
2129  $$ = build_signature($1, new_comma(), $3, NULL);
2130  }
2131 ;
2132 
2133 old_pardef_list:
2134  /* empty */ { $$ = new_empty(); }
2135 | decl_spec_list old_pardef TK_SEMICOLON TK_ELLIPSIS
2136  {
2137  /* You want a comma-separated list of types, but... */
2138  /* bad news: "int * pj" is broken as "int" for
2139  decl_spec_list and "* pj" for old_pardef */
2140  $$ = build_signature($1, $2, new_semicolon(),
2141  new_ellipsis(), NULL);
2142  /*
2143  $$ = build_signature($1, $2, new_comma(),
2144  new_ellipsis(), NULL);
2145  */
2146  PopTypedef();
2147  }
2148 | decl_spec_list old_pardef TK_SEMICOLON old_pardef_list
2149  {
2150  $$ = build_signature($1, $2, new_semicolon(),
2151  $4, NULL);
2152  PopTypedef();
2153  }
2154 ;
2155 
2156 old_pardef:
2157  declarator
2158  {
2159  $$ = $1;
2160  }
2161 | declarator TK_COMMA old_pardef
2162  {
2163  $$ = build_signature($1, new_comma(), $3, NULL);
2164  }
2165 | error
2166  {
2167  csplit_parser_error("In old parameter definition\n");
2168  $$ = string_undefined;
2169  }
2170 ;
2171 
2172 pointer: /* (* ISO 6.7.5 *) */
2173  TK_STAR attributes pointer_opt
2174  {
2175  pips_debug(5, "TK_STAR attributes pointer_opt -> pointer\n");
2176  pips_debug(5, "attributes: \"%s\", pointer_opt: \"%s\"\n", $2, $3);
2177  $$ = build_signature(new_star(), $2, $3, NULL);
2178  }
2179 ;
2180 
2181 pointer_opt:
2182  /* empty */ { $$ = new_empty(); }
2183 | pointer
2184  { $$ = $1; }
2185 ;
2186 
2187 type_name: /* (* ISO 6.7.6 *) */
2188  decl_spec_list abstract_decl
2189  {
2190  PopTypedef();
2191  $$ = build_signature($1, $2, NULL);
2192  }
2193 | decl_spec_list
2194  {
2195  PopTypedef();
2196  $$ = $1;
2197  }
2198 ;
2199 
2200 abstract_decl: /* (* ISO 6.7.6. *) */
2201  pointer_opt abs_direct_decl attributes
2202  {
2203  pips_debug(5, "pointer_opt abs_direct_decl attributes -> abstract_decl\n");
2204  $$ = build_signature($1, $2, $3, NULL);
2205  }
2206 | pointer
2207  {
2208  pips_debug(5, "pointer -> abstract_decl\n");
2209  $$ = $1;
2210  }
2211 ;
2212 
2213 abs_direct_decl: /* (* ISO 6.7.6. We do not support optional declarator for
2214  * functions. Plus Microsoft attributes. See the
2215  * discussion for declarator. *) */
2216  TK_LPAREN attributes abstract_decl TK_RPAREN
2217  {
2218  $$ = build_signature(new_lparen(), $2, $3, new_rparen(), NULL);
2219  }
2220 | TK_LPAREN error TK_RPAREN
2221  {
2222  csplit_parser_error("Parse error: TK_LPAREN error TK_RPAREN\n");
2223  }
2224 
2225 | abs_direct_decl_opt TK_LBRACKET comma_expression_opt TK_RBRACKET
2226  {
2227  $$ = build_signature($1, new_lbracket(), new_signature("IDoNotWantcomma_expression_opt"), new_rbracket(), NULL);
2228  }
2229 /*(* The next shoudl be abs_direct_decl_opt but we get conflicts *)*/
2230 | abs_direct_decl parameter_list_startscope rest_par_list TK_RPAREN
2231  {
2232  $$ = build_signature($1, $2, $3, new_rparen(), NULL);
2233  }
2234 ;
2235 
2236 abs_direct_decl_opt:
2237  abs_direct_decl
2238  {
2239  $$ = $1;
2240  }
2241 | /* empty */ { $$ = new_empty(); }
2242 ;
2243 
2244 function_def: /* (* ISO 6.9.1 *) */
2245  function_def_start block
2246  {
2247  }
2248 
2249 function_def_start: /* (* ISO 6.9.1 *) */
2250  decl_spec_list declarator
2251  {
2252  pips_debug(5, "decl_spec_list declarator->function_def_start\n");
2253  /* let's use a pretty limited stack... */
2254  if(string_undefined_p(csplit_current_function_name)) {
2255  csplit_current_function_name =
2256  csplit_current_function_name2;
2257  csplit_current_function_name2 = string_undefined;
2258  }
2259 
2260  pips_assert("A temptative function name is available",
2261  !string_undefined_p(csplit_current_function_name));
2262  pips_assert("No definite function name is available",
2263  string_undefined_p(csplit_definite_function_name));
2264  csplit_definite_function_name
2265  = strdup(csplit_current_function_name);
2266  pips_debug(5, "Rule 1: Function declaration is located between line %d and line %d\n", get_csplit_current_beginning(), csplit_line_number);
2267  csplit_is_function = 1; /* function's declaration */
2268 
2269  current_function_is_static_p = csplit_is_static_p;
2270  csplit_is_static_p = false;
2271  csplit_definite_function_signature
2272  = simplify_signature(build_signature($1, $2, NULL));
2273  pips_debug(1, "Signature for function \"%s\": \"%s\"\n\n",
2274  csplit_definite_function_name,
2275  csplit_definite_function_signature);
2276  PopTypedef();
2277  }
2278 /* (* Old-style function prototype *) */
2279 | decl_spec_list old_proto_decl
2280  {
2281  /* The signature obtained here must be
2282  post-processed. The declaration list after
2283  the empty parameter list could be entirely
2284  dropped or converted into a type list. But
2285  beware of parameters declared together or
2286  declared in another order. Note that we could
2287  keep the parameter list between the
2288  parentheses and fetch the associated
2289  types. */
2290  pips_debug(5, "decl_spec_list old_proto_decl->function_def_start");
2291  csplit_definite_function_name
2292  = strdup(csplit_current_function_name);
2293  pips_debug(5, "Rule 2: Function declaration is located between line %d and line %d\n", get_csplit_current_beginning(), csplit_line_number);
2294  csplit_is_function = 1; /* function's declaration */
2295  current_function_is_static_p = csplit_is_static_p;
2296  csplit_is_static_p = false;
2297  csplit_definite_function_signature
2298  = simplify_signature(build_signature($1, $2, NULL));
2299  pips_debug(1, "Signature for function \"%s\": \"%s\"\n\n",
2300  csplit_definite_function_name,
2301  csplit_definite_function_signature);
2302  PopTypedef();
2303  }
2304 /* (* New-style function that does not have a return type *) */
2305 | TK_IDENT parameter_list_startscope rest_par_list TK_RPAREN
2306  {
2307  pips_debug(5, "TK_IDENT parameter_list_startscope rest_par_list TK_RPAREN->function_def_start");
2308  /* Create the current function */
2309  pips_debug(5, "Rule 3: Function declaration of \"%s\" is located between line %d and line %d\n", $1, get_csplit_current_beginning(), csplit_line_number);
2310  /* current_function_name = strdup($1); */
2311  csplit_definite_function_name = strdup($1);
2312  csplit_is_function = 1; /* function's declaration */
2313  current_function_is_static_p = csplit_is_static_p;
2314  csplit_is_static_p = false;
2315 
2316  csplit_definite_function_signature
2317  = simplify_signature
2318  (build_signature($1, $2, $3, new_rparen(), NULL));
2319  pips_debug(1, "Signature for function %s: %s\n\n",
2320  csplit_current_function_name,
2321  csplit_definite_function_signature);
2322  }
2323 /* (* No return type and no old-style parameter list *) */
2324 | TK_IDENT TK_LPAREN old_parameter_list_ne TK_RPAREN old_pardef_list
2325  {
2326  pips_debug(5, "TK_IDENT TK_LPAREN old_parameter_list_ne TK_RPAREN old_pardef_list->function_def_start");
2327  pips_debug(5, "Rule 4: Function \"%s\" declaration is located between line %d and line %d\n",
2328  $1,
2329  get_csplit_current_beginning(),
2330  csplit_line_number);
2331  csplit_definite_function_name = strdup($1);
2332  csplit_is_function = 1; /* function's declaration */
2333  current_function_is_static_p = csplit_is_static_p;
2334  csplit_is_static_p = false;
2335 
2336  free_partial_signature($3);
2337  free_partial_signature($5);
2338  csplit_definite_function_signature
2339  = simplify_signature
2340  (build_signature($1, new_lparen(), new_rparen(), NULL));
2341  pips_debug(1, "Signature for function %s: %s\n\n",
2342  csplit_current_function_name,
2343  csplit_definite_function_signature);
2344  }
2345 /* (* No return type and no parameters *) */
2346 | TK_IDENT TK_LPAREN TK_RPAREN
2347  {
2348  pips_debug(5, "TK_IDENT TK_LPAREN TK_RPAREN->function_def_start");
2349  /* MakeCurrentFunction*/
2350  csplit_is_function = 5; /* function's declaration */
2351  pips_debug(5, "Rule 5: Function \"%s\" declaration is located between line %d and line %d\n",
2352  $1,
2353  get_csplit_current_beginning(),
2354  csplit_line_number);
2355  pips_internal_error("Not implemented yet");
2356  }
2357 ;
2358 
2359 /*** GCC attributes ***/
2360 attributes:
2361  /* empty */
2362  { $$ = new_empty(); }
2363 | attribute attributes
2364  { $$ = build_signature($1, $2, NULL); }
2365 ;
2366 
2367 /* (* In some contexts we can have an inline assembly to specify the name to
2368  * be used for a global. We treat this as a name attribute *) */
2369 attributes_with_asm:
2370  /* empty */
2371  { $$ = new_empty(); }
2372 | attribute attributes_with_asm
2373  { $$ = build_signature($1, $2, NULL); }
2374 | TK_ASM TK_LPAREN string_constant TK_RPAREN attributes
2375  {
2376 /* skip the asm declaration ... this is relatively dangerous because it can change the symbol name. Yet it is ok to skip it at split level */
2377 #if 0
2378  free_partial_signature($5);
2379  csplit_parser_error("ASM extensions not implemented\n");
2380  $$ = string_undefined;
2381 #else
2382  { $$ = build_signature($5, NULL, NULL); }
2383 
2384 #endif
2385  }
2386 ;
2387 
2388 attribute:
2389  TK_ATTRIBUTE TK_LPAREN paren_attr_list_ne TK_RPAREN
2390  {
2391  $$ = build_signature(new_signature("attribute"), new_lparen(), $3,
2392  new_rparen(), NULL);
2393  }
2394 | TK_DECLSPEC paren_attr_list_ne
2395  {
2396  $$ = build_signature(new_signature("decl_spec"), $2, NULL);
2397  }
2398 | TK_MSATTR
2399  {
2400  $$ = new_signature("msattr");
2401  }
2402  /* ISO 6.7.3 */
2403 | TK_CONST
2404  {
2405  $$ = new_signature("const");
2406  }
2407 | TK_RESTRICT
2408  {
2409  $$ = new_signature("restrict");
2410  }
2411 | TK_VOLATILE
2412  {
2413  $$ = new_signature("volatile");
2414  }
2415 | TK_STATIC_DIMENSION
2416  {
2417  $$ = new_signature("static");
2418  }
2419 ;
2420 
2421 /** (* PRAGMAS and ATTRIBUTES *) ***/
2422 /* (* We want to allow certain strange things that occur in pragmas, so we
2423  * cannot use directly the language of expressions *) */
2424 attr:
2425 | id_or_typename
2426  { }
2427 | TK_IDENT TK_COLON TK_INTCON
2428  { }
2429 | TK_DEFAULT TK_COLON TK_INTCON
2430  { }
2431 | TK_IDENT TK_LPAREN TK_RPAREN
2432  { }
2433 | TK_IDENT paren_attr_list_ne
2434  { }
2435 | TK_INTCON
2436  { }
2437 | string_constant
2438  { }
2439 | TK_CONST
2440  { }
2441 | TK_SIZEOF expression
2442  {
2443  free_partial_signature($2);
2444  }
2445 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
2446  { }
2447 
2448 | TK_ALIGNOF expression
2449  {
2450  free_partial_signature($2);
2451  }
2452 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
2453  { }
2454 | TK_PLUS expression
2455  {
2456  free_partial_signature($2);
2457  }
2458 | TK_MINUS expression
2459  { free_partial_signature($2);}
2460 | TK_STAR expression
2461  { free_partial_signature($2);}
2462 | TK_AND expression %prec TK_ADDROF
2463 
2464  { free_partial_signature($2);}
2465 | TK_EXCLAM expression
2466  { free_partial_signature($2);}
2467 | TK_TILDE expression
2468  { free_partial_signature($2);}
2469 | attr TK_PLUS attr
2470  { }
2471 | attr TK_MINUS attr
2472  { }
2473 | attr TK_STAR expression
2474  { free_partial_signature($3);}
2475 | attr TK_SLASH attr
2476  { }
2477 | attr TK_PERCENT attr
2478  { }
2479 | attr TK_AND_AND attr
2480  { }
2481 | attr TK_PIPE_PIPE attr
2482  { }
2483 | attr TK_AND attr
2484  {
2485  }
2486 | attr TK_PIPE attr
2487  { }
2488 | attr TK_CIRC attr
2489  { }
2490 | attr TK_EQ_EQ attr
2491  { }
2492 | attr TK_EXCLAM_EQ attr
2493  { }
2494 | attr TK_INF attr
2495  { }
2496 | attr TK_SUP attr
2497  { }
2498 | attr TK_INF_EQ attr
2499  { }
2500 | attr TK_SUP_EQ attr
2501  { }
2502 | attr TK_INF_INF attr
2503  { }
2504 | attr TK_SUP_SUP attr
2505  { }
2506 | attr TK_ARROW id_or_typename
2507  { }
2508 | attr TK_DOT id_or_typename
2509  { }
2510 | TK_LPAREN attr TK_RPAREN
2511  { }
2512 ;
2513 
2514 attr_list_ne:
2515 | attr
2516  { }
2517 | attr TK_COMMA attr_list_ne
2518  { }
2519 | error TK_COMMA attr_list_ne
2520  { }
2521 ;
2522 paren_attr_list_ne:
2523  TK_LPAREN attr_list_ne TK_RPAREN
2524  {
2525  csplit_parser_error("Attribute lists are not supported yet.\n");
2526  $$ = build_signature(new_lparen(), new_signature("IDoNotWantAttrListne"), new_rparen(), NULL);
2527  }
2528 | TK_LPAREN error TK_RPAREN
2529  {
2530  csplit_parser_error("Near attribute list ne");
2531  $$ = string_undefined;
2532  }
2533 ;
2534 /*** GCC TK_ASM instructions ***/
2535 asmattr:
2536  /* empty */
2537  { }
2538 | TK_VOLATILE asmattr
2539  { }
2540 | TK_CONST asmattr
2541  { }
2542 ;
2543 asmtemplate:
2544  one_string_constant
2545  { }
2546 | one_string_constant asmtemplate
2547  { }
2548 ;
2549 asmoutputs:
2550  /* empty */
2551  { }
2552 | TK_COLON asmoperands asminputs
2553  { }
2554 ;
2555 asmoperands:
2556  /* empty */
2557  { }
2558 | asmoperandsne
2559  { }
2560 ;
2561 asmoperandsne:
2562  asmoperand
2563  { }
2564 | asmoperandsne TK_COMMA asmoperand
2565  { }
2566 ;
2567 asmoperand:
2568  string_constant TK_LPAREN expression TK_RPAREN
2569  { free_partial_signature($3);}
2570 | string_constant TK_LPAREN error TK_RPAREN
2571  { }
2572 ;
2573 asminputs:
2574  /* empty */
2575  { }
2576 | TK_COLON asmoperands asmclobber
2577  { }
2578 ;
2579 asmclobber:
2580  /* empty */
2581  { }
2582 | TK_COLON asmcloberlst_ne
2583  { }
2584 ;
2585 asmcloberlst_ne:
2586  one_string_constant
2587  { }
2588 | one_string_constant TK_COMMA asmcloberlst_ne
2589  { }
2590 ;
2591 
2592 %%