1 /* $Id: splitc.y 23035 2016-01-06 16:30:14Z irigoin $ */
3 /******************** SYNTAX ANALYZER ************************************
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
9 *****************************************************************/
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.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
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.
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
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.
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 *)*/
54 #include "pips_config.h"
65 #include "properties.h"
67 #include "preprocessor.h"
69 #define C_ERROR_VERBOSE 1 /* much clearer error messages with bison */
71 /* Increase the parser stack to have SPEC2006/445.gobmk/owl_defendpat.c
72 going through without a:
74 user warning in splitc_error: C memory exhausted near "0" at preprocessed line 13459 (user line 8732)
76 #define YYMAXDEPTH 1000000
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.
82 For the moment, block scope is not considered. CurrentScope can be File,
83 Module, File'FILE_SEP_STRING'Module or TOP-LEVEL*/
85 /* static string CurrentScope = NULL; */
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*/
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;
103 static void reset_csplit_current_function_name()
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;
110 if(!string_undefined_p(csplit_current_function_name2)) {
111 csplit_current_function_name2 = string_undefined;
114 /* static int enum_counter = 0; */
116 /* Shared with the lexical analyzer */
117 bool csplit_is_static_p = false;
118 static bool current_function_is_static_p = false;
120 static void csplit_parser_warning_alist(
121 const char * pips_func,
122 const char * pips_file,
127 if (get_bool_property("NO_USER_WARNING"))
130 string cpn = get_pips_current_pass_name();
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);
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);
148 void csplit_parser_warning_func(
149 const char * pips_func,
150 const char * pips_file,
156 va_start(args, format);
157 csplit_parser_warning_alist(pips_func, pips_file, pips_line, format, &args);
161 /* Redundant with splitc_error()? */
162 void csplit_parser_error(const string msg)
164 /* Should add the current line number of the lexer */
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"); */
172 csplit_parser_warning(msg);
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();
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
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");
198 /* All the following global variables must be replaced by functions, once we have the preprocessor for C */
200 static int csplit_is_typedef = false; /* to know if this is a typedef name or not */
201 static stack TypedefStack = stack_undefined;
203 static void PushTypedef()
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));
211 static void PopTypedef()
213 csplit_is_typedef = (_int) stack_pop(TypedefStack);
214 pips_debug(8, "csplit_is_typedef = %s\n", bool_to_string(csplit_is_typedef));
217 void MakeTypedefStack()
219 pips_assert("TypedefStack is undefined", stack_undefined_p(TypedefStack));
220 TypedefStack = stack_make(int_domain, 0, 0);
223 void ResetTypedefStack()
225 if(stack_empty_p(TypedefStack)) {
226 stack_free(&TypedefStack);
227 TypedefStack = stack_undefined;
230 pips_internal_error("TypedefStack is not empty");
233 void ForceResetTypedefStack()
235 stack_free(&TypedefStack);
236 TypedefStack = stack_undefined;
239 /* Each scope in the compilation unit has its own number
241 * The scope management in the C preprocessor is different from the
242 * scope management in the C parser.
244 #define SCOPE_UNDEFINED (-1)
245 static int c_preprocessor_scope_number = SCOPE_UNDEFINED;
246 static stack c_preprocessor_scope_stack = stack_undefined;
248 void init_preprocessor_scope_stack()
250 c_preprocessor_scope_number = 0;
251 c_preprocessor_scope_stack = stack_make(string_domain, 0, 0);
254 void reset_preprocessor_scope_stack()
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;
262 // pips_internal_error? Could be a bad input C file...
263 pips_user_warning("Preprocessor scope stack is not empty.\n");
266 c_preprocessor_scope_number = SCOPE_UNDEFINED;
270 /* To be used by an error handler */
271 void force_reset_preprocessor_scope_stack()
273 if(c_preprocessor_scope_stack != stack_undefined) {
274 stack_free(&c_preprocessor_scope_stack);
275 c_preprocessor_scope_stack = stack_undefined;
277 c_preprocessor_scope_number = SCOPE_UNDEFINED;
281 void push_new_preprocessor_scope()
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);
290 void pop_preprocessor_scope()
292 stack_pop(c_preprocessor_scope_stack);
296 bool preprocessor_scope_stack_empty_p()
298 return stack_empty_p(c_preprocessor_scope_stack);
301 string get_preprocessor_current_scope()
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
309 sn = (string) stack_head(c_preprocessor_scope_stack);
313 string get_preprocessor_nth_scope(int n)
315 string sn = (string) stack_nth(c_preprocessor_scope_stack, n);
319 int preprocessor_scope_number()
321 int n = stack_size(c_preprocessor_scope_stack);
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. */
329 static int number_of_signatures_built = 0;
330 static int number_of_signatures_freed = 0;
332 static string new_signature(const string s)
334 string new_s = strdup(s);
335 number_of_signatures_built++;
339 static void free_partial_signature(string s)
341 number_of_signatures_freed++;
342 if(!string_undefined_p(s))
346 static string general_build_signature(bool arguments_are_defined_p,
348 va_list * p_some_arguments)
350 /* va_list some_arguments; */
353 string sa[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
354 string r = string_undefined;
356 bool some_argument_undefined_p = false;
358 /* va_start(*some_arguments, s1); */
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);
366 some_argument_undefined_p = true;
369 /* We are in trouble too */
370 pips_internal_error("Unexpected NULL argument");
372 else if(strcmp(s, "")==0) {
376 pips_debug(9, "s%d = \"%s\"\n", count, s);
379 s = va_arg(*p_some_arguments, string);
382 pips_assert("No more than 6 effective arguments (check grammar rules).",
385 if(some_argument_undefined_p)
386 r = string_undefined;
388 r = strdup(concatenate("", sa[0], " ", sa[1], " ", sa[2], " ",
389 sa[3], " ", sa[4], " ", sa[5], "", NULL));
391 number_of_signatures_built++;
394 pips_debug(9, "%d arguments:\n", count);
396 for(i=0; i<count; i++) {
398 for(j=0; i<count; i++) {
399 if(sa[i]==sa[j]&&i!=j) pips_internal_error("Unexpected common arguments\n");
403 for(i=0; i<count; i++) {
404 /* pips_debug(9, "s%d = \"%s\"\n", i, sa[i]); */
405 number_of_signatures_freed++;
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));
415 pips_debug(8, "Returns: \"%s\"\n", string_undefined_p(r)? "STRING_UNDEFINED" : r);
420 /* All arguments must be defined. The result is always defined. */
421 static string build_signature(string s1, ...)
423 va_list some_arguments;
425 va_start(some_arguments, s1);
426 return general_build_signature(true, s1, &some_arguments);
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, ...)
433 va_list some_arguments;
435 va_start(some_arguments, s1);
436 return general_build_signature(false, s1, &some_arguments);
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)
445 string new_s = strdup(s); /* Make sure to allocate enough space... */
447 string destination = new_s;
449 pips_debug(8, "Begin with signature \"%s\"\n", s);
451 pips_assert("The signature is not empty", *s);
453 /* source points to the next character to copy and destination to the
454 last character copied. The first character is already copied. */
456 if(*destination==' ') {
458 /* Do not copy a second space */
461 else if (*source==',' || *source=='(' || *source==')' || *source==';') {
462 /* Overwrite the space in the destination */
463 *destination = *source++;
467 *++destination = *source++;
470 else if(*destination=='(' || *destination=='*') {
472 /* Do not copy a space after some separators */
477 *++destination = *source++;
482 *++destination = *source++;
486 /* Get rid of a trailing SPACE. */
487 if(*destination==' ')
488 *(destination) = '\000';
490 *(destination+1) = '\000';
492 pips_debug(8, "End with signature \"%s\"\n", new_s);
494 free_partial_signature(s);
498 int check_signature_balance()
500 int imbalance = number_of_signatures_built - number_of_signatures_freed;
502 /* pips_internal_error("More signatures freed than allocated: %d\n", imbalance); */
503 pips_debug(5, "More signatures freed than allocated: %d\n", imbalance);
508 /* Beware of the free: no constant strings in signature! */
509 static string new_empty()
511 return new_signature("");
513 static string new_comma()
515 return new_signature(",");
517 static string new_eq()
519 return new_signature("=");
521 static string new_star()
523 return new_signature("*");
525 static string new_semicolon()
527 return new_signature(";");
529 static string new_colon()
531 return new_signature(":");
534 static string new_lbrace()
536 return new_signature("{");
538 static string new_rbrace()
540 return new_signature("}");
542 static string new_lparen()
544 return new_signature("(");
546 static string new_rparen()
548 return new_signature(")");
550 static string new_lbracket()
552 return new_signature("[");
554 static string new_rbracket()
556 return new_signature("]");
558 static string new_ellipsis()
560 return new_signature("...");
564 /* Bison declarations */
572 expression expression;
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
589 %token <string> TK_STRINGCON
590 %token <string> TK_WSTRINGCON
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
598 %token TK_SIZEOF TK_ALIGNOF
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
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
611 %token TK_INF_INF TK_SUP_SUP
612 %token TK_PLUS_PLUS TK_MINUS_MINUS
615 %token TK_LPAREN TK_RBRACE
617 %token TK_LBRACKET TK_RBRACKET
620 %token TK_COMMA TK_ELLIPSIS TK_QUEST
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
628 %token TK_ATTRIBUTE TK_INLINE TK_ASM TK_TYPEOF TK_FUNCTION__ TK_PRETTY_FUNCTION__
630 %token TK_BUILTIN_VA_ARG
631 %token TK_BUILTIN_VA_LIST
632 %token TK_BLOCKATTRIBUTE
634 %token TK_MSASM TK_MSATTR
637 /* sm: cabs tree transformation specification keywords */
638 %token TK_AT_TRANSFORM TK_AT_TRANSFORMEXPR TK_AT_SPECIFIER TK_AT_EXPR
641 /* Added here because the token numbering seems to be fragile */
642 %token <string> TK_COMPLEXCON
644 /* operator precedence */
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
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
662 %left TK_DOT TK_ARROW TK_LPAREN TK_LBRACE
666 /* Non-terminals informations */
669 %type <void> interpret
670 %type <void> file globals
672 %type <string> attributes
673 %type <string> attributes_with_asm
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
689 %type <void> initializer
690 %type <void> initializer_list
691 %type <void> init_designators init_designators_opt
693 %type <string> type_spec
694 %type <string> struct_decl_list
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
706 %type <void> local_labels local_label_names
707 %type <string> old_parameter_list_ne
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
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
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
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
742 interpret: file TK_EOF
744 file: globals /* do nothing */
747 /* empty */ {} /* do nothing */
748 | global globals {} /* do nothing */
749 | TK_SEMICOLON globals{} /* do nothing */
753 /* empty */ {} %prec TK_IDENT
756 /*** Global Definition ***/
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()
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);
771 reset_csplit_current_beginning();
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(),
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(),
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();
796 | TK_ASM TK_LPAREN string_constant TK_RPAREN TK_SEMICOLON
798 reset_csplit_current_beginning();
802 reset_csplit_current_beginning();
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
809 pips_internal_error("Not implemented yet\n");
811 /* Old style function prototype, but without any arguments */
812 | TK_IDENT TK_LPAREN TK_RPAREN TK_SEMICOLON
814 pips_internal_error("Not implemented yet\n");
816 /* transformer for a toplevel construct */
817 | TK_AT_TRANSFORM TK_LBRACE global TK_RBRACE TK_IDENT /*to*/ TK_LBRACE globals TK_RBRACE
819 pips_internal_error("Not implemented yet\n");
821 /* transformer for an expression */
822 | TK_AT_TRANSFORMEXPR TK_LBRACE expression TK_RBRACE TK_IDENT /*to*/ TK_LBRACE expression TK_RBRACE
824 pips_internal_error("Not implemented yet\n");
826 | location error TK_SEMICOLON
828 pips_user_error("Parse error: location error TK_SEMICOLON \n");
835 $$=new_signature(splitc_text);
838 { $$=new_signature(splitc_text);}
839 | TK_AT_NAME TK_LPAREN TK_IDENT TK_RPAREN
841 csplit_parser_warning("CIL AT not implemented\n");
842 $$ = build_signature(new_signature("at_name"), new_lparen(), new_signature($3),
848 /* empty */ { $$ =new_signature("");}
849 | TK_COMMA { $$ = new_comma();}
852 /* *** Expressions *** */
854 /* They may be only needed in declarations to specify bit fields. */
863 /* Elements in enum are symbolic constant which
864 may appear in an array declaration. */
865 $$ = new_signature($1);
867 | TK_SIZEOF expression
869 /* Can be used to dimemsion an argument */
870 $$ = safe_build_signature(new_signature("sizeof"),
873 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
875 $$ = safe_build_signature(new_signature("sizeof"),
876 new_lparen(), $3, new_rparen(),
879 | TK_ALIGNOF expression
881 free_partial_signature($2);
882 $$ = string_undefined;
884 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
886 free_partial_signature($3);
887 $$ = string_undefined;
891 $$ = safe_build_signature(new_signature("+"), $2, NULL);
893 | TK_MINUS expression
895 $$ = safe_build_signature(new_signature("-"), $2, NULL);
899 $$ = safe_build_signature(new_signature("*"), $2, NULL);
901 | TK_AND expression %prec TK_ADDROF
903 $$ = safe_build_signature(new_signature("&"), $2, NULL);
905 | TK_EXCLAM expression
907 $$ = safe_build_signature(new_signature("!"), $2, NULL);
909 | TK_TILDE expression
911 $$ = safe_build_signature(new_signature("~"), $2, NULL);
913 | TK_PLUS_PLUS expression %prec TK_CAST
915 $$ = safe_build_signature(new_signature("++"), $2, NULL);
917 | expression TK_PLUS_PLUS
919 $$ = safe_build_signature($1, new_signature("++"), NULL);
921 | TK_MINUS_MINUS expression %prec TK_CAST
923 $$ = safe_build_signature(new_signature("--"), $2, NULL);
925 | expression TK_MINUS_MINUS
927 $$ = safe_build_signature($1, new_signature("--"), NULL);
929 | expression TK_ARROW id_or_typename
931 $$ = safe_build_signature($1, new_signature("->"), $3, NULL);
933 | expression TK_DOT id_or_typename
935 $$ = safe_build_signature($1, new_signature("."), $3, NULL);
937 | TK_LPAREN block TK_RPAREN
939 $$ = string_undefined;
940 /* $$ = new_signature("block"); */
942 | paren_comma_expression
946 | expression TK_LPAREN arguments TK_RPAREN
948 free_partial_signature($1);
949 /* arguments does not return anything. */
950 $$ = string_undefined;
952 | TK_BUILTIN_VA_ARG TK_LPAREN expression TK_COMMA type_name TK_RPAREN
954 free_partial_signature($3);
955 free_partial_signature($5);
956 $$ = string_undefined;
958 | expression bracket_comma_expression
960 free_partial_signature($1);
961 /* bracket_comma_expression does not return anything. */
962 $$ = string_undefined;
964 | expression TK_QUEST opt_expression TK_COLON expression
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,
976 | expression TK_PLUS expression
978 $$ = safe_build_signature($1, new_signature("+"), $3, NULL);
980 | expression TK_MINUS expression
982 $$ = safe_build_signature($1, new_signature("-"), $3, NULL);
984 | expression TK_STAR expression
986 $$ = safe_build_signature($1, new_signature("*"), $3, NULL);
988 | expression TK_SLASH expression
990 $$ = safe_build_signature($1, new_signature("/"), $3, NULL);
992 | expression TK_PERCENT expression
994 $$ = safe_build_signature($1, new_signature("%"), $3, NULL);
996 | expression TK_AND_AND expression
998 $$ = safe_build_signature($1, new_signature("&&"), $3, NULL);
1000 | expression TK_PIPE_PIPE expression
1002 $$ = safe_build_signature($1, new_signature("||"), $3, NULL);
1004 | expression TK_AND expression
1006 $$ = safe_build_signature($1, new_signature("&"), $3, NULL);
1008 | expression TK_PIPE expression
1010 $$ = safe_build_signature($1, new_signature("|"), $3, NULL);
1012 | expression TK_CIRC expression
1014 $$ = safe_build_signature($1, new_signature("^"), $3, NULL);
1016 | expression TK_EQ_EQ expression
1018 //free_partial_signature($1);
1019 //free_partial_signature($3);
1020 //$$ = string_undefined;
1021 $$ = safe_build_signature($1, new_signature("=="), $3, NULL);
1023 | expression TK_EXCLAM_EQ expression
1025 //free_partial_signature($1);
1026 //free_partial_signature($3);
1027 //$$ = string_undefined;
1028 $$ = safe_build_signature($1, new_signature("!="), $3, NULL);
1030 | expression TK_INF expression
1032 //free_partial_signature($1);
1033 //free_partial_signature($3);
1034 //$$ = string_undefined;
1035 $$ = safe_build_signature($1, new_signature("<"), $3, NULL);
1037 | expression TK_SUP expression
1039 //free_partial_signature($1);
1040 //free_partial_signature($3);
1041 //$$ = string_undefined;
1042 $$ = safe_build_signature($1, new_signature(">"), $3, NULL);
1044 | expression TK_INF_EQ expression
1046 //free_partial_signature($1);
1047 //free_partial_signature($3);
1048 //$$ = string_undefined;
1049 $$ = safe_build_signature($1, new_signature("<="), $3, NULL);
1051 | expression TK_SUP_EQ expression
1053 //free_partial_signature($1);
1054 //free_partial_signature($3);
1055 //$$ = string_undefined;
1056 $$ = safe_build_signature($1, new_signature(">="), $3, NULL);
1058 | expression TK_INF_INF expression
1060 //free_partial_signature($1);
1061 //free_partial_signature($3);
1062 //$$ = string_undefined;
1063 $$ = safe_build_signature($1, new_signature("<<"), $3, NULL);
1065 | expression TK_SUP_SUP expression
1067 //free_partial_signature($1);
1068 //free_partial_signature($3);
1069 //$$ = string_undefined;
1070 $$ = safe_build_signature($1, new_signature(">>"), $3, NULL);
1072 | expression TK_EQ expression
1074 free_partial_signature($1);
1075 free_partial_signature($3);
1076 $$ = string_undefined;
1078 | expression TK_PLUS_EQ expression
1080 free_partial_signature($1);
1081 free_partial_signature($3);
1082 $$ = string_undefined;
1084 | expression TK_MINUS_EQ expression
1086 free_partial_signature($1);
1087 free_partial_signature($3);
1088 $$ = string_undefined;
1090 | expression TK_STAR_EQ expression
1092 free_partial_signature($1);
1093 free_partial_signature($3);
1094 $$ = string_undefined;
1096 | expression TK_SLASH_EQ expression
1098 free_partial_signature($1);
1099 free_partial_signature($3);
1100 $$ = string_undefined;
1102 | expression TK_PERCENT_EQ expression
1104 free_partial_signature($1);
1105 free_partial_signature($3);
1106 $$ = string_undefined;
1108 | expression TK_AND_EQ expression
1110 free_partial_signature($1);
1111 free_partial_signature($3);
1112 $$ = string_undefined;
1114 | expression TK_PIPE_EQ expression
1116 free_partial_signature($1);
1117 free_partial_signature($3);
1118 $$ = string_undefined;
1120 | expression TK_CIRC_EQ expression
1122 free_partial_signature($1);
1123 free_partial_signature($3);
1124 $$ = string_undefined;
1126 | expression TK_INF_INF_EQ expression
1128 free_partial_signature($1);
1129 free_partial_signature($3);
1130 $$ = string_undefined;
1132 | expression TK_SUP_SUP_EQ expression
1134 free_partial_signature($1);
1135 free_partial_signature($3);
1136 $$ = string_undefined;
1138 | TK_LPAREN type_name TK_RPAREN expression
1140 free_partial_signature($2);
1141 free_partial_signature($4);
1142 $$ = string_undefined;
1144 /* (* We handle GCC constructor expressions *) */
1145 | TK_LPAREN type_name TK_RPAREN TK_LBRACE initializer_list_opt TK_RBRACE
1147 free_partial_signature($2);
1148 /* initializer_list_opt does not return anything. */
1149 $$ = string_undefined;
1151 /* (* GCC's address of labels *) */
1152 | TK_AND_AND TK_IDENT
1154 $$ = string_undefined;
1156 | TK_AT_EXPR TK_LPAREN TK_IDENT TK_RPAREN /* expression pattern variable */
1158 $$ = string_undefined;
1162 /* FI: I assume that only integer constant are useful in declarations. */
1167 $$ = new_signature($1);
1171 $$ = string_undefined;
1175 $$ = string_undefined;
1179 $$ = string_undefined;
1183 $$ = string_undefined;
1185 /*add a nul to strings. We do this here (rather than in the lexer) to make
1186 concatenation easy below.*/
1189 $$ = string_undefined;
1194 /* Now that we know this constant isn't part of a wstring, convert it
1195 back to a string for easy viewing. */
1200 one_string_constant:
1201 /* Don't concat multiple strings. For asm templates. */
1209 | string_list one_string
1218 | wstring_list one_string
1221 | wstring_list TK_WSTRINGCON
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". */
1231 | TK_PRETTY_FUNCTION__
1236 expression { free_partial_signature($1);}
1237 | TK_LBRACE initializer_list_opt TK_RBRACE
1240 initializer_list: /* ISO 6.7.8. Allow a trailing COMMA */
1244 | initializer TK_COMMA initializer_list_opt
1248 initializer_list_opt:
1250 | initializer_list { }
1253 init_designators eq_opt init_expression
1256 | gcc_init_designators init_expression
1259 | init_expression { }
1264 /*(* GCC allows missing = *)*/
1270 TK_DOT id_or_typename init_designators_opt
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); }
1277 init_designators_opt:
1279 | init_designators {}
1282 gcc_init_designators: /*(* GCC supports these strange things *)*/
1283 id_or_typename TK_COLON
1290 | comma_expression { free_partial_signature($1); }
1298 //free_partial_signature($1);
1308 | expression TK_COMMA comma_expression
1310 $$ = safe_build_signature($1, new_comma(), $3, NULL);
1312 | error TK_COMMA comma_expression
1314 csplit_parser_error("within expression list.\n");
1315 $$ = string_undefined;
1319 comma_expression_opt:
1320 /* empty */ { $$ = new_empty(); }
1321 | comma_expression { $$ = $1; }
1324 paren_comma_expression:
1325 TK_LPAREN comma_expression TK_RPAREN
1327 $$ = safe_build_signature(new_lparen(), $2,
1328 new_rparen(), NULL);
1330 | TK_LPAREN error TK_RPAREN
1332 csplit_parser_error("Error within parenthesized expression.\n");
1333 $$ = string_undefined;
1337 bracket_comma_expression:
1338 TK_LBRACKET comma_expression TK_RBRACKET
1340 free_partial_signature($2);
1342 | TK_LBRACKET error TK_RBRACKET
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
1351 pips_debug(5, "block found at line %d\n",
1352 csplit_line_number);
1354 | error location TK_RBRACE
1360 | TK_BLOCKATTRIBUTE paren_attr_list_ne
1366 | declaration declaration_list
1373 | statement statement_list
1376 /*(* GCC accepts a label at the end of a block *)*/
1377 | TK_IDENT TK_COLON { }
1382 | TK_LABEL__ local_label_names TK_SEMICOLON local_labels
1388 | TK_IDENT TK_COMMA local_label_names {}
1395 | comma_expression TK_SEMICOLON
1397 free_partial_signature($1);
1400 | TK_IF paren_comma_expression statement %prec TK_IF
1402 free_partial_signature($2);
1404 | TK_IF paren_comma_expression statement TK_ELSE statement
1406 free_partial_signature($2);
1411 paren_comma_expression
1413 /* free_partial_signature($1); */
1421 paren_comma_expression statement
1423 /* free_partial_signature($1); */
1428 statement TK_WHILE paren_comma_expression TK_SEMICOLON
1430 /* free_partial_signature($3); */
1435 TK_LPAREN for_clause
1438 | TK_IDENT TK_COLON statement
1441 | TK_CASE expression TK_COLON
1443 free_partial_signature($2);
1445 | TK_CASE expression TK_ELLIPSIS expression TK_COLON
1447 free_partial_signature($2);
1448 free_partial_signature($4);
1450 | TK_DEFAULT TK_COLON
1453 | TK_RETURN TK_SEMICOLON
1456 | TK_RETURN comma_expression TK_SEMICOLON
1458 free_partial_signature($2);
1460 | TK_BREAK TK_SEMICOLON
1463 | TK_CONTINUE TK_SEMICOLON
1466 | TK_GOTO TK_IDENT TK_SEMICOLON
1469 | TK_GOTO TK_STAR comma_expression TK_SEMICOLON
1471 free_partial_signature($3);
1473 | TK_ASM asmattr TK_LPAREN asmtemplate asmoutputs TK_RPAREN TK_SEMICOLON
1478 { /* In C99 we can have declarations everywhere... */ }
1479 | error location TK_SEMICOLON
1485 opt_expression TK_SEMICOLON opt_expression TK_SEMICOLON opt_expression TK_RPAREN statement
1488 | declaration opt_expression TK_SEMICOLON opt_expression TK_RPAREN statement
1493 declaration: /* ISO 6.7.*/
1494 decl_spec_list init_declarator_list TK_SEMICOLON
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;
1507 | decl_spec_list TK_SEMICOLON
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;
1520 init_declarator_list: /* ISO 6.7 */
1523 $$ = string_undefined;
1525 | init_declarator TK_COMMA init_declarator_list
1527 $$ = string_undefined;
1531 init_declarator: /* ISO 6.7 */
1533 $$ = string_undefined;
1535 | declarator TK_EQ init_expression
1537 $$ = string_undefined;
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 */
1550 TK_TYPEDEF decl_spec_list_opt
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. */
1557 free_partial_signature($2);
1558 $$ = string_undefined;
1560 $$ = build_signature(new_signature("typedef"), $2, NULL);
1562 | TK_EXTERN decl_spec_list_opt
1564 pips_debug(5, "TK_EXTERN decl_spec_list_opt->decl_spec_list\n");
1566 free_partial_signature($2);
1567 $$ = string_undefined;
1569 $$ = build_signature(new_signature("extern"), $2, NULL);
1571 | TK_STATIC decl_spec_list_opt
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);
1579 $$ = build_signature(new_signature("static"), $2, NULL);
1581 | TK_AUTO decl_spec_list_opt
1583 pips_debug(5, "TK_AUTO decl_spec_list_opt->decl_spec_list\n");
1585 free_partial_signature($2);
1586 $$ = string_undefined;
1588 $$ = build_signature(new_signature("auto"), $2, NULL);
1590 | TK_REGISTER decl_spec_list_opt
1592 pips_debug(5, "TK_REGISTER decl_spec_list_opt->decl_spec_list\n");
1594 free_partial_signature($2);
1595 $$ = string_undefined;
1597 $$ = build_signature(new_signature("register"), $2, NULL);
1599 | TK_THREAD decl_spec_list_opt
1601 pips_debug(5, "TK_THREAD decl_spec_list_opt->decl_spec_list\n");
1603 free_partial_signature($2);
1604 $$ = string_undefined;
1606 $$ = build_signature(new_signature("thread"), $2, NULL);
1609 | type_spec decl_spec_list_opt_no_named
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);
1619 pips_debug(5, "$1 and $2 undefined\n");
1620 $$ = string_undefined;
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;
1637 | TK_INLINE decl_spec_list_opt
1639 pips_debug(5, "TK_INLINE decl_spec_list_opt->decl_spec_list\n");
1641 free_partial_signature($2);
1642 $$ = string_undefined;
1644 $$ = build_signature(new_signature("inline"), $2, NULL);
1646 | attribute decl_spec_list_opt
1648 pips_debug(5, "attribute decl_spec_list_opt->decl_spec_list\n");
1650 free_partial_signature($1);
1651 free_partial_signature($2);
1652 $$ = string_undefined;
1654 $$ = build_signature($1, $2, NULL);
1656 /* specifier pattern variable (must be last in spec list) */
1657 | TK_AT_SPECIFIER TK_LPAREN TK_IDENT TK_RPAREN
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);
1667 /* (* In most cases if we see a NAMED_TYPE we must shift it. Thus we declare
1668 * NAMED_TYPE to have right associativity *) */
1670 /* empty */ { $$=new_empty(); PushTypedef();} %prec TK_NAMED_TYPE
1671 | decl_spec_list { $$=$1;}
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 *)
1678 decl_spec_list_opt_no_named: /* empty */
1680 /* Cf "Actions in Mid-Rule" in the Bison doc. */
1681 $<string>$ = new_empty();
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); */
1690 /* FI: I do not feel safe about this. */
1691 /* $$=strdup(splitc_text); */ /* FI: why not $1?*/
1692 /* $$ = strdup("IAmNotSure"); */
1697 "decl_spec_slit->decl_spec_list_opt_no_named\n");
1702 /* To generate the function signature, we need the keywords. */
1704 type_spec: /* ISO 6.7.2 */
1707 pips_debug(8, "TK_VOID->type_spec\n");
1708 $$ = new_signature(splitc_text);
1712 pips_debug(8, "TK_CHAR->type_spec\n");
1713 $$ = new_signature(splitc_text);
1717 pips_debug(8, "TK_SHORT->type_spec\n");
1718 $$ = new_signature(splitc_text);
1722 pips_debug(8, "TK_INT->type_spec\n");
1723 $$ = new_signature(splitc_text);
1727 pips_debug(8, "TK_INT128->type_spec\n");
1728 $$ = new_signature(splitc_text);
1732 pips_debug(8, "TK_UINT128->type_spec\n");
1733 $$ = new_signature(splitc_text);
1737 pips_debug(8, "TK_COMPLEX->type_spec\n");
1738 $$ = new_signature(splitc_text);
1742 pips_debug(8, "TK_LONG->type_spec\n");
1743 $$ = new_signature(splitc_text);
1747 pips_debug(8, "TK_FLOAT->type_spec\n");
1748 $$ = new_signature(splitc_text);
1752 pips_debug(8, "TK_DOUBLE->type_spec\n");
1753 $$ = new_signature(splitc_text);
1757 pips_debug(8, "TK_SIGNED->type_spec\n");
1758 $$ = new_signature(splitc_text);
1762 pips_debug(8, "TK_UNSIGNED->type_spec\n");
1763 $$ = new_signature(splitc_text);
1765 | TK_STRUCT id_or_typename
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
1772 if(!string_undefined_p(csplit_current_function_name)
1773 && strcmp(csplit_current_function_name, $2)==0) {
1774 reset_csplit_current_function_name();
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;
1786 | TK_STRUCT id_or_typename TK_LBRACE /* { } */ struct_decl_list TK_RBRACE
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();
1796 $$ = build_signature(new_signature("bstruct"), $2, new_lbrace(), $4,
1797 new_rbrace(), NULL);
1799 | TK_STRUCT TK_LBRACE /* { } */
1800 struct_decl_list TK_RBRACE
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);
1806 | TK_UNION id_or_typename
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();
1812 $$ = build_signature(new_signature("union"), $2, NULL);
1814 | TK_UNION id_or_typename TK_LBRACE /* { } */ struct_decl_list TK_RBRACE
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();
1820 $$ = build_signature(new_signature("union"), $2, new_lbrace(), $4,
1821 new_rbrace(), NULL);
1823 | TK_UNION TK_LBRACE /* { } */ struct_decl_list TK_RBRACE
1825 pips_debug(8, "TK_UNION TK_LBRACE->type_spec\n");
1826 $$ = build_signature(new_signature("union"), new_lbrace(), $3,
1827 new_rbrace(), NULL);
1829 | TK_ENUM id_or_typename
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();
1835 $$ = build_signature(new_signature("enum"), $2, NULL);
1837 | TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE
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();
1843 $$ = build_signature(new_signature("enum"), $2, new_lbrace(), $4, $5, new_rbrace(), NULL);
1845 | TK_ENUM TK_LBRACE enum_list maybecomma TK_RBRACE
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);
1852 pips_debug(8, "TK_NAMED_TYPE->type_spec\n");
1853 $$ = new_signature($1);
1855 | TK_TYPEOF TK_LPAREN expression TK_RPAREN
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);
1860 | TK_TYPEOF TK_LPAREN type_name TK_RPAREN
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);;
1867 struct_decl_list: /* (* ISO 6.7.2. Except that we allow empty structs. We
1868 * also allow missing field names. *)
1870 /* empty */ { $$ = new_empty(); }
1871 | decl_spec_list TK_SEMICOLON struct_decl_list
1874 $$ = build_signature($1, new_semicolon(), $3, NULL);
1876 | decl_spec_list /* { } */
1877 field_decl_list TK_SEMICOLON struct_decl_list
1880 $$ = build_signature($1, $2, new_semicolon(), $4, NULL);
1882 | error TK_SEMICOLON struct_decl_list
1884 csplit_parser_error("in struct declaration.");
1885 $$ = string_undefined;
1889 field_decl_list: /* (* ISO 6.7.2 *) */
1894 | field_decl TK_COMMA field_decl_list
1896 $$ = build_signature($1, new_comma(), $3, NULL);
1900 field_decl: /* (* ISO 6.7.2. Except that we allow unnamed fields. *) */
1901 declarator { $$ = $1; }
1902 | declarator TK_COLON expression
1904 $$ = build_signature($1, new_colon(), $3, NULL);
1906 | TK_COLON expression
1908 $$ = build_signature(new_colon(), $2, NULL);
1912 enum_list: /* (* ISO 6.7.2.2 *) */
1917 | enum_list TK_COMMA enumerator
1919 $$ = build_signature($1, new_comma(), $3, NULL);
1921 | enum_list TK_COMMA error
1923 csplit_parser_error("in enum list");
1924 $$ = string_undefined;
1931 pips_debug(5, "TK_IDENT->enumerator\n");
1932 pips_debug(9, "TK_IDENT=%s\n", $1);
1933 $$ = new_signature($1);
1935 | TK_IDENT TK_EQ expression
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);
1943 declarator: /* (* ISO 6.7.5. Plus Microsoft declarators.*) */
1944 pointer_opt direct_decl attributes_with_asm
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);
1957 if(true) /* Keep parameter names in signatures. */
1958 $$ = build_signature($1, $2, NULL);
1960 /* This does not work! Do not try it anymore... */
1961 free_partial_signature($2);
1967 direct_decl: /* (* ISO 6.7.5 *) */
1968 /* (* We want to be able to redefine named
1969 * types as variable names *) */
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 */
1978 hash_put(keyword_typedef_table,new_signature($1),(void *) TK_NAMED_TYPE);
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;
1987 else if(true) { /* Keep identifiers in signatures */
1990 else { /* You are going to loose the function
1991 identifier. You may also loose enum
1996 | TK_LPAREN attributes declarator TK_RPAREN
1998 $$ = build_signature(new_lparen(), $2, $3, new_rparen(), NULL);
2000 | direct_decl TK_LBRACKET attributes comma_expression_opt TK_RBRACKET
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))
2010 $$ = build_signature(s1, new_lbracket(), s3, s4, new_rbracket(), NULL);
2012 | direct_decl TK_LBRACKET attributes error TK_RBRACKET
2014 $$ = build_signature($1, new_lbracket(), $3, new_rbracket(), NULL);
2016 | direct_decl parameter_list_startscope rest_par_list TK_RPAREN
2018 $$ = build_signature($1, $2, $3, new_rparen(), NULL);
2022 parameter_list_startscope:
2023 TK_LPAREN { $$ = new_lparen();}
2027 /* empty */ { $$ = new_empty();}
2028 | parameter_decl rest_par_list1
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;
2041 $$ = build_signature($1, $2, NULL);
2045 /* empty */ { $$ = new_empty(); }
2046 | TK_COMMA TK_ELLIPSIS
2048 $$ = build_signature(new_comma(), new_ellipsis(), NULL);
2050 | TK_COMMA parameter_decl rest_par_list1
2052 $$ = build_signature(new_comma(), $2, $3, NULL);
2056 parameter_decl: /* (* ISO 6.7.5 *) */
2057 decl_spec_list declarator
2060 $$ = build_signature($1, $2, NULL);
2062 | decl_spec_list abstract_decl
2064 pips_debug(5, "decl_spec_list abstract_decl->parameter_decl\n");
2066 $$ = build_signature($1, $2, NULL);
2067 $$ = build_signature($1,
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;
2081 $$ = build_signature($1, $2, NULL);
2089 | TK_LPAREN parameter_decl TK_RPAREN
2092 $$ = build_signature(new_lparen(), $2, new_rparen(), NULL);
2096 /* (* Old style prototypes. Like a declarator *) */
2098 pointer_opt direct_old_proto_decl
2100 $$ = build_signature($1, $2, NULL);
2103 direct_old_proto_decl:
2104 direct_decl TK_LPAREN old_parameter_list_ne TK_RPAREN old_pardef_list
2106 /* You do not need the formal parameter list */
2108 $$ = build_signature($1, new_lparen(), $3, new_rparen(),
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);
2116 | direct_decl TK_LPAREN TK_RPAREN
2118 $$ = build_signature($1, new_lparen(), new_rparen(), NULL);
2122 old_parameter_list_ne:
2125 $$ = new_signature($1);
2127 | TK_IDENT TK_COMMA old_parameter_list_ne
2129 $$ = build_signature($1, new_comma(), $3, NULL);
2134 /* empty */ { $$ = new_empty(); }
2135 | decl_spec_list old_pardef TK_SEMICOLON TK_ELLIPSIS
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);
2143 $$ = build_signature($1, $2, new_comma(),
2144 new_ellipsis(), NULL);
2148 | decl_spec_list old_pardef TK_SEMICOLON old_pardef_list
2150 $$ = build_signature($1, $2, new_semicolon(),
2161 | declarator TK_COMMA old_pardef
2163 $$ = build_signature($1, new_comma(), $3, NULL);
2167 csplit_parser_error("In old parameter definition\n");
2168 $$ = string_undefined;
2172 pointer: /* (* ISO 6.7.5 *) */
2173 TK_STAR attributes pointer_opt
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);
2182 /* empty */ { $$ = new_empty(); }
2187 type_name: /* (* ISO 6.7.6 *) */
2188 decl_spec_list abstract_decl
2191 $$ = build_signature($1, $2, NULL);
2200 abstract_decl: /* (* ISO 6.7.6. *) */
2201 pointer_opt abs_direct_decl attributes
2203 pips_debug(5, "pointer_opt abs_direct_decl attributes -> abstract_decl\n");
2204 $$ = build_signature($1, $2, $3, NULL);
2208 pips_debug(5, "pointer -> abstract_decl\n");
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
2218 $$ = build_signature(new_lparen(), $2, $3, new_rparen(), NULL);
2220 | TK_LPAREN error TK_RPAREN
2222 csplit_parser_error("Parse error: TK_LPAREN error TK_RPAREN\n");
2225 | abs_direct_decl_opt TK_LBRACKET comma_expression_opt TK_RBRACKET
2227 $$ = build_signature($1, new_lbracket(), new_signature("IDoNotWantcomma_expression_opt"), new_rbracket(), NULL);
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
2232 $$ = build_signature($1, $2, $3, new_rparen(), NULL);
2236 abs_direct_decl_opt:
2241 | /* empty */ { $$ = new_empty(); }
2244 function_def: /* (* ISO 6.9.1 *) */
2245 function_def_start block
2249 function_def_start: /* (* ISO 6.9.1 *) */
2250 decl_spec_list declarator
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;
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 */
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);
2278 /* (* Old-style function prototype *) */
2279 | decl_spec_list old_proto_decl
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
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);
2304 /* (* New-style function that does not have a return type *) */
2305 | TK_IDENT parameter_list_startscope rest_par_list TK_RPAREN
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;
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);
2323 /* (* No return type and no old-style parameter list *) */
2324 | TK_IDENT TK_LPAREN old_parameter_list_ne TK_RPAREN old_pardef_list
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",
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;
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);
2345 /* (* No return type and no parameters *) */
2346 | TK_IDENT TK_LPAREN TK_RPAREN
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",
2353 get_csplit_current_beginning(),
2354 csplit_line_number);
2355 pips_internal_error("Not implemented yet");
2359 /*** GCC attributes ***/
2362 { $$ = new_empty(); }
2363 | attribute attributes
2364 { $$ = build_signature($1, $2, NULL); }
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:
2371 { $$ = new_empty(); }
2372 | attribute attributes_with_asm
2373 { $$ = build_signature($1, $2, NULL); }
2374 | TK_ASM TK_LPAREN string_constant TK_RPAREN attributes
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 */
2378 free_partial_signature($5);
2379 csplit_parser_error("ASM extensions not implemented\n");
2380 $$ = string_undefined;
2382 { $$ = build_signature($5, NULL, NULL); }
2389 TK_ATTRIBUTE TK_LPAREN paren_attr_list_ne TK_RPAREN
2391 $$ = build_signature(new_signature("attribute"), new_lparen(), $3,
2392 new_rparen(), NULL);
2394 | TK_DECLSPEC paren_attr_list_ne
2396 $$ = build_signature(new_signature("decl_spec"), $2, NULL);
2400 $$ = new_signature("msattr");
2405 $$ = new_signature("const");
2409 $$ = new_signature("restrict");
2413 $$ = new_signature("volatile");
2415 | TK_STATIC_DIMENSION
2417 $$ = new_signature("static");
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 *) */
2427 | TK_IDENT TK_COLON TK_INTCON
2429 | TK_DEFAULT TK_COLON TK_INTCON
2431 | TK_IDENT TK_LPAREN TK_RPAREN
2433 | TK_IDENT paren_attr_list_ne
2441 | TK_SIZEOF expression
2443 free_partial_signature($2);
2445 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
2448 | TK_ALIGNOF expression
2450 free_partial_signature($2);
2452 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
2454 | TK_PLUS expression
2456 free_partial_signature($2);
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
2464 { free_partial_signature($2);}
2465 | TK_EXCLAM expression
2466 { free_partial_signature($2);}
2467 | TK_TILDE expression
2468 { free_partial_signature($2);}
2471 | attr TK_MINUS attr
2473 | attr TK_STAR expression
2474 { free_partial_signature($3);}
2475 | attr TK_SLASH attr
2477 | attr TK_PERCENT attr
2479 | attr TK_AND_AND attr
2481 | attr TK_PIPE_PIPE attr
2490 | attr TK_EQ_EQ attr
2492 | attr TK_EXCLAM_EQ attr
2498 | attr TK_INF_EQ attr
2500 | attr TK_SUP_EQ attr
2502 | attr TK_INF_INF attr
2504 | attr TK_SUP_SUP attr
2506 | attr TK_ARROW id_or_typename
2508 | attr TK_DOT id_or_typename
2510 | TK_LPAREN attr TK_RPAREN
2517 | attr TK_COMMA attr_list_ne
2519 | error TK_COMMA attr_list_ne
2523 TK_LPAREN attr_list_ne TK_RPAREN
2525 csplit_parser_error("Attribute lists are not supported yet.\n");
2526 $$ = build_signature(new_lparen(), new_signature("IDoNotWantAttrListne"), new_rparen(), NULL);
2528 | TK_LPAREN error TK_RPAREN
2530 csplit_parser_error("Near attribute list ne");
2531 $$ = string_undefined;
2534 /*** GCC TK_ASM instructions ***/
2538 | TK_VOLATILE asmattr
2546 | one_string_constant asmtemplate
2552 | TK_COLON asmoperands asminputs
2564 | asmoperandsne TK_COMMA asmoperand
2568 string_constant TK_LPAREN expression TK_RPAREN
2569 { free_partial_signature($3);}
2570 | string_constant TK_LPAREN error TK_RPAREN
2576 | TK_COLON asmoperands asmclobber
2582 | TK_COLON asmcloberlst_ne
2588 | one_string_constant TK_COMMA asmcloberlst_ne