PIPS
cyacc.y
Go to the documentation of this file.
1 /* $Id: cyacc.y 23115 2016-06-07 21:40:12Z irigoin $ */
2 
3 /******************** SYNTAX ANALYZER ************************************
4 
5  Here are the parsing rules, based on the work of people from
6  Open Source Quality projects (http://osq.cs.berkeley.edu/), used
7  by the CCured source-to-source translator for C
8 
9 *****************************************************************/
10 
11 /*(*
12  *
13  * Copyright (c) 2001-2003,
14  * George C. Necula <necula@cs.berkeley.edu>
15  * Scott McPeak <smcpeak@cs.berkeley.edu>
16  * Wes Weimer <weimer@cs.berkeley.edu>
17  * Ben Liblit <liblit@cs.berkeley.edu>
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions are
22  * met:
23  *
24  * 1. Redistributions of source code must retain the above copyright
25  * notice, this list of conditions and the following disclaimer.
26  *
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  *
31  * 3. The names of the contributors may not be used to endorse or promote
32  * products derived from this software without specific prior written
33  * permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
36  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
37  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
38  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
39  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46  *
47  **)/
48 /*(* NOTE: This parser is based on a parser written by Hugues Casse. Since
49  * then I have changed it in numerous ways to the point where it probably
50  * does not resemble Hugues's original one at all *)*/
51 
52 %{
53 #ifdef HAVE_CONFIG_H
54  #include "pips_config.h"
55 #endif
56  /* C declarations */
57 #include <stdio.h>
58 #include <string.h>
59 #include <stdlib.h>
60 #include <ctype.h>
61 
62 #include "genC.h"
63 #include "linear.h"
64 #include "ri.h"
65 #include "ri-util.h"
66 #include "text-util.h"
67 #include "misc.h"
68 #include "properties.h"
69 
70 #include "c_parser_private.h"
71 
72 #include "c_syntax.h"
73 
74 #define C_ERROR_VERBOSE 1 /* much clearer error messages with bison */
75 
76 /* Increase the parser stack to have SPEC2006/445.gobmk/owl_defendpat.c
77  going through without a:
78 
79  user warning in splitc_error: C memory exhausted near "0" at preprocessed line 13459 (user line 8732)
80 */
81 #define YYMAXDEPTH 1000000
82 
83 // To set breakpoint in cyacc.y
84 // void breakpoint(int l) {;}
85 // #define BREAKPOINT breakpoint(__LINE__)
86 #define BREAKPOINT ;
87 
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 */
93 
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). */
95 
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)
99 {
100  initialization_expressions
101  = CONS(EXPRESSION, int_to_expression(init_p), initialization_expressions);
102 }
103 
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,
108  OffsetStack, ... */
109 
110 static void PushFunction(entity f)
111 {
112  stack_push((char *) f, FunctionStack);
113 }
114 
115 static void PopFunction()
116 {
117  stack_pop(FunctionStack);
118  }
119 
120 entity GetFunction()
121 {
122  entity f = stack_head(FunctionStack);
123  return f;
124 }
125 
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
130  // ContextStack
131 static c_parser_context ycontext = c_parser_context_undefined;
132 
133 ␌
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
138  io_intrinsics*.c */
139 static string expression_comment = string_undefined;
140 static int expression_line_number = STATEMENT_NUMBER_UNDEFINED;
141 
142 /* we don't want an expression comment with new lines, it is disgracefull */
143 void reset_expression_comment()
144 {
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;
150  }
151 
152  expression_line_number = STATEMENT_NUMBER_UNDEFINED;
153 }
154 
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);
161  free(tmp);
162  free(expression_comment);
163  }
164  else
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;
169  }
170  return s;
171 }
172 
173 
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);
181  }
182  expression_comment=string_undefined;
183 }
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);
194  free(tmp);
195  free(comments);
196  }
197  else
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;
202  }
203  return s;
204 }
205 ␌
206 
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)
210 {
211  string new_scope = old_scope;
212  string last_scope = string_undefined;
213 
214  pips_debug(8, "old_scope = \"%s\"\n", old_scope);
215  pips_assert("old_scope is a scope", string_block_scope_p(old_scope));
216 
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);
221 
222  if(last_scope==NULL)
223  *new_scope = '\0';
224  else
225  *(last_scope+1) = '\0';
226  }
227  else
228  new_scope = NULL;
229 
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));
233  }
234  else {
235  pips_debug(8, "new_scope = NULL\n");
236  }
237 
238  return new_scope;
239 }
240 
241 /* Allocate a new string containing only block scope information */
242 string scope_to_block_scope(string full_scope)
243 {
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;
247 
248  pips_debug(8, "full_scope = \"%s\"\n", full_scope);
249 
250  if(f_scope==NULL)
251  f_scope = full_scope;
252  else
253  f_scope++;
254 
255  if(l_scope==NULL)
256  block_scope = strdup("");
257  else
258  block_scope = gen_strndup0(f_scope, (unsigned) (l_scope-f_scope+1));
259 
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));
262 
263  return block_scope;
264 }
265 
266 c_parser_context CreateDefaultContext()
267 {
268  c_parser_context c = make_c_parser_context(empty_scope(),
269  type_undefined,
270  storage_undefined,
271  NIL,
272  false,
273  false);
274  pips_debug(8, "New default context %p\n", c);
275  return c;
276 }
277 
278 static int C_scope_identifier = -2;
279 
280 void InitScope()
281 {
282  C_scope_identifier = -1;
283 }
284 
285 static void EnterScope()
286 {
287  c_parser_context nc = CreateDefaultContext();
288  string cs = string_undefined;
289 
290  push_new_c_parser_scope(); // For the lexical analyzer
291 
292  pips_assert("C_scope_identifier has been initialized", C_scope_identifier>-2);
293 
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)
306  );
307  cs = c_parser_context_scope(c);
308  pips_assert("scope contains only block scope information", string_block_scope_p(cs));
309  }
310  else
311  cs = "";
312 
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);
320 
321  char * stf = c_parser_context_scope(nc);
322  c_parser_context_scope(nc) = strdup(concatenate(cs, ns, BLOCK_SEP_STRING, NULL));
323  free(stf);
324  free(ns);
325  }
326  else {
327  char * stf = c_parser_context_scope(nc);
328  c_parser_context_scope(nc) = strdup(cs);
329  free(stf);
330  }
331 
332  stack_push((char *) nc, ContextStack);
333  //ycontext = nc;
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);
338 }
339 
340 int ScopeStackSize()
341 {
342  return stack_size(ContextStack);
343 }
344 
345 string GetScope()
346 {
347  string s = "";
348 
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
351  parser */
352  if(!stack_empty_p(ContextStack)) {
353  c_parser_context c = (c_parser_context) stack_head(ContextStack);
354 
355  s = c_parser_context_scope(c);
356  }
357 
358  return s;
359 }
360 
361 string GetParentScope()
362 {
363  string s = "";
364 
365  if(!stack_empty_p(ContextStack) && stack_size(ContextStack)>=2) {
366  c_parser_context c = (c_parser_context) stack_nth(ContextStack,2);
367 
368  s = c_parser_context_scope(c);
369  }
370 
371  return s;
372 }
373 
374 void ExitScope()
375 {
376  c_parser_context c = (c_parser_context) stack_head(ContextStack);
377 
378  pop_c_parser_scope_stack();
379 
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)
390  );
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);
401  }
402  else {
403  // ycontext = c_parser_context_undefined;
404  pips_debug(8, "Back to undefined context scope\n");
405  }
406 }
407 
408 void PushContext(c_parser_context c)
409 {
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));
413 }
414 
415 void PopContext()
416 {
417  c_parser_context fc = (c_parser_context) stack_head(ContextStack);
418 
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");
424  }
425  else {
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));
429  }
430 }
431 
432 c_parser_context GetContext()
433 {
434 
435  c_parser_context c = c_parser_context_undefined;
436 
437  if(!stack_empty_p(ContextStack))
438  c = (c_parser_context) stack_head(ContextStack);
439  else
440  // Should we return a default context?
441  // Not really compatible with a clean memory allocation policy
442  pips_internal_error("No current context");
443 
444  pips_debug(8, "Context %p is obtained from stack position %d\n",
445  c, stack_size(ContextStack));
446 
447  return c;
448 }
449 
450 c_parser_context GetContextCopy()
451 {
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));
458  return cc;
459 }
460 /* Declaration counter
461  *
462  * It is used to declare the formal parameters in function declarations.
463  */
464  static int declaration_counter = 0;
465 
466  void reset_declaration_counter()
467  {
468  declaration_counter = 0;
469  }
470 
471  int get_declaration_counter()
472  {
473  return declaration_counter;
474  }
475 ␌
476  /* Each scope in the current unit has its own number.
477  *
478  * The scope management in the C parser is the same as in the C preprocessor.
479  *
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.
483  */
484 #define SCOPE_UNDEFINED (-1)
485  static int c_parser_scope_number = SCOPE_UNDEFINED;
486  static stack c_parser_scope_stack = stack_undefined;
487 
488  void init_c_parser_scope_stack()
489  {
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);
494  }
495 
496  void reset_c_parser_scope_stack()
497  {
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;
502  }
503  else {
504  // pips_internal_error? Could be a bad input C file...
505  pips_user_warning("Parser scope stack is not empty.\n");
506  }
507  }
508  c_parser_scope_number = SCOPE_UNDEFINED;
509  return;
510  }
511 
512  /* To be used by an error handler */
513  void force_reset_c_parser_scope_stack()
514  {
515  if(c_parser_scope_stack != stack_undefined) {
516  stack_free(&c_parser_scope_stack);
517  c_parser_scope_stack = stack_undefined;
518  }
519  c_parser_scope_number = SCOPE_UNDEFINED;
520  return;
521  }
522 
523  void push_new_c_parser_scope()
524  {
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);
529  return;
530  }
531 
532  void pop_c_parser_scope_stack()
533  {
534  stack_pop(c_parser_scope_stack);
535  return;
536  }
537 
538 bool c_parser_scope_stack_empty_p()
539 {
540  return stack_empty_p(c_parser_scope_stack);
541 }
542 
543 string get_c_parser_current_scope()
544  {
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
548  sn = "";
549  }
550  else
551  sn = (string) stack_head(c_parser_scope_stack);
552  return sn;
553  }
554 
555 string get_c_parser_nth_scope(int n)
556  {
557  string sn = (string) stack_nth(c_parser_scope_stack, n);
558  return sn;
559  }
560 
561 int c_parser_number_of_scopes()
562  {
563  int n = stack_size(c_parser_scope_stack);
564  return n;
565  }
566 ␌
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
573  outermost order. */
574 
575 static list internal_derived_entity_declarations = NIL;
576 
577 static void RecordDerivedEntityDeclaration(entity de)
578 {
579  internal_derived_entity_declarations
580  = gen_nconc(internal_derived_entity_declarations,
581  CONS(ENTITY, de, NIL));
582 }
583 
584 static list GetDerivedEntityDeclarations()
585 {
586  list l = internal_derived_entity_declarations;
587  /* The list spine is going to be reused by the caller. No need to
588  free. */
589  internal_derived_entity_declarations = NIL;
590  return l;
591 }
592 
593 static void ResetDerivedEntityDeclarations()
594 {
595  if(!ENDP(internal_derived_entity_declarations)) {
596  gen_free_list(internal_derived_entity_declarations);
597  internal_derived_entity_declarations = NIL;
598  }
599 }
600 %}
601 
602 /* Bison declarations */
603 
604 %union {
605  cons * liste;
606  entity entity;
607  expression expression;
608  statement statement;
609  string string;
610  type type;
611  parameter parameter;
612  int integer;
613  qualifier qualifier;
614 }
615 
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
621 
622 %token <string> TK_STRINGCON
623 %token <string> TK_WSTRINGCON
624 
625 %token TK_EOF
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
630 
631 %token TK_SIZEOF TK_ALIGNOF
632 
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
636 
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
643 %token TK_PIPE_PIPE
644 %token TK_INF_INF TK_SUP_SUP
645 %token TK_PLUS_PLUS TK_MINUS_MINUS
646 
647 %token TK_RPAREN
648 %token TK_LPAREN TK_RBRACE
649 %token TK_LBRACE
650 %token TK_LBRACKET TK_RBRACKET
651 %token TK_COLON
652 %token TK_SEMICOLON
653 %token TK_COMMA TK_ELLIPSIS TK_QUEST
654 
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
658 %token TK_IF
659 %token TK_ELSE
660 
661 %token TK_ATTRIBUTE TK_INLINE TK_ASM TK_TYPEOF TK_FUNCTION__ TK_PRETTY_FUNCTION__
662 %token TK_LABEL__
663 %token TK_BUILTIN_VA_ARG
664 %token TK_BUILTIN_VA_LIST
665 %token TK_BLOCKATTRIBUTE
666 %token TK_DECLSPEC
667 %token TK_MSASM TK_MSATTR
668  /* The string that follows a #pragma: */
669 %token <string> TK_PRAGMA
670  /* The token _Pragma from C99: */
671 %token TK__Pragma
672 
673 /* sm: cabs tree transformation specification keywords */
674 %token TK_AT_TRANSFORM TK_AT_TRANSFORMEXPR TK_AT_SPECIFIER TK_AT_EXPR
675 %token TK_AT_NAME
676 
677 /* Added here because the token numbering seems to be fragile */
678 %token <string> TK_COMPLEXCON
679 
680 /* operator precedence */
681 %nonassoc TK_IF
682 %nonassoc TK_ELSE
683 %left TK_COMMA
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
686 %left TK_PIPE_PIPE
687 %left TK_AND_AND
688 %left TK_PIPE
689 %left TK_CIRC
690 %left TK_AND
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
696 %right TK_CAST
697 %right TK_EXCLAM TK_TILDE TK_PLUS_PLUS TK_MINUS_MINUS TK_RPAREN TK_ADDROF TK_SIZEOF TK_ALIGNOF
698 %left TK_LBRACKET
699 %left TK_DOT TK_ARROW TK_LPAREN TK_LBRACE
700 %right TK_NAMED_TYPE
701 %left TK_IDENT
702 
703 /* Non-terminals informations */
704 %start interpret
705 %type <liste> file interpret globals
706 %type <liste> global
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
722 
723 %type <expression> initializer
724 %type <liste> initializer_list
725 %type <liste> init_designators init_designators_opt
726 
727 %type <liste> type_spec
728 %type <liste> struct_decl_list
729 
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
742 
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
753 
754 %type <string> label
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
760 
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
768 
769  /* For now, pass pragmas as strings and list of strings: */
770 %type <string> pragma
771 %type <liste> pragmas
772 
773 %%
774 
775 interpret: file TK_EOF
776  {YYACCEPT;};
777 file: globals
778  {
779  /* To handle special case: compilation unit module */
780  list dsl = $1;
781  list dl = statements_to_declarations(dsl);
782 
783  pips_assert("Here, only continue statements are expected",
784  continue_statements_p(dsl));
785 
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());
793  }
794  ifdebug(8) {
795  pips_debug(8, "Declaration list for compilation unit %s: ",
796  get_current_module_name());
797  print_entities(dl);
798  pips_debug(8, "\n");
799  }
800  ModuleStatement = make_statement(entity_empty_label(),
801  STATEMENT_NUMBER_UNDEFINED,
802  STATEMENT_ORDERING_UNDEFINED,
803  string_undefined,
804  make_instruction_block(dsl),
805  dl, NULL, empty_extensions (), make_synchronization_none());
806  if(ENDP(dl)) {
807  pips_user_warning("ISO C forbids an empty source file\n");
808  }
809  }
810  }
811  }
812 ;
813 
814 globals:
815  /* empty */ { $$ = NIL; }
816 | {is_external = true; } global globals
817  {
818  list dsl = $3;
819  list gdsl = $2;
820 
821  /* PRAGMA */
822  if(!ENDP(dsl) && gen_length(gdsl)==1)
823  {
824  statement stmt = STATEMENT(CAR(dsl));
825  statement stmt_pragma = STATEMENT(CAR(gdsl));
826  list exs = extensions_extension(statement_extensions(stmt_pragma));
827  if (!ENDP(exs))
828  {
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);
832  gdsl = NIL;
833  }
834  }
835 
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));
843  }
844  ifdebug(9) {
845  list gdl = statements_to_declarations(gdsl);
846  fprintf(stderr, "New variables $2 (%p) are declared\n", gdl);
847  print_entities(gdl);
848  fprintf(stderr, "\n");
849  fprintf(stderr, "*******Current declarations dl (%p) are: \n", dl);
850  print_entities(dl);
851  fprintf(stderr, "\n");
852  gen_free_list(gdl);
853  }
854  gen_free_list(dl);
855  }
856 
857  /* The order of declarations must be
858  preserved: a structure is declared before
859  it is used to declare a variable */
860  /*
861  $$ = NIL;
862  MAP(ENTITY, v, {
863  if(!gen_in_list_p(v, $3))
864  $$ = gen_nconc($$, CONS(ENTITY, v , NIL));}, $2);
865  $$ = gen_nconc($$, $3);
866  */
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);
870 
871  ifdebug(9) {
872  list udl = statements_to_declarations($$);
873  fprintf(stderr, "*******Updated $$ declarations (%p) are: \n", $$);
874  fprintf(stderr, "\n");
875  if(ENDP($$))
876  fprintf(stderr, "Empty list\n");
877  else
878  print_entities(udl);
879  fprintf(stderr, "\n");
880  }
881 
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");
893  }
894  else {
895  pips_internal_error("A function does not have a functional type\n");
896  }
897  }
898  ResetCurrentModule();
899  }
900  }
901 | TK_SEMICOLON globals
902  {
903  pips_assert("Declarations are unique", gen_once_p($2));
904  ifdebug(8) {
905  list udl = statements_to_declarations($2);
906  fprintf(stderr, "*******Current declarations are: \n");
907  print_entities(udl);
908  fprintf(stderr, "\n");
909  }
910  $$ = $2;
911  }
912 ;
913 
914 location:
915  /* empty */ {} %prec TK_IDENT
916 
917 /*** Global Definition ***/
918 global:
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
922  {
923  CParserError("ASM not implemented\n");
924  $$ = NIL;
925  }
926 | TK_PRAGMA /*attr*/
927  {
928  /*
929  CParserError("PRAGMA not implemented at top level\n");
930  $$ = NIL;
931  */
932  statement s = make_continue_statement(entity_empty_label());
933  add_pragma_str_to_statement(s, $1, true);
934  $$ = CONS(STATEMENT, s, NIL);
935  }
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 */
939 | TK_IDENT TK_LPAREN
940  {
941  entity oe = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
942  free($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();
948  }
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)));
952  else
953  CCleanLocalEntities(oe);
954  PushFunction(e);
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();
960  }
961  old_parameter_list_ne TK_RPAREN old_pardef_list TK_SEMICOLON
962  {
963  entity e = GetFunction();
964  if (type_undefined_p(entity_type(e)))
965  {
966  list paras = MakeParameterList($4,$6,FunctionStack);
967  functional f = make_functional(paras,make_type_unknown());
968  entity_type(e) = make_type_functional(f);
969  }
970  pips_assert("Current function entity is consistent",entity_consistent_p(e));
971  PopFunction();
972  stack_pop(FormalStack);
973  StackPop(OffsetStack);
974  gen_free_list($4);
975  $$ = NIL;
976  // FI: commented out while trying to
977  //retrieve all comments
978  //discard_C_comment();
979  }
980 /* Old style function prototype, but without any arguments
981 
982  Not used because of conflicts...
983 | TK_IDENT TK_LPAREN TK_RPAREN TK_SEMICOLON
984  {
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)))
988  {
989  functional f = make_functional(NIL,make_type_unknown());
990  entity_type(e) = make_type_functional(f);
991  }
992  if (storage_undefined_p(entity_storage(e))) {
993  // entity_storage(e) = make_storage_return(e);
994  entity_storage(e) = make_storage_rom();
995  }
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));
999  $$ = NIL;
1000  // FI: commented out while trying to
1001  //retrieve all comments
1002  //discard_C_comment();
1003  }
1004 */
1005 /* transformer for a toplevel construct */
1006 | TK_AT_TRANSFORM TK_LBRACE global TK_RBRACE TK_IDENT /*to*/ TK_LBRACE globals TK_RBRACE
1007  {
1008  CParserError("CIL AT not implemented\n");
1009  $$ = NIL;
1010  }
1011 /* transformer for an expression */
1012 | TK_AT_TRANSFORMEXPR TK_LBRACE expression TK_RBRACE TK_IDENT /*to*/ TK_LBRACE expression TK_RBRACE
1013  {
1014  CParserError("CIL AT not implemented\n");
1015  $$ = NIL;
1016  }
1017 | location error TK_SEMICOLON
1018  {
1019  CParserError("Parse error: location error TK_SEMICOLON \n");
1020  $$ = NIL;
1021  }
1022 ;
1023 
1024 id_or_typename:
1025  TK_IDENT
1026  {}
1027 | TK_NAMED_TYPE
1028  {}
1029 | TK_AT_NAME TK_LPAREN TK_IDENT TK_RPAREN
1030  {
1031  CParserError("CIL AT not implemented\n");
1032  }
1033 ;
1034 
1035 maybecomma:
1036  /* empty */
1037 | TK_COMMA /* do nothing */
1038 ;
1039 
1040 /* *** Expressions *** */
1041 
1042 expression:
1043  constant
1044  {
1045  $$ = MakeNullaryCall($1);
1046  }
1047 | TK_IDENT
1048  {
1049  /* Create the expression corresponding to this identifier */
1050  $$ = IdentifierToExpression($1);
1051  free($1);
1052  }
1053 | TK_SIZEOF expression
1054  {
1055  $$ = MakeSizeofExpression($2);
1056  }
1057 | TK_SIZEOF TK_LPAREN type_name TK_RPAREN
1058  {
1059  $$ = MakeSizeofType($3);
1060  }
1061 | TK_ALIGNOF expression
1062  {
1063  CParserError("ALIGNOF not implemented\n");
1064  }
1065 | TK_ALIGNOF TK_LPAREN type_name TK_RPAREN
1066  {
1067  CParserError("ALIGNOF not implemented\n");
1068  }
1069 | TK_PLUS expression %prec TK_CAST
1070  {
1071  $$ = MakeUnaryCall(CreateIntrinsic(UNARY_PLUS_OPERATOR_NAME), $2);
1072  }
1073 | TK_MINUS expression %prec TK_CAST
1074  {
1075  $$ = MakeUnaryCall(CreateIntrinsic(UNARY_MINUS_OPERATOR_NAME), $2);
1076  }
1077 | TK_STAR expression
1078  {
1079  $$ = MakeUnaryCall(CreateIntrinsic(DEREFERENCING_OPERATOR_NAME), $2);
1080  }
1081 | TK_AND expression %prec TK_ADDROF
1082  {
1083  $$ = MakeUnaryCall(CreateIntrinsic(ADDRESS_OF_OPERATOR_NAME), $2);
1084  }
1085 | TK_EXCLAM expression
1086  {
1087  $$ = MakeUnaryCall(CreateIntrinsic(C_NOT_OPERATOR_NAME), $2);
1088  }
1089 | TK_TILDE expression
1090  {
1091  $$ = MakeUnaryCall(CreateIntrinsic(BITWISE_NOT_OPERATOR_NAME), $2);
1092  }
1093 | TK_PLUS_PLUS expression %prec TK_CAST
1094  {
1095  $$ = MakeUnaryCall(CreateIntrinsic(PRE_INCREMENT_OPERATOR_NAME), $2);
1096  }
1097 | expression TK_PLUS_PLUS
1098  {
1099  $$ = MakeUnaryCall(CreateIntrinsic(POST_INCREMENT_OPERATOR_NAME), $1);
1100  }
1101 | TK_MINUS_MINUS expression %prec TK_CAST
1102  {
1103  $$ = MakeUnaryCall(CreateIntrinsic(PRE_DECREMENT_OPERATOR_NAME), $2);
1104  }
1105 | expression TK_MINUS_MINUS
1106  {
1107  $$ = MakeUnaryCall(CreateIntrinsic(POST_DECREMENT_OPERATOR_NAME), $1);
1108  }
1109 | expression TK_ARROW id_or_typename
1110  {
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);
1115  }
1116 | expression TK_DOT id_or_typename
1117  {
1118  expression exp = MemberIdentifierToExpression($1,$3);
1119  $$ = MakeBinaryCall(CreateIntrinsic(FIELD_OPERATOR_NAME),$1,exp);
1120  }
1121 | TK_LPAREN block TK_RPAREN
1122  {
1123  CParserError("GNU extension not implemented\n");
1124  }
1125 | paren_comma_expression
1126  {
1127  if(false) {
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')))
1133  break;
1134  if(fullspace)
1135  free(ccc);
1136  else {
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;
1141  else {
1142  char *tmp = expression_comment;
1143  asprintf(&expression_comment,"%s%s",expression_comment, ccc);
1144  free(tmp);
1145  }
1146  }
1147  }
1148  expression_line_number = pop_current_C_line_number();
1149  }
1150  $$ = MakeCommaExpression($1);
1151  }
1152 | expression TK_LPAREN arguments TK_RPAREN
1153  {
1154  $$ = MakeFunctionExpression($1,$3);
1155  }
1156 | TK_BUILTIN_VA_ARG TK_LPAREN expression TK_COMMA type_name TK_RPAREN
1157  {
1158 
1159  expression e = $3;
1160  type t = $5;
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());
1167 
1168  $$ = r;
1169  //CParserError("BUILTIN_VA_ARG not implemented\n");
1170  }
1171 | expression bracket_comma_expression
1172  {
1173  $$ = MakeArrayExpression($1,$2);
1174  }
1175 | expression TK_QUEST opt_expression TK_COLON expression
1176  {
1177  $$ = MakeTernaryCall(CreateIntrinsic(CONDITIONAL_OPERATOR_NAME), $1, $3, $5);
1178  }
1179 | expression TK_PLUS expression
1180  {
1181  $$ = MakeBinaryCall(CreateIntrinsic(PLUS_C_OPERATOR_NAME), $1, $3);
1182  }
1183 | expression TK_MINUS expression
1184  {
1185  $$ = MakeBinaryCall(CreateIntrinsic(MINUS_C_OPERATOR_NAME), $1, $3);
1186  }
1187 | expression TK_STAR expression
1188  {
1189  $$ = MakeBinaryCall(CreateIntrinsic(MULTIPLY_OPERATOR_NAME), $1, $3);
1190  }
1191 | expression TK_SLASH expression
1192  {
1193  $$ = MakeBinaryCall(CreateIntrinsic(DIVIDE_OPERATOR_NAME), $1, $3);
1194  }
1195 | expression TK_PERCENT expression
1196  {
1197  $$ = MakeBinaryCall(CreateIntrinsic(C_MODULO_OPERATOR_NAME), $1, $3);
1198  }
1199 | expression TK_AND_AND expression
1200  {
1201  $$ = MakeBinaryCall(CreateIntrinsic(C_AND_OPERATOR_NAME), $1, $3);
1202  }
1203 | expression TK_PIPE_PIPE expression
1204  {
1205  $$ = MakeBinaryCall(CreateIntrinsic(C_OR_OPERATOR_NAME), $1, $3);
1206  }
1207 | expression TK_AND expression
1208  {
1209  $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_AND_OPERATOR_NAME), $1, $3);
1210  }
1211 | expression TK_PIPE expression
1212  {
1213  $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_OR_OPERATOR_NAME), $1, $3);
1214  }
1215 | expression TK_CIRC expression
1216  {
1217  $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_XOR_OPERATOR_NAME), $1, $3);
1218  }
1219 | expression TK_EQ_EQ expression
1220  {
1221  $$ = MakeBinaryCall(CreateIntrinsic(C_EQUAL_OPERATOR_NAME), $1, $3);
1222  }
1223 | expression TK_EXCLAM_EQ expression
1224  {
1225  $$ = MakeBinaryCall(CreateIntrinsic(C_NON_EQUAL_OPERATOR_NAME), $1, $3);
1226  }
1227 | expression TK_INF expression
1228  {
1229  $$ = MakeBinaryCall(CreateIntrinsic(C_LESS_THAN_OPERATOR_NAME), $1, $3);
1230  }
1231 | expression TK_SUP expression
1232  {
1233  $$ = MakeBinaryCall(CreateIntrinsic(C_GREATER_THAN_OPERATOR_NAME), $1, $3);
1234  }
1235 | expression TK_INF_EQ expression
1236  {
1237  $$ = MakeBinaryCall(CreateIntrinsic(C_LESS_OR_EQUAL_OPERATOR_NAME), $1, $3);
1238  }
1239 | expression TK_SUP_EQ expression
1240  {
1241  $$ = MakeBinaryCall(CreateIntrinsic(C_GREATER_OR_EQUAL_OPERATOR_NAME), $1, $3);
1242  }
1243 | expression TK_INF_INF expression
1244  {
1245  $$ = MakeBinaryCall(CreateIntrinsic(LEFT_SHIFT_OPERATOR_NAME), $1, $3);
1246  }
1247 | expression TK_SUP_SUP expression
1248  {
1249  $$ = MakeBinaryCall(CreateIntrinsic(RIGHT_SHIFT_OPERATOR_NAME), $1, $3);
1250  }
1251 | expression TK_EQ expression
1252  {
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");
1265  }
1266  }
1267  (void) simplify_C_expression(rhs);
1268  $$ = make_assign_expression(lhs, rhs);
1269  }
1270 | expression TK_PLUS_EQ expression
1271  {
1272  (void) simplify_C_expression($3);
1273  $$ = MakeBinaryCall(CreateIntrinsic(PLUS_UPDATE_OPERATOR_NAME), $1, $3);
1274  }
1275 | expression TK_MINUS_EQ expression
1276  {
1277  (void) simplify_C_expression($3);
1278  $$ = MakeBinaryCall(CreateIntrinsic(MINUS_UPDATE_OPERATOR_NAME), $1, $3);
1279  }
1280 | expression TK_STAR_EQ expression
1281  {
1282  (void) simplify_C_expression($3);
1283  $$ = MakeBinaryCall(CreateIntrinsic(MULTIPLY_UPDATE_OPERATOR_NAME), $1, $3);
1284  }
1285 | expression TK_SLASH_EQ expression
1286  {
1287  (void) simplify_C_expression($3);
1288  $$ = MakeBinaryCall(CreateIntrinsic(DIVIDE_UPDATE_OPERATOR_NAME), $1, $3);
1289  }
1290 | expression TK_PERCENT_EQ expression
1291  {
1292  (void) simplify_C_expression($3);
1293  $$ = MakeBinaryCall(CreateIntrinsic(MODULO_UPDATE_OPERATOR_NAME), $1, $3);
1294  }
1295 | expression TK_AND_EQ expression
1296  {
1297  (void) simplify_C_expression($3);
1298  $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_AND_UPDATE_OPERATOR_NAME), $1, $3);
1299  }
1300 | expression TK_PIPE_EQ expression
1301  {
1302  (void) simplify_C_expression($3);
1303  $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_OR_UPDATE_OPERATOR_NAME), $1, $3);
1304  }
1305 | expression TK_CIRC_EQ expression
1306  {
1307  (void) simplify_C_expression($3);
1308  $$ = MakeBinaryCall(CreateIntrinsic(BITWISE_XOR_UPDATE_OPERATOR_NAME), $1, $3);
1309  }
1310 | expression TK_INF_INF_EQ expression
1311  {
1312  (void) simplify_C_expression($3);
1313  $$ = MakeBinaryCall(CreateIntrinsic(LEFT_SHIFT_UPDATE_OPERATOR_NAME), $1, $3);
1314  }
1315 | expression TK_SUP_SUP_EQ expression
1316  {
1317  (void) simplify_C_expression($3);
1318  $$ = MakeBinaryCall(CreateIntrinsic(RIGHT_SHIFT_UPDATE_OPERATOR_NAME), $1, $3);
1319  }
1320 | TK_LPAREN type_name TK_RPAREN expression
1321  {
1322  $$ = MakeCastExpression($2,$4);
1323  }
1324 /* (* We handle GCC constructor expressions *) */
1325 | TK_LPAREN type_name TK_RPAREN TK_LBRACE initializer_list_opt TK_RBRACE
1326  {
1327  $$ = MakeCastExpression($2,MakeBraceExpression($5));
1328  }
1329 /* (* GCC's address of labels *) */
1330 | TK_AND_AND TK_IDENT
1331  {
1332  CParserError("GCC's address of labels not implemented\n");
1333  }
1334 | TK_AT_EXPR TK_LPAREN TK_IDENT TK_RPAREN /* expression pattern variable */
1335  {
1336  CParserError("GCC's address of labels not implemented\n");
1337  }
1338 ;
1339 
1340 constant:
1341  TK_INTCON
1342  { // Do we know about the size? 2, 4 or 8 bytes?
1343  $$ = make_C_constant_entity($1, is_basic_int, 4);
1344  free($1);
1345  }
1346 | TK_FLOATCON
1347  {
1348  $$ = MakeConstant($1, is_basic_float);
1349  free($1);
1350  }
1351 | TK_COMPLEXCON
1352  {
1353  /* some work left to accomodate imaginary
1354  constants */
1355  $$ = MakeConstant($1, is_basic_float);
1356  free($1);
1357  }
1358 | TK_CHARCON
1359  {
1360  $$ = make_C_constant_entity($1, is_basic_int, 1);
1361  free($1);
1362  }
1363 | string_constant
1364  {
1365  /* The size will be fixed later, hence 0 here. */
1366  $$ = make_C_constant_entity($1, is_basic_string, 0);
1367  free($1);
1368  }
1369 /*add a nul to strings. We do this here (rather than in the lexer) to make
1370  concatenation easy below.*/
1371 | wstring_list
1372  {
1373  $$ = MakeConstant(list_to_string($1),is_basic_string);
1374  free($1);
1375  }
1376 ;
1377 
1378 string_constant:
1379 /* Now that we know this constant isn't part of a wstring, convert it
1380  back to a string for easy viewing. */
1381  string_list
1382  {
1383  /* Hmmm... Looks like a memory leak on all the
1384  strings... */
1385  $$ = list_to_string(gen_nreverse($1));
1386  }
1387 ;
1388 one_string_constant:
1389 /* Don't concat multiple strings. For asm templates. */
1390  TK_STRINGCON
1391  {}
1392 ;
1393 string_list:
1394  one_string
1395  {
1396  $$ = CONS(STRING,$1,NIL);
1397  }
1398 | string_list one_string
1399  {
1400  $$ = CONS(STRING,$2,$1);
1401  }
1402 ;
1403 
1404 wstring_list:
1405  TK_WSTRINGCON
1406  {
1407  $$ = CONS(STRING,$1,NIL);
1408  }
1409 | wstring_list one_string
1410  {
1411  $$ = CONS(STRING,$2,$1);
1412  }
1413 | wstring_list TK_WSTRINGCON
1414  {
1415  $$ = gen_nconc($1,CONS(STRING,$2,NIL));
1416  }
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". */
1419 
1420 one_string:
1421  TK_STRINGCON { }
1422 | TK_FUNCTION__
1423  { CParserError("TK_FUNCTION not implemented\n"); }
1424 | TK_PRETTY_FUNCTION__
1425  { CParserError("TK_PRETTY_FUNCTION not implemented\n"); }
1426 ;
1427 
1428 init_expression:
1429  expression {
1430  expression ie = $1;
1431  /* ifdebug(8) { */
1432  /* fprintf(stderr, "Initialization expression: "); */
1433  /* print_expression(ie); */
1434  /* fprintf(stderr, "\n"); */
1435  /* } */
1436  $$ = ie;
1437  }
1438 | TK_LBRACE initializer_list_opt TK_RBRACE
1439  {
1440  /* Deduce the size of an array by its initialization ?*/
1441  $$ = MakeBraceExpression($2);
1442  }
1443 
1444 initializer_list: /* ISO 6.7.8. Allow a trailing COMMA */
1445  initializer
1446  {
1447  $$ = CONS(EXPRESSION,$1,NIL);
1448  }
1449 | initializer TK_COMMA initializer_list_opt
1450  {
1451  $$ = CONS(EXPRESSION,$1,$3);
1452  }
1453 ;
1454 initializer_list_opt:
1455  /* empty */ { $$ = NIL; }
1456 | initializer_list { }
1457 ;
1458 initializer:
1459  init_designators eq_opt init_expression
1460  {
1461  CParserError("Complicated initialization not implemented\n");
1462  }
1463 | gcc_init_designators init_expression
1464  {
1465  CParserError("gcc init designators not implemented\n");
1466  }
1467 | init_expression { }
1468 ;
1469 eq_opt:
1470  TK_EQ
1471  { }
1472  /*(* GCC allows missing = *)*/
1473 | /*(* empty *)*/
1474  {
1475  CParserError("gcc missing = not implemented\n");
1476  }
1477 ;
1478 init_designators:
1479  TK_DOT id_or_typename init_designators_opt
1480  { }
1481 | TK_LBRACKET expression TK_RBRACKET init_designators_opt
1482  { }
1483 | TK_LBRACKET expression TK_ELLIPSIS expression TK_RBRACKET
1484  { }
1485 ;
1486 init_designators_opt:
1487  /* empty */ { $$ = NIL; }
1488 | init_designators {}
1489 ;
1490 
1491 gcc_init_designators: /*(* GCC supports these strange things *)*/
1492  id_or_typename TK_COLON
1493  {
1494  CParserError("gcc init designators not implemented\n");
1495  }
1496 ;
1497 
1498 arguments:
1499  /* empty */ { $$ = NIL; }
1500 | comma_expression { }
1501 ;
1502 
1503 opt_expression:
1504  /* empty */
1505  { $$ = expression_undefined; } /* This should be a null expression,
1506  not expression_undefined*/
1507 | comma_expression
1508  { $$ = MakeCommaExpression($1); }
1509 ;
1510 
1511 comma_expression:
1512  expression
1513  {
1514  pips_debug(1, "Reduction %d: expression -> comma_expression\n", __LINE__);
1515  (void) simplify_C_expression($1);
1516  $$ = CONS(EXPRESSION,$1,NIL);
1517  }
1518 | expression TK_COMMA comma_expression
1519  {
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);
1523  }
1524 | error TK_COMMA comma_expression
1525  {
1526  CParserError("Parse error: error TK_COMMA comma_expression \n");
1527  }
1528 ;
1529 
1530 comma_expression_opt:
1531  /* empty */ { $$ = NIL; }
1532 | comma_expression { }
1533 ;
1534 
1535 statement_paren_comma_expression:
1536  TK_LPAREN comma_expression TK_RPAREN
1537  {
1538  push_current_C_comment();
1539  push_current_C_line_number();
1540  save_expression_comment_as_statement_comment();
1541  $$ = $2;
1542  }
1543 | TK_LPAREN error TK_RPAREN
1544  {
1545  CParserError("Parse error: TK_LPAREN error TK_RPAREN \n");
1546  }
1547 ;
1548 paren_comma_expression:
1549  TK_LPAREN comma_expression TK_RPAREN
1550  {
1551  if(false) {
1552  push_current_C_comment();
1553  push_current_C_line_number();
1554  }
1555  $$ = $2;
1556  }
1557 | TK_LPAREN error TK_RPAREN
1558  {
1559  CParserError("Parse error: TK_LPAREN error TK_RPAREN \n");
1560  }
1561 ;
1562 
1563 bracket_comma_expression:
1564  TK_LBRACKET comma_expression TK_RBRACKET
1565  {
1566  $$ = $2;
1567  }
1568 | TK_LBRACKET error TK_RBRACKET
1569  {
1570  CParserError("Parse error: TK_LBRACKET error TK_RBRACKET\n");
1571  }
1572 ;
1573 
1574 /*** statements ***/
1575 
1576 statements_inside_block:
1577  TK_LBRACE
1578  { EnterScope();
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();
1585  }
1586 local_labels block_attrs statement_list
1587  {
1588  $$ = MakeBlock($5);
1589  ExitScope();
1590  }
1591 
1592 block: /* ISO 6.8.2 */
1593  statements_inside_block TK_RBRACE
1594  {
1595  $$ = $1;
1596  }
1597 
1598 | error location TK_RBRACE
1599 { abort();CParserError("Parse error: error location TK_RBRACE \n"); }
1600 ;
1601 
1602 
1603 block_attrs:
1604 {}
1605 /*| TK_BLOCKATTRIBUTE paren_attr_list_ne
1606  { CParserError("BLOCKATTRIBUTE not implemented\n"); }*/
1607 ;
1608 
1609 
1610 statement_list:
1611  /* empty */ { $$ = NIL; }
1612 | pragmas {
1613  statement s = make_continue_statement(entity_empty_label());
1614  add_pragma_strings_to_statement(s, gen_nreverse($1),false);
1615  gen_free_list($1);
1616  $$ = CONS(STATEMENT, s, NIL);
1617  }
1618 | statement statement_list
1619  {
1620  $$ = CONS(STATEMENT,$1,$2);
1621  }
1622 /*(* GCC accepts a label at the end of a block *)*/
1623 | label { CParserError("gcc not implemented\n"); }
1624 ;
1625 
1626 local_labels:
1627  /* empty */ {}
1628 | TK_LABEL__ local_label_names TK_SEMICOLON local_labels
1629  { CParserError("LABEL__ not implemented\n"); }
1630 ;
1631 
1632 local_label_names:
1633  TK_IDENT {free($1);}
1634 | TK_IDENT TK_COMMA local_label_names {free($1);}
1635 ;
1636 
1637 label:
1638  TK_IDENT TK_COLON
1639  {
1640  // Push the comment associated with the label:
1641  push_current_C_comment();
1642  $$ = $1;
1643  }
1644 ;
1645 
1646 
1647 pragma:
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);
1654  $$ = $3;
1655  }
1656 | TK_PRAGMA {
1657  pips_debug(1, "Found #pragma %s\n", c_lval.string);
1658  $$ = c_lval.string;
1659  }
1660 ;
1661 
1662 
1663 pragmas:
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);
1667  }
1668 | pragma pragmas {
1669  /* Concatenate the pragma to the list of pragmas */
1670  $$ = CONS(STRING,$1,$2);
1671 }
1672 ;
1673 
1674 
1675 /* To avoid shift-reduce conflict, enumerate statement with and without pragma: */
1676 statement: pragmas statement_without_pragma
1677 {
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: */
1682  gen_free_list($1);
1683  $$ = $2;
1684  reset_token_has_been_seen_p();
1685 }
1686 | statement_without_pragma {
1687  $$ = $1;
1688  reset_token_has_been_seen_p();
1689  }
1690 ;
1691 
1692 
1693 statement_without_pragma:
1694  TK_SEMICOLON
1695  {
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;
1705  $$ = s;
1706  }
1707 | comma_expression TK_SEMICOLON
1708  {
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)));
1715  gen_free_list($1);
1716  }
1717  else {
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();
1725  }
1726  $$ = flush_expression_comment(s);
1727  }
1728 | block { }
1729 | declaration {
1730  /* In C99 we can have a declaration anywhere!
1731 
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
1736  this... */
1737  pips_debug(1, "Reduction %d: declaration -> statement_without_pragma\n", __LINE__);
1738  list sl = $1;
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));
1742  }
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);
1750 }
1751 | TK_IF statement_paren_comma_expression statement %prec TK_IF
1752  {
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($$);
1760  }
1761 | TK_IF statement_paren_comma_expression statement TK_ELSE statement
1762  {
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($$);
1769  }
1770 | TK_SWITCH
1771  {
1772  stack_push((char *) make_sequence(NIL),SwitchGotoStack);
1773  stack_push((char *) make_basic_int(loop_counter++), LoopStack);
1774  /* push_current_C_comment(); */
1775  }
1776  statement_paren_comma_expression
1777  {
1778  stack_push((char *)MakeCommaExpression($3),SwitchControllerStack);
1779  }
1780  statement
1781  {
1782 
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);
1791  }
1792 | TK_WHILE
1793  {
1794  stack_push((char *) make_basic_int(loop_counter++), LoopStack);
1795  /* push_current_C_comment(); */
1796  }
1797  statement_paren_comma_expression statement
1798  {
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);
1806  }
1807 | TK_DO
1808  {
1809  stack_push((char *) make_basic_int(loop_counter++), LoopStack);
1810  /* push_current_C_comment(); */
1811  }
1812  statement TK_WHILE statement_paren_comma_expression TK_SEMICOLON
1813  {
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);
1819  }
1820 | for_clause
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
1826  {
1827  /* Save the comments agregated in the for close up to now: */
1828  push_current_C_comment();
1829  }
1830  TK_RPAREN
1831  statement
1832  {
1833  $$ = MakeForloop($2, $4, $6, $9);
1834  $$=flush_expression_comment($$);
1835  }
1836 | for_clause /* A C99 for loop with a declaration in it */
1837  {
1838  /* We need a new variable scope to avoid
1839  conflict names between the loop index and
1840  some previous upper declarations: */
1841  EnterScope();
1842  }
1843  declaration
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
1848  {
1849  /* Save the comments agregated in the for close up to now: */
1850  push_current_C_comment();
1851  }
1852  statement
1853  {
1854  $$ = MakeForloopWithIndexDeclaration($3, $4, $6, $9);
1855  $$=flush_expression_comment($$);
1856  ExitScope();
1857  }
1858 | label statement
1859  {
1860  /* Create the statement with label comment in
1861  front of it: */
1862  $$ = MakeLabeledStatement($1,$2, pop_current_C_comment());
1863  free($1);
1864  /* ifdebug(8) { */
1865  /* pips_debug(8,"Adding label '%s' to statement:\n", $1); */
1866  /* print_statement($$); */
1867  /* } */
1868  }
1869 | TK_CASE expression TK_COLON
1870  {
1871  $$ = MakeCaseStatement($2);
1872  }
1873 | TK_CASE expression TK_ELLIPSIS expression TK_COLON
1874  {
1875  CParserError("case e1..e2 : not implemented\n");
1876  }
1877 | TK_DEFAULT TK_COLON
1878  {
1879  $$ = MakeDefaultStatement();
1880  }
1881 | TK_RETURN TK_SEMICOLON
1882  {
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());
1892  else
1893  $$ = C_MakeReturnStatement(NIL,
1894  get_current_C_line_number(),
1895  get_current_C_comment());
1896  /*
1897  $$ = make_statement(entity_empty_label(),
1898  get_current_C_line_number(),
1899  STATEMENT_ORDERING_UNDEFINED,
1900  get_current_C_comment(),
1901  C_MakeReturn(NIL),
1902  NIL,
1903  string_undefined,
1904  empty_extensions());
1905  */
1906 
1907  statement_consistent_p($$);
1908  }
1909 | TK_RETURN comma_expression TK_SEMICOLON
1910  {
1911  /* $$ = call_to_statement(make_call(CreateIntrinsic(C_RETURN_FUNCTION_NAME),$2)); */
1912  list el = $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);
1917  }
1918  else if(gen_length(el)==1)
1919  res = EXPRESSION(CAR($2));
1920 
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? */
1929  /*
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");
1934  */
1935  }
1936  }
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());
1945  else
1946  $$ = C_MakeReturnStatement(el,
1947  get_current_C_line_number(),
1948  get_current_C_comment());
1949  /*
1950  $$ = make_statement(entity_empty_label(),
1951  get_current_C_line_number(),
1952  STATEMENT_ORDERING_UNDEFINED,
1953  get_current_C_comment(),
1954  C_MakeReturn($2),
1955  NIL,
1956  string_undefined,
1957  empty_extensions());
1958  */
1959  $$=flush_expression_comment($$);
1960  statement_consistent_p($$);
1961  }
1962 | TK_BREAK TK_SEMICOLON
1963  {
1964  $$ = MakeBreakStatement(get_current_C_comment());
1965  }
1966 | TK_CONTINUE TK_SEMICOLON
1967  {
1968  $$ = MakeContinueStatement(get_current_C_comment());
1969  }
1970 | TK_GOTO TK_IDENT TK_SEMICOLON
1971  {
1972  $$ = MakeGotoStatement($2);
1973  free($2);
1974  }
1975 | TK_GOTO TK_STAR comma_expression TK_SEMICOLON
1976  {
1977  CParserError("GOTO * exp not implemented\n");
1978  }
1979 | TK_ASM asmattr TK_LPAREN string_constant asmoutputs TK_RPAREN TK_SEMICOLON
1980  {
1981  call c = make_call(
1982  entity_intrinsic(ASM_FUNCTION_NAME),
1983  CONS(EXPRESSION,entity_to_expression(
1984  make_C_constant_entity($4, is_basic_string, 0)
1985  ),NIL)
1986  );
1987  free($4);
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());
1996  }
1997 | TK_MSASM
1998  { CParserError("ASM not implemented\n"); }
1999 | error location TK_SEMICOLON
2000  {
2001  CParserError("Parse error: error location TK_SEMICOLON\n");
2002  }
2003 ;
2004 
2005 
2006 for_clause:
2007  TK_FOR
2008  {
2009  /* Number the loops in prefix depth-first: */
2010  stack_push((char *) make_basic_int(loop_counter++),
2011  LoopStack);
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
2018  before the for.
2019 
2020  Issue trigered by several examples such as
2021  validation/Semantics-New/do01.tpips
2022 
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
2028  on.
2029  */
2030  push_current_C_comment();
2031  }
2032  TK_LPAREN
2033 ;
2034 
2035 
2036 declaration: /* ISO 6.7.*/
2037  decl_spec_list init_declarator_list TK_SEMICOLON
2038  {
2039  pips_debug(1, "Reduction %d: decl_spec_list init_declarator_list TK_SEMICOLON -> declaration\n", __LINE__);
2040 
2041  list el1 = $1;
2042  list el2 = $2;
2043  list el12 = gen_nconc(el1,el2);
2044  statement s = statement_undefined;
2045 
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));
2049 
2050  if(!ENDP(el12)) {
2051  list el0 = GetDerivedEntityDeclarations();
2052  FOREACH(ENTITY, e, el0) {
2053  if(!gen_in_list_p(e, el12))
2054  el12 = CONS(ENTITY, e, el12);
2055  }
2056  gen_free_list(el0);
2057 
2058  ifdebug(8) {
2059  fprintf(stderr, "At %d, make_declarations_statement for ", __LINE__);
2060  print_entities(el12);
2061  fprintf(stderr, "\n");
2062  }
2063 
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);
2068 
2069  ifdebug(1) {
2070  fprintf(stderr, "New declaration statement for entities: ");
2071  print_entities(el12);
2072  fprintf(stderr, "\n");
2073  }
2074  pips_assert("no duplicate declaration",
2075  gen_once_p(el12));
2076  }
2077  else {
2078  pips_internal_error("Unexpected case");
2079  }
2080 
2081  UpdateEntities(el2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,true);
2082  PopContext();
2083  remove_entity_type_stacks(el12);
2084  CleanUpEntities(el12);
2085  $$ = CONS(STATEMENT,s,NIL);
2086  reset_token_has_been_seen_p();
2087  }
2088 | decl_spec_list TK_SEMICOLON
2089  {
2090  pips_debug(1, "Reduction %d: decl_spec_list TK_SEMICOLON -> declaration\n", __LINE__);
2091  list dl = $1;
2092  FOREACH(ENTITY, e, dl) {
2093  value v = entity_initial(e);
2094  if(value_undefined_p(v))
2095  entity_initial(e) = make_value_unknown();
2096  }
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);
2106  PopContext();
2107  ResetDerivedEntityDeclarations();
2108  $$ = CONS(STATEMENT,s, NIL);
2109  BREAKPOINT;
2110  }
2111 ;
2112 
2113 init_declarator_list: /* ISO 6.7 */
2114  init_declarator
2115  {
2116 
2117  $$ = CONS(ENTITY,$1,NIL);
2118  }
2119 | init_declarator TK_COMMA init_declarator_list
2120  {
2121  $$ = CONS(ENTITY,$1,$3);
2122  }
2123 
2124 ;
2125 init_declarator: /* ISO 6.7 */
2126  declarator {
2127  /* The default initial value is often zero,
2128  but not so for formal parameters or
2129  functions */
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));
2134  }
2135 | declarator TK_EQ init_expression
2136  {
2137  entity v = $1;
2138  expression nie = $3;
2139 
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");
2145  }
2146  else {
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");
2152  }
2153  }
2154 ;
2155 
2156 decl_spec_list:
2157  {
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));
2162  }
2163  else {
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
2168  qualifiers */
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
2177  the stack state */
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!*/
2187  //c_parse
2188  //r_context_scope(ycontext) = empty_scope();
2189 
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
2195  them.
2196 
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
2200  scope first.
2201  */
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();
2206  }
2207  pips_debug(8, "new context %p with scope \"%s\" copied from context %p (stack size=%d)\n",
2208  ycontext,
2209  c_parser_context_scope(ycontext),
2210  stack_head(ContextStack),
2211  stack_size(ContextStack));
2212  }
2213  }
2214 my_decl_spec_list {pips_debug(1, "Reduction %d: my_decl_spec_list -> decl_spec_list\n", __LINE__); $$ = $2;}
2215 ;
2216 
2217 my_decl_spec_list: /* ISO 6.7 */
2218  /* ISO 6.7.1 */
2219  TK_TYPEDEF decl_spec_list_opt
2220  {
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));
2226  $$ = $2;
2227  }
2228 | TK_EXTERN decl_spec_list_opt
2229  {
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();
2248  $$ = $2;
2249  }
2250 | TK_STATIC decl_spec_list_opt
2251  {
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));
2255  $$ = $2;
2256  }
2257 | TK_THREAD decl_spec_list_opt
2258  {
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));
2263  $$ = $2;
2264  }
2265 | TK_AUTO decl_spec_list_opt
2266  {
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));
2271  $$ = $2;
2272  }
2273 | TK_REGISTER decl_spec_list_opt
2274  {
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));
2279  $$ = $2;
2280  }
2281  /* ISO 6.7.2 */
2282 | type_spec decl_spec_list_opt_no_named
2283  {
2284  pips_debug(1, "Reduction %d: type_spec decl_spec_list_opt_no_named -> my_decl_spec_list\n", __LINE__);
2285  BREAKPOINT;
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));
2294  if(ENDP(el)) {
2295  rl = sl;
2296  }
2297  else if(ENDP(sl)) {
2298  //BREAKPOINT;
2299  rl = el;
2300  ifdebug(8) {
2301  //pips_debug(8, "New declaration statement for entities:\n");
2302  print_entities(el);
2303  fprintf(stderr, "\n");
2304  }
2305  }
2306  else if(gen_length(sl)==1) {
2307  // FI: I'm not sure it ever happens
2308  // statement s = STATEMENT(CAR(sl));
2309  ifdebug(8) {
2310  //pips_debug(8, "Previous (unexpected) continue statement for entities: ");
2311  //print_entities(statement_declarations(s));
2312  print_entities(el);
2313  fprintf(stderr, "\n");
2314  pips_debug(8, "New entities added: ");
2315  print_entities(el);
2316  fprintf(stderr, "\n");
2317  // rl = sl;
2318  }
2319  //statement_declarations(s) =
2320  //gen_nconc(el, statement_declarations(s));
2321  rl = gen_nconc(el, sl);
2322  }
2323  else {
2324  pips_internal_error("Multiple statements not expected\n");
2325  /* statement s = */
2326  /* make_continue_statement(entity_empty_label()); */
2327  /* statement_declarations(s) = el; */
2328  // $$ = gen_nconc($1,$2);
2329  //$$ = $2;
2330  //rl = gen_nconc(CONS(STATEMENT, s, NIL),sl);
2331  }
2332  $$ = rl;
2333  }
2334  /* ISO 6.7.4 */
2335 | TK_INLINE decl_spec_list_opt
2336  {
2337  c_parser_user_warning("Keyword \"inline\" ignored\n");
2338  pips_assert("Entity list for declarations", entities_p($2));
2339  $$ = $2;
2340  }
2341 | attribute decl_spec_list_opt
2342  {
2343  list ql = c_parser_context_qualifiers(ycontext);
2344  qualifier nq = $1;
2345 
2346  c_parser_context_qualifiers(ycontext)
2347  = insert_qualifier(ql, nq);
2348 
2349  pips_assert("Entity list for declarations", entities_p($2));
2350  $$ = $2;
2351  }
2352 /* specifier pattern variable (must be last in spec list) */
2353 | TK_AT_SPECIFIER TK_LPAREN TK_IDENT TK_RPAREN
2354  {
2355  CParserError("CIL AT not implemented\n");
2356  }
2357 ;
2358 
2359 /* (* In most cases if we see a NAMED_TYPE we must shift it. Thus we declare
2360  * NAMED_TYPE to have right associativity *) */
2361 decl_spec_list_opt:
2362  /* empty */
2363  {
2364  //stack_push((char *) ycontext, ContextStack);
2365  PushContext(ycontext);
2366  $$ = NIL;
2367  } %prec TK_NAMED_TYPE
2368 | my_decl_spec_list { }
2369 ;
2370 
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 *)
2374  */
2375 decl_spec_list_opt_no_named:
2376  /* empty */
2377  {
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);
2386  else {
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));
2391  free(stf);
2392  PushContext(ycontext);
2393  }
2394  $$ = NIL;
2395  } %prec TK_IDENT
2396 | my_decl_spec_list {pips_debug(1, "Reduction %d: my_decl_spec_list -> decl_spec_list_opt_no_named\n", __LINE__);
2397  }
2398 ;
2399 
2400 
2401 type_spec: /* ISO 6.7.2 */
2402  TK_VOID
2403  {
2404  c_parser_context_type(ycontext) = make_type_void(NIL);
2405  $$ = NIL;
2406  }
2407 | TK_CHAR
2408  {
2409  c_parser_context_type(ycontext) = make_standard_integer_type(c_parser_context_type(ycontext),
2410  DEFAULT_CHARACTER_TYPE_SIZE);
2411  $$ = NIL;
2412  }
2413 | TK_SHORT
2414  {
2415  c_parser_context_type(ycontext) = make_standard_integer_type(c_parser_context_type(ycontext),
2416  DEFAULT_SHORT_INTEGER_TYPE_SIZE);
2417  $$ = NIL;
2418  }
2419 | TK_INT
2420  {
2421  pips_debug(1, "Reduction %d: TK_INT -> type_spec\n", __LINE__);
2422  if (c_parser_context_type(ycontext) == type_undefined)
2423  {
2424  variable v = make_variable(make_basic_int(DEFAULT_INTEGER_TYPE_SIZE),NIL,NIL);
2425  c_parser_context_type(ycontext) = make_type_variable(v);
2426  }
2427  $$ = NIL;
2428  }
2429 | TK_INT128
2430  {
2431  pips_debug(1, "Reduction %d: TK_INT128 -> type_spec\n", __LINE__);
2432  if (c_parser_context_type(ycontext) == type_undefined)
2433  {
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);
2436  }
2437  $$ = NIL;
2438  }
2439 | TK_UINT128
2440  {
2441  pips_debug(1, "Reduction %d: TK_UINT128 -> type_spec\n", __LINE__);
2442  if (c_parser_context_type(ycontext) == type_undefined)
2443  {
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);
2446  }
2447  $$ = NIL;
2448  }
2449 | TK_COMPLEX
2450  {
2451  if (c_parser_context_type(ycontext) == type_undefined)
2452  {
2453  variable v = make_variable(make_basic_complex(DEFAULT_COMPLEX_TYPE_SIZE),NIL,NIL);
2454  c_parser_context_type(ycontext) = make_type_variable(v);
2455  }
2456  else {
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);
2461 
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;
2468  }
2469  }
2470  $$ = NIL;
2471  }
2472 | TK_LONG
2473  {
2474  c_parser_context_type(ycontext) = make_standard_long_integer_type(c_parser_context_type(ycontext));
2475  $$ = NIL;
2476  }
2477 | TK_FLOAT
2478  {
2479  variable v = make_variable(make_basic_float(DEFAULT_REAL_TYPE_SIZE),NIL,NIL);
2480  c_parser_context_type(ycontext) = make_type_variable(v);
2481  $$ = NIL;
2482  }
2483 | TK_DOUBLE
2484  {
2485  variable v = variable_undefined;
2486  type t = c_parser_context_type(ycontext);
2487 
2488  if(type_undefined_p(t))
2489  v = make_variable(make_basic_float(DEFAULT_DOUBLEPRECISION_TYPE_SIZE),NIL,NIL);
2490  else {
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"
2493 );
2494  v = make_variable(make_basic_complex(DEFAULT_DOUBLECOMPLEX_TYPE_SIZE), NIL, NIL);
2495  }
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);
2500  else
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);
2505  free_type(t);
2506  }
2507  c_parser_context_type(ycontext) = make_type_variable(v);
2508  $$ = NIL;
2509  }
2510 | TK_SIGNED
2511  {
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);
2521  else
2522  pips_internal_error("???");
2523  }
2524  variable v = make_variable(make_basic_int(DEFAULT_SIGNED_TYPE_SIZE*10+
2525  size),NIL,NIL);
2526  c_parser_context_type(ycontext) = make_type_variable(v);
2527  $$ = NIL;
2528  }
2529 | TK_UNSIGNED
2530  {
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);
2539  else
2540  pips_internal_error("???");
2541  }
2542  variable v = make_variable(make_basic_int(DEFAULT_UNSIGNED_TYPE_SIZE*10+
2543  size),NIL,NIL);
2544  c_parser_context_type(ycontext) = make_type_variable(v);
2545  $$ = NIL;
2546  }
2547 | TK_STRUCT id_or_typename
2548  {
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);
2574  }
2575  else {
2576  add_initialization_expression(0);
2577  dl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2578  }
2579  $$ = dl;
2580  }
2581 | TK_STRUCT id_or_typename TK_LBRACE
2582  {
2583  code c = make_code(NIL,$2,sequence_undefined,NIL, make_language_c());
2584  stack_push((char *) c, StructNameStack);
2585  }
2586  struct_decl_list TK_RBRACE
2587  {
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
2590  derived entities */
2591  list fl = $5;
2592  /* Create the struct entity */
2593  entity ent = MakeDerivedEntity($2,fl,is_external,is_type_struct);
2594  /* Record the declaration of the struct
2595  entity */
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));
2610  }
2611  c_parser_context_type(ycontext) = make_type_variable(v);
2612  stack_pop(StructNameStack);
2613  BREAKPOINT;
2614  //add_initialization_expression(1);
2615  $$ = rl;
2616  }
2617 | TK_STRUCT TK_LBRACE
2618  {
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());
2622  free(istr);
2623  stack_push((char *) c, StructNameStack);
2624  }
2625  struct_decl_list TK_RBRACE
2626  {
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));
2630  list el = $4;
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);
2640  BREAKPOINT;
2641  //add_initialization_expression(1);
2642  $$ = rl;
2643  }
2644 | TK_UNION id_or_typename
2645  {
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);
2662  }
2663  else {
2664  add_initialization_expression(0);
2665  dl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2666  }
2667  //list dl = CONS(ENTITY, ent, NIL);
2668  $$ = dl;
2669  }
2670 | TK_UNION id_or_typename TK_LBRACE
2671  {
2672  code c = make_code(NIL,$2,sequence_undefined, NIL, make_language_c());
2673  stack_push((char *) c, StructNameStack);
2674  }
2675  struct_decl_list TK_RBRACE
2676  {
2677  list fl = $5;
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);
2690  $$ = rl;
2691  }
2692 | TK_UNION TK_LBRACE
2693  {
2694  string n = int2a(derived_counter++);
2695  code c = make_code(NIL,
2696  strdup(concatenate(DUMMY_UNION_PREFIX,n,NULL)),
2697  sequence_undefined,
2698  NIL,
2699  make_language_c());
2700  free(n);
2701  stack_push((char *) c, StructNameStack);
2702  }
2703  struct_decl_list TK_RBRACE
2704  {
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);
2719  $$ = rl;
2720  }
2721 | TK_ENUM id_or_typename
2722  {
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());
2738  else {
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. */
2744  ;
2745  }
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);
2753  }
2754  else {
2755  add_initialization_expression(0);
2756  dl = CONS(ENTITY,ent,CONS(ENTITY, phv, NIL));
2757  }
2758  //list dl = CONS(ENTITY, ent, NIL);
2759  $$ = dl;
2760  }
2761 | TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE
2762  {
2763  pips_debug(1, "Reduction %d: TK_ENUM id_or_typename TK_LBRACE enum_list maybecomma TK_RBRACE -> type_spec\n", __LINE__);
2764  string en = $2;
2765  list ml = $4;
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);
2770 
2771  InitializeEnumMemberValues(ml);
2772  c_parser_context_type(ycontext) = make_type_variable(v);
2773  list rl = CONS(ENTITY, ent, NIL);
2774  $$ = rl;
2775  }
2776 | TK_ENUM TK_LBRACE enum_list maybecomma TK_RBRACE
2777  {
2778  /* Create the enum entity with unique name */
2779  string n = int2a(derived_counter++);
2780  string s = strdup(concatenate(DUMMY_ENUM_PREFIX,n,NULL));
2781  free(n);
2782  entity ent = MakeDerivedEntity(s,$3,is_external,is_type_enum);
2783  variable v = make_variable(make_basic_derived(ent),NIL,NIL);
2784 
2785  InitializeEnumMemberValues($3);
2786  c_parser_context_type(ycontext) = make_type_variable(v);
2787  $$ = CONS(ENTITY,ent,NIL);
2788  }
2789 | TK_NAMED_TYPE
2790  {
2791  entity ent;
2792  ent = FindOrCreateEntityFromLocalNameAndPrefix($1,TYPEDEF_PREFIX,is_external);
2793 
2794  /* Specify the type of the variable that follows this declaration specifier */
2795  if (c_parser_context_typedef(ycontext))
2796  {
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);
2801  }
2802  else
2803  {
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);
2808  $$ = NIL;
2809  }
2810 
2811  }
2812 | TK_TYPEOF TK_LPAREN expression TK_RPAREN
2813  {
2814  CParserError("TYPEOF not implemented\n");
2815  }
2816 | TK_TYPEOF TK_LPAREN type_name TK_RPAREN
2817  {
2818  CParserError("TYPEOF not implemented\n");
2819  }
2820 ;
2821 
2822 struct_decl_list: /* (* ISO 6.7.2. Except that we allow empty structs. We
2823  * also allow missing field names. *)
2824  */
2825 /* empty */ { pips_debug(1, "Reduction %d: empty -> struct_decl_list\n", __LINE__); $$ = NIL; }
2826 | decl_spec_list TK_SEMICOLON struct_decl_list
2827  {
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)),
2838  is_external);
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);
2843  free(s);
2844 
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;
2850 
2851  $$ = CONS(ENTITY,ent,$3);
2852 
2853  //stack_pop(ContextStack);
2854  PopContext();
2855  }
2856 | decl_spec_list
2857  {
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);
2864  free(stf);
2865  c_parser_context_storage(ycontext) = make_storage_rom();
2866  }
2867  field_decl_list TK_SEMICOLON struct_decl_list
2868  {
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*/
2871 
2872  UpdateDerivedEntities($1,$3,ContextStack);
2873 
2874  /* Create the list of member entities */
2875  list l1 = $3;
2876  list l2 = $5;
2877  list nl2 = NIL;
2878  FOREACH(ENTITY, e, l2) {
2879  if(!gen_in_list_p(e, l1))
2880  nl2 = CONS(ENTITY, e, nl2);
2881  }
2882  nl2 = gen_nreverse(nl2);
2883  list rl = gen_nconc(l1, nl2);
2884  gen_free_list(l2);
2885  $$ = rl;
2886  PopContext();
2887 
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.
2892 
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;
2898  }
2899 | error TK_SEMICOLON struct_decl_list
2900  {
2901  CParserError("Parse error: error TK_SEMICOLON struct_decl_list\n");
2902  }
2903 ;
2904 
2905 field_decl_list: /* (* ISO 6.7.2 *) */
2906  field_decl
2907  {
2908  entity f = $1;
2909  $$ = CONS(ENTITY, f,NIL);
2910  }
2911 | field_decl TK_COMMA field_decl_list
2912  {
2913  entity f = $1;
2914  $$ = CONS(ENTITY,f,$3);
2915  }
2916 ;
2917 
2918 field_decl: /* (* ISO 6.7.2. Except that we allow unnamed fields. *) */
2919  declarator
2920  {
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. */
2925  entity e = $1;
2926  type t = entity_type(e);
2927 
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);
2932 
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;
2945  }
2946  }
2947  }
2948 
2949  $$ = e;
2950  }
2951 | declarator TK_COLON expression
2952  {
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);
2958 
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);
2963  $$ = $1;
2964  }
2965 | TK_COLON expression
2966  {
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);
2981  free(n);
2982  $$ = ent;
2983  }
2984 ;
2985 
2986 enum_list: /* (* ISO 6.7.2.2 *) */
2987  enumerator
2988  {
2989  /* initial_value = 0 or $3*/
2990  $$ = CONS(ENTITY,$1,NIL);
2991  enum_counter = 1;
2992  }
2993 | enum_list TK_COMMA enumerator
2994  {
2995  /* Attention to the reverse recursive definition*/
2996  $$ = gen_nconc($1,CONS(ENTITY,$3,NIL));
2997  enum_counter ++;
2998  }
2999 | enum_list TK_COMMA error
3000  {
3001  CParserError("Parse error: enum_list TK_COMMA error\n");
3002  }
3003 ;
3004 
3005 enumerator:
3006  TK_IDENT
3007  {
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
3011 
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 */
3014 
3015  entity ent = CreateEntityFromLocalNameAndPrefix($1,"",is_external);
3016  free($1);
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);
3020 
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);*/
3029  $$ = ent;
3030  }
3031 | TK_IDENT TK_EQ expression
3032  {
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 */
3036  //int i;
3037  value vinit = value_undefined;
3038  entity ent = CreateEntityFromLocalNameAndPrefix($1,"",is_external);
3039  free($1);
3040  variable v =
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);
3044 
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);
3051 
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)));
3055  }
3056  else {
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 */
3059  bool is_ok = false;
3060  if(expression_call_p($3)) {
3061  call c = syntax_call(expression_syntax($3));
3062  entity m = call_function(c);
3063 
3064  if(entity_symbolic_p(m)) {
3065  is_ok = true;
3066  }
3067  }
3068  if(is_ok)
3069  entity_initial(ent) =
3070  make_value_symbolic(make_symbolic($3, make_constant_unknown()));
3071  else {
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");
3076  }
3077  }
3078 
3079  $$ = ent;
3080  }
3081 ;
3082 
3083 declarator: /* (* ISO 6.7.5. Plus Microsoft declarators.*) */
3084  pointer_opt direct_decl attributes_with_asm
3085  {
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(
3092  make_variable(
3093  basic_undefined,
3094  NIL,
3095  $3
3096  )
3097  );
3098  }
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);
3102  }
3103  else {
3104  c_parser_user_warning("some _asm(..) attributes are going to be lost for entity `%s'\n",entity_name($2));
3105  }
3106  }
3107  $$ = $2;
3108  }
3109 ;
3110 
3111 direct_decl: /* (* ISO 6.7.5 *) */
3112  /* (* We want to be able to redefine named
3113  * types as variable names *) */
3114  id_or_typename
3115  {
3116  /* FI: A variable cannot be redeclared
3117  within the same scope, but this is not
3118  checked yet. */
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);
3136  }
3137  else {
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 */
3147  if(cm!=e) {
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");
3155  }
3156  else {
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)*/);
3161  }
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)*/);
3165  }
3166  else {
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");
3171  }
3172  }
3173  }
3174  }
3175 
3176  entity_type(e) = type_undefined;
3177  //discard_C_comment();
3178  //push_current_C_comment();
3179  $$ = e;
3180  }
3181 | TK_LPAREN attributes declarator TK_RPAREN
3182  {
3183  /* Add attributes such as const, restrict, ... to variable's qualifiers */
3184  UpdateParenEntity($3, $2);
3185  $$ = $3;
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;
3193  }
3194 | direct_decl TK_LBRACKET attributes comma_expression_opt TK_RBRACKET
3195  {
3196  /* This is the last dimension of an array (i.e a[1][2][3] => [3]).
3197  Questions:
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*/
3202  list el = $4;
3203  if(gen_length(el)<=1)
3204  UpdateArrayEntity($1,$3,el);
3205  else {
3206  expression d = MakeCommaExpression(el);
3207  UpdateArrayEntity($1,$3,CONS(EXPRESSION, d, NIL));
3208  }
3209  }
3210 | direct_decl TK_LBRACKET attributes error TK_RBRACKET
3211  {
3212  CParserError("Parse error: direct_decl TK_LBRACKET attributes error TK_RBRACKET\n");
3213  }
3214 | direct_decl parameter_list_startscope
3215  {
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
3225  unknown... */
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();
3228  }
3229  //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3230  PushFunction(e);
3231  }
3232  rest_par_list TK_RPAREN
3233  {
3234  entity m = get_current_module_entity();
3235  entity e = GetFunction();
3236  entity ne = e;
3237  pips_assert("ne is an entity",
3238  entity_domain_number(ne)==entity_domain);
3239  PopFunction();
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);
3255  }
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
3263  global or local. */
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
3269  */
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);
3275  }
3276  $$ = ne;
3277  };
3278 
3279 parameter_list_startscope:
3280  TK_LPAREN
3281  {
3282  stack_push((char *) make_basic_logical(true), FormalStack);
3283  stack_push((char *) make_basic_int(1),OffsetStack);
3284  }
3285 ;
3286 
3287 rest_par_list:
3288  /* empty */ { $$ = NIL; }
3289 | parameter_decl rest_par_list1
3290  {
3291  $$ = CONS(PARAMETER,$1,$2);
3292  }
3293 ;
3294 rest_par_list1:
3295  /* empty */ { $$ = NIL; }
3296 | TK_COMMA
3297  {
3298  StackPush(OffsetStack);
3299  }
3300  TK_ELLIPSIS
3301  {
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),
3306  NIL, NIL));
3307  $$ = CONS(PARAMETER,
3308  make_parameter(make_type_varargs(at),
3309  make_mode(CurrentMode,UU),
3310  make_dummy_unknown()),
3311  NIL);
3312  }
3313 | TK_COMMA
3314  {
3315  StackPush(OffsetStack);
3316  }
3317  parameter_decl rest_par_list1
3318  {
3319  $$ = CONS(PARAMETER,$3,$4);
3320  }
3321 ;
3322 
3323 parameter_decl: /* (* ISO 6.7.5 *) */
3324  decl_spec_list declarator
3325  {
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);
3333  PopContext();
3334  }
3335 | decl_spec_list abstract_decl
3336  {
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);
3343  free_entity($2);
3344  //stack_pop(ContextStack);
3345  PopContext();
3346  }
3347 | decl_spec_list
3348  {
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);
3355  PopContext();
3356  }
3357 | TK_LPAREN parameter_decl TK_RPAREN
3358  { $$ = $2; }
3359 ;
3360 
3361 /* (* Old style prototypes. Like a declarator *) */
3362 old_proto_decl:
3363  pointer_opt direct_old_proto_decl
3364  {
3365  if (!type_undefined_p($1))
3366  UpdatePointerEntity($2,$1,NIL);
3367  $$ = $2;
3368  }
3369 ;
3370 
3371 direct_old_proto_decl:
3372  direct_decl TK_LPAREN
3373  {
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)));
3378  PushFunction(e);
3379  stack_push((char *) make_basic_logical(true),FormalStack);
3380  stack_push((char *) make_basic_int(1),OffsetStack);
3381  }
3382  old_parameter_list_ne TK_RPAREN old_pardef_list
3383  {
3384  entity e = GetFunction();
3385  list paras = MakeParameterList($4,$6,FunctionStack);
3386  PopFunction();
3387  stack_pop(FormalStack);
3388  StackPop(OffsetStack);
3389  (void) UpdateFunctionEntity(e, paras);
3390  //CreateReturnEntity(e);
3391  gen_free_list($4);
3392  $$ = e;
3393  }
3394 /* Never used because of conflict
3395 | direct_decl TK_LPAREN TK_RPAREN
3396  {
3397  (void) UpdateFunctionEntity($1,NIL);
3398  }
3399 */
3400 ;
3401 
3402 old_parameter_list_ne:
3403  TK_IDENT
3404  {
3405  $$ = CONS(STRING,$1,NIL);
3406  }
3407 | TK_IDENT TK_COMMA old_parameter_list_ne
3408  {
3409  $$ = CONS(STRING,$1,$3);
3410  }
3411 ;
3412 
3413 old_pardef_list:
3414  /* empty */ { $$ = NIL; }
3415 | decl_spec_list old_pardef TK_SEMICOLON TK_ELLIPSIS
3416  {
3417  UpdateEntities($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external,false);
3418  //stack_pop(ContextStack);
3419  PopContext();
3420  /* Can we have struct/union definition in $1 ?*/
3421  /*$$ = gen_nconc($1,$2);*/
3422  $$ = $2;
3423  }
3424 | decl_spec_list old_pardef TK_SEMICOLON old_pardef_list
3425  {
3426  /* Rule used for C_syntax/activate.c,
3427  decl33.c and adi.c. CreateReturnEntity()
3428  only useful for activate.c */
3429  list el = $2;
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);
3437  PopContext();
3438  /* Can we have struct/union definition in $1 ?*/
3439  /*$$ = gen_nconc($1,gen_nconc(el,$4));*/
3440  $$ = gen_nconc(el,$4);
3441  }
3442 ;
3443 
3444 old_pardef:
3445  declarator
3446  {
3447  $$ = CONS(ENTITY,$1,NIL);
3448  }
3449 | declarator TK_COMMA old_pardef
3450  {
3451  $$ = CONS(ENTITY,$1,$3);
3452  }
3453 | error
3454  {
3455  CParserError("Parse error: error \n");
3456  }
3457 ;
3458 
3459 pointer: /* (* ISO 6.7.5 *) */
3460  TK_STAR attributes pointer_opt
3461  { /* decl24.c, decl50.c, decl51.c, decl52.c,
3462  decl53.c :
3463  const attribute lost or misplaced for pointers */
3464  list al = $2;
3465  type t = $3;
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;
3470  }
3471 ;
3472 
3473 pointer_opt:
3474  /* empty */ { $$ = type_undefined;}
3475 | pointer { }
3476 ;
3477 
3478 type_name: /* (* ISO 6.7.6 *) */
3479  decl_spec_list abstract_decl
3480  {
3481  entity e = $2;
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);
3488  gen_free_list(el);
3489  free_entity(e);
3490  //stack_pop(ContextStack);
3491  PopContext();
3492  }
3493 | decl_spec_list
3494  {
3495  c_parser_context ycontext = stack_head(ContextStack);
3496  $$ = c_parser_context_type(ycontext);
3497  //stack_pop(ContextStack);
3498  PopContext();
3499  }
3500 ;
3501 
3502 abstract_decl: /* (* ISO 6.7.6. *) */
3503  pointer_opt abs_direct_decl attributes
3504  {
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);
3508  $$ = $2;
3509  }
3510 | pointer
3511  {
3512  string n = int2a(abstract_counter++);
3513  entity e = FindOrCreateCurrentEntity(strdup(concatenate(DUMMY_ABSTRACT_PREFIX,
3514  n,NULL)),
3515  ContextStack,
3516  FormalStack,
3517  FunctionStack,
3518  is_external);
3519  free(n);
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;*/
3531  $$ = e;
3532  }
3533 ;
3534 
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
3539  {
3540  UpdateParenEntity($3,$2);
3541  $$ = $3;
3542  stack_push((char *) entity_type($$),
3543  get_from_entity_type_stack_table($$));
3544  entity_type($$) = type_undefined;
3545  }
3546 | TK_LPAREN error TK_RPAREN
3547  {
3548  CParserError("Parse error: TK_LPAREN error TK_RPAREN\n");
3549  }
3550 
3551 | abs_direct_decl_opt TK_LBRACKET comma_expression_opt TK_RBRACKET
3552  {
3553  UpdateArrayEntity($1,NIL,$3);
3554  }
3555 /*(* The next shoudl be abs_direct_decl_opt but we get conflicts *)*/
3556 | abs_direct_decl_opt parameter_list_startscope
3557  {
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)));
3562  PushFunction(e);
3563  }
3564  rest_par_list TK_RPAREN
3565  {
3566  entity e = GetFunction();
3567  PopFunction();
3568  stack_pop(FormalStack);
3569  StackPop(OffsetStack);
3570  (void) UpdateFunctionEntity(e,$4);
3571  $$ = e;
3572  }
3573 ;
3574 
3575 abs_direct_decl_opt:
3576  abs_direct_decl
3577  { }
3578 | /* empty */ {
3579  string n = int2a(abstract_counter++);
3580  entity e = FindOrCreateCurrentEntity(strdup(concatenate(DUMMY_ABSTRACT_PREFIX,
3581  n,NULL)),
3582  ContextStack,FormalStack,
3583  FunctionStack,
3584  is_external);
3585  free(n);
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;
3591  $$ = e;
3592  }
3593 ;
3594 
3595 function_def: /* (* ISO 6.9.1 *) */
3596  function_def_start
3597  {
3598  InitializeBlock();
3599  is_external = false;
3600  }
3601  block
3602  {
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(); */
3611  is_external = true;
3612  }
3613 
3614 function_def_start: /* (* ISO 6.9.1 *) */
3615  decl_spec_list declarator
3616  {
3617  UpdateEntity($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external, false);
3618  //stack_pop(ContextStack);
3619  PopContext();
3620  pips_debug(2,"Create current module %s\n",entity_user_name($2));
3621  MakeCurrentModule($2);
3622  reset_token_has_been_seen_p();
3623  clear_C_comment();
3624  pips_assert("Module is consistent\n",entity_consistent_p($2));
3625  }
3626 /* (* Old-style function prototype *) */
3627 | decl_spec_list old_proto_decl
3628  {
3629  UpdateEntity($2,ContextStack,FormalStack,FunctionStack,OffsetStack,is_external, false);
3630  //stack_pop(ContextStack);
3631  PopContext();
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();
3635  clear_C_comment();
3636  pips_assert("Module is consistent\n",entity_consistent_p($2));
3637  }
3638 /* (* New-style function that does not have a return type *) */
3639 | TK_IDENT parameter_list_startscope
3640  {
3641  entity oe = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,$1);
3642  free($1);
3643  entity e = oe; //RenameFunctionEntity(oe);
3644  pips_debug(2,"Create current module \"%s\" with no return type\n",
3645  entity_name(e));
3646  MakeCurrentModule(e);
3647  reset_token_has_been_seen_p();
3648  clear_C_comment();
3649  //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3650  PushFunction(e);
3651  }
3652  rest_par_list TK_RPAREN
3653  {
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,
3664  //false);
3665  UpdateEntity2(e, FormalStack, OffsetStack);
3666  PopFunction();
3667  stack_pop(FormalStack);
3668  StackPop(OffsetStack);
3669  }
3670 /* (* No return type and old-style parameter list *) */
3671 | TK_IDENT TK_LPAREN old_parameter_list_ne
3672  {
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);
3676  free($1);
3677  MakeCurrentModule(e);
3678  clear_C_comment();
3679  //pips_assert("e is a module", module_name_p(entity_module_name(e)));
3680  PushFunction(e);
3681  stack_push((char *) make_basic_logical(true),FormalStack);
3682  stack_push((char *) make_basic_int(1),OffsetStack);
3683  }
3684  TK_RPAREN old_pardef_list
3685  {
3686  list paras = MakeParameterList($3,$6,FunctionStack);
3687  gen_free_list($3);
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));
3692  PopFunction();
3693  stack_pop(FormalStack);
3694  StackPop(OffsetStack);
3695  }
3696 /* (* No return type and no parameters *) */
3697 /* Never used because of conflict
3698 
3699 | TK_IDENT TK_LPAREN TK_RPAREN
3700  {
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);
3707  clear_C_comment();
3708  pips_assert("Current module entity is consistent\n",entity_consistent_p(e));
3709  }
3710 */;
3711 
3712 /*** GCC attributes ***/
3713 attributes:
3714  /* empty */
3715  { $$ = NIL; }
3716 | attribute attributes
3717  /*{ $$ = CONS(QUALIFIER,$1,$2); }*/
3718  { $$ = insert_qualifier($2, $1);}
3719 ;
3720 
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:
3724  /* empty */
3725  { $$ = NIL; }
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);}
3730 ;
3731 
3732 attribute:
3733 /*
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"); }
3738  |
3739 */
3740  TK_MSATTR
3741  { CParserError("ATTRIBUTE not implemented\n"); }
3742  /* ISO 6.7.3 */
3743 | TK_CONST
3744  {
3745  $$ = make_qualifier_const();
3746  }
3747 | TK_RESTRICT
3748  {
3749  $$ = make_qualifier_restrict();
3750  }
3751 | TK_VOLATILE
3752  {
3753  $$ = make_qualifier_volatile();
3754  }
3755 | TK_STATIC_DIMENSION
3756  {
3757  $$ = make_qualifier_static_dimension();
3758  }
3759 ;
3760 
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 *) */
3764 /*
3765 attr:
3766 | id_or_typename
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"); }
3776 | TK_INTCON
3777  { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3778 | string_constant
3779  { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3780 | TK_CONST
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"); }
3786 
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
3798 
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"); }
3804 | attr TK_PLUS attr
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"); }
3818 | attr TK_AND attr
3819  {
3820  CParserError("PRAGMAS and ATTRIBUTES not implemented\n");
3821  }
3822 | attr TK_PIPE attr
3823  { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3824 | attr TK_CIRC attr
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"); }
3830 | attr TK_INF attr
3831  { CParserError("PRAGMAS and ATTRIBUTES not implemented\n"); }
3832 | attr TK_SUP attr
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"); }
3848 ;
3849 
3850 attr_list_ne:*/
3851 /* Never used because of conflict
3852 |
3853 */
3854 /* attr
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"); }
3860  ;
3861 paren_attr_list_ne:
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"); }
3866 ;
3867 */
3868 /*** GCC TK_ASM instructions ***/
3869 asmattr:
3870  /* empty */
3871  { }
3872 | TK_VOLATILE asmattr
3873  { CParserError("ASM not implemented\n"); }
3874 | TK_CONST asmattr
3875  { CParserError("ASM not implemented\n"); }
3876 ;
3877 
3878 asmoutputs:
3879  /* empty */
3880  { }
3881 | TK_COLON asmoperands asminputs
3882  { CParserError("ASM not implemented\n"); }
3883 ;
3884 asmoperands:
3885  /* empty */
3886  { }
3887 | asmoperandsne
3888  { CParserError("ASM not implemented\n"); }
3889 ;
3890 asmoperandsne:
3891  asmoperand
3892  { CParserError("ASM not implemented\n"); }
3893 | asmoperandsne TK_COMMA asmoperand
3894  { CParserError("ASM not implemented\n"); }
3895 ;
3896 asmoperand:
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"); }
3901 ;
3902 asminputs:
3903  /* empty */
3904  { }
3905 | TK_COLON asmoperands asmclobber
3906  { CParserError("ASM not implemented\n"); }
3907 ;
3908 asmclobber:
3909  /* empty */
3910  { }
3911 | TK_COLON asmcloberlst_ne
3912  { CParserError("ASM not implemented\n"); }
3913 ;
3914 asmcloberlst_ne:
3915  one_string_constant
3916  { CParserError("ASM not implemented\n"); }
3917 | one_string_constant TK_COMMA asmcloberlst_ne
3918  { CParserError("ASM not implemented\n"); }
3919 ;
3920 
3921 %%