1 /* $Id: cyacc.y 23115 2016-06-07 21:40:12Z 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"
66 #include "text-util.h"
68 #include "properties.h"
70 #include "c_parser_private.h"
74 #define C_ERROR_VERBOSE 1 /* much clearer error messages with bison */
76 /* Increase the parser stack to have SPEC2006/445.gobmk/owl_defendpat.c
77 going through without a:
79 user warning in splitc_error: C memory exhausted near "0" at preprocessed line 13459 (user line 8732)
81 #define YYMAXDEPTH 1000000
83 // To set breakpoint in cyacc.y
84 // void breakpoint(int l) {;}
85 // #define BREAKPOINT breakpoint(__LINE__)
88 static int CurrentMode = 0; /**< to know the mode of the formal parameter: by value or by reference*/
89 static bool is_external = true; /**< to know if the variable is declared inside or outside a function, so its scope
90 is the current function or the compilation unit or TOP-LEVEL*/
91 static int enum_counter = 0; /**< to compute the enumerator value: val(i) = val(i-1) + 1 */
92 static int abstract_counter = 1; /**< to create temporary entities for abstract types */
94 static list initialization_expressions = NIL; /**< to preserve information about the declarations for the prettyprinter, especially for the global variables, but also the derived types (struct, union, enum). */
96 /* init_p = 0 => no initialization for a variable or no definition
97 for a derived entity (struct, union, maybe enum) */
98 static void add_initialization_expression(int init_p)
100 initialization_expressions
101 = CONS(EXPRESSION, int_to_expression(init_p), initialization_expressions);
104 /* The following structures must be stacks because all the related
105 entities are in recursive structures. Since there are not stacks
106 with basic types such as integer or logical domain, I used
107 basic_domain to avoid creating special stacks for FormalStack,
110 static void PushFunction(entity f)
112 stack_push((char *) f, FunctionStack);
115 static void PopFunction()
117 stack_pop(FunctionStack);
122 entity f = stack_head(FunctionStack);
126 // FI: I assumed it was the current context; in fact the current
127 // context is rather the top of the ContextStack. I tried to maintain
128 // as an invariant ycontext==stack_head(ContextStack). But this is not
129 // be a good idea as it interferes with cyacc.y use of ycontext and
131 static c_parser_context ycontext = c_parser_context_undefined;
134 /* FI: these two variables are used in conjunction with comma
135 expressions. I do not remember why they are needed. They sometimes
136 stay set although they have become useless. The parser used not to
137 reset them systematically, which caused problems with
139 static string expression_comment = string_undefined;
140 static int expression_line_number = STATEMENT_NUMBER_UNDEFINED;
142 /* we don't want an expression comment with new lines, it is disgracefull */
143 void reset_expression_comment()
145 if(!string_undefined_p(expression_comment)) {
146 /* Too bad. This should not happen, but it happens with comma
147 expressions in header files */
148 free(expression_comment);
149 expression_comment = string_undefined;
152 expression_line_number = STATEMENT_NUMBER_UNDEFINED;
155 /* flushes all expression comments and add them to statement s */
156 static statement flush_expression_comment(statement s) {
157 if(!empty_comments_p(expression_comment)) {
158 if(!empty_comments_p(statement_comments(s))) {
159 char *tmp = statement_comments(s);
160 asprintf(&statement_comments(s),"%s%s",statement_comments(s),expression_comment);
162 free(expression_comment);
165 statement_comments(s) = expression_comment;
166 statement_number(s) = expression_line_number;
167 expression_line_number = STATEMENT_NUMBER_UNDEFINED;
168 expression_comment=string_undefined;
174 /* after a while (crocodile) expression comments are pushed into a list that
175 is purged upon call to add_expression_comment */
176 static list all_expression_comments_as_statement_comments = NIL;
177 static void save_expression_comment_as_statement_comment() {
178 if(!string_undefined_p(expression_comment)) {
179 all_expression_comments_as_statement_comments =
180 CONS(STRING,expression_comment, all_expression_comments_as_statement_comments);
182 expression_comment=string_undefined;
184 /* flushes all statement comments and add them to statement s */
185 static statement flush_statement_comment(statement s) {
186 s=flush_expression_comment(s); // should not be necessary
187 if(!ENDP(all_expression_comments_as_statement_comments)) {
188 pips_assert("not on a block",!statement_block_p(s));
189 all_expression_comments_as_statement_comments = gen_nreverse(all_expression_comments_as_statement_comments);
190 char * comments = list_to_string(all_expression_comments_as_statement_comments);
191 if(!empty_comments_p(statement_comments(s))) {
192 char *tmp = statement_comments(s);
193 asprintf(&statement_comments(s),"%s%s",statement_comments(s), comments);
198 statement_comments(s) = comments;
199 FOREACH(STRING,s,all_expression_comments_as_statement_comments) free(s);
200 gen_free_list(all_expression_comments_as_statement_comments);
201 all_expression_comments_as_statement_comments=NIL;
207 /* The scope is moved up the scope tree and a NULL is return when
208 there are no more scope to explore. */
209 string pop_block_scope(string old_scope)
211 string new_scope = old_scope;
212 string last_scope = string_undefined;
214 pips_debug(8, "old_scope = \"%s\"\n", old_scope);
215 pips_assert("old_scope is a scope", string_block_scope_p(old_scope));
217 if(strlen(old_scope)>0) {
218 /* get rid of last block separator */
219 new_scope[strlen(new_scope)-1] = '\0';
220 last_scope = strrchr(new_scope, BLOCK_SEP_CHAR);
225 *(last_scope+1) = '\0';
230 if(new_scope!=NULL) {
231 pips_debug(8, "new_scope = \"%s\"\n", new_scope);
232 pips_assert("new_scope is a scope", string_block_scope_p(new_scope));
235 pips_debug(8, "new_scope = NULL\n");
241 /* Allocate a new string containing only block scope information */
242 string scope_to_block_scope(string full_scope)
244 string l_scope = strrchr(full_scope, BLOCK_SEP_CHAR);
245 string f_scope = strchr(full_scope, MODULE_SEP);
246 string block_scope = string_undefined;
248 pips_debug(8, "full_scope = \"%s\"\n", full_scope);
251 f_scope = full_scope;
256 block_scope = strdup("");
258 block_scope = gen_strndup0(f_scope, (unsigned) (l_scope-f_scope+1));
260 pips_debug(8, "f_scope = \"%s\", l_scope = \"%s\"\n", f_scope, l_scope);
261 pips_assert("block_scope is a scope", string_block_scope_p(block_scope));
266 c_parser_context CreateDefaultContext()
268 c_parser_context c = make_c_parser_context(empty_scope(),
274 pips_debug(8, "New default context %p\n", c);
278 static int C_scope_identifier = -2;
282 C_scope_identifier = -1;
285 static void EnterScope()
287 c_parser_context nc = CreateDefaultContext();
288 string cs = string_undefined;
290 push_new_c_parser_scope(); // For the lexical analyzer
292 pips_assert("C_scope_identifier has been initialized", C_scope_identifier>-2);
294 if(!stack_empty_p(ContextStack)) {
295 c_parser_context c = (c_parser_context) stack_head(ContextStack);
296 pips_assert("The current context is defined", !c_parser_context_undefined_p(c));
297 pips_assert("The current context scope is defined",
298 !string_undefined_p(c_parser_context_scope(c))
299 && c_parser_context_scope(c)!=NULL);
300 pips_assert("The current context only contains scope information",
301 //type_undefined_p(c_parser_context_type(c)) &&
302 storage_undefined_p(c_parser_context_storage(c))
303 && ENDP(c_parser_context_qualifiers(c))
304 //&& !c_parser_context_typedef(c)
305 //&& !c_parser_context_static(c)
307 cs = c_parser_context_scope(c);
308 pips_assert("scope contains only block scope information", string_block_scope_p(cs));
313 // Add scope information if any
314 C_scope_identifier++;
315 // A scope is needed right away to distinguish between formal
316 // parameters and local variables. See
317 // Validation/C_syntax/block_scope01.c, identifier x in function foo
318 if(C_scope_identifier>=0) {
319 string ns = int2a(C_scope_identifier);
321 char * stf = c_parser_context_scope(nc);
322 c_parser_context_scope(nc) = strdup(concatenate(cs, ns, BLOCK_SEP_STRING, NULL));
327 char * stf = c_parser_context_scope(nc);
328 c_parser_context_scope(nc) = strdup(cs);
332 stack_push((char *) nc, ContextStack);
334 //pips_assert("ycontext is consistant with stack_head(ContextStack)",
335 // ycontext==stack_head(ContextStack));
336 pips_debug(8, "New block scope string: \"%s\" for context %p\n",
337 c_parser_context_scope(nc), nc);
342 return stack_size(ContextStack);
349 /* FI: I do not know if it wouldn't be better to initialize the
350 ContextStack with a default context before calling the C
352 if(!stack_empty_p(ContextStack)) {
353 c_parser_context c = (c_parser_context) stack_head(ContextStack);
355 s = c_parser_context_scope(c);
361 string GetParentScope()
365 if(!stack_empty_p(ContextStack) && stack_size(ContextStack)>=2) {
366 c_parser_context c = (c_parser_context) stack_nth(ContextStack,2);
368 s = c_parser_context_scope(c);
376 c_parser_context c = (c_parser_context) stack_head(ContextStack);
378 pop_c_parser_scope_stack();
380 pips_assert("The current context is defined", !c_parser_context_undefined_p(c));
381 pips_assert("The current context scope is defined",
382 !string_undefined_p(c_parser_context_scope(c))
383 && c_parser_context_scope(c)!=NULL);
384 pips_assert("The current context only contains scope information",
385 //type_undefined_p(c_parser_context_type(c)) &&
386 storage_undefined_p(c_parser_context_storage(c))
387 && ENDP(c_parser_context_qualifiers(c))
388 //&& !c_parser_context_typedef(c)
389 //&& !c_parser_context_static(c)
391 pips_debug(8, "Exiting context scope \"\%s\" in context %p\n",
392 c_parser_context_scope(c), c);
393 free_c_parser_context(c);
394 (void) stack_pop(ContextStack);
395 if(!stack_empty_p(ContextStack)) {
396 c_parser_context oc = (c_parser_context) stack_head(ContextStack);
397 //pips_assert("ycontext is consistant with stack_head(ContextStack)",
398 // ycontext==stack_head(ContextStack));
399 pips_debug(8, "Back to context scope \"\%s\" in context %p\n",
400 c_parser_context_scope(oc), oc);
403 // ycontext = c_parser_context_undefined;
404 pips_debug(8, "Back to undefined context scope\n");
408 void PushContext(c_parser_context c)
410 stack_push((char *) c, ContextStack);
411 pips_debug(8, "Context %p with scope \"%s\" is put in stack position %d\n",
412 c, c_parser_context_scope(c), stack_size(ContextStack));
417 c_parser_context fc = (c_parser_context) stack_head(ContextStack);
419 pips_debug(8, "Context %p with scope \"%s\" is popped from stack position %d\n",
420 fc, c_parser_context_scope(fc), stack_size(ContextStack));
421 (void)stack_pop(ContextStack);
422 if(stack_empty_p(ContextStack)) {
423 pips_debug(8, "context stack is now empty\n");
426 c_parser_context h = (c_parser_context) stack_head(ContextStack);
427 pips_debug(8, "Context %p with scope \"%s\" is top of stack at position %d\n",
428 h, c_parser_context_scope(h), stack_size(ContextStack));
432 c_parser_context GetContext()
435 c_parser_context c = c_parser_context_undefined;
437 if(!stack_empty_p(ContextStack))
438 c = (c_parser_context) stack_head(ContextStack);
440 // Should we return a default context?
441 // Not really compatible with a clean memory allocation policy
442 pips_internal_error("No current context");
444 pips_debug(8, "Context %p is obtained from stack position %d\n",
445 c, stack_size(ContextStack));
450 c_parser_context GetContextCopy()
452 c_parser_context c = (c_parser_context) stack_head(ContextStack);
453 c_parser_context cc = copy_c_parser_context(c);
454 pips_debug(8, "Context copy %p with scope \"%s\" is obtained from context %p with scope \"%s\" at stack position %d\n",
455 cc, c_parser_context_scope(cc),
456 c, c_parser_context_scope(c),
457 stack_size(ContextStack));
460 /* Declaration counter
462 * It is used to declare the formal parameters in function declarations.
464 static int declaration_counter = 0;
466 void reset_declaration_counter()
468 declaration_counter = 0;
471 int get_declaration_counter()
473 return declaration_counter;
476 /* Each scope in the current unit has its own number.
478 * The scope management in the C parser is the same as in the C preprocessor.
480 * The scope numbers defined here are used by the C parser lexical
481 * analyzer to disambiguate between named types and variables, but
482 * different scopes are defined for the internal representation.
484 #define SCOPE_UNDEFINED (-1)
485 static int c_parser_scope_number = SCOPE_UNDEFINED;
486 static stack c_parser_scope_stack = stack_undefined;
488 void init_c_parser_scope_stack()
490 c_parser_scope_number = 0;
491 pips_assert("The stack is undefined",
492 stack_undefined_p(c_parser_scope_stack));
493 c_parser_scope_stack = stack_make(string_domain, 0, 0);
496 void reset_c_parser_scope_stack()
498 if(c_parser_scope_stack != stack_undefined) {
499 if(stack_empty_p(c_parser_scope_stack)) {
500 stack_free(&c_parser_scope_stack);
501 c_parser_scope_stack = stack_undefined;
504 // pips_internal_error? Could be a bad input C file...
505 pips_user_warning("Parser scope stack is not empty.\n");
508 c_parser_scope_number = SCOPE_UNDEFINED;
512 /* To be used by an error handler */
513 void force_reset_c_parser_scope_stack()
515 if(c_parser_scope_stack != stack_undefined) {
516 stack_free(&c_parser_scope_stack);
517 c_parser_scope_stack = stack_undefined;
519 c_parser_scope_number = SCOPE_UNDEFINED;
523 void push_new_c_parser_scope()
525 c_parser_scope_number++;
526 string sn = string_undefined;
527 (void) asprintf(&sn, "%d", c_parser_scope_number);
528 stack_push((void *) sn, c_parser_scope_stack);
532 void pop_c_parser_scope_stack()
534 stack_pop(c_parser_scope_stack);
538 bool c_parser_scope_stack_empty_p()
540 return stack_empty_p(c_parser_scope_stack);
543 string get_c_parser_current_scope()
545 string sn = string_undefined;
546 if(c_parser_scope_stack_empty_p()) {
547 // We are at the global level: no scope has been entered yet
551 sn = (string) stack_head(c_parser_scope_stack);
555 string get_c_parser_nth_scope(int n)
557 string sn = (string) stack_nth(c_parser_scope_stack, n);
561 int c_parser_number_of_scopes()
563 int n = stack_size(c_parser_scope_stack);
567 /* When struct and union declarations are nested, the rules cannot
568 return information about the internal declarations because they
569 must return type information. Hence internal declarations must be
570 recorded and re-used when the final continue/declaration statement
571 is generated. In order not to confuse the prettyprinter, they must
572 appear first in the declaration list, that is in the innermost to
575 static list internal_derived_entity_declarations = NIL;
577 static void RecordDerivedEntityDeclaration(entity de)
579 internal_derived_entity_declarations
580 = gen_nconc(internal_derived_entity_declarations,
581 CONS(ENTITY, de, NIL));
584 static list GetDerivedEntityDeclarations()
586 list l = internal_derived_entity_declarations;
587 /* The list spine is going to be reused by the caller. No need to
589 internal_derived_entity_declarations = NIL;
593 static void ResetDerivedEntityDeclarations()
595 if(!ENDP(internal_derived_entity_declarations)) {
596 gen_free_list(internal_derived_entity_declarations);
597 internal_derived_entity_declarations = NIL;
602 /* Bison declarations */
607 expression expression;
616 %token <string> TK_IDENT
617 %token <string> TK_CHARCON
618 %token <string> TK_INTCON
619 %token <string> TK_FLOATCON
620 %token <string> TK_NAMED_TYPE
622 %token <string> TK_STRINGCON
623 %token <string> TK_WSTRINGCON
626 %token TK_CHAR TK_INT TK_INT128 TK_UINT128 TK_DOUBLE TK_FLOAT TK_VOID TK_COMPLEX
627 %token TK_ENUM TK_STRUCT TK_TYPEDEF TK_UNION
628 %token TK_SIGNED TK_UNSIGNED TK_LONG TK_SHORT
629 %token TK_VOLATILE TK_EXTERN TK_STATIC TK_STATIC_DIMENSION TK_CONST TK_RESTRICT TK_AUTO TK_REGISTER TK_THREAD
631 %token TK_SIZEOF TK_ALIGNOF
633 %token TK_EQ TK_PLUS_EQ TK_MINUS_EQ TK_STAR_EQ TK_SLASH_EQ TK_PERCENT_EQ
634 %token TK_AND_EQ TK_PIPE_EQ TK_CIRC_EQ TK_INF_INF_EQ TK_SUP_SUP_EQ
635 %token TK_ARROW TK_DOT
637 %token TK_EQ_EQ TK_EXCLAM_EQ TK_INF TK_SUP TK_INF_EQ TK_SUP_EQ
638 %token TK_PLUS TK_MINUS TK_STAR
639 %token TK_SLASH TK_PERCENT
640 %token TK_TILDE TK_AND
641 %token TK_PIPE TK_CIRC
642 %token TK_EXCLAM TK_AND_AND
644 %token TK_INF_INF TK_SUP_SUP
645 %token TK_PLUS_PLUS TK_MINUS_MINUS
648 %token TK_LPAREN TK_RBRACE
650 %token TK_LBRACKET TK_RBRACKET
653 %token TK_COMMA TK_ELLIPSIS TK_QUEST
655 %token TK_BREAK TK_CONTINUE TK_GOTO TK_RETURN
656 %token TK_SWITCH TK_CASE TK_DEFAULT
657 %token TK_WHILE TK_DO TK_FOR
661 %token TK_ATTRIBUTE TK_INLINE TK_ASM TK_TYPEOF TK_FUNCTION__ TK_PRETTY_FUNCTION__
663 %token TK_BUILTIN_VA_ARG
664 %token TK_BUILTIN_VA_LIST
665 %token TK_BLOCKATTRIBUTE
667 %token TK_MSASM TK_MSATTR
668 /* The string that follows a #pragma: */
669 %token <string> TK_PRAGMA
670 /* The token _Pragma from C99: */
673 /* sm: cabs tree transformation specification keywords */
674 %token TK_AT_TRANSFORM TK_AT_TRANSFORMEXPR TK_AT_SPECIFIER TK_AT_EXPR
677 /* Added here because the token numbering seems to be fragile */
678 %token <string> TK_COMPLEXCON
680 /* operator precedence */
684 %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
685 %right TK_QUEST TK_COLON
691 %left TK_EQ_EQ TK_EXCLAM_EQ
692 %left TK_INF TK_SUP TK_INF_EQ TK_SUP_EQ
693 %left TK_INF_INF TK_SUP_SUP
694 %left TK_PLUS TK_MINUS
695 %left TK_STAR TK_SLASH TK_PERCENT TK_CONST TK_RESTRICT TK_VOLATILE
697 %right TK_EXCLAM TK_TILDE TK_PLUS_PLUS TK_MINUS_MINUS TK_RPAREN TK_ADDROF TK_SIZEOF TK_ALIGNOF
699 %left TK_DOT TK_ARROW TK_LPAREN TK_LBRACE
703 /* Non-terminals informations */
705 %type <liste> file interpret globals
707 %type <liste> attributes attributes_with_asm asmattr
708 %type <qualifier> attribute
709 %type <statement> statement
710 %type <statement> statement_without_pragma
711 %type <entity> constant
712 %type <string> string_constant
713 %type <expression> expression
714 %type <expression> opt_expression
715 %type <expression> init_expression
716 %type <liste> comma_expression
717 %type <liste> paren_comma_expression statement_paren_comma_expression
718 %type <liste> arguments
719 %type <liste> bracket_comma_expression
720 %type <liste> string_list
721 %type <liste> wstring_list
723 %type <expression> initializer
724 %type <liste> initializer_list
725 %type <liste> init_designators init_designators_opt
727 %type <liste> type_spec
728 %type <liste> struct_decl_list
730 %type <parameter> parameter_decl
731 %type <entity> enumerator
732 %type <liste> enum_list
733 %type <liste> declaration
734 %type <void> function_def
735 %type <void> function_def_start
736 %type <type> type_name
737 %type <statement> block statements_inside_block
738 %type <liste> local_labels local_label_names
739 %type <liste> old_parameter_list_ne
740 %type <liste> old_pardef_list
741 %type <liste> old_pardef
743 %type <entity> init_declarator
744 %type <liste> init_declarator_list
745 %type <entity> declarator
746 %type <entity> field_decl
747 %type <liste> field_decl_list
748 %type <entity> direct_decl
749 %type <entity> abs_direct_decl abs_direct_decl_opt
750 %type <entity> abstract_decl
751 %type <type> pointer pointer_opt
752 %type <void> location
755 %type <string> id_or_typename
756 %type <liste> comma_expression_opt
757 %type <liste> initializer_list_opt
758 %type <string> one_string_constant
759 %type <string> one_string
761 %type <liste> rest_par_list rest_par_list1
762 %type <liste> statement_list
763 %type <liste> decl_spec_list /* to store the list of entities such as struct, union and enum, typedef*/
764 %type <liste> my_decl_spec_list
765 %type <liste> decl_spec_list_opt_no_named
766 %type <liste> decl_spec_list_opt
767 %type <entity> old_proto_decl direct_old_proto_decl
769 /* For now, pass pragmas as strings and list of strings: */
770 %type <string> pragma
771 %type <liste> pragmas
775 interpret: file TK_EOF
779 /* To handle special case: compilation unit module */
781 list dl = statements_to_declarations(dsl);
783 pips_assert("Here, only continue statements are expected",
784 continue_statements_p(dsl));
786 if (true /* dl != NIL*/) { /* A C file with comments only is OK */
787 if(!entity_undefined_p(get_current_module_entity())) {
788 if(!compilation_unit_p(get_current_module_name())) {
789 pips_assert("Each variable is declared once", gen_once_p(dl));
790 pips_internal_error("Compilation unit rule used for non"
791 " compilation unit %s\n",
792 get_current_module_name());
795 pips_debug(8, "Declaration list for compilation unit %s: ",
796 get_current_module_name());
800 ModuleStatement = make_statement(entity_empty_label(),
801 STATEMENT_NUMBER_UNDEFINED,
802 STATEMENT_ORDERING_UNDEFINED,
804 make_instruction_block(dsl),
805 dl, NULL, empty_extensions (), make_synchronization_none());
807 pips_user_warning("ISO C forbids an empty source file\n");
815 /* empty */ { $$ = NIL; }
816 | {is_external = true; } global globals
822 if(!ENDP(dsl) && gen_length(gdsl)==1)
824 statement stmt = STATEMENT(CAR(dsl));
825 statement stmt_pragma = STATEMENT(CAR(gdsl));
826 list exs = extensions_extension(statement_extensions(stmt_pragma));
829 extensions_extension(statement_extensions(stmt)) = gen_nconc(exs, extensions_extension(statement_extensions(stmt)));
830 extensions_extension(statement_extensions(stmt_pragma)) = NIL;
831 gen_full_free_list(gdsl);
836 ifdebug(1) { // the successive calls to statements_to_declarations are too costly, so I only activate the test upond debug(1)
837 list dl = statements_to_declarations(dsl);
838 /* Each variable should be declared only
839 once. Type and initial value conflict
840 should have been detected earlier. */
841 if(!compilation_unit_p(get_current_module_name())) {
842 pips_assert("Each variable is declared once", gen_once_p(dl));
845 list gdl = statements_to_declarations(gdsl);
846 fprintf(stderr, "New variables $2 (%p) are declared\n", gdl);
848 fprintf(stderr, "\n");
849 fprintf(stderr, "*******Current declarations dl (%p) are: \n", dl);
851 fprintf(stderr, "\n");
857 /* The order of declarations must be
858 preserved: a structure is declared before
859 it is used to declare a variable */
863 if(!gen_in_list_p(v, $3))
864 $$ = gen_nconc($$, CONS(ENTITY, v , NIL));}, $2);
865 $$ = gen_nconc($$, $3);
867 /* Redeclarations are possible in C as long as they are compatible */
868 /* It is assumed that compatibility is checked somewhere else... */
869 $$ = gen_nconc(gdsl, dsl);
872 list udl = statements_to_declarations($$);
873 fprintf(stderr, "*******Updated $$ declarations (%p) are: \n", $$);
874 fprintf(stderr, "\n");
876 fprintf(stderr, "Empty list\n");
879 fprintf(stderr, "\n");
882 if(!compilation_unit_p(get_current_module_name())) {
883 list udl = statements_to_declarations($$);
884 pips_assert("Each variable is declared once", gen_once_p(udl));
885 entity m = get_current_module_entity();
886 if(strcmp(entity_local_name(m),"main")==0) {
887 type mt = entity_type(m);
888 if(type_functional_p(mt)) {
889 type rt = functional_result(type_functional(mt));
890 if(!scalar_integer_type_p(rt))
891 /* Too late for line numbers, do not use c_parser_user_warning */
892 c_parser_user_warning("The \"main\" function should return an int value\n");
895 pips_internal_error("A function does not have a functional type\n");
898 ResetCurrentModule();
901 | TK_SEMICOLON globals
903 pips_assert("Declarations are unique", gen_once_p($2));
905 list udl = statements_to_declarations($2);
906 fprintf(stderr, "*******Current declarations are: \n");
908 fprintf(stderr, "\n");
915 /* empty */ {} %prec TK_IDENT
917 /*** Global Definition ***/
919 declaration {pips_debug(1, "Reduction %d: declaration -> global\n", __LINE__); /* discard_C_comment();*/ /* fprintf(stderr, "declaration\n");*/ declaration_counter++; }
920 | function_def { $$ = NIL;}
921 | TK_ASM TK_LPAREN string_constant TK_RPAREN TK_SEMICOLON
923 CParserError("ASM not implemented\n");
929 CParserError("PRAGMA not implemented at top level\n");
932 statement s = make_continue_statement(entity_empty_label());
933 add_pragma_str_to_statement(s, $1, true);
934 $$ = CONS(STATEMENT, s, NIL);
936 /* Old-style function prototype. This should be somewhere else, like in
937 "declaration". For now we keep it at global scope only because in local
938 scope it looks too much like a function call */
941 entity oe = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
943 entity e = oe; //RenameFunctionEntity(oe);
944 pips_debug(2,"Create function %s with old-style function prototype\n",$1);
945 if (storage_undefined_p(entity_storage(e))) {
946 //entity_storage(e) = make_storage_return(e);
947 entity_storage(e) = make_storage_rom();
949 if (value_undefined_p(entity_initial(e)))
950 entity_initial(e) = make_value(is_value_code,make_code(NIL,strdup(""),make_sequence(NIL),NIL, make_language_c()));
951 //pips_assert("e is a module", module_name_p(entity_module_name(e)));
953 CCleanLocalEntities(oe);
955 stack_push((char *) make_basic_logical(true),FormalStack);
956 stack_push((char *) make_basic_int(1),OffsetStack);
957 // FI: commented out while looking for
958 //declaration comments
959 //discard_C_comment();
961 old_parameter_list_ne TK_RPAREN old_pardef_list TK_SEMICOLON
963 entity e = GetFunction();
964 if (type_undefined_p(entity_type(e)))
966 list paras = MakeParameterList($4,$6,FunctionStack);
967 functional f = make_functional(paras,make_type_unknown());
968 entity_type(e) = make_type_functional(f);
970 pips_assert("Current function entity is consistent",entity_consistent_p(e));
972 stack_pop(FormalStack);
973 StackPop(OffsetStack);
976 // FI: commented out while trying to
977 //retrieve all comments
978 //discard_C_comment();
980 /* Old style function prototype, but without any arguments
982 Not used because of conflicts...
983 | TK_IDENT TK_LPAREN TK_RPAREN TK_SEMICOLON
985 entity e = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
986 pips_debug(2,"Create function %s with old-style prototype, without any argument\n",$1);
987 if (type_undefined_p(entity_type(e)))
989 functional f = make_functional(NIL,make_type_unknown());
990 entity_type(e) = make_type_functional(f);
992 if (storage_undefined_p(entity_storage(e))) {
993 // entity_storage(e) = make_storage_return(e);
994 entity_storage(e) = make_storage_rom();
996 if (value_undefined_p(entity_initial(e)))
997 entity_initial(e) = make_value(is_value_code,make_code(NIL,strdup(""),make_sequence(NIL),NIL, make_language_c()));
998 pips_assert("Current function entity is consistent",entity_consistent_p(e));
1000 // FI: commented out while trying to
1001 //retrieve all comments
1002 //discard_C_comment();
1005 /* transformer for a toplevel construct */
1006 | TK_AT_TRANSFORM TK_LBRACE global TK_RBRACE TK_IDENT /*to*/ TK_LBRACE globals TK_RBRACE
1008 CParserError("CIL AT not implemented\n");
1011 /* transformer for an expression */
1012 | TK_AT_TRANSFORMEXPR TK_LBRACE expression TK_RBRACE TK_IDENT /*to*/ TK_LBRACE expression TK_RBRACE
1014 CParserError("CIL AT not implemented\n");
1017 | location error TK_SEMICOLON
1019 CParserError("Parse error: location error TK_SEMICOLON \n");
1029 | TK_AT_NAME TK_LPAREN TK_IDENT TK_RPAREN
1031 CParserError("CIL AT not implemented\n");
1037 | TK_COMMA /* do nothing */
1040 /* *** Expressions *** */
1045 $$ = MakeNullaryCall($1);
1049 /* Create the expression corresponding to this identifier */
1050 $$ = IdentifierToExpression($1);
1053 | TK_SIZEOF expression
1055 $$ = MakeSizeofExpression($2);
1057 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
1059 $$ = MakeSizeofType($3);
1061 | TK_ALIGNOF expression
1063 CParserError("ALIGNOF not implemented\n");
1065 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
1067 CParserError("ALIGNOF not implemented\n");
1069 | TK_PLUS expression %prec TK_CAST
1071 $$ = MakeUnaryCall(CreateIntrinsic(UNARY_PLUS_OPERATOR_NAME), $2);
1073 | TK_MINUS expression %prec TK_CAST
1075 $$ = MakeUnaryCall(CreateIntrinsic(UNARY_MINUS_OPERATOR_NAME), $2);
1077 | TK_STAR expression
1079 $$ = MakeUnaryCall(CreateIntrinsic(DEREFERENCING_OPERATOR_NAME), $2);
1081 | TK_AND expression %prec TK_ADDROF
1083 $$ = MakeUnaryCall(CreateIntrinsic(ADDRESS_OF_OPERATOR_NAME), $2);
1085 | TK_EXCLAM expression
1087 $$ = MakeUnaryCall(CreateIntrinsic(C_NOT_OPERATOR_NAME), $2);
1089 | TK_TILDE expression
1091 $$ = MakeUnaryCall(CreateIntrinsic(BITWISE_NOT_OPERATOR_NAME), $2);
1093 | TK_PLUS_PLUS expression %prec TK_CAST
1095 $$ = MakeUnaryCall(CreateIntrinsic(PRE_INCREMENT_OPERATOR_NAME), $2);
1097 | expression TK_PLUS_PLUS
1099 $$ = MakeUnaryCall(CreateIntrinsic(POST_INCREMENT_OPERATOR_NAME), $1);
1101 | TK_MINUS_MINUS expression %prec TK_CAST
1103 $$ = MakeUnaryCall(CreateIntrinsic(PRE_DECREMENT_OPERATOR_NAME), $2);
1105 | expression TK_MINUS_MINUS
1107 $$ = MakeUnaryCall(CreateIntrinsic(POST_DECREMENT_OPERATOR_NAME), $1);
1109 | expression TK_ARROW id_or_typename
1111 /* Find the struct/union type of the expression
1112 then the struct/union member entity and transform it to expression */
1113 expression exp = MemberIdentifierToExpression($1,$3);
1114 $$ = MakeBinaryCall(CreateIntrinsic(POINT_TO_OPERATOR_NAME),$1,exp);
1116 | expression TK_DOT id_or_typename
1118 expression exp = MemberIdentifierToExpression($1,$3);
1119 $$ = MakeBinaryCall(CreateIntrinsic(FIELD_OPERATOR_NAME),$1,exp);
1121 | TK_LPAREN block TK_RPAREN
1123 CParserError("GNU extension not implemented\n");
1125 | paren_comma_expression
1128 char * ccc = pop_current_C_comment();
1129 if(!empty_comments_p(ccc)) {
1130 bool fullspace=true;
1131 for(const char *iter=ccc;*iter;++iter)
1132 if(!(fullspace=(isspace(*iter)&&*iter!='\n')))
1137 /* paren_comma_expression is a list of
1138 expressions, maybe reduced to one */
1139 if(empty_comments_p(expression_comment))
1140 expression_comment=ccc;
1142 char *tmp = expression_comment;
1143 asprintf(&expression_comment,"%s%s",expression_comment, ccc);
1148 expression_line_number = pop_current_C_line_number();
1150 $$ = MakeCommaExpression($1);
1152 | expression TK_LPAREN arguments TK_RPAREN
1154 $$ = MakeFunctionExpression($1,$3);
1156 | TK_BUILTIN_VA_ARG TK_LPAREN expression TK_COMMA type_name TK_RPAREN
1161 sizeofexpression e1 = make_sizeofexpression_expression(e);
1162 sizeofexpression e2 = make_sizeofexpression_type(t);
1163 list l = CONS(SIZEOFEXPRESSION, e1,
1164 CONS(SIZEOFEXPRESSION, e2, NIL));
1165 syntax s = make_syntax_va_arg(l);
1166 expression r = make_expression(s, make_normalized_complex());
1169 //CParserError("BUILTIN_VA_ARG not implemented\n");
1171 | expression bracket_comma_expression
1173 $$ = MakeArrayExpression($1,$2);
1175 | expression TK_QUEST opt_expression TK_COLON expression
1177 $$ = MakeTernaryCall(CreateIntrinsic(CONDITIONAL_OPERATOR_NAME), $1, $3, $5);
1179 | expression TK_PLUS expression
1181 $$ = MakeBinaryCall(CreateIntrinsic(PLUS_C_OPERATOR_NAME), $1, $3);
1183 | expression TK_MINUS expression
1185 $$ = MakeBinaryCall(CreateIntrinsic(MINUS_C_OPERATOR_NAME), $1, $3);
1187 | expression TK_STAR expression
1189 $$ = MakeBinaryCall(CreateIntrinsic(MULTIPLY_OPERATOR_NAME), $1, $3);
1191 | expression TK_SLASH expression
1193 $$ = MakeBinaryCall(CreateIntrinsic(DIVIDE_OPERATOR_NAME), $1, $3);
1195 | expression TK_PERCENT expression
1197 $$ = MakeBinaryCall(CreateIntrinsic(C_MODULO_OPERATOR_NAME), $1, $3);
1199 | expression TK_AND_AND expression
1201 $$ = MakeBinaryCall(CreateIntrinsic(C_AND_OPERATOR_NAME), $1, $3);
1203 | expression TK_PIPE_PIPE expression
1205 $$ = MakeBinaryCall(CreateIntrinsic(C_OR_OPERATOR_NAME), $1, $3);
1207 | expression TK_AND expression
1209 $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_AND_OPERATOR_NAME), $1, $3);
1211 | expression TK_PIPE expression
1213 $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_OR_OPERATOR_NAME), $1, $3);
1215 | expression TK_CIRC expression
1217 $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_XOR_OPERATOR_NAME), $1, $3);
1219 | expression TK_EQ_EQ expression
1221 $$ = MakeBinaryCall(CreateIntrinsic(C_EQUAL_OPERATOR_NAME), $1, $3);
1223 | expression TK_EXCLAM_EQ expression
1225 $$ = MakeBinaryCall(CreateIntrinsic(C_NON_EQUAL_OPERATOR_NAME), $1, $3);
1227 | expression TK_INF expression
1229 $$ = MakeBinaryCall(CreateIntrinsic(C_LESS_THAN_OPERATOR_NAME), $1, $3);
1231 | expression TK_SUP expression
1233 $$ = MakeBinaryCall(CreateIntrinsic(C_GREATER_THAN_OPERATOR_NAME), $1, $3);
1235 | expression TK_INF_EQ expression
1237 $$ = MakeBinaryCall(CreateIntrinsic(C_LESS_OR_EQUAL_OPERATOR_NAME), $1, $3);
1239 | expression TK_SUP_EQ expression
1241 $$ = MakeBinaryCall(CreateIntrinsic(C_GREATER_OR_EQUAL_OPERATOR_NAME), $1, $3);
1243 | expression TK_INF_INF expression
1245 $$ = MakeBinaryCall(CreateIntrinsic(LEFT_SHIFT_OPERATOR_NAME), $1, $3);
1247 | expression TK_SUP_SUP expression
1249 $$ = MakeBinaryCall(CreateIntrinsic(RIGHT_SHIFT_OPERATOR_NAME), $1, $3);
1251 | expression TK_EQ expression
1253 expression lhs = $1;
1254 expression rhs = $3;
1255 /* Check the left hand side expression */
1256 if(expression_reference_p(lhs)) {
1257 reference r = expression_reference(lhs);
1258 entity v = reference_variable(r);
1259 type t = ultimate_type(entity_type(v));
1260 if(type_functional_p(t)) {
1261 c_parser_user_warning("Ill. left hand side reference to function \"%s\""
1262 " or variable \"%s\" not declared\n",
1263 entity_user_name(v), entity_user_name(v));
1264 CParserError("Ill. left hand side expression");
1267 (void) simplify_C_expression(rhs);
1268 $$ = make_assign_expression(lhs, rhs);
1270 | expression TK_PLUS_EQ expression
1272 (void) simplify_C_expression($3);
1273 $$ = MakeBinaryCall(CreateIntrinsic(PLUS_UPDATE_OPERATOR_NAME), $1, $3);
1275 | expression TK_MINUS_EQ expression
1277 (void) simplify_C_expression($3);
1278 $$ = MakeBinaryCall(CreateIntrinsic(MINUS_UPDATE_OPERATOR_NAME), $1, $3);
1280 | expression TK_STAR_EQ expression
1282 (void) simplify_C_expression($3);
1283 $$ = MakeBinaryCall(CreateIntrinsic(MULTIPLY_UPDATE_OPERATOR_NAME), $1, $3);
1285 | expression TK_SLASH_EQ expression
1287 (void) simplify_C_expression($3);
1288 $$ = MakeBinaryCall(CreateIntrinsic(DIVIDE_UPDATE_OPERATOR_NAME), $1, $3);
1290 | expression TK_PERCENT_EQ expression
1292 (void) simplify_C_expression($3);
1293 $$ = MakeBinaryCall(CreateIntrinsic(MODULO_UPDATE_OPERATOR_NAME), $1, $3);
1295 | expression TK_AND_EQ expression
1297 (void) simplify_C_expression($3);
1298 $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_AND_UPDATE_OPERATOR_NAME), $1, $3);
1300 | expression TK_PIPE_EQ expression
1302 (void) simplify_C_expression($3);
1303 $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_OR_UPDATE_OPERATOR_NAME), $1, $3);
1305 | expression TK_CIRC_EQ expression
1307 (void) simplify_C_expression($3);
1308 $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_XOR_UPDATE_OPERATOR_NAME), $1, $3);
1310 | expression TK_INF_INF_EQ expression
1312 (void) simplify_C_expression($3);
1313 $$ = MakeBinaryCall(CreateIntrinsic(LEFT_SHIFT_UPDATE_OPERATOR_NAME), $1, $3);
1315 | expression TK_SUP_SUP_EQ expression
1317 (void) simplify_C_expression($3);
1318 $$ = MakeBinaryCall(CreateIntrinsic(RIGHT_SHIFT_UPDATE_OPERATOR_NAME), $1, $3);
1320 | TK_LPAREN type_name TK_RPAREN expression
1322 $$ = MakeCastExpression($2,$4);
1324 /* (* We handle GCC constructor expressions *) */
1325 | TK_LPAREN type_name TK_RPAREN TK_LBRACE initializer_list_opt TK_RBRACE
1327 $$ = MakeCastExpression($2,MakeBraceExpression($5));
1329 /* (* GCC's address of labels *) */
1330 | TK_AND_AND TK_IDENT
1332 CParserError("GCC's address of labels not implemented\n");
1334 | TK_AT_EXPR TK_LPAREN TK_IDENT TK_RPAREN /* expression pattern variable */
1336 CParserError("GCC's address of labels not implemented\n");
1342 { // Do we know about the size? 2, 4 or 8 bytes?
1343 $$ = make_C_constant_entity($1, is_basic_int, 4);
1348 $$ = MakeConstant($1, is_basic_float);
1353 /* some work left to accomodate imaginary
1355 $$ = MakeConstant($1, is_basic_float);
1360 $$ = make_C_constant_entity($1, is_basic_int, 1);
1365 /* The size will be fixed later, hence 0 here. */
1366 $$ = make_C_constant_entity($1, is_basic_string, 0);
1369 /*add a nul to strings. We do this here (rather than in the lexer) to make
1370 concatenation easy below.*/
1373 $$ = MakeConstant(list_to_string($1),is_basic_string);
1379 /* Now that we know this constant isn't part of a wstring, convert it
1380 back to a string for easy viewing. */
1383 /* Hmmm... Looks like a memory leak on all the
1385 $$ = list_to_string(gen_nreverse($1));
1388 one_string_constant:
1389 /* Don't concat multiple strings. For asm templates. */
1396 $$ = CONS(STRING,$1,NIL);
1398 | string_list one_string
1400 $$ = CONS(STRING,$2,$1);
1407 $$ = CONS(STRING,$1,NIL);
1409 | wstring_list one_string
1411 $$ = CONS(STRING,$2,$1);
1413 | wstring_list TK_WSTRINGCON
1415 $$ = gen_nconc($1,CONS(STRING,$2,NIL));
1417 /* Only the first string in the list needs an L, so L"a" "b" is the same
1418 * as L"ab" or L"a" L"b". */
1423 { CParserError("TK_FUNCTION not implemented\n"); }
1424 | TK_PRETTY_FUNCTION__
1425 { CParserError("TK_PRETTY_FUNCTION not implemented\n"); }
1432 /* fprintf(stderr, "Initialization expression: "); */
1433 /* print_expression(ie); */
1434 /* fprintf(stderr, "\n"); */
1438 | TK_LBRACE initializer_list_opt TK_RBRACE
1440 /* Deduce the size of an array by its initialization ?*/
1441 $$ = MakeBraceExpression($2);
1444 initializer_list: /* ISO 6.7.8. Allow a trailing COMMA */
1447 $$ = CONS(EXPRESSION,$1,NIL);
1449 | initializer TK_COMMA initializer_list_opt
1451 $$ = CONS(EXPRESSION,$1,$3);
1454 initializer_list_opt:
1455 /* empty */ { $$ = NIL; }
1456 | initializer_list { }
1459 init_designators eq_opt init_expression
1461 CParserError("Complicated initialization not implemented\n");
1463 | gcc_init_designators init_expression
1465 CParserError("gcc init designators not implemented\n");
1467 | init_expression { }
1472 /*(* GCC allows missing = *)*/
1475 CParserError("gcc missing = not implemented\n");
1479 TK_DOT id_or_typename init_designators_opt
1481 | TK_LBRACKET expression TK_RBRACKET init_designators_opt
1483 | TK_LBRACKET expression TK_ELLIPSIS expression TK_RBRACKET
1486 init_designators_opt:
1487 /* empty */ { $$ = NIL; }
1488 | init_designators {}
1491 gcc_init_designators: /*(* GCC supports these strange things *)*/
1492 id_or_typename TK_COLON
1494 CParserError("gcc init designators not implemented\n");
1499 /* empty */ { $$ = NIL; }
1500 | comma_expression { }
1505 { $$ = expression_undefined; } /* This should be a null expression,
1506 not expression_undefined*/
1508 { $$ = MakeCommaExpression($1); }
1514 pips_debug(1, "Reduction %d: expression -> comma_expression\n", __LINE__);
1515 (void) simplify_C_expression($1);
1516 $$ = CONS(EXPRESSION,$1,NIL);
1518 | expression TK_COMMA comma_expression
1520 pips_debug(1, "Reduction %d: expression TK_COMMA comma_expression -> comma_expression\n", __LINE__);
1521 (void) simplify_C_expression($1);
1522 $$ = CONS(EXPRESSION,$1,$3);
1524 | error TK_COMMA comma_expression
1526 CParserError("Parse error: error TK_COMMA comma_expression \n");
1530 comma_expression_opt:
1531 /* empty */ { $$ = NIL; }
1532 | comma_expression { }
1535 statement_paren_comma_expression:
1536 TK_LPAREN comma_expression TK_RPAREN
1538 push_current_C_comment();
1539 push_current_C_line_number();
1540 save_expression_comment_as_statement_comment();
1543 | TK_LPAREN error TK_RPAREN
1545 CParserError("Parse error: TK_LPAREN error TK_RPAREN \n");
1548 paren_comma_expression:
1549 TK_LPAREN comma_expression TK_RPAREN
1552 push_current_C_comment();
1553 push_current_C_line_number();
1557 | TK_LPAREN error TK_RPAREN
1559 CParserError("Parse error: TK_LPAREN error TK_RPAREN \n");
1563 bracket_comma_expression:
1564 TK_LBRACKET comma_expression TK_RBRACKET
1568 | TK_LBRACKET error TK_RBRACKET
1570 CParserError("Parse error: TK_LBRACKET error TK_RBRACKET\n");
1574 /*** statements ***/
1576 statements_inside_block:
1579 /* To avoid some parasitic line skipping after the
1580 block opening brace. May be it should be
1581 cleaner to keep this eventual line-break as a
1582 comment in the statement, for subtler user
1583 source layout representation? */
1584 discard_C_comment();
1586 local_labels block_attrs statement_list
1592 block: /* ISO 6.8.2 */
1593 statements_inside_block TK_RBRACE
1598 | error location TK_RBRACE
1599 { abort();CParserError("Parse error: error location TK_RBRACE \n"); }
1605 /*| TK_BLOCKATTRIBUTE paren_attr_list_ne
1606 { CParserError("BLOCKATTRIBUTE not implemented\n"); }*/
1611 /* empty */ { $$ = NIL; }
1613 statement s = make_continue_statement(entity_empty_label());
1614 add_pragma_strings_to_statement(s, gen_nreverse($1),false);
1616 $$ = CONS(STATEMENT, s, NIL);
1618 | statement statement_list
1620 $$ = CONS(STATEMENT,$1,$2);
1622 /*(* GCC accepts a label at the end of a block *)*/
1623 | label { CParserError("gcc not implemented\n"); }
1628 | TK_LABEL__ local_label_names TK_SEMICOLON local_labels
1629 { CParserError("LABEL__ not implemented\n"); }
1633 TK_IDENT {free($1);}
1634 | TK_IDENT TK_COMMA local_label_names {free($1);}
1640 // Push the comment associated with the label:
1641 push_current_C_comment();
1648 TK__Pragma TK_LPAREN string_constant TK_RPAREN {
1649 /* Well, indeed this has not been tested at the time of writing since
1650 the _Pragma("...") is replaced by a #pragma ... in the C
1651 preprocessor, at least in gcc 4.4. */
1652 /* The pragma string has been strdup()ed in the lexer... */
1653 pips_debug(1, "Found _Pragma(\"%s\")\n", $3);
1657 pips_debug(1, "Found #pragma %s\n", c_lval.string);
1664 pragma { /* Only one pragma... The common case, return it in a list */
1665 pips_debug(1, "No longer pragma\n");
1666 $$ = CONS(STRING, $1, NIL);
1669 /* Concatenate the pragma to the list of pragmas */
1670 $$ = CONS(STRING,$1,$2);
1675 /* To avoid shift-reduce conflict, enumerate statement with and without pragma: */
1676 statement: pragmas statement_without_pragma
1678 add_pragma_strings_to_statement($2, gen_nreverse($1),
1679 false /* Do not reallocate the strings*/);
1680 /* Reduce the CO2 impact of this code, even there is huge memory leaks
1681 everywhere around in this file: */
1684 reset_token_has_been_seen_p();
1686 | statement_without_pragma {
1688 reset_token_has_been_seen_p();
1693 statement_without_pragma:
1696 /* Null statement in C is represented as continue statement in Fortran*/
1697 /* FI: the comments should be handled at
1698 another level, so as not to repeat the
1699 same code over and over again? */
1700 string sc = get_current_C_comment();
1701 int sn = get_current_C_line_number();
1702 statement s = make_continue_statement(entity_empty_label());
1703 statement_comments(s) = sc;
1704 statement_number(s) = sn;
1707 | comma_expression TK_SEMICOLON
1709 pips_debug(1, "Reduction %d: comma_expression TK_SEMICOLON -> statement_without_pragma\n", __LINE__);
1710 statement s = statement_undefined;
1711 if (gen_length($1)==1) {
1712 /* This uses the current comment and
1713 current line number. */
1714 s = ExpressionToStatement(EXPRESSION(CAR($1)));
1718 /* FI: I do not know how
1719 expression_comment is supposed to
1720 work for real comma expressions */
1721 s = call_to_statement(make_call(CreateIntrinsic(COMMA_OPERATOR_NAME),$1));
1722 statement_number(s) =
1723 get_current_C_line_number();
1724 statement_comments(s) = get_current_C_comment();
1726 $$ = flush_expression_comment(s);
1730 /* In C99 we can have a declaration anywhere!
1732 Declaration returns a statement list. Maybe
1733 it could be changed to return only a
1734 statement? Well sometimes NIL is returned
1735 here so deeper work is required for
1737 pips_debug(1, "Reduction %d: declaration -> statement_without_pragma\n", __LINE__);
1739 if (gen_length(sl) > 1) {
1740 /* print_statements(sl); */
1741 pips_internal_error("There should be no more than 1 declaration at a time here instead of %zd\n", gen_length(sl));
1743 /* Extract the statement from the list and free
1744 the list container: */
1745 statement s = make_statement_from_statement_list_or_empty_block(sl);
1746 // Necessary for comma02.c
1747 // statement_comments(s) = get_current_C_comment();
1748 // statement_number(s) = get_current_C_line_number();
1749 $$ = flush_expression_comment(s);
1751 | TK_IF statement_paren_comma_expression statement %prec TK_IF
1753 $$ = test_to_statement(make_test(MakeCommaExpression($2), $3,
1754 make_empty_block_statement()));
1755 pips_assert("statement is a test", statement_test_p($$));
1756 string sc = pop_current_C_comment();
1757 int sn = pop_current_C_line_number();
1758 $$ = add_comment_and_line_number($$, sc, sn);
1759 $$ = flush_statement_comment($$);
1761 | TK_IF statement_paren_comma_expression statement TK_ELSE statement
1763 $$ = test_to_statement(make_test(MakeCommaExpression($2),$3,$5));
1764 pips_assert("statement is a test", statement_test_p($$));
1765 string sc = pop_current_C_comment();
1766 int sn = pop_current_C_line_number();
1767 $$ = add_comment_and_line_number($$, sc, sn);
1768 $$ = flush_statement_comment($$);
1772 stack_push((char *) make_sequence(NIL),SwitchGotoStack);
1773 stack_push((char *) make_basic_int(loop_counter++), LoopStack);
1774 /* push_current_C_comment(); */
1776 statement_paren_comma_expression
1778 stack_push((char *)MakeCommaExpression($3),SwitchControllerStack);
1783 $$ = MakeSwitchStatement($5);
1784 string sc = pop_current_C_comment();
1785 int sn = pop_current_C_line_number();
1786 $$ = add_comment_and_line_number($$, sc, sn);
1787 //$$ = flush_statement_comment($$); SG too dangerous, maybe on a block
1788 stack_pop(SwitchGotoStack);
1789 stack_pop(SwitchControllerStack);
1790 stack_pop(LoopStack);
1794 stack_push((char *) make_basic_int(loop_counter++), LoopStack);
1795 /* push_current_C_comment(); */
1797 statement_paren_comma_expression statement
1799 string sc = pop_current_C_comment();
1800 int sn = pop_current_C_line_number();
1801 pips_assert("While loop body consistent",statement_consistent_p($4));
1802 $$ = MakeWhileLoop($3,$4,true);
1803 $$ = add_comment_and_line_number($$, sc, sn);
1804 $$ = flush_statement_comment($$);
1805 stack_pop(LoopStack);
1809 stack_push((char *) make_basic_int(loop_counter++), LoopStack);
1810 /* push_current_C_comment(); */
1812 statement TK_WHILE statement_paren_comma_expression TK_SEMICOLON
1814 $$ = MakeWhileLoop($5,$3,false);
1815 /* The line number and comment are related to paren_comma_expression and not to TK_DO */
1816 (void) pop_current_C_line_number();
1817 (void) pop_current_C_comment();
1818 stack_pop(LoopStack);
1821 /* Since opt_expression may reset the comments, we should try to
1822 preserve them first everytime. To do some days. Right now it is not
1823 a top priority... */
1824 opt_expression /* So it is a C89 for loop */
1825 TK_SEMICOLON opt_expression TK_SEMICOLON opt_expression
1827 /* Save the comments agregated in the for close up to now: */
1828 push_current_C_comment();
1833 $$ = MakeForloop($2, $4, $6, $9);
1834 $$=flush_expression_comment($$);
1836 | for_clause /* A C99 for loop with a declaration in it */
1838 /* We need a new variable scope to avoid
1839 conflict names between the loop index and
1840 some previous upper declarations: */
1844 /* Since opt_expression may reset the comments, we should try to
1845 preserve them first everytime. To do some days. Right now it is not
1846 a top priority... */
1847 opt_expression TK_SEMICOLON opt_expression TK_RPAREN
1849 /* Save the comments agregated in the for close up to now: */
1850 push_current_C_comment();
1854 $$ = MakeForloopWithIndexDeclaration($3, $4, $6, $9);
1855 $$=flush_expression_comment($$);
1860 /* Create the statement with label comment in
1862 $$ = MakeLabeledStatement($1,$2, pop_current_C_comment());
1865 /* pips_debug(8,"Adding label '%s' to statement:\n", $1); */
1866 /* print_statement($$); */
1869 | TK_CASE expression TK_COLON
1871 $$ = MakeCaseStatement($2);
1873 | TK_CASE expression TK_ELLIPSIS expression TK_COLON
1875 CParserError("case e1..e2 : not implemented\n");
1877 | TK_DEFAULT TK_COLON
1879 $$ = MakeDefaultStatement();
1881 | TK_RETURN TK_SEMICOLON
1883 /* $$ = call_to_statement(make_call(CreateIntrinsic(C_RETURN_FUNCTION_NAME),NIL)); */
1884 if(!get_bool_property("C_PARSER_RETURN_SUBSTITUTION"))
1885 $$ = make_statement(entity_empty_label(),
1886 get_current_C_line_number(),
1887 STATEMENT_ORDERING_UNDEFINED,
1888 get_current_C_comment(),
1889 call_to_instruction(make_call(CreateIntrinsic(C_RETURN_FUNCTION_NAME),NIL)),
1890 NIL, string_undefined,
1891 empty_extensions (), make_synchronization_none());
1893 $$ = C_MakeReturnStatement(NIL,
1894 get_current_C_line_number(),
1895 get_current_C_comment());
1897 $$ = make_statement(entity_empty_label(),
1898 get_current_C_line_number(),
1899 STATEMENT_ORDERING_UNDEFINED,
1900 get_current_C_comment(),
1904 empty_extensions());
1907 statement_consistent_p($$);
1909 | TK_RETURN comma_expression TK_SEMICOLON
1911 /* $$ = call_to_statement(make_call(CreateIntrinsic(C_RETURN_FUNCTION_NAME),$2)); */
1913 expression res = expression_undefined;
1914 if(gen_length(el)>1) {
1915 res = make_call_expression(CreateIntrinsic(COMMA_OPERATOR_NAME), el);
1916 el = CONS(EXPRESSION, res, NIL);
1918 else if(gen_length(el)==1)
1919 res = EXPRESSION(CAR($2));
1921 if(expression_reference_p(res)) {
1922 reference r = expression_reference(res);
1923 entity v = reference_variable(r);
1924 type t = ultimate_type(entity_type(v));
1925 if(type_functional_p(t)) {
1926 /* pointers to functions, hence
1927 functions can be returned in C */
1928 /* FI: relationship with undeclared? */
1930 c_parser_user_warning("Ill. returned value: reference to function \"%s\""
1931 " or variable \"%s\" not declared\n",
1932 entity_user_name(v), entity_user_name(v));
1933 CParserError("Ill. return expression");
1937 if(!get_bool_property("C_PARSER_RETURN_SUBSTITUTION"))
1938 $$ = make_statement(entity_empty_label(),
1939 get_current_C_line_number(),
1940 STATEMENT_ORDERING_UNDEFINED,
1941 get_current_C_comment(),
1942 make_instruction(is_instruction_call,
1943 make_call(CreateIntrinsic(C_RETURN_FUNCTION_NAME), el)),
1944 NIL, string_undefined, empty_extensions (), make_synchronization_none());
1946 $$ = C_MakeReturnStatement(el,
1947 get_current_C_line_number(),
1948 get_current_C_comment());
1950 $$ = make_statement(entity_empty_label(),
1951 get_current_C_line_number(),
1952 STATEMENT_ORDERING_UNDEFINED,
1953 get_current_C_comment(),
1957 empty_extensions());
1959 $$=flush_expression_comment($$);
1960 statement_consistent_p($$);
1962 | TK_BREAK TK_SEMICOLON
1964 $$ = MakeBreakStatement(get_current_C_comment());
1966 | TK_CONTINUE TK_SEMICOLON
1968 $$ = MakeContinueStatement(get_current_C_comment());
1970 | TK_GOTO TK_IDENT TK_SEMICOLON
1972 $$ = MakeGotoStatement($2);
1975 | TK_GOTO TK_STAR comma_expression TK_SEMICOLON
1977 CParserError("GOTO * exp not implemented\n");
1979 | TK_ASM asmattr TK_LPAREN string_constant asmoutputs TK_RPAREN TK_SEMICOLON
1982 entity_intrinsic(ASM_FUNCTION_NAME),
1983 CONS(EXPRESSION,entity_to_expression(
1984 make_C_constant_entity($4, is_basic_string, 0)
1988 $$ = make_statement(
1989 entity_empty_label(),
1990 get_current_C_line_number(),
1991 STATEMENT_ORDERING_UNDEFINED,
1992 get_current_C_comment(),
1993 make_instruction_call(c),
1994 NIL, string_undefined,
1995 empty_extensions(), make_synchronization_none());
1998 { CParserError("ASM not implemented\n"); }
1999 | error location TK_SEMICOLON
2001 CParserError("Parse error: error location TK_SEMICOLON\n");
2009 /* Number the loops in prefix depth-first: */
2010 stack_push((char *) make_basic_int(loop_counter++),
2012 /* Record the line number of thw "for" keyword: */
2013 push_current_C_line_number();
2014 /* Try to save a max of comments. The issue is
2015 that opt_expression's afterwards can reset
2016 the comments if there is a comma_expression
2017 in them. So at least preserve the commemts
2020 Issue trigered by several examples such as
2021 validation/Semantics-New/do01.tpips
2023 But I think now (RK, 2011/02/05 :-) ) that in
2024 a source-to-source compiler comments should
2025 appear *explicitly* in the parser syntax and
2026 not be dealt by some side effects in the
2027 lexer as now in PIPS with some stacks and so
2030 push_current_C_comment();
2036 declaration: /* ISO 6.7.*/
2037 decl_spec_list init_declarator_list TK_SEMICOLON
2039 pips_debug(1, "Reduction %d: decl_spec_list init_declarator_list TK_SEMICOLON -> declaration\n", __LINE__);
2043 list el12 = gen_nconc(el1,el2);
2044 statement s = statement_undefined;
2046 pips_assert("el1 is an entity list", entities_p(el1));
2047 pips_assert("el2 is an entity list", entities_p(el2));
2048 pips_assert("Variable in el1 has not been declared before", !gen_in_list_p(el1, el2));
2051 list el0 = GetDerivedEntityDeclarations();
2052 FOREACH(ENTITY, e, el0) {
2053 if(!gen_in_list_p(e, el12))
2054 el12 = CONS(ENTITY, e, el12);
2059 fprintf(stderr, "At %d, make_declarations_statement for ", __LINE__);
2060 print_entities(el12);
2061 fprintf(stderr, "\n");
2064 int sn = get_current_C_line_number();
2065 string sc = get_current_C_comment();
2066 s = make_declarations_statement(el12, sn, sc);
2067 initialization_expressions = add_prettyprint_control_list_to_declaration_statement(s, initialization_expressions);
2070 fprintf(stderr, "New declaration statement for entities: ");
2071 print_entities(el12);
2072 fprintf(stderr, "\n");
2074 pips_assert("no duplicate declaration",
2078 pips_internal_error("Unexpected case");
2081 UpdateEntities(el2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,true);
2083 remove_entity_type_stacks(el12);
2084 CleanUpEntities(el12);
2085 $$ = CONS(STATEMENT,s,NIL);
2086 reset_token_has_been_seen_p();
2088 | decl_spec_list TK_SEMICOLON
2090 pips_debug(1, "Reduction %d: decl_spec_list TK_SEMICOLON -> declaration\n", __LINE__);
2092 FOREACH(ENTITY, e, dl) {
2093 value v = entity_initial(e);
2094 if(value_undefined_p(v))
2095 entity_initial(e) = make_value_unknown();
2097 // FI: we build a declaration statement
2098 // for each field of an enum...
2099 int sn = get_current_C_line_number();
2100 string sc = get_current_C_comment();
2101 pips_debug(8, "New declaration statement at line %d\n", __LINE__);
2102 statement s = make_declarations_statement(dl, sn, sc);
2103 initialization_expressions = add_prettyprint_control_list_to_declaration_statement(s, initialization_expressions);
2104 reset_token_has_been_seen_p();
2105 //UpdateEntities(dl,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,true);
2107 ResetDerivedEntityDeclarations();
2108 $$ = CONS(STATEMENT,s, NIL);
2113 init_declarator_list: /* ISO 6.7 */
2117 $$ = CONS(ENTITY,$1,NIL);
2119 | init_declarator TK_COMMA init_declarator_list
2121 $$ = CONS(ENTITY,$1,$3);
2125 init_declarator: /* ISO 6.7 */
2127 /* The default initial value is often zero,
2128 but not so for formal parameters or
2130 if(value_undefined_p(entity_initial($1)))
2131 entity_initial($1) = make_value_unknown();
2132 add_initialization_expression(0);
2133 pips_debug(1, "declarator to init_declarator for entity %s\n", entity_name($1));
2135 | declarator TK_EQ init_expression
2138 expression nie = $3;
2140 if(expression_undefined_p(nie)) {
2141 /* Do nothing, leave the initial field of entity as it is. */
2142 c_parser_user_warning("Undefined init_expression, why not use value_unknown?\n");
2143 add_initialization_expression(0);
2144 pips_debug(1, "declarator TK_EQ init_expression to init_declarator, with expression undefined\n");
2147 (void) simplify_C_expression(nie);
2148 /* Put init_expression in the initial value of entity declarator*/
2149 set_entity_initial(v, nie);
2150 add_initialization_expression(1);
2151 pips_debug(1, "declarator TK_EQ init_expression to init_declarator\n");
2158 if(stack_empty_p(ContextStack)) {
2159 ycontext = CreateDefaultContext();
2160 pips_debug(8, "new default context %p with scope \"%s\"\n", ycontext,
2161 c_parser_context_scope(ycontext));
2164 /* Copy may be excessive as only the scope needs to be preserved...*/
2165 //ycontext = copy_c_parser_context((c_parser_context)stack_head(ContextStack));
2166 ycontext = GetContextCopy();
2167 /* FI: You do not want to propagate
2169 gen_full_free_list(c_parser_context_qualifiers(ycontext));
2170 c_parser_context_qualifiers(ycontext) = NIL;
2171 /* How can these two problems occur since
2172 ycontext is only a copy of the
2173 ContextStack's head? Are we in the
2174 middle of a stack_push() /stack_pop()?
2175 The previous policy was to always
2176 allocate a new ycontext, regardless of
2178 /* FI: a bit afraid of freeing the past type if any */
2179 c_parser_context_type(ycontext) = type_undefined;
2180 /* A new context is entered: no longer typedef as in
2181 "typedef int f(int a)" when we hit "int a"*/
2182 c_parser_context_typedef(ycontext) = false;
2183 /* FI: sometimes, the scope is erased and lost */
2184 //if(strcmp(c_parser_context_scope(ycontext), "TOP-LEVEL:")==0)
2185 // c_parser_context_scope(ycontext) = empty_scope();
2186 /* Finally, to avoid problems!*/
2188 //r_context_scope(ycontext) = empty_scope();
2190 /* Only block scope information is inherited */
2191 if(!string_block_scope_p(c_parser_context_scope(ycontext))
2192 && !string_struct_scope_p(c_parser_context_scope(ycontext))) {
2193 /* FI: too primitive; we need to push
2194 and pop contexts more than to update
2197 Problem with "extern f(x), g(y);". f
2198 anf g are definitvely top-level, but x
2199 and y must be searched in the current
2202 pips_debug(8, "Reset modified scope \"%s\"\n",
2203 c_parser_context_scope(ycontext));
2204 free(c_parser_context_scope(ycontext));
2205 c_parser_context_scope(ycontext) = empty_scope();
2207 pips_debug(8, "new context %p with scope \"%s\" copied from context %p (stack size=%d)\n",
2209 c_parser_context_scope(ycontext),
2210 stack_head(ContextStack),
2211 stack_size(ContextStack));
2214 my_decl_spec_list {pips_debug(1, "Reduction %d: my_decl_spec_list -> decl_spec_list\n", __LINE__); $$ = $2;}
2217 my_decl_spec_list: /* ISO 6.7 */
2219 TK_TYPEDEF decl_spec_list_opt
2221 /* Add TYPEDEF_PREFIX to entity name prefix and make it a rom storage */
2222 c_parser_context_typedef(ycontext) = true;
2223 c_parser_context_storage(ycontext) = make_storage_rom();
2224 //pips_assert("CONTINUE for declarations", continue_statements_p($2));
2225 pips_assert("Entity list for declarations", entities_p($2));
2228 | TK_EXTERN decl_spec_list_opt
2230 /* This can be a variable or a function, whose storage is ram or return */
2231 /* What is the scope in cyacc.y of this
2232 scope modification? Too much because the
2233 TOP_LEVEL scope is going to be used for
2234 argument types as well... */
2235 pips_debug(8, "Scope of context %p forced to TOP_LEVEL_MODULE_NAME\n", ycontext);
2236 free(c_parser_context_scope(ycontext));
2237 c_parser_context_scope(ycontext) = strdup(concatenate(TOP_LEVEL_MODULE_NAME,
2238 MODULE_SEP_STRING,NULL));
2239 pips_assert("Entity list for declarations", entities_p($2));
2240 /* FI: because of C laxity about
2241 redeclarations in compilation unit, the
2242 EXTERN information should be carried by
2243 the declaration statement to be able to
2244 regenerate precise source-to-source. */
2245 // fprintf(stderr, "Force extern declaration.\n");
2246 // statement dls = STATEMENT(CAR($2));
2247 set_prettyprint_control_list_to_extern();
2250 | TK_STATIC decl_spec_list_opt
2252 pips_debug(1, "Reduction %d: TK_STATIC decl_spec_list_opt -> my_decl_spec_list\n", __LINE__);
2253 c_parser_context_static(ycontext) = true;
2254 pips_assert("Entity list for declarations", entities_p($2));
2257 | TK_THREAD decl_spec_list_opt
2259 /* Add to type variable qualifiers */
2260 c_parser_context_qualifiers(ycontext) = gen_nconc(c_parser_context_qualifiers(ycontext),
2261 CONS(QUALIFIER,make_qualifier_thread(),NIL));
2262 pips_assert("Entity list for declarations", entities_p($2));
2265 | TK_AUTO decl_spec_list_opt
2267 /* Make dynamic storage for current entity */
2268 c_parser_context_qualifiers(ycontext) = gen_nconc(c_parser_context_qualifiers(ycontext),
2269 CONS(QUALIFIER,make_qualifier_auto(),NIL));
2270 pips_assert("Entity list for declarations", entities_p($2));
2273 | TK_REGISTER decl_spec_list_opt
2275 /* Add to type variable qualifiers */
2276 c_parser_context_qualifiers(ycontext) = gen_nconc(c_parser_context_qualifiers(ycontext),
2277 CONS(QUALIFIER,make_qualifier_register(),NIL));
2278 pips_assert("Entity list for declarations", entities_p($2));
2282 | type_spec decl_spec_list_opt_no_named
2284 pips_debug(1, "Reduction %d: type_spec decl_spec_list_opt_no_named -> my_decl_spec_list\n", __LINE__);
2286 // el contains only hidden internal PIPS
2287 // entities, but some of them at least must
2288 // be seen by the prettyprinter
2289 list el = $1; // entity list
2290 list sl = $2; // entity list
2291 list rl = list_undefined;
2292 pips_assert("el contains an entity list", entities_p(el));
2293 pips_assert("sl contains an entity list", entities_p(sl));
2301 //pips_debug(8, "New declaration statement for entities:\n");
2303 fprintf(stderr, "\n");
2306 else if(gen_length(sl)==1) {
2307 // FI: I'm not sure it ever happens
2308 // statement s = STATEMENT(CAR(sl));
2310 //pips_debug(8, "Previous (unexpected) continue statement for entities: ");
2311 //print_entities(statement_declarations(s));
2313 fprintf(stderr, "\n");
2314 pips_debug(8, "New entities added: ");
2316 fprintf(stderr, "\n");
2319 //statement_declarations(s) =
2320 //gen_nconc(el, statement_declarations(s));
2321 rl = gen_nconc(el, sl);
2324 pips_internal_error("Multiple statements not expected\n");
2326 /* make_continue_statement(entity_empty_label()); */
2327 /* statement_declarations(s) = el; */
2328 // $$ = gen_nconc($1,$2);
2330 //rl = gen_nconc(CONS(STATEMENT, s, NIL),sl);
2335 | TK_INLINE decl_spec_list_opt
2337 c_parser_user_warning("Keyword \"inline\" ignored\n");
2338 pips_assert("Entity list for declarations", entities_p($2));
2341 | attribute decl_spec_list_opt
2343 list ql = c_parser_context_qualifiers(ycontext);
2346 c_parser_context_qualifiers(ycontext)
2347 = insert_qualifier(ql, nq);
2349 pips_assert("Entity list for declarations", entities_p($2));
2352 /* specifier pattern variable (must be last in spec list) */
2353 | TK_AT_SPECIFIER TK_LPAREN TK_IDENT TK_RPAREN
2355 CParserError("CIL AT not implemented\n");
2359 /* (* In most cases if we see a NAMED_TYPE we must shift it. Thus we declare
2360 * NAMED_TYPE to have right associativity *) */
2364 //stack_push((char *) ycontext, ContextStack);
2365 PushContext(ycontext);
2367 } %prec TK_NAMED_TYPE
2368 | my_decl_spec_list { }
2371 /* (* We add this separate rule to handle the special case when an appearance
2372 * of NAMED_TYPE should not be considered as part of the specifiers but as
2373 * part of the declarator. IDENT has higher precedence than NAMED_TYPE *)
2375 decl_spec_list_opt_no_named:
2378 pips_debug(1, "Reduction %d: empty -> decl_spec_list_opt_no_named\n", __LINE__);
2379 // decl48.c: ycontext is not good because
2380 // the current scope information is lost.
2381 // I do not want to remove the Push to keep
2382 // the Push/Pop balance ok
2383 //PushContext(ycontext);
2384 if(stack_empty_p(ContextStack))
2385 PushContext(ycontext);
2387 c_parser_context y = GetContext();
2388 string stf = (c_parser_context_scope(ycontext));
2389 c_parser_context_scope(ycontext) =
2390 strdup(c_parser_context_scope(y));
2392 PushContext(ycontext);
2396 | my_decl_spec_list {pips_debug(1, "Reduction %d: my_decl_spec_list -> decl_spec_list_opt_no_named\n", __LINE__);
2401 type_spec: /* ISO 6.7.2 */
2404 c_parser_context_type(ycontext) = make_type_void(NIL);
2409 c_parser_context_type(ycontext) = make_standard_integer_type(c_parser_context_type(ycontext),
2410 DEFAULT_CHARACTER_TYPE_SIZE);
2415 c_parser_context_type(ycontext) = make_standard_integer_type(c_parser_context_type(ycontext),
2416 DEFAULT_SHORT_INTEGER_TYPE_SIZE);
2421 pips_debug(1, "Reduction %d: TK_INT -> type_spec\n", __LINE__);
2422 if (c_parser_context_type(ycontext) == type_undefined)
2424 variable v = make_variable(make_basic_int(DEFAULT_INTEGER_TYPE_SIZE),NIL,NIL);
2425 c_parser_context_type(ycontext) = make_type_variable(v);
2431 pips_debug(1, "Reduction %d: TK_INT128 -> type_spec\n", __LINE__);
2432 if (c_parser_context_type(ycontext) == type_undefined)
2434 variable v = make_variable(make_basic_int(DEFAULT_LONG_LONG_LONG_INTEGER_TYPE_SIZE),NIL,NIL);
2435 c_parser_context_type(ycontext) = make_type_variable(v);
2441 pips_debug(1, "Reduction %d: TK_UINT128 -> type_spec\n", __LINE__);
2442 if (c_parser_context_type(ycontext) == type_undefined)
2444 variable v = make_variable(make_basic_int(DEFAULT_LONG_LONG_LONG_INTEGER_TYPE_SIZE+10),NIL,NIL);
2445 c_parser_context_type(ycontext) = make_type_variable(v);
2451 if (c_parser_context_type(ycontext) == type_undefined)
2453 variable v = make_variable(make_basic_complex(DEFAULT_COMPLEX_TYPE_SIZE),NIL,NIL);
2454 c_parser_context_type(ycontext) = make_type_variable(v);
2457 /* Can be qualified by float, double and long double */
2458 type t = c_parser_context_type(ycontext);
2459 variable v = type_variable(t);
2460 basic b = variable_basic(v);
2462 pips_assert("prefix is for type variable",type_variable_p(t));
2463 if(basic_float_p(b)) {
2464 basic_tag(b) = is_basic_complex;
2465 basic_complex(b) = 2*basic_complex(b);
2466 if(basic_complex(b)==DEFAULT_COMPLEX_TYPE_SIZE)
2467 basic_complex(b) += 1;
2474 c_parser_context_type(ycontext) = make_standard_long_integer_type(c_parser_context_type(ycontext));
2479 variable v = make_variable(make_basic_float(DEFAULT_REAL_TYPE_SIZE),NIL,NIL);
2480 c_parser_context_type(ycontext) = make_type_variable(v);
2485 variable v = variable_undefined;
2486 type t = c_parser_context_type(ycontext);
2488 if(type_undefined_p(t))
2489 v = make_variable(make_basic_float(DEFAULT_DOUBLEPRECISION_TYPE_SIZE),NIL,NIL);
2491 if(default_complex_type_p(t)) {
2492 c_parser_user_warning("'complex double' declaration is not in the C99 standard but we accept it. You should use 'double complex' instead.\n"
2494 v = make_variable(make_basic_complex(DEFAULT_DOUBLECOMPLEX_TYPE_SIZE), NIL, NIL);
2496 /* This secondary test is probably
2497 useless. See the case of TK_COMPLEX. */
2498 else if(standard_long_integer_type_p(t))
2499 v = make_variable(make_basic_float(DEFAULT_QUADPRECISION_TYPE_SIZE),NIL,NIL);
2501 /* FI: we should probably have a user
2502 or internal error here since we
2503 ignore the beginning of the type declaration*/
2504 v = make_variable(make_basic_float(DEFAULT_DOUBLEPRECISION_TYPE_SIZE),NIL,NIL);
2507 c_parser_context_type(ycontext) = make_type_variable(v);
2512 /* see the IR document or ri-util.h for explanation */
2513 int size = DEFAULT_INTEGER_TYPE_SIZE;
2514 type t_old = c_parser_context_type(ycontext);
2515 if(!type_undefined_p(t_old)) {
2516 // FI: memory leak for t_old
2517 variable v_old = type_variable(t_old);
2518 basic b_old = variable_basic(v_old);
2519 if(basic_int_p(b_old))
2520 size = basic_int(b_old);
2522 pips_internal_error("???");
2524 variable v = make_variable(make_basic_int(DEFAULT_SIGNED_TYPE_SIZE*10+
2526 c_parser_context_type(ycontext) = make_type_variable(v);
2531 int size = DEFAULT_INTEGER_TYPE_SIZE;
2532 type t_old = c_parser_context_type(ycontext);
2533 if(!type_undefined_p(t_old)) {
2534 // FI: memory leak for t_old
2535 variable v_old = type_variable(t_old);
2536 basic b_old = variable_basic(v_old);
2537 if(basic_int_p(b_old))
2538 size = basic_int(b_old);
2540 pips_internal_error("???");
2542 variable v = make_variable(make_basic_int(DEFAULT_UNSIGNED_TYPE_SIZE*10+
2544 c_parser_context_type(ycontext) = make_type_variable(v);
2547 | TK_STRUCT id_or_typename
2549 pips_debug(1, "Reduction %d: TK_STRUCT id_or_typename -> type_spec\n", __LINE__);
2550 // FI: this next call is now useless
2551 set_prettyprint_control_list_to_dummy();
2552 /* Find the entity associated to the struct, current scope can be [file%][module:][block]*/
2553 entity ent = FindOrCreateEntityFromLocalNameAndPrefix($2,STRUCT_PREFIX,is_external);
2554 /* Specify the type of the variable that follows this declaration specifier */
2555 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2556 /* To handle mesa.c (SPEC 2000 benchmark)
2557 We have struct HashTable in a file, but do not know its structure and scope,
2558 because it is declared in other file */
2559 if (type_undefined_p(entity_type(ent)))
2560 entity_type(ent) = make_type_struct(NIL);
2561 if (storage_undefined_p(entity_storage(ent)))
2562 entity_storage(ent) = make_storage_rom();
2563 c_parser_context_type(ycontext) = make_type_variable(v);
2564 /* Declaration statement "struct s;"
2565 disappears with $$ = NIL... See for
2566 instance decl68.c. A place holder
2567 variable is added, just in case. */
2568 /* This may be useless, but will be fixed by
2569 make_declarations_statement() */
2570 entity phv = make_place_holder_variable(ent);
2571 list dl = list_undefined;
2572 if(entity_undefined_p(phv)) {
2573 dl = CONS(ENTITY,ent,NIL);
2576 add_initialization_expression(0);
2577 dl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2581 | TK_STRUCT id_or_typename TK_LBRACE
2583 code c = make_code(NIL,$2,sequence_undefined,NIL, make_language_c());
2584 stack_push((char *) c, StructNameStack);
2586 struct_decl_list TK_RBRACE
2588 pips_debug(1, "Reduction %d: TK_STRUCT id_or_typename TK_LBRACE struct_decl_list TK_RBRACE -> type_spec\n", __LINE__);
2589 /* field list, which may also contain nested
2592 /* Create the struct entity */
2593 entity ent = MakeDerivedEntity($2,fl,is_external,is_type_struct);
2594 /* Record the declaration of the struct
2596 RecordDerivedEntityDeclaration(ent);
2597 /* Specify the type of the variable that follows this declaration specifier*/
2598 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2599 /* Take from $5 the struct/union entities */
2600 list le = TakeDerivedEntities(fl);
2601 list rl = gen_in_list_p(ent, le)?
2602 le : gen_nconc(le,CONS(ENTITY,ent,NIL));
2603 /* Fields do not need to appear in the
2604 declaration list, but they are used later
2605 to decide which derived entities are
2606 defined and which ones are used. */
2607 FOREACH(ENTITY, f, fl) {
2608 if(entity_field_p(f) && !gen_in_list_p(f,rl))
2609 rl = gen_nconc(rl, CONS(ENTITY, f, NIL));
2611 c_parser_context_type(ycontext) = make_type_variable(v);
2612 stack_pop(StructNameStack);
2614 //add_initialization_expression(1);
2617 | TK_STRUCT TK_LBRACE
2619 string istr = int2a(derived_counter++);
2620 code c = make_code(NIL,strdup(concatenate(DUMMY_STRUCT_PREFIX,
2621 istr,NULL)),sequence_undefined, NIL, make_language_c());
2623 stack_push((char *) c, StructNameStack);
2625 struct_decl_list TK_RBRACE
2627 pips_debug(1, "Reduction %d: TK_STRUCT TK_LBRACE struct_decl_list TK_RBRACE -> type_spec\n", __LINE__);
2628 /* Create the struct entity with unique name s */
2629 string s = code_decls_text((code) stack_head(StructNameStack));
2631 pips_assert("el is an entity list", entities_p(el));
2632 entity ent = MakeDerivedEntity(s,el,is_external,is_type_struct);
2633 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2634 pips_assert("el is an entity list", entities_p(el));
2635 /* Take from el the struct/union entities */
2636 list le = TakeDerivedEntities(el);
2637 list rl = gen_nconc(le,CONS(ENTITY,ent,NIL));
2638 c_parser_context_type(ycontext) = make_type_variable(v);
2639 stack_pop(StructNameStack);
2641 //add_initialization_expression(1);
2644 | TK_UNION id_or_typename
2646 set_prettyprint_control_list_to_dummy();
2647 /* Find the entity associated to the union, current scope can be [file%][module:][block]*/
2648 entity ent = FindOrCreateEntityFromLocalNameAndPrefix($2,UNION_PREFIX,is_external);
2649 /* Specify the type of the variable that follows this declaration specifier */
2650 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2651 if (type_undefined_p(entity_type(ent)))
2652 entity_type(ent) = make_type_union(NIL);
2653 if (storage_undefined_p(entity_storage(ent)))
2654 entity_storage(ent) = make_storage_rom();
2655 c_parser_context_type(ycontext) = make_type_variable(v);
2656 /* This may be useless, but will be fixed by
2657 make_declarations_statement() */
2658 entity phv = make_place_holder_variable(ent);
2659 list dl = list_undefined;
2660 if(entity_undefined_p(phv)) {
2661 dl = CONS(ENTITY,ent,NIL);
2664 add_initialization_expression(0);
2665 dl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2667 //list dl = CONS(ENTITY, ent, NIL);
2670 | TK_UNION id_or_typename TK_LBRACE
2672 code c = make_code(NIL,$2,sequence_undefined, NIL, make_language_c());
2673 stack_push((char *) c, StructNameStack);
2675 struct_decl_list TK_RBRACE
2678 entity ent = MakeDerivedEntity($2,fl,is_external,is_type_union);
2679 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2680 /* Take from $5 the indirectly declared
2681 struct/union entities as in "struct {struct ... ". */
2682 // FI: struct are treated much more carefully to avoid
2683 // multiple occurences of one entity
2684 list le = TakeDerivedEntities($5);
2685 list rl = gen_nconc(le,CONS(ENTITY,ent,NIL));
2686 //rl = gen_nconc(rl, fl);
2687 //rl = gen_nconc(rl, le);
2688 c_parser_context_type(ycontext) = make_type_variable(v);
2689 stack_pop(StructNameStack);
2692 | TK_UNION TK_LBRACE
2694 string n = int2a(derived_counter++);
2695 code c = make_code(NIL,
2696 strdup(concatenate(DUMMY_UNION_PREFIX,n,NULL)),
2701 stack_push((char *) c, StructNameStack);
2703 struct_decl_list TK_RBRACE
2705 /* Create the union entity with unique name */
2706 string s = code_decls_text((code) stack_head(StructNameStack));
2707 entity ent = MakeDerivedEntity(s,$4,is_external,is_type_union);
2708 RecordDerivedEntityDeclaration(ent);
2709 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2710 /* Take from $4 the struct/union entities */
2711 (void)TakeDerivedEntities($4);
2712 //$$ = gen_nconc(le,CONS(ENTITY,ent,NIL));
2713 //$$ = CONS(ENTITY,ent,le);
2714 // entity phv = make_place_holder_variable(ent));
2715 // list rl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2716 list rl = CONS(ENTITY,ent,NIL);
2717 c_parser_context_type(ycontext) = make_type_variable(v);
2718 stack_pop(StructNameStack);
2721 | TK_ENUM id_or_typename
2723 pips_debug(1, "Reduction %d: TK_ENUM id_or_typename -> type_spec\n", __LINE__);
2724 set_prettyprint_control_list_to_dummy();
2725 /* Find the entity associated to the enum */
2726 entity ent = FindOrCreateEntityFromLocalNameAndPrefix($2,ENUM_PREFIX,is_external);
2727 /* Specify the type of the variable that follows this declaration specifier */
2728 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2729 if (type_undefined_p(entity_type(ent)))
2730 entity_type(ent) = make_type_enum(NIL);
2731 /* FI: What should the initial value be? */
2732 if (value_undefined_p(entity_initial(ent)))
2733 entity_initial(ent) = make_value_unknown();
2734 if (storage_undefined_p(entity_storage(ent)))
2735 entity_storage(ent) = make_storage_rom();
2736 if(!entity_undefined_p(get_current_module_entity()))
2737 AddEntityToDeclarations(ent, get_current_module_entity());
2739 /* This happens with the old style
2740 function declaration at least */
2741 /* Oops, we have to assume that the enum
2742 is also defined in the compilation
2743 unit... else it would be useless. */
2746 c_parser_context_type(ycontext) = make_type_variable(v);
2747 /* This may be useless, but will be fixed by
2748 make_declarations_statement() */
2749 entity phv = make_place_holder_variable(ent);
2750 list dl = list_undefined;
2751 if(entity_undefined_p(phv)) {
2752 dl = CONS(ENTITY,ent,NIL);
2755 add_initialization_expression(0);
2756 dl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2758 //list dl = CONS(ENTITY, ent, NIL);
2761 | TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE
2763 pips_debug(1, "Reduction %d: TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE -> type_spec\n", __LINE__);
2766 /* Create the enum entity */
2767 entity ent = MakeDerivedEntity(en,ml,is_external,is_type_enum);
2768 RecordDerivedEntityDeclaration(ent);
2769 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2771 InitializeEnumMemberValues(ml);
2772 c_parser_context_type(ycontext) = make_type_variable(v);
2773 list rl = CONS(ENTITY, ent, NIL);
2776 | TK_ENUM TK_LBRACE enum_list maybecomma TK_RBRACE
2778 /* Create the enum entity with unique name */
2779 string n = int2a(derived_counter++);
2780 string s = strdup(concatenate(DUMMY_ENUM_PREFIX,n,NULL));
2782 entity ent = MakeDerivedEntity(s,$3,is_external,is_type_enum);
2783 variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2785 InitializeEnumMemberValues($3);
2786 c_parser_context_type(ycontext) = make_type_variable(v);
2787 $$ = CONS(ENTITY,ent,NIL);
2792 ent = FindOrCreateEntityFromLocalNameAndPrefix($1,TYPEDEF_PREFIX,is_external);
2794 /* Specify the type of the variable that follows this declaration specifier */
2795 if (c_parser_context_typedef(ycontext))
2797 /* typedef T1 T2 => the type of T2 will be that of T1*/
2798 pips_debug(8,"typedef T1 T2 where T1 = %s\n",entity_name(ent));
2799 c_parser_context_type(ycontext) = entity_type(ent);
2800 $$ = CONS(ENTITY,ent,NIL);
2804 /* T1 var => the type of var is basic typedef */
2805 variable v = make_variable(make_basic_typedef(ent),NIL,NIL);
2806 pips_debug(8,"T1 var where T1 = %s\n",entity_name(ent));
2807 c_parser_context_type(ycontext) = make_type_variable(v);
2812 | TK_TYPEOF TK_LPAREN expression TK_RPAREN
2814 CParserError("TYPEOF not implemented\n");
2816 | TK_TYPEOF TK_LPAREN type_name TK_RPAREN
2818 CParserError("TYPEOF not implemented\n");
2822 struct_decl_list: /* (* ISO 6.7.2. Except that we allow empty structs. We
2823 * also allow missing field names. *)
2825 /* empty */ { pips_debug(1, "Reduction %d: empty -> struct_decl_list\n", __LINE__); $$ = NIL; }
2826 | decl_spec_list TK_SEMICOLON struct_decl_list
2828 pips_debug(1, "Reduction %d:decl_spec_list TK_SEMICOLON struct_decl_list -> struct_decl_list\n", __LINE__);
2829 //c_parser_context ycontext = stack_head(ContextStack);
2830 c_parser_context ycontext = GetContext();
2831 /* Create the struct member entity with unique name, the name of the
2832 struct/union is added to the member name prefix */
2833 string istr = int2a(derived_counter++);
2834 string s = strdup(concatenate("PIPS_MEMBER_",istr,NULL));
2835 string derived = code_decls_text((code) stack_head(StructNameStack));
2836 entity ent = CreateEntityFromLocalNameAndPrefix(s,strdup(concatenate(derived,
2837 MEMBER_SEP_STRING,NULL)),
2839 pips_debug(5,"Current derived name: %s\n",derived);
2840 pips_debug(5,"Member name: %s\n",entity_name(ent));
2841 entity_storage(ent) = make_storage_rom();
2842 entity_type(ent) = c_parser_context_type(ycontext);
2845 /* Temporally put the list of struct/union
2846 entities defined in $1 to initial value
2847 of ent. FI: where is it retrieved? in
2848 TakeDerivedEntities()? */
2849 entity_initial(ent) = (value) $1;
2851 $$ = CONS(ENTITY,ent,$3);
2853 //stack_pop(ContextStack);
2858 //c_parser_context ycontext = stack_head(ContextStack);
2859 c_parser_context ycontext = GetContext();
2860 /* Add struct/union name and MEMBER_SEP_STRING to entity name */
2861 string derived = code_decls_text((code) stack_head(StructNameStack));
2862 string stf = (c_parser_context_scope(ycontext));
2863 c_parser_context_scope(ycontext) = CreateMemberScope(derived,is_external);
2865 c_parser_context_storage(ycontext) = make_storage_rom();
2867 field_decl_list TK_SEMICOLON struct_decl_list
2869 pips_debug(1, "Reduction %d: decl_spec_list field_decl_list TK_SEMICOLON struct_decl_list -> struct_decl_list\n", __LINE__);
2870 /* Update the entity in field_decl_list with final type, storage, initial value*/
2872 UpdateDerivedEntities($1,$3,ContextStack);
2874 /* Create the list of member entities */
2878 FOREACH(ENTITY, e, l2) {
2879 if(!gen_in_list_p(e, l1))
2880 nl2 = CONS(ENTITY, e, nl2);
2882 nl2 = gen_nreverse(nl2);
2883 list rl = gen_nconc(l1, nl2);
2888 /* This code is not good ...
2889 I have problem with the global variable ycontext and recursion: ycontext is crushed
2890 when this decl_spec_list in struct_decl_list is entered, so the scope and storage
2891 of the new context are given to the old context, before it is pushed in the stack.
2893 For the moment, I reset the changed values of the context, by hoping that in C,
2894 before a STRUCT/UNION declaration, there is no extern, ... */
2895 free(c_parser_context_scope(ycontext));
2896 c_parser_context_scope(ycontext) = empty_scope();
2897 c_parser_context_storage(ycontext) = storage_undefined;
2899 | error TK_SEMICOLON struct_decl_list
2901 CParserError("Parse error: error TK_SEMICOLON struct_decl_list\n");
2905 field_decl_list: /* (* ISO 6.7.2 *) */
2909 $$ = CONS(ENTITY, f,NIL);
2911 | field_decl TK_COMMA field_decl_list
2914 $$ = CONS(ENTITY,f,$3);
2918 field_decl: /* (* ISO 6.7.2. Except that we allow unnamed fields. *) */
2921 /* For debugging... */
2922 /* It's probably the last place where you
2923 can use the qualifier from the context to
2924 update the type of e when e is a pointer. */
2926 type t = entity_type(e);
2928 /* FI: Well, this piece of code may be fully
2929 useless because t or pt is always undefined. */
2930 if(false && !type_undefined_p(t)) {
2931 type ut = ultimate_type(t);
2933 if(pointer_type_p(ut)) {
2934 type pt = type_to_final_pointed_type(ut);
2935 if(!type_undefined_p(pt) && type_variable_p(pt)) {
2936 variable v = type_variable(pt);
2937 list ql = c_parser_context_qualifiers(ycontext);
2938 pips_assert("the current qualifier list is empty",
2939 ENDP(variable_qualifiers(v)));
2940 /* FI: because of the above assert, the
2941 next statement could be simplified */
2942 variable_qualifiers(v) =
2943 gen_nconc(variable_qualifiers(v), ql);
2944 c_parser_context_qualifiers(ycontext) = NIL;
2951 | declarator TK_COLON expression
2953 value nv = EvalExpression($3);
2954 constant c = value_constant_p(nv)?
2955 value_constant(nv) : make_constant_unknown();
2956 symbolic s = make_symbolic($3, c);
2957 variable v = make_variable(make_basic_bit(s),NIL,NIL);
2959 /*pips_assert("Width of bit-field must be a positive constant integer",
2960 integer_constant_expression_p($3)); */
2961 /* Ignore for this moment if the bit is signed or unsigned */
2962 entity_type($1) = make_type_variable(v);
2965 | TK_COLON expression
2967 //c_parser_context ycontext = stack_head(ContextStack);
2968 c_parser_context ycontext = GetContext();
2969 /* Unnamed bit-field : special and unique name */
2970 string n = int2a(derived_counter++);
2971 string s = strdup(concatenate(DUMMY_MEMBER_PREFIX,n,NULL));
2972 entity ent = CreateEntityFromLocalNameAndPrefix(s,c_parser_context_scope(ycontext),is_external);
2973 value nv = EvalExpression($2);
2974 constant c = value_constant_p(nv)?
2975 value_constant(nv) : make_constant_unknown();
2976 symbolic se = make_symbolic($2, c);
2977 variable v = make_variable(make_basic_bit(se),NIL,NIL);
2978 /* pips_assert("Width of bit-field must be a positive constant integer",
2979 integer_constant_expression_p($2)); */
2980 entity_type(ent) = make_type_variable(v);
2986 enum_list: /* (* ISO 6.7.2.2 *) */
2989 /* initial_value = 0 or $3*/
2990 $$ = CONS(ENTITY,$1,NIL);
2993 | enum_list TK_COMMA enumerator
2995 /* Attention to the reverse recursive definition*/
2996 $$ = gen_nconc($1,CONS(ENTITY,$3,NIL));
2999 | enum_list TK_COMMA error
3001 CParserError("Parse error: enum_list TK_COMMA error\n");
3008 /* Create an entity of is_basic_int, storage rom
3009 initial_value = 0 if it is the first member
3010 initial_value = intial_value(precedessor) + 1
3012 No need to add current struct/union/enum name to the name's scope of the member entity
3013 for ENUM, as in the case of STRUCT and UNION */
3015 entity ent = CreateEntityFromLocalNameAndPrefix($1,"",is_external);
3017 variable v = make_variable(make_basic_int(DEFAULT_INTEGER_TYPE_SIZE),NIL,NIL);
3018 type rt = make_type(is_type_variable, v);
3019 functional f = make_functional(NIL, rt);
3021 entity_storage(ent) = make_storage_rom();
3022 entity_type(ent) = make_type_functional(f);
3023 /* The information is not yet available, but
3024 I need to recognize this entity as
3025 symbolic for next rule */
3026 entity_initial(ent) = make_value_symbolic(make_symbolic(expression_undefined, make_constant_unknown()));
3027 // enum_list is not available yet. Values should be fixed later.
3028 /* entity_initial(ent) = MakeEnumeratorInitialValue(enum_list,enum_counter);*/
3031 | TK_IDENT TK_EQ expression
3033 /* Create an entity of is_basic_int, storage rom, initial_value = $3 */
3034 /* No, enum member must be functional
3035 entity, just like Fortran's parameters */
3037 value vinit = value_undefined;
3038 entity ent = CreateEntityFromLocalNameAndPrefix($1,"",is_external);
3041 make_variable(make_basic_int(DEFAULT_INTEGER_TYPE_SIZE),NIL,NIL);
3042 type rt = make_type(is_type_variable, v);
3043 functional f = make_functional(NIL, rt);
3045 //pips_assert("Enumerated value must be a constant integer",
3046 // signed_integer_constant_expression_p($3));
3047 //i = signed_integer_constant_expression_value($3);
3048 vinit = EvalExpression($3);
3049 entity_storage(ent) = make_storage_rom();
3050 entity_type(ent) = make_type_functional(f);
3052 if(value_constant_p(vinit) && constant_int_p(value_constant(vinit))) {
3053 entity_initial(ent) =
3054 make_value_symbolic(make_symbolic($3, value_constant(vinit)));
3057 /* Error or reference to a previous member of the same enum (enum04.c) */
3058 /* FI: it might be easier to delay systematically the evaluation */
3060 if(expression_call_p($3)) {
3061 call c = syntax_call(expression_syntax($3));
3062 entity m = call_function(c);
3064 if(entity_symbolic_p(m)) {
3069 entity_initial(ent) =
3070 make_value_symbolic(make_symbolic($3, make_constant_unknown()));
3072 /* Let's try to delay evaluation anyway (enum05.c) */
3073 entity_initial(ent) =
3074 make_value_symbolic(make_symbolic($3, make_constant_unknown()));
3075 //pips_internal_error("Constant integer expression not evaluated\n");
3083 declarator: /* (* ISO 6.7.5. Plus Microsoft declarators.*) */
3084 pointer_opt direct_decl attributes_with_asm
3086 /* Update the type of the direct_decl entity with pointer_opt and attributes*/
3087 if (!type_undefined_p($1))
3088 UpdatePointerEntity($2,$1,$3);
3089 else if(!entity_undefined_p($2) &&!ENDP($3) ) {
3090 if(type_undefined_p(entity_type($2))) {
3091 entity_type($2) = make_type_variable(
3099 else if( type_variable_p(entity_type($2) ) ){
3100 variable v = type_variable(entity_type($2));
3101 variable_qualifiers(v)=gen_nconc(variable_qualifiers(v),$3);
3104 c_parser_user_warning("some _asm(..) attributes are going to be lost for entity `%s'\n",entity_name($2));
3111 direct_decl: /* (* ISO 6.7.5 *) */
3112 /* (* We want to be able to redefine named
3113 * types as variable names *) */
3116 /* FI: A variable cannot be redeclared
3117 within the same scope, but this is not
3119 entity e = FindOrCreateCurrentEntity($1,ContextStack,FormalStack,FunctionStack,is_external);
3120 /* Initialize the type stack and push the
3121 type of found/created entity to the
3122 stack. It can be undefined if the entity
3123 has not been parsed, or a given type
3124 which is used later to check if the
3125 declarations are the same for one entity.
3126 This stack is put temporarily in the
3127 storage of the entity, not a global
3128 variable for each declarator to avoid
3129 being erased by recursion (FI: this last
3130 sentence seems to be wrong) */
3131 stack s = get_from_entity_type_stack_table(e);
3132 if(stack_undefined_p(s)) {
3133 s = stack_make(type_domain,0,0);
3134 stack_push((char *) entity_type(e),s);
3135 put_to_entity_type_stack_table(e,s);
3138 /* e has already been defined since a type
3139 stack is associated to it. At least, if
3140 the mapping from entity to type stack
3141 is well managed. Since entities are
3142 sometimes destroyed, a new entity might
3143 end up with the same memory address and
3144 hence the same type stack. */
3145 entity cm = get_current_module_entity();
3146 /* A function can be redeclared inside itself. see C_syntax/extern.c */
3148 /* Dummy parameters can also be redeclared
3149 as long as their types are equal */
3150 if(dummy_parameter_entity_p(e)) {
3151 c_parser_user_warning("Dummy parameter \"%s\" is redefined.\n",
3152 entity_user_name(e));
3153 CParserError("Dummy redefinition accepted by gcc but not compatible with ISO standard."
3154 " Try to compile with \"gcc -ansi -c\"\n");
3157 type t = (type) stack_head(s);
3158 if(type_undefined_p(t)) {
3159 c_parser_user_warning("Symbol \"%s\" is redefined.\n",
3160 entity_user_name(e) /* entity_name(e)*/);
3162 else if(type_functional_p(t)) {
3163 c_parser_user_warning("Function \"%s\" is redefined.\n",
3164 entity_user_name(e) /* entity_name(e)*/);
3167 c_parser_user_warning("Variable \"%s\" is redefined.\n",
3168 entity_user_name(e) /* entity_name(e)*/);
3169 CParserError("Variable redefinitions are not compatible with ISO standard."
3170 " Try to compile with \"gcc -ansi -c\"\n");
3176 entity_type(e) = type_undefined;
3177 //discard_C_comment();
3178 //push_current_C_comment();
3181 | TK_LPAREN attributes declarator TK_RPAREN
3183 /* Add attributes such as const, restrict, ... to variable's qualifiers */
3184 UpdateParenEntity($3, $2);
3186 stack_push((char *) entity_type($$),
3187 get_from_entity_type_stack_table($$));
3188 // FI: if I rely on the stack, I won't know for a while what
3189 // this entity is. And I'd like to make a difference between
3190 // a function and a pointer to a function before I declare
3191 // dummy arguments. But Nga's design has to be redone:-(.
3192 entity_type($$) = type_undefined;
3194 | direct_decl TK_LBRACKET attributes comma_expression_opt TK_RBRACKET
3196 /* This is the last dimension of an array (i.e a[1][2][3] => [3]).
3198 - What can be attributes ?
3199 - Why comma_expression, it can be a list of expressions ?
3200 - When the comma_expression is empty (corresponding to the first dimension),
3201 the array is of unknown size => can be determined by the intialization ? TO BE DONE*/
3203 if(gen_length(el)<=1)
3204 UpdateArrayEntity($1,$3,el);
3206 expression d = MakeCommaExpression(el);
3207 UpdateArrayEntity($1,$3,CONS(EXPRESSION, d, NIL));
3210 | direct_decl TK_LBRACKET attributes error TK_RBRACKET
3212 CParserError("Parse error: direct_decl TK_LBRACKET attributes error TK_RBRACKET\n");
3214 | direct_decl parameter_list_startscope
3216 /* Well, here it can be a function or a pointer to a function */
3217 entity e = $1; //RenameFunctionEntity($1);
3218 if (value_undefined_p(entity_initial(e))
3219 ||value_unknown_p(entity_initial(e))) {
3220 /* If it is a pointer, its value is going
3221 to be "unknown" or "expression"; if it is
3222 a function, its value is going to be
3223 "code". If the value cannot stay
3224 undefined, it should be made
3226 entity_initial(e) = make_value(is_value_code,make_code(NIL,strdup(""),make_sequence(NIL), NIL, make_language_c()));
3227 //entity_initial(e) = make_value_unknown();
3229 //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3232 rest_par_list TK_RPAREN
3234 entity m = get_current_module_entity();
3235 entity e = GetFunction();
3237 pips_assert("ne is an entity",
3238 entity_domain_number(ne)==entity_domain);
3240 stack_pop(FormalStack);
3241 StackPop(OffsetStack);
3242 /* Intrinsic functions in C such as printf, fprintf, ... are considered
3243 as entities with functional type ???
3244 if (!intrinsic_entity_p(e))*/
3245 /* e can be a function or a pointer to a
3246 function. The information is available
3247 somewhere in the stacks... */
3248 stack ts = get_from_entity_type_stack_table(e);
3249 if(!stack_undefined_p(ts)) {
3250 type et = (type) stack_head(ts);
3251 if(type_undefined_p(et))
3252 ne = RenameFunctionEntity(e);
3253 else if(!type_variable_p(et))
3254 ne = RenameFunctionEntity(e);
3256 pips_assert("ne is an entity",
3257 entity_domain_number(ne)==entity_domain);
3258 UpdateFunctionEntity(ne,$4);
3259 pips_assert("ne is an entity",
3260 entity_domain_number(ne)==entity_domain);
3261 /* No need to declare C user functions
3262 extern in a compilation unit; they are
3264 if(!entity_undefined_p(m)
3265 && compilation_unit_entity_p(m)
3266 && !intrinsic_entity_p(ne)) {
3267 /* Too early: pointers to functions are still
3268 * seen as functions here. Let's delay
3270 // RemoveFromExterns(ne);
3271 pips_assert("ne is an entity",
3272 entity_domain_number(ne)==entity_domain);
3273 removable_extern_entities =
3274 CONS(ENTITY, ne, removable_extern_entities);
3279 parameter_list_startscope:
3282 stack_push((char *) make_basic_logical(true), FormalStack);
3283 stack_push((char *) make_basic_int(1),OffsetStack);
3288 /* empty */ { $$ = NIL; }
3289 | parameter_decl rest_par_list1
3291 $$ = CONS(PARAMETER,$1,$2);
3295 /* empty */ { $$ = NIL; }
3298 StackPush(OffsetStack);
3302 /*$$ = CONS(PARAMETER,make_parameter(make_type_varargs(type_undefined),
3303 make_mode(CurrentMode,UU), make_dummy_unknown()),NIL); */
3304 type at = make_type(is_type_variable,
3305 make_variable(make_basic(is_basic_overloaded, UU),
3307 $$ = CONS(PARAMETER,
3308 make_parameter(make_type_varargs(at),
3309 make_mode(CurrentMode,UU),
3310 make_dummy_unknown()),
3315 StackPush(OffsetStack);
3317 parameter_decl rest_par_list1
3319 $$ = CONS(PARAMETER,$3,$4);
3323 parameter_decl: /* (* ISO 6.7.5 *) */
3324 decl_spec_list declarator
3326 UpdateEntity($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,false);
3327 $$ = make_parameter(copy_type(entity_type($2)),
3328 make_mode(CurrentMode,UU),
3329 make_dummy_identifier($2)); //FI: or should it
3330 // be entity_undefined? Are we parsing a compilation unit or a function?
3331 /* Set CurentMode where ???? */
3332 //stack_pop(ContextStack);
3335 | decl_spec_list abstract_decl
3337 UpdateAbstractEntity($2,ContextStack);
3338 $$ = make_parameter(copy_type(entity_type($2)),
3339 make_mode(CurrentMode,UU),
3340 make_dummy_unknown()); //FI: to be checked
3341 RemoveFromExterns($2);
3342 gen_remove(&removable_extern_entities, (void *) $2);
3344 //stack_pop(ContextStack);
3349 c_parser_context ycontext = stack_head(ContextStack);
3350 $$ = make_parameter(copy_type(c_parser_context_type(ycontext)),
3351 make_mode(CurrentMode,UU),
3352 make_dummy_unknown());
3353 /* function prototype*/
3354 //stack_pop(ContextStack);
3357 | TK_LPAREN parameter_decl TK_RPAREN
3361 /* (* Old style prototypes. Like a declarator *) */
3363 pointer_opt direct_old_proto_decl
3365 if (!type_undefined_p($1))
3366 UpdatePointerEntity($2,$1,NIL);
3371 direct_old_proto_decl:
3372 direct_decl TK_LPAREN
3374 entity e = $1; //RenameFunctionEntity($1);
3375 if (value_undefined_p(entity_initial(e)))
3376 entity_initial($1) = make_value(is_value_code,make_code(NIL,strdup(""),make_sequence(NIL),NIL, make_language_c()));
3377 //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3379 stack_push((char *) make_basic_logical(true),FormalStack);
3380 stack_push((char *) make_basic_int(1),OffsetStack);
3382 old_parameter_list_ne TK_RPAREN old_pardef_list
3384 entity e = GetFunction();
3385 list paras = MakeParameterList($4,$6,FunctionStack);
3387 stack_pop(FormalStack);
3388 StackPop(OffsetStack);
3389 (void) UpdateFunctionEntity(e, paras);
3390 //CreateReturnEntity(e);
3394 /* Never used because of conflict
3395 | direct_decl TK_LPAREN TK_RPAREN
3397 (void) UpdateFunctionEntity($1,NIL);
3402 old_parameter_list_ne:
3405 $$ = CONS(STRING,$1,NIL);
3407 | TK_IDENT TK_COMMA old_parameter_list_ne
3409 $$ = CONS(STRING,$1,$3);
3414 /* empty */ { $$ = NIL; }
3415 | decl_spec_list old_pardef TK_SEMICOLON TK_ELLIPSIS
3417 UpdateEntities($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,false);
3418 //stack_pop(ContextStack);
3420 /* Can we have struct/union definition in $1 ?*/
3421 /*$$ = gen_nconc($1,$2);*/
3424 | decl_spec_list old_pardef TK_SEMICOLON old_pardef_list
3426 /* Rule used for C_syntax/activate.c,
3427 decl33.c and adi.c. CreateReturnEntity()
3428 only useful for activate.c */
3430 entity f = stack_head(FunctionStack);
3431 SubstituteDummyParameters(f, el);
3432 UpdateEntities(el,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,false);
3433 // The functional type of f could be
3434 // completed with the parameter types...
3435 CreateReturnEntity(f);
3436 //stack_pop(ContextStack);
3438 /* Can we have struct/union definition in $1 ?*/
3439 /*$$ = gen_nconc($1,gen_nconc(el,$4));*/
3440 $$ = gen_nconc(el,$4);
3447 $$ = CONS(ENTITY,$1,NIL);
3449 | declarator TK_COMMA old_pardef
3451 $$ = CONS(ENTITY,$1,$3);
3455 CParserError("Parse error: error \n");
3459 pointer: /* (* ISO 6.7.5 *) */
3460 TK_STAR attributes pointer_opt
3461 { /* decl24.c, decl50.c, decl51.c, decl52.c,
3463 const attribute lost or misplaced for pointers */
3466 //c_parser_context_qualifiers(ycontext) =
3467 // gen_nconc(c_parser_context_qualifiers(ycontext), al);
3468 $$ = make_type_variable(make_variable(make_basic_pointer(t), NIL, al));
3469 //c_parser_context_qualifiers(ycontext) = NIL;
3474 /* empty */ { $$ = type_undefined;}
3478 type_name: /* (* ISO 6.7.6 *) */
3479 decl_spec_list abstract_decl
3482 list el = CONS(ENTITY, e, NIL);
3483 UpdateAbstractEntity(e,ContextStack);
3484 $$ = copy_type(entity_type(e));
3485 RemoveFromExterns(e); // should be useless
3486 gen_remove(&removable_extern_entities, (void *) e);
3487 remove_entity_type_stacks(el);
3490 //stack_pop(ContextStack);
3495 c_parser_context ycontext = stack_head(ContextStack);
3496 $$ = c_parser_context_type(ycontext);
3497 //stack_pop(ContextStack);
3502 abstract_decl: /* (* ISO 6.7.6. *) */
3503 pointer_opt abs_direct_decl attributes
3505 /* Update the type of the direct_decl entity with pointer_opt and attributes*/
3506 if (!type_undefined_p($1))
3507 UpdatePointerEntity($2,$1,$3);
3512 string n = int2a(abstract_counter++);
3513 entity e = FindOrCreateCurrentEntity(strdup(concatenate(DUMMY_ABSTRACT_PREFIX,
3520 UpdatePointerEntity(e,$1,NIL);
3521 /* Initialize the type stack and push the type of found/created entity to the stack.
3522 It can be undefined if the entity has not been parsed, or a given type which is
3523 used later to check if the declarations are the same for one entity.
3524 This stack is put temporarily in the storage of the entity, not a global variable
3525 for each declarator to avoid being erased by recursion */
3526 stack s = stack_make(type_domain, 0, 0);
3527 //entity_storage($$) = (storage) s;
3528 stack_push((char *) entity_type(e),s);
3529 put_to_entity_type_stack_table(e, s);
3530 /*entity_type($$) = type_undefined;*/
3535 abs_direct_decl: /* (* ISO 6.7.6. We do not support optional declarator for
3536 * functions. Plus Microsoft attributes. See the
3537 * discussion for declarator. *) */
3538 TK_LPAREN attributes abstract_decl TK_RPAREN
3540 UpdateParenEntity($3,$2);
3542 stack_push((char *) entity_type($$),
3543 get_from_entity_type_stack_table($$));
3544 entity_type($$) = type_undefined;
3546 | TK_LPAREN error TK_RPAREN
3548 CParserError("Parse error: TK_LPAREN error TK_RPAREN\n");
3551 | abs_direct_decl_opt TK_LBRACKET comma_expression_opt TK_RBRACKET
3553 UpdateArrayEntity($1,NIL,$3);
3555 /*(* The next shoudl be abs_direct_decl_opt but we get conflicts *)*/
3556 | abs_direct_decl_opt parameter_list_startscope
3558 entity e = $1; //RenameFunctionEntity($1);
3559 if (value_undefined_p(entity_initial(e)))
3560 entity_initial(e) = make_value(is_value_code,make_code(NIL,strdup(""),make_sequence(NIL),NIL, make_language_c()));
3561 //pips_assert("e is a module", module_name_p(entity_module_name($1)));
3564 rest_par_list TK_RPAREN
3566 entity e = GetFunction();
3568 stack_pop(FormalStack);
3569 StackPop(OffsetStack);
3570 (void) UpdateFunctionEntity(e,$4);
3575 abs_direct_decl_opt:
3579 string n = int2a(abstract_counter++);
3580 entity e = FindOrCreateCurrentEntity(strdup(concatenate(DUMMY_ABSTRACT_PREFIX,
3582 ContextStack,FormalStack,
3586 stack s = stack_make(type_domain,0,0);
3587 //entity_storage($$) = (storage) s;
3588 stack_push((char *) entity_type(e),s);
3589 put_to_entity_type_stack_table(e, s);
3590 entity_type(e) = type_undefined;
3595 function_def: /* (* ISO 6.9.1 *) */
3599 is_external = false;
3603 /* Make value_code for current module here */
3604 //list dl = statement_declarations($3);
3605 ModuleStatement = $3;
3606 pips_assert("Module statement is consistent",
3607 statement_consistent_p(ModuleStatement));
3608 pips_assert("No illegal redundant declarations",
3609 check_declaration_uniqueness_p(ModuleStatement));
3610 /* Let's delay this? ResetCurrentModule(); */
3614 function_def_start: /* (* ISO 6.9.1 *) */
3615 decl_spec_list declarator
3617 UpdateEntity($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external, false);
3618 //stack_pop(ContextStack);
3620 pips_debug(2,"Create current module %s\n",entity_user_name($2));
3621 MakeCurrentModule($2);
3622 reset_token_has_been_seen_p();
3624 pips_assert("Module is consistent\n",entity_consistent_p($2));
3626 /* (* Old-style function prototype *) */
3627 | decl_spec_list old_proto_decl
3629 UpdateEntity($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external, false);
3630 //stack_pop(ContextStack);
3632 pips_debug(2,"Create current module %s with old-style prototype\n",entity_user_name($2));
3633 MakeCurrentModule($2);
3634 reset_token_has_been_seen_p();
3636 pips_assert("Module is consistent\n",entity_consistent_p($2));
3638 /* (* New-style function that does not have a return type *) */
3639 | TK_IDENT parameter_list_startscope
3641 entity oe = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
3643 entity e = oe; //RenameFunctionEntity(oe);
3644 pips_debug(2,"Create current module \"%s\" with no return type\n",
3646 MakeCurrentModule(e);
3647 reset_token_has_been_seen_p();
3649 //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3652 rest_par_list TK_RPAREN
3654 /* Functional type is unknown or int (by default) or void ?*/
3655 //functional f = make_functional($4,make_type_unknown());
3656 functional f = make_functional($4,MakeIntegerResult());
3657 entity e = GetFunction();
3658 entity_type(e) = make_type_functional(f);
3659 pips_assert("Current module entity is consistent\n",entity_consistent_p(e));
3660 // Too late for full UpdateEntity() but at
3661 //least the return value and the formal
3662 //parameters should be properly defined
3663 //UpdateEntity(e,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,
3665 UpdateEntity2(e, FormalStack, OffsetStack);
3667 stack_pop(FormalStack);
3668 StackPop(OffsetStack);
3670 /* (* No return type and old-style parameter list *) */
3671 | TK_IDENT TK_LPAREN old_parameter_list_ne
3673 entity oe = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
3674 entity e= oe; //RenameFunctionEntity(oe);
3675 pips_debug(2,"Create current module %s with no return type + old-style parameter list\n",$1);
3677 MakeCurrentModule(e);
3679 //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3681 stack_push((char *) make_basic_logical(true),FormalStack);
3682 stack_push((char *) make_basic_int(1),OffsetStack);
3684 TK_RPAREN old_pardef_list
3686 list paras = MakeParameterList($3,$6,FunctionStack);
3688 functional f = make_functional(paras,make_type_unknown());
3689 entity e = GetFunction();
3690 entity_type(e) = make_type_functional(f);
3691 pips_assert("Current module entity is consistent\n",entity_consistent_p(e));
3693 stack_pop(FormalStack);
3694 StackPop(OffsetStack);
3696 /* (* No return type and no parameters *) */
3697 /* Never used because of conflict
3699 | TK_IDENT TK_LPAREN TK_RPAREN
3701 entity e = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
3702 /* Functional type is unknown or int (by default) or void ?* /
3703 functional f = make_functional(NIL,make_type_unknown());
3704 entity_type(e) = make_type_functional(f);
3705 pips_debug(2,"Create current module %s with no return type and no parameters\n",$1);
3706 MakeCurrentModule(e);
3708 pips_assert("Current module entity is consistent\n",entity_consistent_p(e));
3712 /*** GCC attributes ***/
3716 | attribute attributes
3717 /*{ $$ = CONS(QUALIFIER,$1,$2); }*/
3718 { $$ = insert_qualifier($2, $1);}
3721 /* (* In some contexts we can have an inline assembly to specify the name to
3722 * be used for a global. We treat this as a name attribute *) */
3723 attributes_with_asm:
3726 | attribute attributes_with_asm
3727 { $$ = CONS(QUALIFIER,$1,$2); }
3728 | TK_ASM TK_LPAREN string_constant TK_RPAREN attributes
3729 { $$ = CONS(QUALIFIER,make_qualifier_asm($3), $5);}
3734 TK_ATTRIBUTE TK_LPAREN paren_attr_list_ne TK_RPAREN
3735 { CParserError("ATTRIBUTE not implemented\n"); }
3736 | TK_DECLSPEC paren_attr_list_ne
3737 { CParserError("ATTRIBUTE not implemented\n"); }
3741 { CParserError("ATTRIBUTE not implemented\n"); }
3745 $$ = make_qualifier_const();
3749 $$ = make_qualifier_restrict();
3753 $$ = make_qualifier_volatile();
3755 | TK_STATIC_DIMENSION
3757 $$ = make_qualifier_static_dimension();
3761 /** (* PRAGMAS and ATTRIBUTES *) ***/
3762 /* (* We want to allow certain strange things that occur in pragmas, so we
3763 * cannot use directly the language of expressions *) */
3767 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3768 | TK_IDENT TK_COLON TK_INTCON
3769 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3770 | TK_DEFAULT TK_COLON TK_INTCON
3771 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3772 | TK_IDENT TK_LPAREN TK_RPAREN
3773 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3774 | TK_IDENT paren_attr_list_ne
3775 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3777 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3779 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3781 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3782 | TK_SIZEOF expression
3783 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3784 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
3785 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3787 | TK_ALIGNOF expression
3788 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3789 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
3790 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3791 | TK_PLUS expression
3792 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3793 | TK_MINUS expression
3794 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3795 | TK_STAR expression
3796 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3797 | TK_AND expression %prec TK_ADDROF
3799 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3800 | TK_EXCLAM expression
3801 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3802 | TK_TILDE expression
3803 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3805 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3806 | attr TK_MINUS attr
3807 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3808 | attr TK_STAR expression
3809 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3810 | attr TK_SLASH attr
3811 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3812 | attr TK_PERCENT attr
3813 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3814 | attr TK_AND_AND attr
3815 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3816 | attr TK_PIPE_PIPE attr
3817 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3820 CParserError("PRAGMAS and ATTRIBUTES not implemented\n");
3823 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3825 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3826 | attr TK_EQ_EQ attr
3827 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3828 | attr TK_EXCLAM_EQ attr
3829 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3831 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3833 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3834 | attr TK_INF_EQ attr
3835 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3836 | attr TK_SUP_EQ attr
3837 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3838 | attr TK_INF_INF attr
3839 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3840 | attr TK_SUP_SUP attr
3841 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3842 | attr TK_ARROW id_or_typename
3843 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3844 | attr TK_DOT id_or_typename
3845 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3846 | TK_LPAREN attr TK_RPAREN
3847 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3851 /* Never used because of conflict
3855 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3856 | attr TK_COMMA attr_list_ne
3857 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3858 | error TK_COMMA attr_list_ne
3859 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3862 TK_LPAREN attr_list_ne TK_RPAREN
3863 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3864 | TK_LPAREN error TK_RPAREN
3865 { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3868 /*** GCC TK_ASM instructions ***/
3872 | TK_VOLATILE asmattr
3873 { CParserError("ASM not implemented\n"); }
3875 { CParserError("ASM not implemented\n"); }
3881 | TK_COLON asmoperands asminputs
3882 { CParserError("ASM not implemented\n"); }
3888 { CParserError("ASM not implemented\n"); }
3892 { CParserError("ASM not implemented\n"); }
3893 | asmoperandsne TK_COMMA asmoperand
3894 { CParserError("ASM not implemented\n"); }
3897 string_constant TK_LPAREN expression TK_RPAREN
3898 { CParserError("ASM not implemented\n"); }
3899 | string_constant TK_LPAREN error TK_RPAREN
3900 { CParserError("ASM not implemented\n"); }
3905 | TK_COLON asmoperands asmclobber
3906 { CParserError("ASM not implemented\n"); }
3911 | TK_COLON asmcloberlst_ne
3912 { CParserError("ASM not implemented\n"); }
3916 { CParserError("ASM not implemented\n"); }
3917 | one_string_constant TK_COMMA asmcloberlst_ne
3918 { CParserError("ASM not implemented\n"); }