PIPS
util.c
Go to the documentation of this file.
1 /*
2 
3  $Id: util.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "genC.h"
34 #include "linear.h"
35 #include "ri.h"
36 #include "ri-util.h"
37 #include "workspace-util.h"
38 #include "c_parser_private.h"
39 #include "c_syntax.h"
40 
41 #include "text-util.h"
42 #include "prettyprint.h" // should be prettyprint-util.h
43  // for print_expressions() used
44  // in an error message which should be clarified
45  // for real users...
46  // and for much more...
47 
48 #include "cyacc.h"
49 
50 #include "resources.h"
51 #include "database.h"
52 
53 #include "misc.h"
54 #include "properties.h"
55 
56 /* Compared to pips_user_warning(), the name of the calling function
57  * is lost, which does not help maintenance but generates more
58  * user-friendly messages.
59  */
61  const char * pips_func,
62  const char * pips_file,
63  const int pips_line,
64  const char * format,
65  va_list * args)
66 {
67  if (get_bool_property("NO_USER_WARNING"))
68  return;
69 
70  // First and current line number in PIPS preprocessed file (ifn)
72  int fln = get_previous_c_lineno();
73  int uln = c_lineno;
74  string ifn_src = safe_get_line_interval(ifn, fln, uln);
75 
76  // Previous and current line numbers, in user input file (uifn)
77  // ??? string_undefined for pips generated code?
79  int pln = get_previous_C_line_number();
80  int cln = get_current_C_line_number();
81 
82  // Do not print more than 10 lines: the beginning of the user
83  // input C file may be full of includes and comments all
84  // considered related to the first declaration.
85  pips_assert("consistent line numbers", 1 <= pln && pln <= cln);
86  if (pln < cln-9)
87  pln = cln-9;
88 
89  string uifn_src = safe_get_line_interval(uifn, pln, cln);
90 
91  string more;
92 
93  asprintf(&more,
94  "Source code after preprocessing:\n%s"
95  "Input source code, before preprocessing:\n%s",
96  ifn_src, uifn_src);
97 
100  (const string) pips_func, (const string) pips_file, pips_line,
101  NULL, uifn, pln, cln,
102  NULL, more, (const string) format, args);
103 
104  free(more);
105 
106  // else???
107  /* Parser warning on C code synthesized by PIPS */
108  // pips_internal_error("Some synthesized code raises a "
109  // "C parser warning.\n");
110 }
111 
113  const char * pips_func,
114  const char * pips_file,
115  const int pips_line,
116  const char * format,
117  ...)
118 {
119  va_list args;
120  va_start(args, format);
121  c_parser_user_warning_alist(pips_func, pips_file, pips_line, format, &args);
122  va_end(args);
123 }
124 
125 /* The data structure to tackle the memory allocation problem due to
126  reparsing of compilation unit
127 
128 static int previoussizeofGlobalArea;
129 entity previouscompunit;
130 
131 */
132 
133 /* To keep track of the current dummy parameter naming. */
134 /* A function can be redeclared and it is difficult to make a
135  difference between "void foo(int u, int u);", which not in the
136  standard, and "void foo(int u); void foo(int u); which is fine" */
138 
140 //{current_dummy_parameter_number=n+c_lineno;}
141 //{current_dummy_parameter_number=n+get_current_C_line_number();}
143 
146 
149 
150 /******************* TOP LEVEL ENTITY **********************/
151 
153 {
155 }
156 
158 {
159  /* To be economic, group this top-level entity to it areas*/
160  /* FI: this is not convenient if top-level:top-level is a
161  module. All global variables should be declared there. I need
162  also to generate stubs for global variables... Do I? Yes, because
163  the points-to information is computed bottom-up. */
166  //entity_type(e) = make_type(is_type_area, make_area(0, NIL));
167  entity_type(e) =
169  //entity_initial(e) = make_value_unknown();
171  NIL, make_language_c());
173 }
174 
175 
176 /******************* CURRENT MODULE AREAS **********************/
177 /* In C we have 4 areas
178  1. globalStaticArea: For the Global Variables, these variables are added into StaticArea.
179  2. moduleStaticArea: For the Static module variables
180  3. localStaticArea(SticArea): General Static variables
181  4. DynamicArea
182  The GlobalStaticArea and ModuleStaticArea are basically static areas but they are not defined globally.
183  It is to be added to the Declarations for C
184 */
185 
187 {
194 
201 
202  //HeapArea = FindOrCreateEntity(compilation_unit_name, HEAP_AREA_LOCAL_NAME);
209 
210  /* Create a hidden pointer in the heap area to modelize malloc and
211  free effects and to keep track of the corresponding abstract
212  state. */
213  /* FI: I use a complex type to avoid seeing this variable in the
214  transformers and preconditions... OK, it's not a clean way to
215  do it. Should we create another area to allocate this abstract
216  heap state? */
217  /* FI: I keep the code below, because it may turn useful again if
218  context-insensitive address values must be generated. */
219  /*
220  if(!compilation_unit_entity_p(get_current_module_entity())) {
221  make_entity(AddPackageToName(get_current_module_name(),
222  MALLOC_EFFECTS_NAME),
223  make_scalar_complex_type(DEFAULT_COMPLEX_TYPE_SIZE),
224 
225  Chose a storage... Maybe in MALLOC_EFFECTS_PACKAGE_NAME?
226 
227  make_storage(is_storage_ram,
228  make_ram(entity_undefined, DynamicArea, 0, NIL))
229 
230  make_storage(is_storage_ram,
231  make_ram(get_current_module_entity(),
232  HeapArea,
233  0, NIL)),
234  make_value(is_value_unknown, UU));
235  }
236  */
237 
238  // Dynamic variables whose size are not known are stored in Stack area
245 
249 
253 
254  /* This is because of the reparsing of the compilation unit
255  The area is set to zero and all the declarations are overrided and the memory is reallocated
256  The area is reset to only when it is called by same compilation unit twice.
257  The code is dangerous hence it is commented. Please have a look
258 
259  if( get_current_compilation_unit_entity() == get_current_module_entity() &&
260  (get_current_compilation_unit_entity() == previouscompilationunit))
261  area_size(type_area(entity_type(msae))) = 0;
262 
263  if( get_current_compilation_unit_entity() == get_current_module_entity() &&
264  (get_current_compilation_unit_entity() == previouscompilationunit))
265  area_size(type_area(entity_type(gsae))) = previoussizeofGlobalArea ;
266  */
267 }
268 
270  tag bt,
271  size_t size)
272 {
273  return make_C_or_Fortran_constant_entity(name, bt, size, false, c_parser_error);
274 }
275 
276 
278 {
279  /* Function name variable __function__ and __FUNCTION__ */
280  const char * mn = entity_local_name(m);
281  string bs = "0`"; // first local scope in a module: should be
282  // returned by a function to stay consistent in
283  // case of change
284  string fn1 = strdup(concatenate(bs, IMPLICIT_VARIABLE_NAME_1, NULL));
285  string fn2 = strdup(concatenate(bs, IMPLICIT_VARIABLE_NAME_2, NULL));
286  entity func_name1 = FindOrCreateEntity(mn, fn1);
287  entity func_name2 = FindOrCreateEntity(mn, fn2);
288  const char * name = entity_user_name(m);
289  string cn = strdup(concatenate("\"", mn, "\"", NULL));
292  strlen(name)+1);
293  free(cn);
294  entity a = DynamicArea; /* Should be static, but not compatible with
295  FREIA inlining. */
296 
297  entity_type(func_name1) = make_char_array_type(strlen(name)+1);
298  entity_storage(func_name1) =
300  /* It is not clear if the encoding is correct or not. It may also
301  be correct but not supported. This could be checked by computing
302  the preconditions for strings and/or by adding initial values to
303  the symbol table display. */
305  AddEntityToDeclarations(func_name1, m);
306 
307  entity_type(func_name2) = make_char_array_type(strlen(name)+1);
308  entity_storage(func_name2) =
311  AddEntityToDeclarations(func_name2, m);
312  /* Since the declarations are not added to a statement_declarations
313  field, they are not going to be prettyprinted. */
314 
315  free(fn1);
316  free(fn2);
317 }
318 /******************* COMPILATION UNIT **********************/
319 
321 {
323 }
324 
325 
326 /* A compilation unit is also considered as a module*/
327 
328 void MakeCurrentCompilationUnitEntity(const char* name)
329 {
331  /* value v = entity_initial(e); */
332  /* if(value_code_p(v)) { */
333  /* code c = value_code(v); */
334  /* language l = code_language(c); */
335  /* if(language_unknown_p(l)) */
336  /* code_language(c) = make_language_c(); */
337  /* else if(language_fortran_p(l) || language_fortran95_p(l)) */
338  /* pips_internal_error("A compilation unit should have language \"C\".\n"); */
339  /* } */
340  /* else */
341  /* pips_internal_error("A compilation unit should have value \"code\".\n"); */
342 
343  pips_debug(4,"Set current module entity for compilation unit %s\n",name);
345  //init_stack_storage_table();
346  init_c_areas();
347 }
348 
349 void ResetCurrentCompilationUnitEntity(bool is_compilation_unit_parser)
350 {
351  /* Let's redo the memory allocation for variables whose name has changed:-(*/
352  if(is_compilation_unit_parser)
354  else
356 
357  /* reset_entity_type_stack_table(); */
358  if (get_bool_property("PARSER_DUMP_SYMBOL_TABLE"))
360  pips_debug(4,"Reset current module entity for compilation unit \"%s\"\n",
363 }
364 
365 /************* EXPRESSIONS (half moved to ri-util ******************/
366 
367 /* e is now owned by returned expression and must not be used any longer */
369 {
370  /* There are 2 cases:
371 
372  1. The first argument corresponds to a function name (an entity).
373 
374  In this case, we create a normal call expression and the
375  corresponding entity is added to the list of callees.
376 
377  2. The first argument can be any expression denoting a called
378  function (a pointer to a function,... such as
379  (*ctx->Driver.RenderString)() in the benchmark mesa in
380  SPEC2000). In this case, we create a function application
381  expression.
382  */
384  syntax s = expression_syntax(e);
385  switch (syntax_tag(s))
386  {
387  case is_syntax_reference:
388  {
390  free_expression(e);
392 
393  ifdebug(8) {
394  pips_debug(8, "Call to \"\%s\" with %zd argument(s)\n",
395  entity_name(ent), gen_length(le));
396  print_expressions(le);
397  }
398 
399  if(!intrinsic_entity_p(ent)) {
402  type ut = ultimate_type(entity_type(ent));
403 
404  if(type_functional_p(ut))
405  AddToCalledModules(ent);
406  else {
407  /* Must be a pointer to a function */
408  const char * eun = entity_user_name(ent);
409  c_parser_user_warning("Call to an unknown function via function pointer \"\%s\"\n",
410  eun);
411  }
412 
413  if(!gen_in_list_p(ent, cudl)) {
414  /* Undeclared functions return int by default */
415  type ft = entity_type(ent);
417 
418  pips_assert("function's type is ultimately functional or pointer to functional",
420  f = type_functional(ft);
423  AddToDeclarations(ent, cf);
424  }
425  }
426  pips_debug(6,"Normal function or intrinsics call\n");
427  (void)check_C_function_type(ent,le);
428  exp = make_call_expression(ent,le);
429  /* This cannot be checked unless bootstrap typing is improved
430  for varargs intrinsics, mostly IOs. */
431  /*
432  if(!ok) {
433  c_parser_user_warning("Actual arguments do not fit the declared formal "
434  "arguments of function \"%s\"\n",
435  entity_user_name(ent));
436  CParserError("Type mismatch\n");
437  }
438  */
439  break;
440  }
441  case is_syntax_call:
442  {
443  application a = make_application(e,le);
444  pips_debug(6,"Application function call\n");
446  break;
447  }
448  case is_syntax_range:
449  case is_syntax_cast:
451  case is_syntax_subscript:
453  CParserError("This is not a functional expression\n");
454  break;
455  default:
456  {
457  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
458  }
459  }
460  return exp;
461 }
462 
464 {
465  if (type_variable_p(t))
466  {
468  pips_debug(6,"Basic tag is %d\n",basic_tag(b));
469  switch (basic_tag(b)) {
470  case is_basic_pointer:
471  {
472  type tp = basic_pointer(b);
474  }
475  case is_basic_typedef:
476  {
477  entity te = basic_typedef(b);
478  type tp = entity_type(te);
480  }
481  case is_basic_derived:
482  {
483  entity de = basic_derived(b);
484  const char * name = entity_user_name(de);
485  string id = strdup(concatenate(name,MEMBER_SEP_STRING,m,NULL));
487  free(id);
488  return exp;
489  }
490  default:
491  break;
492  }
493  }
494  CParserError("Cannot find the field identifier from current type\n");
495  return expression_undefined;
496 }
497 
499 {
500  /* Find the name of struct/union of m from the type of expression e*/
501 
502  syntax s = expression_syntax(e);
503  ifdebug(6)
504  {
505  pips_debug(6,"Find the struct/union of \"%s\" from expression:\n",m);
506  print_expression(e);
507  }
508  switch (syntax_tag(s))
509  {
510  case is_syntax_call:
511  {
512  call c = syntax_call(s);
513  entity f = call_function(c);
514  pips_debug(6,"Called operator is \"%s\"\n",entity_name(f));
515  if(ENTITY_PLUS_C_P(f))
516  {
522 
524  exp = e1;
525  else if(basic_pointer_p(b2) && (basic_int_p(b1)||basic_bit_p(b1)))
526  exp = e2;
527  else
528  CParserError("Pointer arithmetic error, incompatible types");
529  free_basic(b1);
530  free_basic(b2);
531 
533  }
536  {
539  }
540  else if(ENTITY_MINUS_C_P(f))
541  {
542  /* The first expression must be a pointer */
545  }
546  else if(ENTITY_PLUS_P(f))
547  {
548  /* standard integer arithmetic: why bother? why take the CDR? */
551  }
552  else if (ENTITY_FIELD_P(f) || ENTITY_POINT_TO_P(f))
553  {
556  }
557  else if (ENTITY_DEREFERENCING_P(f))
558  {
561  }
562  /* FI: seems too simple. No need to remember if you sarted with "." or "->"? */
563  else if (ENTITY_ADDRESS_OF_P(f))
564  {
567  }
568  else if (ENTITY_ASSIGN_P(f))
569  {
572  }
573  else if (ENTITY_CONDITIONAL_P(f))
574  {
575  /* Let use the second argument */
578  }
579  /* More types of call must be taken into account: typedef and
580  pointer to functions */
581  else if (true || type_functional_p(entity_type(f)))
582  {
583  /* User defined call and intrinsics not processed above */
584  type ft = call_to_functional_type(c, true);
586  if(overloaded_type_p(t))
587  pips_internal_error("Unresolved expression type\n");
589  }
590  break;
591  }
592  case is_syntax_reference:
593  {
595  type t = ultimate_type(entity_type(ent));
596  pips_debug(6,"Reference expression\n");
597 
598  if(type_functional_p(t)) {
599  /* A call must have occured somewhere... */
602  }
605 
606  if(type_functional_p(pt)) {
607  /* An apply must have occured somewhere... */
610  }
611  else
613  }
614  else
616  }
617  case is_syntax_cast:
618  {
619  type t = cast_type(syntax_cast(s));
620  pips_debug(6,"Cast expression\n");
622  }
623  case is_syntax_range:
624  break;
626  break;
627  case is_syntax_subscript:
628  {
629  /* expression exp = subscript_array(syntax_subscript(s)); */
630  /* pips_debug(6,"Subscripting array expression\n"); */
631  /* return MemberIdentifierToExpression(exp, m); */
632  type t = expression_to_type(e);
634  }
636  {
638  return MemberIdentifierToExpression(fe, m);
639  break;
640  }
641  default:
642  {
643  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
644  }
645  }
646  CParserError("Cannot find the field identifier from current expression\n");
647  return expression_undefined;
648 }
649 
651 {
654 
655  pips_debug(5,"Identifier is \"%s\" and entity_name is \"\%s\"\n",
656  s, safe_entity_name(ent));
657 
658  if (entity_undefined_p(ent)) {
659  /* Could this be non declared variables ?*/
660  /* This identifier has not been passed by the parser.
661  It is probably a function call => try this case now and complete others later.
662  The scope of this function is global */
663  pips_debug(5,"Create unparsed global function: %s\n",s);
665  //entity_storage(ent) = make_storage_return(ent);
669  /* This may be a call or a reference in case a functional pointer is initialized */
671  /*return MakeNullaryCall(ent);*/
672  }
673  else if(type_undefined_p(entity_type(ent))) {
674  /* FI: This may happen when a variable is used to initialize another
675  variable within the same declaration statement: see
676  decl29.c. This might not be a general fix as the type could be
677  functional: to be checked. But setting up type earlier would require a huge
678  change in the parser rules. Unless FindOrCreateCurrentEntity()
679  could do a better job? But the information added is later
680  destroyed by the parser. */
683  }
684  else {
685  switch (type_tag(entity_type(ent))) {
686  case is_type_variable:
687  case is_type_functional:
688  {
689  value iv = entity_initial(ent);
690 
691  if(!value_undefined_p(iv) && value_symbolic_p(iv))
692  /* Generate a call to an enum member */
694  else
697 
698  break;
699  }
700  default:
701  {
702  CParserError("Which kind of expression?\n");
703  }
704  }
705  }
706  return exp;
707 }
708 
709 /* FI: this function is called for a bracketed comma expression
710  *
711  * The two arguments are (should be) reused within the returned expression
712  */
714 {
715  /* There are two cases:
716 
717  1. Simple array reference, where the first argument is a simple
718  array or pointer name. We create a reference expression (syntax =
719  reference).
720 
721  2. Complicated subscripting array, where the first argument can be
722  a function call (foo()[]), a structure or union member
723  (str[5].field[7], ... We create a subscripting expression (syntax =
724  subscript).
725  */
726 
729  list sl = lexp;
730 
731  if(!ENDP(CDR(lexp))) {
733  sl = CONS(EXPRESSION, se, NIL);
734  }
735 
736  switch(syntax_tag(s)) {
737  case is_syntax_reference:
738  {
739  /* FI: Memory leak with exp? */
741  entity ent = reference_variable(r);
742  list l = reference_indices(r);
743  pips_debug(6,"Normal reference expression\n");
745  break;
746  }
747  case is_syntax_call:
748  case is_syntax_range:
749  case is_syntax_cast:
751  case is_syntax_subscript:
753  {
754  /* FI: we might have preexisting subscript? No, in this
755  context, only one index due to lack of type information? */
756  subscript a = make_subscript(exp,sl);
758  pips_debug(6,"Subscripting array expression\n");
760  break;
761  }
762  default:
763  {
764  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
765  }
766  }
767  return e;
768 }
769 
770 
771 /******************* TYPES *******************/
772 
773 // Moved to ri-util/type.c
774 
775 /******************* ENTITIES *******************/
776 
777 
779 {
780  /* Find an entity from its local name.
781  We have to look for all possible prefixes, which are:
782  blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX
783 
784  How about multiple results ? The order of prefixes ? */
785 
786  entity ent = entity_undefined;
788  int i;
789  //c_parser_context cpc = GetScope();
790  //string scope = scope_to_block_scope(c_parser_context_scope(cpc));
791 
792  for (i=0; prefixes[i]!=NULL; i++)
793  {
795  return ent;
796  }
797 
798  if(entity_undefined_p(ent)) {
799  /* Is it a static function? It must have been parsed in the compilation unit */
800  string sname = strdup(concatenate(compilation_unit_name, name, NULL));
801  ent = FindEntity(compilation_unit_name, sname);
802  free(sname);
803  return ent;
804  }
805 
806  c_parser_user_warning("Cannot find entity %s\n", name);
807 
808  return entity_undefined;
809 }
810 
812 {
813  entity e;
814 
816  return e;
818 }
819 
821  string prefix,
822  string scope,
823  bool is_external)
824 {
826  string ls = strdup(scope);
827  string ls_head = ls;
828 
829  pips_assert("Should not be used", false);
830 
831  pips_assert("scope is a block scope", string_block_scope_p(scope));
832 
833  do {
834  string sname = strdup(concatenate(ls, name, NULL));
836  free(sname);
837  }
838  while(e != entity_undefined && (ls = pop_block_scope(ls)));
839 
840  if(entity_undefined_p(e)) {
841  /* The current scope will be automatically added */
843  }
844  free(ls_head);
845  pips_debug(8, "Entity returned: \"%s\"\n", entity_name(e));
846  return e;
847 }
848 
849 /* The parameter "scope" is potentially destroyed. */
850 entity FindEntityFromLocalNameAndPrefixAndScope(string name, string prefix, string scope)
851 {
852  entity ent = entity_undefined;
853 
855  string global_name = string_undefined;
856  /* Add block scope case here */
857  do {
859  global_name = (concatenate(/*compilation_unit_name,*/
861  scope,prefix,name,NULL));
862  else
864  scope,prefix,name,NULL));
865  ent = gen_find_tabulated(global_name,entity_domain);
866  /* return values are not C variables... but they are entities. */
867  if(!entity_undefined_p(ent)
869  && storage_return_p(entity_storage(ent))) {
870  ent = entity_undefined;
871  }
872  } while(entity_undefined_p(ent) && (scope = pop_block_scope(scope))!=NULL);
873  }
874  return ent;
875 }
876 
878 {
879  /* Find an entity from its local name and prefix.
880  We have to look from the most enclosing scope.
881 
882  Possible name combinations and the looking order:
883 
884  1. FILE!MODULE:BLOCK`PREFIXname or MODULE:BLOCK`PREFIXname
885  2. FILE!MODULE:PREFIXname or MODULE:PREFIXname
886  3. FILE!:PREFIXname (used to be FILE!PREFIXname)
887  4. TOP-LEVEL:PREFIXname
888 
889  with 5 possible prefixes: blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX
890 
891  "!" is FILE_SEP_STRING and ":" is MODULE_SEP_STRING and "`" is BLOCK_SEP_STRING
892  */
893 
894  entity ent = entity_undefined;
895  string global_name = string_undefined;
896  string scope = scope_to_block_scope(GetScope());
897  string ls = strdup(scope);
898  string ls_head = ls;
899 
900  pips_debug(5,"Entity local name is \"%s\" with prefix \"%s\" and scope \"%s\"\n",
901  name,prefix,scope);
902  pips_assert("Scope is a block scope", string_block_scope_p(scope));
903  free(scope);
904 
905  /* First, look up the surrounding scopes */
907 
908  /* Is it a formal parameter not yet converted in the function frame? */
909  if(entity_undefined_p(ent)) {
910  /* Should we change the current dummy parameter number? */
912 
914  prefix,name,NULL));
915  ent = gen_find_tabulated(global_name,entity_domain);
916  free(sn);
917  }
918 
919  /* Is it a static variable declared in the compilation unit? */
920  /* we have an issue there : a static function will be declared FILE!MODULE:FILE!name,
921  * but a static variable will be declared FILE!MODULE:name
922  * so try both ... CleanupEntity has been fixed to remove buggy situations ...*/
923  if(entity_undefined_p(ent)) {
925  prefix,name,NULL));
926  ent = gen_find_tabulated(global_name,entity_domain);
927  }
928  if(entity_undefined_p(ent)) {
930  prefix,name,NULL));
931  ent = gen_find_tabulated(global_name,entity_domain);
932  }
933 
934  /* Is it a global variable declared in the compilation unit? */
935  if(entity_undefined_p(ent)) {
937  prefix,name,NULL));
938  ent = gen_find_tabulated(global_name,entity_domain);
939  }
940 
941  /* Is it a local type used within a function declaration? */
942  if(entity_undefined_p(ent) && strcmp(ls, "")==0 && ScopeStackSize()>=2) {
943  string lls = strdup(scope_to_block_scope(GetParentScope()));
945  free(lls);
946  }
947 
948  if(entity_undefined_p(ent)) {
949  pips_debug(8, "Cannot find entity with local name \"%s\" with prefix \"%s\" at line %d\n",
951  /* It may be a parser error or a normal behavior when an entity is
952  used before it is defined as, for example, a struct in a typedef:
953  typedef struct foo foo; */
954  /* CParserError("Variable appears to be undefined\n"); */
955  } else
956  pips_debug(5,"Entity global name is %s\n",entity_name(ent));
957  //free(global_name);
958  free(ls_head);
959  return ent;
960 }
961 
963 {
964  /* We have to know the context:
965 
966  - if the entity is declared outside any function, their scope is
967  the CurrentCompilationUnit
968 
969  - if the entity is declared inside a function, we have to know
970  the CurrentBlock, which is omitted for the moment
971 
972  - if the function is static, their scope is
973  CurrentCompilationUnit#CurrentModule
974 
975  - if the function is global, their scope is CurrentModule
976  */
977  entity ent = entity_undefined;
978 
979  if (is_external) {
980  pips_debug(5,"Entity local name is %s with prefix %s\n",name,prefix);
981  char *local_name;
982  asprintf(&local_name,"%s%s",prefix,name);
983  // See TRAC Ticket #787
984 #define FILE_LOCAL_USER_DEFINED_TYPES_P (true)
986  /* The entity is created local to the file. For instance,
987  * derived and user-named types. This makes type checking more
988  * difficult as types such as FILE * vary from C file to C file,
989  * but this is consistent with the C standard and the behavior
990  * of production compilers: the same local name can be used for
991  * two different types in two different files.
992  */
994  }
995  else {
996  /* These types are created globally, which makes type checking
997  * much easier but forbid homonym types in different files.
998  */
1000  }
1001  free(local_name);
1002  }
1003  else {
1004  string scope = scope_to_block_scope(GetScope());
1005 
1006  pips_debug(5,"Entity local name is %s with prefix %s and scope \"%s\"\n",
1007  name,prefix,scope);
1008  pips_assert("scope is a block scope", string_block_scope_p(scope));
1009 
1010  char * local_name;
1011  asprintf(&local_name,"%s%s%s",scope,prefix,name);
1014  }
1015  else {
1017  }
1018  free(local_name);
1019  free(scope);
1020  }
1021  pips_debug(5,"Entity global name is %s\n",entity_name(ent));
1022  return ent;
1023 }
1024 
1026 {
1028  if(entity_undefined_p(f))
1029  pips_debug(5,"Current module is undefined\n");
1030  else {
1031  value fv = entity_initial(f);
1032  pips_debug(5,"Current module is function \"%s\"\n", entity_name(f));
1033  if(!value_undefined_p(fv)) {
1034  code fc = value_code(fv);
1035  if(!code_undefined_p(fc)) {
1036  list el = code_externs(fc);
1037  list le = gen_last(el);
1038  pips_debug(8, "Number of extern variables and functions: %zd\n",
1039  gen_length(el));
1040  if(gen_length(el)>0) {
1041  pips_debug(8, "Last entity %s in cons %p with car=%p and cdr=%p\n",
1042  entity_name(ENTITY(CAR(le))),
1043  le,
1044  &(le->car),
1045  (void *) (le->cdr));
1046  }
1047  pips_assert("externs is an entity list", entity_list_p(el));
1048  }
1049  }
1050  }
1051  return true;
1052 }
1053 
1054 /* Store named type for the lexical analyzer, which has to decide if a
1055  * character string is the name of a type or the name of a
1056  * variable.
1057  *
1058  * See is_c_parser_keyword_typedef() in clex.l
1059  */
1060 void c_parser_put_new_typedef(const char* name)
1061 {
1062  string s = get_c_parser_current_scope();
1063  string sname = string_undefined;
1064  if(same_string_p(s, ""))
1065  sname = strdup(name);
1066  else
1067  sname = strdup(concatenate(name,"%", s, NULL));
1068  hash_put(keyword_typedef_table, sname,(void *) TK_NAMED_TYPE);
1069  pips_debug(5, "Add typedef name %s to hash table\n",sname);
1070 }
1071 
1072 /* This function is used by libraries "step"* and "task_parallelization"
1073  *
1074  * FI: I have no idea why it works although the keyword_typedef_table
1075  * should not be initialized... It could not be made static, because
1076  * it might be used by any file in the c_syntax library.
1077  */
1078 void put_new_typedef(const char* name)
1079 {
1081  pips_debug(5,"Add typedef name %s to hash table\n",name);
1082 }
1083 
1084 /* This function finds or creates the current entity. Only entity full
1085  name is created, other fields such as type, storage and initial
1086  value are undefined. */
1087 
1089  stack ContextStack __attribute__ ((__unused__)),
1092  bool is_external)
1093 {
1094  entity ent;
1096  string full_scope = c_parser_context_scope(context);
1097  string scope = strrchr(full_scope, BLOCK_SEP_CHAR);
1098  string block_scope = scope_to_block_scope(full_scope);
1100  bool is_typedef = c_parser_context_typedef(context);
1101  bool is_static = c_parser_context_static(context);
1102  entity function = entity_undefined;
1103  bool is_formal;
1104 
1105  if(scope!=NULL)
1106  scope++;
1107  else {
1108  scope = full_scope;
1109  }
1110 
1111  if(!string_block_scope_p(block_scope)) {
1112  pips_assert("block_scope is TOP-LEVEL:", same_string_p(block_scope, "TOP-LEVEL:"));
1113  free(block_scope);
1114  block_scope = empty_scope();
1115  }
1116 
1118  is_formal = false;
1119  else {
1120  is_formal= true;
1121  function = stack_head(FunctionStack);
1122  }
1123 
1124  ifdebug(5) {
1126  if(entity_undefined_p(f))
1127  pips_debug(5,"Entity local name \"%s\"\n",name);
1128  else {
1129  value fv = entity_initial(f);
1130  pips_debug(5,"Entity local name \"%s\" in function \"%s\"\n",name, entity_name(f));
1131  if(!value_undefined_p(fv)) {
1132  code fc = value_code(fv);
1133  if(!code_undefined_p(fc)) {
1134  list el = code_externs(fc);
1135  pips_assert("externs is an entity list", entity_list_p(el));
1136  }
1137  }
1138  }
1139  pips_debug(5,"Context %p\n",context);
1140  if (full_scope != NULL) {
1141  pips_debug(5,"Current scope: \"%s\"\n",full_scope);
1142  pips_debug(5,"Local declaration scope: \"%s\"\n",scope);
1143  pips_debug(5,"Block scope: \"%s\"\n",block_scope);
1144  pips_assert("block_scope is a block scope", string_block_scope_p(block_scope));
1145  }
1146  pips_debug(5,"type %p: %s\n", ct, list_to_string(safe_c_words_entity(ct, NIL)));
1147  pips_debug(5,"is_typedef: %d\n",is_typedef);
1148  pips_debug(5,"is_static: %d\n",is_static);
1149  pips_debug(5,"is_external: %d\n",is_external);
1150  pips_debug(5,"is_formal: %d\n",is_formal);
1151  if (is_formal)
1152  pips_debug(5,"of current function %s\n",entity_user_name(function));
1153  /* function is only used for formal variables*/
1154  }
1155 
1156  if (is_typedef)
1157  {
1158  /* Tell the lexer about the new type names : add to
1159  keyword_typedef_table. Because of scopes, different types
1160  can have the same name... */
1162  /*
1163  hash_put(keyword_typedef_table,strdup(name),(void *) TK_NAMED_TYPE);
1164  pips_debug(5,"Add typedef name %s to hash table\n",name);
1165  */
1167  }
1168  else
1169  {
1170  if (strcmp(scope,"") != 0 && !is_formal)
1171  {
1172  /* Prefix for the current struct: use full_scope */
1173  char * mname = strdup(module_name(full_scope));
1174  char * tname = name;
1175  asprintf(&name,"%s%s",local_name(full_scope),name);
1176  ent = FindOrCreateEntity(mname,name);
1177  free(mname);free(tname);
1178  if (is_external
1179  && !member_entity_p(ent) /* Maybe it would have been
1180  better to push "external" in
1181  the context */
1182  /* && strstr(scope,TOP_LEVEL_MODULE_NAME) != NULL*/ )
1183  {
1184  /* This entity is declared in a compilation unit with
1185  keyword EXTERN. Add it to the storage of the
1186  compilation unit to help code prettyprint unless if
1187  has already been declared earlier in the current
1188  compilation unit. See C_syntax/global_extern.c */
1190  code c = value_code(entity_initial(com_unit));
1191  list el = code_externs(c);
1192  if(type_undefined_p(entity_type(ent))
1193  || intrinsic_entity_p(ent)) {
1194  /* ent has not been declared earlier */
1195  //ram_shared(storage_ram(entity_storage(com_unit))) =
1196  //gen_nconc(ram_shared(storage_ram(entity_storage(com_unit))), CONS(ENTITY,ent,NIL));
1197  pips_debug(8, "Variable \"%s\" added to external declarations of \"%s\"\n",
1198  entity_name(ent), entity_name(com_unit));
1199  pips_assert("ent is an entity", entity_domain_number(ent)==entity_domain);
1200  pips_assert("com_unit is an entity", entity_domain_number(com_unit)==entity_domain);
1201  pips_assert("el is a pure entity list", entity_list_p(el));
1202  //code_externs(c) = gen_nconc(el,
1203  //CONS(ENTITY,ent,NIL));
1204  AddToExterns(ent, com_unit);
1205  el = code_externs(value_code(entity_initial(com_unit)));
1206  pips_assert("el is a pure entity list", entity_list_p(el));
1207  }
1208  else if(!gen_in_list_p(ent, el)
1209  && !type_undefined_p(entity_type(ent))
1210  && !type_functional_p(entity_type(ent))) {
1211  /* A global entity may already have been seen in a
1212  previous compilation unit and so it is already
1213  typed but still must be declared as extern. See
1214  test case C_syntax/declarations.c */
1215  /* The bad news is: function are not yet fully typed
1216  when this is executed and their type is "variable",
1217  the future result type; hence, they are declared
1218  "extern" no matter what... Do we want to clean up
1219  the code_externs list later since the extern
1220  keyword is useless for functions? No other simple
1221  solution found... */
1222  /* FI: The test above may be stronger than the previous one,
1223  but I'm pretty conservative when dealing with the
1224  parser. */
1225  AddToExterns(ent, com_unit);
1226  }
1227  }
1228  else if(strstr(full_scope,TOP_LEVEL_MODULE_NAME)!=NULL) {
1230  if(type_undefined_p(entity_type(ent))
1231  || !type_functional_p(entity_type(ent))) {
1232  /* This variable is declared extern within a function
1233  body. */
1234  AddToExterns(ent, function);
1235  }
1236  }
1237  else {
1238  /* Impossible: this is not detected here */
1239  /* This entity may have already been declared external but
1240  is redeclared inside the same module. See
1241  C_syntax/global_extern.c */
1242  /*
1243  entity com_unit = get_current_compilation_unit_entity();
1244  list el = code_externs(value_code(entity_initial(com_unit)));
1245  if(entity_is_argument_p(ent, el))
1246  code_externs(value_code(entity_initial(com_unit))) =
1247  arguments_rm_entity(el, ent);
1248  */
1249  }
1250  }
1251  else
1252  {
1253  if (is_formal) {
1254  /* Formal parameter for a function declaration or for a
1255  function definition or for a pointer to a function or
1256  for a functional typedef */
1257  stack st = get_from_entity_type_stack_table(function);
1259 
1260  if(typedef_entity_p(function)) {
1261  // To get a unique identifier for each function typedef
1263  char * module_name;
1265 
1266  ent = FindOrCreateEntity(module_name,name);
1267  free(module_name);
1268  }
1269  else if(!type_undefined_p(ft) && type_variable_p(ft)
1271 
1272  // To get a unique identifier for each function pointerdeclaration, dummy or not
1274  char * module_name;
1276 
1277  ent = FindOrCreateEntity(module_name,name);
1278  free(module_name);
1279  }
1280  else {
1281  /* It is too early to define formal parameters. Let's start with dummy parameters */
1282  // To get a unique identifier for each function (This
1283  // may not be sufficient as a function can be declared
1284  // any number of times with any parameter names)
1286  char * module_name;
1288  ent = FindOrCreateEntity(module_name,name);
1289  free(module_name);
1290  /*
1291  if(top_level_entity_p(function))
1292  ent = find_or_create_entity(strdup(concatenate(entity_user_name(function),
1293  MODULE_SEP_STRING,name,NULL)));
1294  else {
1295  // The function is local to a compilation unit
1296  // Was this the best possible design?
1297  string mn = entity_module_name(function);
1298  string ln = entity_local_name(function);
1299  ent = find_or_create_entity(strdup(concatenate(mn,ln,
1300  MODULE_SEP_STRING,name,NULL)));
1301  }
1302  */
1303  }
1304  }
1305  else
1306  {
1307  /* scope = NULL, not extern/typedef/struct/union/enum */
1308  if (is_external)
1309  {
1310  /* This is a variable/function declared outside any module's body*/
1311  if (is_static) {
1312  /* If it is a function, we'd like to increase its
1313  name. If it's a variable, we'd like not to
1314  increase its name with the compilation unit
1315  name. But we do not have much information here to
1316  make the decision. Let's assume it's a function
1317  and postpone to UpdateEntity() */
1318  /* Depending on the type, we should or not
1319  introduce a MODULE_SEP_STRING, but the type is
1320  still not fully known. Wait for UpdateFunctionEntity(). */
1321  char * local_name;
1324  free(local_name);
1325  }
1326  else {
1327  /* We may have to remove it from the extern list:
1328  C_syntax/global_extern01.c */
1331  list el = code_externs(value_code(entity_initial(com_unit)));
1332  if(entity_is_argument_p(ent, el)) {
1333  type ent_t = entity_type(ent);
1334  if(!type_undefined_p(ent_t) && !type_functional_p(ent_t))
1335  /* code_externs(value_code(entity_initial(com_unit))) = */
1336  /* arguments_rm_entity(el, ent); */
1337  RemoveFromExterns(ent);
1338  }
1339  }
1340  }
1341  else
1342  {
1343  /* This is a variable/function declared inside a module's body: add block scope here
1344  Attention, the scope of a function declared in module is the module, not global.*/
1345  char * local_name;
1346  asprintf(&local_name,"%s%s",block_scope,name);
1348  /* The module name is unambiguous because it is used by pipdbm */
1350  else
1352  free(local_name);
1353  /* FI: why is ct not exploited? Because the
1354  information is later destroyed. I guess it is
1355  related to the type_stack stored in the entity_
1356  initial field. */
1357  /* entity_type(ent) = copy_type(ct); */
1358  }
1359  }
1360  }
1361  }
1362  pips_debug(5,"Entity global name \"%s\"\n\n",entity_name(ent));
1363  free(block_scope);
1364  return ent;
1365 }
1366 
1367 
1369 {
1370  type t = entity_type(e);
1371  pips_debug(3,"Update entity in parentheses \"%s\" with type \"%s\"\n",
1373  if (lq != NIL) {
1374  if (type_undefined_p(t))
1376  else {
1377  if (type_variable_p(t)) {
1378  variable v = type_variable(t);
1380  }
1381  else {
1382  CParserError("Attributes for not variable type\n");
1383  }
1384  }
1385  }
1386 }
1387 
1388 
1390 {
1391  dimension d;
1392  if (le == NIL)
1393  {
1395  pips_debug(5,"Unbounded dimension\n");
1396  }
1397  else
1398  {
1399  /* Take only the first expression of le, do not know why it can be a list ?*/
1400  expression e = EXPRESSION(CAR(le));
1401  intptr_t up;
1402 
1403  if (false && expression_integer_value(e,&up))
1404  /* use the integer value */ /* If we do this, we cannot restitute the source code */
1406  else
1407  /* Build a new expression e' == e-1 */
1410  e,
1411  int_to_expression(1)),
1412  ql);
1413 
1414  ifdebug(9)
1415  {
1416  pips_debug(5,"Array dimension:");
1417  print_expression(e);
1418  pips_debug(8,"Array lower bound:");
1420  pips_debug(5,"Array dimension:");
1422  }
1423  }
1424  return d;
1425 }
1426 
1428 {
1429  /* This function replaces the type pointed by the pointer pt
1430  (this can be a pointer of pointer,... so we have to go until the last one)
1431  by the type t*/
1432  pips_debug(3,"Update final pointer type %d and %d\n", type_tag(pt), type_tag(t));
1434  {
1436  if (type_undefined_p(ppt))
1438  return UpdateFinalPointer(ppt,t);
1439  }
1440  CParserError("pt is not a pointer\n");
1441  return type_undefined;
1442 }
1443 
1445 {
1446  type t = entity_type(e);
1447  ifdebug(3) {
1448  list pdl = NIL;
1449  pips_debug(3,"Update pointer entity %s with type pt=\"%s\"\n",
1450  entity_name(e), list_to_string(c_words_entity(pt, NIL, &pdl)));
1451  gen_free_list(pdl);
1452  }
1453  if (type_undefined_p(t))
1454  {
1455  pips_debug(3,"Undefined entity type\n");
1456  entity_type(e) = pt;
1457  /*
1458  if(type_undefined_p(pt)) {
1459  type npt = make_type(is_type_variable,
1460  make_variable(make_basic(is_basic_pointer, type_undefined),
1461  NIL, NIL));
1462  entity_type(e) = npt;
1463  }
1464  else if(type_variable_p(pt) && basic_pointer_p(variable_basic(type_variable(pt))))
1465  entity_type(e) = pt;
1466  else {
1467  type npt = make_type(is_type_variable,
1468  make_variable(make_basic(is_basic_pointer, pt),
1469  NIL, NIL));
1470  entity_type(e) = npt;
1471  }
1472  */
1473 
1475  }
1476  else
1477  {
1478  switch (type_tag(t)) {
1479  case is_type_variable:
1480  {
1481  /* Make e an array of pointers whose type is this of pt */
1482  variable v = type_variable(t);
1483  pips_debug(3,"Array of pointers\n");
1486  gen_nconc(variable_qualifiers(v),lq)));
1487  break;
1488  }
1489  case is_type_functional:
1490  {
1491  /* Make e a function returns a pointer */
1493  pips_debug(3,"Function returns a pointer \n");
1494  entity_type(e) =
1496  break;
1497  }
1498  default:
1499  {
1500  CParserError("Entity is neither an array of pointers nor a pointer to a function?\n");
1501  }
1502  }
1503  }
1504  ifdebug(3) {
1505  list pdl = NIL;
1506  pips_debug(3,"Ends with type \"%s\" for entity %s\n",
1508  entity_name(e));
1509  gen_free_list(pdl);
1510  }
1511 
1512 }
1513 
1515 {
1516  type t = entity_type(e);
1517  pips_debug(3,"Update array entity %s\n",entity_name(e));
1518 
1519  /* lq is for what ? e or le ????: lq should be for le*/
1520  if (type_undefined_p(t))
1521  {
1522  pips_debug(3,"First array dimension\n");
1523  entity_type(e) =
1525  CONS(DIMENSION,MakeDimension(le, lq),NIL),
1526  NIL));
1527  }
1528  else
1529  {
1530  pips_debug(3,"Next array dimension\n");
1531  if (type_variable_p(t))
1532  {
1533  variable v = type_variable(t);
1535  variable_dimensions(v) =
1537  CONS(DIMENSION, MakeDimension(le, lq), NIL));
1538  }
1539  else
1540  {
1541  CParserError("Dimension for not variable type\n");
1542  }
1543  }
1544 }
1545 
1546 /* Rename function oe if necessary.
1547  *
1548  * The function name may be wrong because not enough information was
1549  * available when it was created by FindOrCreateCurrentEntity().
1550  *
1551  * oe must be a function and not a pointer to a function
1552  *
1553  * oe should be added to the declarations of the current block
1554  */
1555 
1557 {
1558  entity ne = oe;
1559  string oen = entity_name(oe);
1560  const char* oeln = entity_local_name(oe);
1561  string sn = local_name_to_scope(oeln);
1562  //type oet = entity_type(oe);
1563 
1564  /* A C function or intrinsics name should include no scope
1565  information. But a functional typedef should. */
1566  if(!typedef_entity_p(oe) && !empty_string_p(sn)) {
1567  if(strchr(oen, MODULE_SEP)!=NULL) {
1568  //string mn = entity_module_name(ne);
1569  const char * ln = entity_user_name(ne);
1570  value voe = entity_initial(oe);
1572  stack ns = stack_copy(s);
1573 
1574  /* In fact, we'd like to know if it is found before we create it... */
1576  if(entity_undefined_p(ne)) {
1578  entity_type(ne) = copy_type(entity_type(oe));
1580  /* FI I do not understand how formal parameters could be declared before */
1581  if(value_undefined_p(voe) || value_unknown_p(voe))
1584  else {
1585  list dl = list_undefined;
1587 
1589  FOREACH(ENTITY, v, dl) {
1590  storage s = entity_storage(v);
1591  if(storage_formal_p(s)) {
1592  formal fs = storage_formal(s);
1593  formal_function(fs) = ne;
1594  }
1595  }
1596  }
1598  }
1599 
1600  pips_debug(1, "entity %s renamed %s\n", entity_name(oe), entity_name(ne));
1601 
1602  /* We assume oe is not already part of a declaration list since
1603  its formal parameters have been taken care of */
1605  }
1606  }
1607  free(sn);
1608  return ne;
1609 }
1610 
1611 /* The parser has found out that an entity is a function and partially
1612  sets its type. The function may also be an intrinsics and be
1613  already fully defined. */
1615 {
1616  type t = entity_type(oe);
1617  //string oeln = entity_local_name(oe);
1618  //string sn = local_name_to_scope(oeln);
1619  //entity ne = oe;
1620 
1621  pips_debug(3,"Update function entity \"%s\"\n",entity_name(oe));
1622 
1623  ifdebug(8) {
1624  pips_debug(8, "with type list la: ");
1625  if(ENDP(la)) {
1626  (void) fprintf(stderr, "empty list");
1627  }
1628  MAP(PARAMETER, at, {
1629  (void) fprintf(stderr, "%s, ", list_to_string(safe_c_words_entity(parameter_type(at), NIL)));
1630  }, la);
1631  (void) fprintf(stderr, "\n");
1632  }
1633 
1634  /* If oe is an intrinsics, nothing should be done if we are
1635  compiling a function that redeclares intrinsics, because they are
1636  usually badly or at least only partly redeclared.
1637 
1638  However, il should be updated if it's declared in a compilation unit
1639  as the header files may contain more up-to-date information than
1640  bootstrap. Or if its type has already been placed in the type
1641  stack and been undefined in the entity.
1642 
1643  Note that a user function might have the same name as a C
1644  intrinsic. Then we are in trouble.
1645  */
1646  if(intrinsic_entity_p(oe)
1649  && !type_undefined_p(entity_type(oe)))
1650  return;
1651 
1652  /* Is oe's name compatible with a function name? Well oe might be a
1653  pointer... */
1654  // pips_assert("A function name does not include a scope", empty_string_p(sn));
1655 
1656  if (type_undefined_p(t))
1658  else if(type_functional_p(t)) {
1659  /* FI: We used never to bump into this case... */
1661  functional_parameters(f) = la;
1662  }
1663  else {
1664  pips_internal_error("What should be done here?");
1665  CParserError("This entity must have undefined type\n");
1666  }
1667 
1668  pips_debug(3,"Update function entity \"%s\" with type \"\%s\"\n",
1669  entity_name(oe),
1671 }
1672 
1673 /* This function replaces the undefined field in t1 by t2.
1674 
1675  If t1 is an array type and the basic of t1 is undefined, it is
1676  replaced by the basic of t2.
1677 
1678  If t1 is a pointer type, if the pointed type is undefined it is
1679  replaced by t2.
1680 
1681  If t1 is a functional type, if the result type of t1 is undefined,
1682  it is replaced by t2.
1683 
1684  If t1 is a void type, then either t2 also is a void type or an
1685  error is raised.
1686 
1687  The function is recursive.
1688 
1689  FI: This function used to create sharing between t1 and t2, which
1690  creates problems when t2 is later freed. t1 may be updated and
1691  returned or a new type may be created. */
1692 
1694 {
1695  if (type_undefined_p(t1)) {
1696  if(!type_undefined_p(t2))
1697  return copy_type(t2);
1698  else
1699  return t2;
1700  }
1701 
1702  if(type_undefined_p(t2)) {
1703  /* This may happen when a type is implicitly declared as in
1704  "extern m[3];" */
1705  /* We used to use type_unknown when the type was implicit, but
1706  type_unknown does not let us store dimension information. We
1707  need here a new kind of basic, basic unknown or basic
1708  implicit. This would let us be more respectful of the source
1709  code, but requires a modification of the internal
1710  representation. It is mostly a prettyprint issue. See ticket
1711  225. */
1713  }
1714 
1715  switch (type_tag(t1))
1716  {
1717  case is_type_variable:
1718  {
1719  variable v = type_variable(t1);
1721  {
1722  pips_assert("type t2 is defined", !type_undefined_p(t2));
1723  if (type_variable_p(t2))
1728  CParserError("t1 is a variable type but not t2\n");
1729  }
1730  else
1731  {
1732  /* Basic pointer */
1734  {
1738  variable_qualifiers(v)));
1739  }
1740  else {
1741  /* t1 is already fully defined */
1742  if(type_equal_p(t1,t2))
1743  return t2;
1744  else if(overloaded_type_p(t1))
1745  return t2;
1746  else
1747  CParserError("This basic has an undefined field?\n");
1748  }
1749  }
1750  break;
1751  }
1752  case is_type_functional:
1753  {
1756  {
1757  type nt = type_undefined;
1758  if (type_undefined_p(t2))
1759  nt = make_type_unknown();
1760  else
1761  nt = copy_type(t2);
1763  }
1765  }
1766  case is_type_void:
1767  {
1768  if(type_void_p(t2)) {
1769  /* Redundant update */
1770  ;
1771  }
1772  else {
1773  /* Could be a pips internal error... */
1774  CParserError("void type to be updated by a non void type...\n");
1775  }
1776  return t1;
1777  }
1778  default:
1779  {
1780  CParserError("t1 has which kind of type?\n");
1781  }
1782  }
1783  return type_undefined;
1784 }
1785 
1786 
1787 // No Declaration Check for variables and functions
1789 
1791 {
1792  entity e = reference_variable(r);
1795 
1796  if(variable_entity_p(e)) {
1798  || gen_in_list_p(e, entity_declarations(cu))))
1799  {
1800  declarationerror_p = true;
1801  user_log("\n\nNo declaration of variable \"%s\" (\"%s\") in module \"%s\'\n",
1803  }
1804  }
1805  /* There can be a reference to variable of storage return when a
1806  function pointer is assigned a function */
1807  /* FI: this may be a bad decision choice to confuse a function and
1808  its return value. It might be better to keep storage "rom"
1809  systematically for functions and to restore this test. */
1810  /*
1811  // if(storage_return_p(entity_storage(e))){
1812  // declarationerror_p = true;
1813  // user_log("\n\nNo declaration of variable \"%s\" (\"%s\") in module \"%s\"\n",
1814  // entity_user_name(e),entity_name(e),get_current_module_name());
1815  }
1816  */
1817 
1818  return true;
1819 }
1820 
1821 
1822 static bool callnodeclfilter(call c)
1823 {
1824  entity e = call_function(c);
1825  if(value_code_p(entity_initial(e))) {
1828  {
1829  // Implicit declaration of an external function: returns an int
1830  // Compute arguments type from call c
1831  type ot = entity_type(e);
1832  // Too bad we assume the old type is no good
1835  NIL,
1836  NIL));
1837  list ptl = NIL;
1838  list args = call_arguments(c);
1839  list carg = list_undefined;
1840  type ft = type_undefined;
1841 
1842  for(carg=args; !ENDP(carg); POP (carg)) {
1843  expression ce = EXPRESSION(CAR(carg));
1844  type ct = expression_to_user_type(ce);
1845  /* Here, there is no known dummy parameter entity... unless
1846  we build a default dummy parameter, using unique names such as v1, v2, v3,.. */
1848 
1849  ptl = gen_nconc(ptl, CONS(PARAMETER, cp, NIL));
1850  }
1852 
1853  free_type(ot);
1854  entity_type(e) = ft;
1855 
1858  c_parser_user_warning("\n\nNo declaration of function %s in module %s\n"
1859  "Implicit declaration added\n",
1861  }
1862  }
1863 
1864  return true;
1865 }
1866 
1867 static void
1869 {
1870  declarationerror_p = false;
1873 
1874  if(declarationerror_p)
1875  CParserError("Illegal Input\n");
1876 }
1877 
1878 
1879 /* This function allocates the memory to the Current Compilation Unit */
1880 
1882 {
1884  entity var = entity_undefined;
1885 
1886  pips_debug(8,"MEMORY ALLOCATION BEGINS\n");
1887 
1888  /* Check that all variables used or defined are declared */
1890 
1891  /* Allocate variables */
1892  for(; !ENDP(ld); ld = CDR(ld)) {
1893  var = ENTITY(CAR(ld));
1895  storage s = entity_storage(var);
1896  type t = entity_type(var);
1897  type ut = ultimate_type(t);
1898 
1899  // Make sure that the ultimate type is variable */
1900  if(!type_variable_p(ut) && storage_ram_p(s)) {
1901  /* We are in trouble */
1902  pips_internal_error("Variable %s has not a variable type",
1903  entity_user_name(var));
1904  }
1905 
1906  // Add some preconditions here
1907  if(storage_ram_p(s)) {
1908  ram r = storage_ram(s);
1909  entity a = ram_section(r);
1910  /* check the type of variable here to avoid conflicting declarations */
1911  // External variable list: evl
1913  if(!gen_in_list_p(var, evl)) {
1916  && ram_offset(r) != DYNAMIC_RAM_OFFSET ) {
1917  if(first_p) {
1918  /* The C parser is no longer active when this warning is emitted.
1919  * It is not possible to rely on its line numbers.
1920  */
1921  // c_parser_user_warning
1923  ("Multiple declarations of variable \"%s\" in different files\n",
1924  entity_local_name(var));
1925  if(top_level_entity_p(a)
1927  /* No way to know if a pointer is initialized or
1928  not */
1929  ||value_code_p(entity_initial(var)))) {
1930  /* This may happen with variables such as
1931  "__morecore" which is a functional pointer to a
1932  malloc like function and which is declared in a
1933  header file. */
1934  ;
1935  }
1936  else {
1937  // CParserError("Fix your source code!\n");
1938  /* It may or not be an error, depending on conflicting
1939  * initializations or not. It seems better to leave
1940  * this for gcc or clang to decide before running
1941  * PIPS.
1942  */
1943  }
1944  /* Do not modify the initial allocation */
1945  ;
1946  }
1947  }
1948  else {
1950  add_C_variable_to_area(a,var);
1951  }
1952  }
1953  else {
1954  /* Do not allocate the memory for external variables:
1955  Set the offset of ram -2 which signifies UNKNOWN offset
1956  */
1957 
1958  // Check type here to avoid conflict declarations
1959  if(ram_offset(r) == UNKNOWN_RAM_OFFSET)
1961  }
1962  }
1963  }
1964  }
1965 }
1966 
1968 {
1970 }
1971 
1973 {
1975 }
1976 
1977 /* This function is for MemoryAllocation for Module of C programs*/
1978 
1980 {
1982  entity var = entity_undefined;
1983 
1984  pips_debug(8,"MEMORY ALLOCATION BEGINS\n");
1986  //print_entities(ld);
1987  for(; !ENDP(ld); ld = CDR(ld))
1988  {
1989  var = ENTITY(CAR(ld));
1990 
1992  {
1993  storage s = entity_storage(var);
1994  if(storage_ram_p(s))
1995  {
1996  ram r = storage_ram(s);
1997  entity a = ram_section(r);
2000  if(a == StackArea)
2002  else
2003  add_C_variable_to_area(a,var);
2004  }
2005  else{
2006  if(ram_offset(r) == UNKNOWN_RAM_OFFSET)
2008  }
2009  }
2010  if(storage_formal_p(s))
2011  {
2012  //DO NOTHING
2013  }
2014  }
2015  }
2016 }
2017 ␌
2018 /* If f has regular formal parameters, destroy them. */
2020 {
2021  value fv = entity_initial(f);
2022 
2023  pips_assert("The function value is defined", !value_undefined_p(fv));
2024  pips_assert("The entity has a functional type", type_functional_p(entity_type(f)));
2025  pips_assert("The entity is not a typedef", !typedef_entity_p(f));
2026 
2027  if(!value_undefined_p(fv)) {
2028  code fc = value_code(fv);
2029  list dl = code_declarations(fc);
2030  list cd = list_undefined;
2031  list formals = NIL;
2032 
2033  pips_assert("the value is code", value_code_p(fv));
2034 
2035  /* make a list of formal parameters */
2036  for(cd = dl; !ENDP(cd); POP(cd)) {
2037  entity v = ENTITY(CAR(cd));
2038  if(entity_formal_p(v)) {
2039  pips_debug(8, "Formal parameter: \"%s\"\n", entity_name(v));
2040  formals = gen_nconc(formals, CONS(ENTITY, v, NIL));
2041  }
2042  }
2043 
2044  /* Remove the formals from f's declaration list and from the
2045  symbol table */
2046  for(cd = formals; !ENDP(cd); POP(cd)) {
2047  entity p = ENTITY(CAR(cd));
2048  storage ps = entity_storage(p);
2049  formal pfs = storage_formal(ps);
2050 
2051  gen_remove(&code_declarations(fc), (void *) p);
2052  /* FI: The storage might point to another dummy argument
2053  (although it should not) */
2055  /* Let's hope there are no other pointers towards dummy formal parameters */
2056  //free_entity(p);
2057  }
2058  gen_free_list(formals);
2059  }
2060 }
2061 
2062 /* If f has dummy formal parameters, replace them by standard formal parameters */
2064 {
2065  value fv = entity_initial(f);
2066 
2067  pips_assert("The function value is defined", !value_undefined_p(fv));
2068  pips_assert("The entity has a functional type", type_functional_p(entity_type(f)));
2069  pips_assert("The entity is not a typedef", !typedef_entity_p(f));
2070 
2071  if(!value_undefined_p(fv)) {
2072  code fc = value_code(fv);
2074  list cd = list_undefined;
2075  list formals = NIL;
2076  string mn = string_undefined;
2077  // This is a minimal list of references. We need all references.
2078  //list refs1 = extract_references_from_declarations(dl);
2080 
2081  ifdebug(8) {
2082  int l2 = gen_length(refs);
2083 
2084  pips_debug(8, "refs (%d elements):\n", l2);
2085  print_references(refs);
2086  }
2087 
2088  pips_assert("the value is code", value_code_p(fv));
2089 
2090  /* make a list of formal dumy parameters; depending on the kind of
2091  function declaration, dummy formal parameters are used (new C
2092  function declaration style), or not (old C function declaration
2093  style).
2094 
2095  FI: Maybe, it would be better to unify the use of summy formal
2096  parameter in the parser?
2097  */
2098  for(cd = dl; !ENDP(cd); POP(cd)) {
2099  entity v = ENTITY(CAR(cd));
2100  if(entity_formal_p(v)) {
2101  pips_debug(8, "Formal parameter: \"%s\"\n", entity_name(v));
2103  formals = gen_nconc(formals, CONS(ENTITY, v, NIL));
2104  //pips_assert("v is a dummy parameter", dummy_parameter_entity_p(v));
2105  }
2106  }
2107 
2108  /* Is it a local function or global function? */
2109  if(top_level_entity_p(f))
2110  mn = strdup(entity_user_name(f));
2111  else
2112  /* mn = strdup(concatenate(entity_module_name(f),entity_local_name(f), NULL)); */
2113  mn = strdup(entity_local_name(f));
2114 
2115  /* Remore the dummy formals from f's declaration list (and from the
2116  symbol table?) and replace them by equivalent regular formal parameters */
2117  for(cd = formals; !ENDP(cd); POP(cd)) {
2118  entity p = ENTITY(CAR(cd));
2119  const char * pn = entity_user_name(p);
2120  entity new_p = entity_undefined;
2121  //storage ps = entity_storage(p);
2122  //formal pfs = storage_formal(ps);
2123 
2125  new_p = FindOrCreateEntity(mn, pn );
2127  entity_type(new_p) = copy_type(entity_type(p));
2129  pips_debug(8, "Formal dummy parameter \"%s\" is replaced "
2130  "by standard formal parameter \"%s\"\n",
2131  entity_name(p), entity_name(new_p));
2132 
2133  /* Substitute p by new_p in the declaration references for cases
2134  such as "foo(n, double a[n])" */
2135  /* This only works if the refs list points to the actual
2136  references and not to copies... */
2137  FOREACH(REFERENCE, r, refs){
2138  entity e = reference_variable(r);
2139 
2140  /* sg: this test used to be if e == p, but it missed some cases
2141  * because reference_variable may have been generated incorectly before
2142  * using a TOP_LEVEL variable instead of the dummy */
2143  if(same_entity_lname_p(e,p)) {
2144  reference_variable(r) = new_p;
2145  pips_debug(8, "reference %p to \"%s\" changed into reference to \"\%s\"\n",
2146  r, entity_name(p), entity_name(new_p));
2147  }
2148  }
2149 
2150  /* A substitution could be performed instead...*/
2151  gen_remove(&code_declarations(fc), (void *) p);
2153 
2154  /* FI: The storage might point to another dummy argument
2155  (although it should not) */
2156  //formal_function(pfs) = entity_undefined;
2157  /* Let's hope there are no other pointers towards dummy formal parameters */
2158  //free_entity(p); // FI: we may use them in the type data structures in spite of the MAP on refs?
2159  }
2160  }
2161  gen_free_list(dl);
2162 
2163  ifdebug(1) {
2164  dl = module_all_declarations(f);
2165  /* Check substitution in formal parameter declarations */
2166  ifdebug(8) {
2167  pips_debug(8, "list of declared variables:\n");
2168  print_entities(dl);
2169  (void) fprintf(stderr, "\n");
2170  }
2172  MAP(REFERENCE, r, {
2173  entity v = reference_variable(r);
2174  if(dummy_parameter_entity_p(v)) {
2175  pips_debug(8, "Substitution failed for reference %p and variable \"%s\"\n",
2176  r, entity_name(v));
2177  pips_internal_error("Failed substitution");
2178  }
2179  }, refs);
2180  gen_free_list(dl);
2181  }
2182 
2183  /* FI: just in case? */
2184  remove_entity_type_stacks(formals);
2185 
2186  /* Do not free the dummy formal parameter variable as they are
2187  preserved in the dummy field for accurate prettyprinting */
2188  /*
2189  MAP(ENTITY, df, {
2190  free_entity(df);
2191  }, formals);
2192  */
2193 
2194  free(mn);
2195  gen_free_list(formals);
2196  }
2197 }
2198 
2199 /* To chase formals in type declarations */
2200 //static list dummy_formal_list;
2201 //
2202 //static void cancel_dummy_reference(reference r)
2203 //{
2204 // entity v = reference_variable(r);
2205 //
2206 // pips_debug(8, "Reference to \"\%s\" found\n", entity_name(v));
2207 //
2208 // if(gen_in_list_p((void*) v, dummy_formal_list)) {
2209 // reference_variable(r) = entity_undefined;
2210 // pips_debug(8, "Reference to \"\%s\" removed\n", entity_name(v));
2211 // }
2212 //}
2213 
2214 /*
2215 //static void clean_up_dummy_parameter_type(type t, list fpl)
2216 //{
2217 // pips_internal_error("This function should not be called");
2218 // dummy_formal_list = fpl;
2219 // gen_multi_recurse(t, reference_domain, gen_true, cancel_dummy_reference, NULL);
2220 //}
2221 */
2222 
2223 /* If f has dummy formal parameters, replace them by standard formal parameters */
2225 {
2226  value fv = entity_initial(f);
2227 
2228  pips_assert("The function value is defined", !value_undefined_p(fv));
2229  pips_assert("The entity has a functional type", type_functional_p(entity_type(f)));
2230  pips_assert("The entity is not a typedef", !typedef_entity_p(f));
2231 
2232  if(!value_undefined_p(fv) && !value_intrinsic_p(fv)) {
2233  code fc = value_code(fv);
2234  list dl = code_declarations(fc);
2235  list cd = list_undefined;
2236  list formals = NIL;
2237  type ft = entity_type(f);
2239  list cformals = list_undefined;
2240  list cfp = list_undefined;
2241  int nformals=-1;
2242  int nfp = gen_length(fp);
2243 
2244  pips_assert("the value is code", value_code_p(fv));
2245 
2246  /* make a list of formal dummy parameters */
2247  for(cd = dl; !ENDP(cd); POP(cd)) {
2248  entity v = ENTITY(CAR(cd));
2249  if(entity_formal_p(v)) {
2250  pips_debug(8, "Formal dummy parameter: \"%s\"\n", entity_name(v));
2251  /* Since the compilation order is not known, the standard
2252  formal parameters may already exist and they should not be
2253  removed. */
2255  formals = gen_nconc(formals, CONS(ENTITY, v, NIL));
2256  }
2257  }
2258  nformals = gen_length(formals);
2259 
2260  /* Update the "dummy" field of the "parameter" data structure */
2261 
2262  if(nformals==nfp) {
2263  /* This special case could be ignored and handled like the next
2264  one to avoid cut-and-past and/or the definition of a new
2265  function. */
2266  for(cformals=formals, cfp = fp; !ENDP(cfp); POP(cformals), POP(cfp)) {
2267  parameter p = PARAMETER(CAR(cfp));
2268  entity ep = ENTITY(CAR(cformals));
2269  dummy d = parameter_dummy(p);
2270 
2271  if(dummy_identifier_p(d)) {
2272  entity oep = dummy_identifier(d);
2273 
2274  MAP(REFERENCE, r, {
2275  entity v = reference_variable(r);
2276 
2277  if(v==oep) {
2278  pips_debug(8, "Reference to \"\%s\" now refers \"\%s\"\n",
2279  entity_name(oep), entity_name(ep));
2280  reference_variable(r) = ep;
2281  }
2282  }, refs);
2283  }
2284 
2285  update_dummy_parameter(p, ep);
2286  }
2287  }
2288  else if(nformals>0) {
2289  int i = -1;
2290  for(cfp=fp, i= 1;!ENDP(cfp); POP(cfp), i++) {
2291  entity ep = find_ith_parameter(f,i);
2292  if(!entity_undefined_p(ep)) {
2293  parameter p = PARAMETER(CAR(cfp));
2294  dummy d = parameter_dummy(p);
2295 
2296  if(dummy_identifier_p(d)) {
2297  entity oep = dummy_identifier(d);
2298 
2299  MAP(REFERENCE, r, {
2300  entity v = reference_variable(r);
2301 
2302  if(v==oep) {
2303  pips_debug(8, "Reference to \"\%s\" now refers \"\%s\"\n",
2304  entity_name(oep), entity_name(ep));
2305  reference_variable(r) = ep;
2306  }
2307  }, refs);
2308  }
2309 
2310  update_dummy_parameter(p, ep);
2311  }
2312  }
2313  }
2314  else {
2315  /* no dummy naming information available as in foo(int); */
2316  ;
2317  }
2318 
2319  if(true) {
2320 
2321  /* FI: just in case? */
2322  remove_entity_type_stacks(formals);
2323 
2324  /* Remore the dummy formals from f's declaration list (and from
2325  the symbol table?) but keep all pointers towards them in the
2326  declarations as in "void foo(n,a[n])" */
2327  for(cd = formals; !ENDP(cd); POP(cd)) {
2328  entity p = ENTITY(CAR(cd));
2329  //type pt = entity_type(p);
2330  //storage ps = entity_storage(p);
2331  //formal pfs = storage_formal(ps);
2332 
2333  pips_debug(8, "Formal dummy parameter \"%s\" is removed from declarations\n",
2334  entity_name(p));
2335 
2336  //clean_up_dummy_parameter_type(pt, formals);
2337  gen_remove(&code_declarations(fc), (void *) p);
2338 
2339  /* FI: The storage might point to another dummy argument
2340  (although it should not) */
2341  //formal_function(pfs) = entity_undefined;
2342  /* Let's hope there are no other pointers towards dummy formal parameters */
2343  /* No, there may be occurences due to dependent types. */
2344  //free_entity(p);
2345  }
2346  }
2347  gen_free_list(formals);
2348  }
2349 }
2350 
2352 {
2353  for(list cel=el; !ENDP(cel); POP(cel)) {
2354  entity v = ENTITY(CAR(cel));
2355  if(dummy_parameter_entity_p(v)) {
2356  const char* mn = entity_local_name(f);
2357  const char * ln = entity_user_name(v);
2358  entity nv = FindOrCreateEntity(mn, ln);
2360  /* The copy could be avoided by substituting v->s with nv->s */
2361  stack ns = stack_copy(s);
2362  ENTITY_(CAR(cel)) = nv;
2363 
2364  /* Store type information. Might be useless. */
2367 
2368  /* Inherit any attribute you can */
2369  if(!type_undefined_p(entity_type(v)))
2370  entity_type(nv) = copy_type(entity_type(v));
2375  }
2376  }
2377 }
2378 ␌
2379 /* If necessary, create the return entity, which is a hidden variable
2380  used in PIPS internal representation to carry the value returned by
2381  a function. */
2383 {
2385  /* c_parser_user_warning() should not be called as it may be some
2386  * times too late to get significant line numbers.
2387  */
2388  c_parser_user_warning("Type of \"%s\" is undefined."
2389  " Return value cannot be created.\n",
2390  entity_user_name(f));
2391  }
2392  else {
2394 
2395  pips_debug(8, "For module \"%s\"\n", entity_name(f));
2396 
2397  if(type_functional_p(ft)) {
2399 
2400  if(type_undefined_p(rt)) {
2401  c_parser_user_warning("Return type of \"%s\" is undefined."
2402  " Return value cannot be created.\n",
2403  entity_user_name(f));
2404  }
2405  else if(!type_void_p(rt)) {
2406  /* Create the return value */
2407  const char* fn = entity_local_name(f);
2408  entity re = FindOrCreateEntity(fn,fn);
2409  if(type_undefined_p(entity_type(re))) {
2410  entity_type(re) = copy_type(rt);
2412  /* set the language */
2414  AddToDeclarations(re, f);
2415  }
2416  }
2417  }
2418  else
2419  pips_internal_error("This function should only be called with a function entity");
2420  }
2421 }
2422 ␌
2423 /* A subset of UpdateEntity, used when the function entity is already
2424  more defined because the return type is implicit. See call site
2425  cyacc.y
2426 
2427  The return value is created when needed.
2428 
2429  The dummy parameters are used to create the formal parameters.
2430  */
2432  stack FormalStack __attribute__ ((__unused__)),
2433  stack OffsetStack __attribute__ ((__unused__)))
2434 {
2437  list cl = list_undefined;
2438  int rank = 1; // formal parameter offset
2439 
2440  pips_assert("f has a functional type", type_functional_p(ft));
2441 
2443 
2444  for(cl = dl; !ENDP(cl); POP(cl)) {
2445  entity v = ENTITY(CAR(cl));
2446  if(dummy_parameter_entity_p(v)) {
2447  const char * ln = entity_user_name(v);
2448  const char* mn = entity_local_name(f);
2449  entity fp = FindEntity(mn, ln);
2450  if(entity_undefined_p(fp)) {
2451  fp = FindOrCreateEntity(mn, ln);
2452  entity_type(fp) = copy_type(entity_type(v));
2455  rank++;
2456  ENTITY_(CAR(cl)) = fp; // substitute v by fp in the declaration list
2457  }
2458  }
2459  }
2460 
2461 }
2462 ␌
2463 /* Update the entity with final type, storage and initial value;
2464  and also (sometimes?) declare it at the module level
2465 
2466  Replace dummy arguments by formal arguments for functions
2467 
2468  Generate the return variables for functions returning a result
2469 
2470  And probably much more...
2471  */
2472 
2474  stack OffsetStack, bool is_external, bool is_declaration)
2475 {
2476  //stack s = (stack) entity_storage(e);
2478  type t = entity_type(e);
2481  type t1,t2;
2483 
2484  pips_debug(3,"Update entity begins for \"%s\" with context %p\n", entity_name(e), context);
2485 
2486  /* If e is an intrinsics, nothing should be done, unless you are in
2487  the compilation unit: but the intrinsic type has already been
2488  put aside in the type stack linked to the entity and destroyed */
2490  return;
2491 
2492  if (lq != NIL)
2493  {
2494  /* tc must have variable type, add lq to its qualifiers */
2497  else if(type_void_p(tc))
2498  type_void(tc) = lq;
2499  /*else
2500  const void, void is not of type variable, store const where ?????????
2501  CParserError("Entity has qualifier but no type or is not variable type in the context?\n");*/
2503  }
2504 
2505  /************************* TYPE PART *******************************************/
2506 
2507  /* Use the type stack in entity_storage to create the final type for the entity*/
2508  //pips_assert("context type tc is defined", !type_undefined_p(tc));
2509  t2 = UpdateType(t,tc);
2510 
2511  if(t2!=t) {
2512  if(!stack_undefined_p(s)) {
2513  while (stack_size(s) > 1)
2514  {
2515  t1 = stack_pop(s);
2516  t2 = UpdateType(t1,t2);
2517  }
2518  if(type_undefined_p(t2)) {
2519  /* The default type is int, or a function returning an int */
2521  }
2522  }
2523  entity_type(e) = t2;
2524  }
2525 
2526  /* FI: it might be a good idea to use the type "unknown" or a
2527  future type "default" to improve the prettyprinting by not
2528  adding implicit "int" declarations. */
2529  if(type_undefined_p(entity_type(e))) {
2530  /* The default type is int */
2531  entity_type(e) =
2533  }
2534  /* FI: This elseif branch is apparently useless because the
2535  probleme must be dealt with later in the parser */
2536  else if(type_functional_p(entity_type(e))) {
2538  type rt = functional_result(f);
2539  if(type_undefined_p(rt)) {
2540  /* The default return type is int */
2541  functional_result(f) =
2543  }
2544  }
2545  pips_assert("the entity type is defined", !type_undefined_p(entity_type(e)));
2546 
2547  /************************* STORAGE PART *******************************************/
2548 
2549  /* FI: no longer true, I believe "this field is always
2550  pre-defined. It is temporarilly used to store a type. See cyacc.y
2551  rule direct-decl:" */
2552 
2553 
2555  pips_debug(3,"Current storage context is %d\n",
2558  if(typedef_entity_p(e)) {
2560  }
2561  }
2562  else if (!stack_undefined_p(FormalStack) && (FormalStack != NULL)
2563  && !stack_empty_p(FormalStack)) {
2564  entity function = stack_head(FunctionStack);
2566  pips_debug(3,"Create formal variable %s for function %s with offset %d\n",
2567  entity_name(e),entity_name(function),offset);
2568  if(!value_intrinsic_p(entity_initial(function))) {
2569  /* FI: Intrinsic do not have formal named parameters in PIPS
2570  RI, however such parameters can be named in intrinsic
2571  declarations. Problem with Validation/C_syntax/memcof.c */
2572  AddToDeclarations(e,function);
2573  }
2574  if(dummy_parameter_entity_p(e)) {
2575  if(typedef_entity_p(function) /* || type_variable_p(entity_type(function)) */)
2576  /* Storage does also matter for typedef (and function pointer) */
2577  /* How to access the information about the function type? */
2579  else
2581  }
2582  else
2583  /* FI: This branch should never be executed */
2585  }
2586  else if(type_variable_p(ultimate_type(entity_type(e)))) {
2587  /* The entities for the type_variable is added to the
2588  current module and the declarations*/
2589  entity function = get_current_module_entity();
2590 
2591  /* It is too early to use extern_entity_p() */
2592  //if(extern_entity_p(function, e))
2593  if(strstr(entity_name(e),TOP_LEVEL_MODULE_NAME) != NULL)
2595  /* Keyword EXTERN has just been encountered */
2596  /* Yes, but this may have been already recognized in
2597  FindOrCreateCurrentEntity() and this may not imply the
2598  declaration as extern is another declaration of e has
2599  already been encountered. */
2600  type et = ultimate_type(entity_type(e));
2601  if(type_functional_p(et))
2602  AddToExterns(e,function);
2603  }
2604 
2605  /* To avoid multiple declarations */
2606  list el = code_externs(value_code(entity_initial(function)));
2608  if(!gen_in_list_p(e, el) && gen_in_list_p(e, dl)) {
2609  if(compilation_unit_entity_p(function)) {
2610  /* Too late to check that the first declaration did not
2611  include an initialization */
2612  c_parser_user_warning("Multiple declarations of variable \"%s\".\n",
2613  entity_local_name(e));
2614  }
2615  else {
2616  user_log("Multiple declarations of variable \"%s\" in file\"%s\".\n",
2618  CParserError("Illegal Input");
2619  }
2620  }
2621 
2622  AddToDeclarations(e,function);
2623 
2624  // Check here if already stored the value
2626  entity_storage(e) =
2628  }
2630  /* The function should also added to the declarations */
2633  else if(!intrinsic_entity_p(e)) {
2634  /* We are defining the current module entity */
2635  CreateReturnEntity(e);
2636  }
2637  else {
2638  /* Test case C_syntax/function_name_conflict01.c */
2639  c_parser_user_warning("Intrinsic %s redefined.\n"
2640  "This is not supported by PIPS. Please rename \"%s\"\n",
2642  /* Unfortunately, an intrinsics cannot be redefined, just like a user function
2643  * or subroutine after editing because intrinsics are not handled like
2644  * user functions or subroutines. They are not added to the called_modules
2645  * list of other modules, unless the redefining module is parsed FIRST.
2646  * There is not mechanism in PIPS to control the parsing order.
2647  */
2648  CParserError("Name conflict between a "
2649  "function and an intrinsic\n");
2650  }
2652  }
2653  else
2654  pips_assert("not implemented yet", false);
2655 
2656 
2657  /************************* INITIAL VALUE PART ****************************************/
2660  //type t = entity_type(e);
2661  //type ut = ultimate_type(t);
2662  //if(type_functional(ut) && !typedef_entity_p(e))
2663  // entity_initial(e) = make_value_code(make_code(NIL, strdup(""),make_sequence(NIL),NIL, make_language_c()));
2664  //else
2665  // entity_initial(e) = make_value_unknown();
2666  }
2667 
2668  /* Be careful if standard arguments are needed: replace the dummy parameters */
2669  if(true || !is_declaration) {
2670  type t = entity_type(e);
2671  /* FI: intrinsic may need to be processed here if they use dynamic
2672  typing, a.k.a. dependent types but they do not have a code
2673  value!*/
2675  if(is_declaration) {
2676  /* They cannot be removed in general because they may appear
2677  in declarations as in foo(int n, double a[n]) */
2678  value ev = entity_initial(e);
2679  code ec = value_code(ev);
2680  list cmdl = code_declarations(ec);
2682 
2683  RemoveDummyArguments(e, refs);
2684 
2685  /* FI: I do not know if refs contains copies of references or just pointer to them */
2686  gen_free_list(refs);
2687  }
2688  else
2689  UseFormalArguments(e);
2690  }
2691  }
2692 
2693  /* If e is a function pointer, check the storage of its formal parameters */
2694  if(pointer_type_p(entity_type(e))) {
2696  if(type_functional_p(pt)) {
2697  code c = value_code(entity_initial(e));
2698 
2699  pips_assert("Although it's a pointer to a function, it has code...",
2701 
2702  if(code_undefined_p(c))
2703  pips_internal_error("Well, the code field is not defined yet...");
2704  else {
2705  list dl = code_declarations(c);
2706  list cl = list_undefined;
2707 
2708  for(cl=dl; !ENDP(cl); POP(cl)) {
2709  entity pe = ENTITY(CAR(cl));
2710 
2711  if(formal_parameter_p(pe)) {
2712  storage ps = entity_storage(pe);
2713 
2714  pips_debug(8, "Change storage from \"formal\" to \"rom\" for entity \"%s\"\n",
2715  entity_name(pe));
2716  free_storage(ps);
2718  }
2719  }
2720  }
2721  }
2722  }
2723 
2724  pips_debug(3,"Update entity ends for \"%s\" with type \"%s\" and storage \"%s\"\n",
2725  entity_name(e),
2728 
2729  pips_assert("Current entity is consistent",entity_consistent_p(e));
2730 }
2731 
2732 
2734  stack OffsetStack, bool is_external, bool is_declaration)
2735 {
2736  FOREACH(ENTITY, e, le) {
2737  if(!derived_entity_p(e))
2739  is_external,is_declaration);
2740  }
2741 }
2742 
2743 /* if returned entity != original entity, e **must** be freed,
2744  * otherwise an invalid entity is still tabulated */
2746 {
2747  entity ne = e;
2748  type et = entity_type(e);
2749  const char* eln = entity_local_name(e);
2750 
2751  if(static_module_name_p(eln) && !type_functional_p(et)) {
2752  /* The variable name is wrong */
2753  const char* neln = strstr(eln, FILE_SEP_STRING)+1;
2754  const char* emn = entity_module_name(e);
2755 
2756  ne = FindOrCreateEntity(emn, neln);
2757 
2758  entity_type(ne) = copy_type(entity_type(e));
2761 
2762  pips_assert("entity has type variable", type_variable_p(et));
2763  pips_debug(1, "Entity %s should have a functional type\n", entity_name(e));
2764  pips_debug(1, "New Entity %s created\n", entity_name(ne));
2765  /* Entity e should be removed... but it's pretty dangerous. */
2766  /* let the caller do it */
2767  }
2768 
2769  return ne;
2770 }
2771 
2773 {
2774  list ce = list_undefined;
2775  bool found = false;
2776 
2777  for(ce=le; !ENDP(ce); POP(ce)) {
2778  entity e = ENTITY(CAR(ce));
2779  entity ne = CleanUpEntity(e);
2780  if(ne!=e) {
2783  list de = list_undefined;
2784  storage s = entity_storage(e);
2785 
2786  /* update entity in module declarations */
2787  found = false;
2788  for(de=d; !ENDP(de); POP(de)) {
2789  entity ed = ENTITY(CAR(de));
2790  if(ed==e) {
2791  CAR(de).p = (gen_chunk *) ne;
2792  found = true;
2793  }
2794  }
2795  if(!found)
2796  pips_internal_error("Entity to be replaced not declared");
2797 
2798  /* Update storage area */
2799  found = false;
2800  if(storage_ram_p(s)) {
2801  ram r = storage_ram(s);
2802  entity a = ram_section(r);
2804  list lde = list_undefined;
2805 
2806  for(lde=ld; !ENDP(lde); POP(lde)) {
2807  entity ed = ENTITY(CAR(lde));
2808  if(ed==e) {
2809  found = true;
2810  CAR(lde).p = (gen_chunk *) ne;
2811  }
2812  }
2813  if(!found)
2814  pips_internal_error("Entity to be replaced not allocated in its ram area");
2815  }
2816  else {
2817  pips_internal_error("Unexpected storage kind");
2818  }
2819 
2820  /* Update entity in current entity list */
2821  CAR(ce).p = (gen_chunk *) ne;
2822 
2823  /* Remove entity from potentially removable externs and add it
2824  the new entity */
2825  gen_remove(&removable_extern_entities, (void *) e);
2827 
2828  /* Apparently, formal parameters may have been declared for such
2829  * an entity and PIPS code dumps when the symbol table is
2830  * written.
2831  *
2832  * See decl62.c and decl63.c
2833  */
2834  //free_entity(e);
2835  }
2836  }
2837 }
2838 
2839 
2840 /******************* ABSTRACT TYPE DECLARATION ***************************/
2841 
2843 {
2844  /* Update the entity with final type, storage */
2845 
2846  //stack s = (stack) entity_storage(e);
2848  type t = entity_type(e);
2851  type t1,t2;
2853 
2854  pips_debug(3,"Update abstract entity %s\n",entity_name(e));
2855 
2856  if (lq != NIL)
2857  {
2858  /* tc must have variable type, add lq to its qualifiers */
2861  /*else
2862  const void, void is not of type variable, store const where ?????????
2863  CParserError("Entity has qualifier but no type or is not variable type in the context?\n");*/
2864  }
2865 
2866  /************************* TYPE PART *******************************************/
2867 
2868  /* Use the type stack in entity_storage to create the final type for the entity*/
2869  t2 = UpdateType(t,tc);
2870 
2871  while (stack_size(s) > 1)
2872  {
2873  t1 = stack_pop(s);
2874  t2 = UpdateType(t1,t2);
2875  }
2876  entity_type(e) = t2;
2877 
2878  /************************* STORAGE PART *******************************************/
2879 
2881 }
2882 
2883 
2885 {
2887  if(!entity_undefined_p(f)) {
2889 
2890  gen_remove(&code_externs(fc), (void *) e);
2891  }
2892  else {
2893  /* This may happen when functional arguments are dealt with */
2894  c_parser_user_warning("The C parser should not execute this call.\n");
2895  }
2896 }
2897 
2899 {
2900  // the entity e can be extern variable and extern functions
2902 
2903  pips_assert("le is an entity list", entity_list_p(le));
2904 
2905  if(!gen_in_list_p(e, le))
2906  {
2907  pips_debug(5,"Add entity %s to extern declaration %s \n",
2909  pips_assert("e is an entity", entity_domain_number(e)==entity_domain);
2910  pips_assert("mod is an entity", entity_domain_number(mod)==entity_domain);
2913  CONS(ENTITY,e,NIL));
2914 
2916  pips_assert("le is an entity list", entity_list_p(le));
2917  }
2918 }
2919 
2920 /* FI: check the difference with AddEntityToDeclarations()
2921  *
2922  * Here, the declared entity is added to the module declarations only.
2923  */
2925 {
2927 
2928  if (!gen_in_list_p(e,dl))
2929  {
2930  pips_debug(5,"Add entity \"%s\" (\"%s\") to module %s\n",
2931  entity_user_name(e),
2932  entity_name(e),
2933  entity_user_name(mod));
2936  CONS(ENTITY,e,NIL));
2937  }
2938 }
2939 ␌
2940 /************************* STRUCT/UNION ENTITY*********************/
2941 
2943 {
2944  /* Update the derived entity with final type and rom storage.
2945  If the entity has bit type, do not need to update its type*/
2946  type t = entity_type(e);
2947  pips_debug(3,"Update derived entity %s\n",entity_name(e));
2948  if (!bit_type_p(t))
2949  {
2950  //stack s = (stack) entity_storage(e);
2954  type t1,t2;
2956 
2957  /* what about context qualifiers ? */
2958  t2 = UpdateType(t,tc);
2959 
2960  while (stack_size(s) > 1)
2961  {
2962  t1 = stack_pop(s);
2963  t2 = UpdateType(t1,t2);
2964  }
2965  entity_type(e) = t2;
2966 
2967  if(!ENDP(ql)) {
2968  if(type_void_p(t2)) {
2969  type_void(t2) = ql;
2970  }
2971  else if(type_variable_p(t2)) {
2972  if(pointer_type_p(t2)) {
2973  // The qualifiers must be stored on the effective pointed type
2974  // type pt = type_to_final_pointed_type(t2);
2975  // type pt = type_to_pointed_type(t2);
2977  if(type_void_p(pt))
2978  type_void(pt) = ql;
2979  else if(type_variable_p(pt)) {
2980  // If pt is a typedef, the typedef is altered...
2982  //variable_qualifiers(type_variable(t2)) = ql;
2983  }
2984  else if(type_functional_p(pt)) {
2985  /* What do we do for functional types for instance? */
2986  /* FI: I assume the qualifiers are carried by the
2987  result */
2989  type rt = functional_result(f);
2990  if(type_variable_p(rt))
2992  else
2993  pips_internal_error("???");
2994  }
2995  else {/* What do we do for functional types for instance? */
2996  // FI: I assume the qualifiers are carried by the result
2997  pips_internal_error("???");
2998  }
2999  }
3000  else {
3002  }
3003  }
3004  else
3005  pips_internal_error("unexpected type");
3006  /* Although it should be popped from the stack, the current
3007  context seems to be used later in case of typedef, such as
3008  seen in decl24.c */
3010  }
3011  }
3013 
3014  /* Temporally put the list of struct/union entities defined in
3015  decl_psec_list to initial value of ent */
3016  entity_initial(e) = (value) ld;
3017 
3018 }
3019 
3021 {
3022  list lres = NIL;
3023 
3024  if(!ENDP(le)) { /* To simplify debugging */
3025 
3026  pips_debug(8, "Begin\n");
3027 
3028  ifdebug(8) {
3029  pips_debug(8, "Input entity list: ");
3030  print_entities(le);
3031  fprintf(stderr, "\n");
3032  }
3033 
3034  FOREACH (ENTITY, e, le) {
3035  /* The list is stored there at line 2087 of cyacc.y (5 August
3036  2009) */
3037  //list ltmp = (list) entity_initial(e);
3038  list sltmp = (list) entity_initial(e);
3039  if(!ENDP(sltmp)) {
3040  // pips_assert("sltmp has only one element", gen_length(sltmp)==1);
3041  // statement stmp = STATEMENT(CAR(sltmp));
3042  // list ltmp = statement_declarations(stmp);
3043  list ltmp = sltmp;
3044 
3045  //pips_assert("sltmp is a continue statement list",
3046  // continue_statements_p(sltmp));
3047  pips_assert("e is an entity",
3048  check_entity(e) /* e->_type_==entity_domain*/ );
3049  pips_debug(8, "entity e: %s (%p)\n", entity_name(e), e);
3050 
3051  if (ltmp != NIL) {
3052  /* lres = gen_nconc(lres,ltmp);*/
3053  FOREACH(ENTITY, de, ltmp) {
3054 
3055  pips_assert("de is an entity", de->_type_==entity_domain);
3056  pips_debug(8, "entity de: %s (%p)\n", entity_name(de), de);
3057 
3058  if(!gen_in_list_p(de, lres)) {
3059  lres = gen_nconc(lres, CONS(ENTITY, de, NIL));
3060  }
3061  }
3062  }
3063  }
3064  /* The ltmp lists seem to be somehow shared as shown in
3065  * ngspice/main.tpips. The previous implementation of the
3066  * current function generated cyclic lists. The new
3067  * implementation is incompatible with a proper memory
3068  * management.
3069  *
3070  * I do not understand what's done in c_syntax/cyacc.y. The
3071  * trace obtained from C_syntax/ngspice01.c shows that the same
3072  * derived entities appear several times when dummy structs and
3073  * unions are embedded as in ngspice01.c
3074  */
3075  //gen_free_list(ltmp);
3077  }
3078  pips_assert ("an acyclic list is generated", !gen_list_cyclic_p (lres));
3079 
3080  ifdebug(8) {
3081  pips_debug(8, "Output entity list: ");
3082  if(ENDP(lres)) {
3083  fprintf(stderr, "NIL\n");
3084  }
3085  else {
3086  print_entities(lres);
3087  fprintf(stderr, "\n");
3088  }
3089  }
3090 
3091  pips_debug(8, "End\n");
3092  }
3093 
3094  return lres;
3095 }
3096 
3098 {
3099  FOREACH (ENTITY, e, le) {
3101  }
3102 }
3103 
3105 {
3106  // enum member with implicit values are not yet fully instantiated
3107  list cem = list_undefined;
3108  _int cv = 0;
3109 
3110  for(cem = lem; !ENDP(cem); POP(cem)) {
3111  entity em = ENTITY(CAR(cem));
3112  value emv = entity_initial(em);
3113 
3114  if(value_undefined_p(emv)) {
3115  entity_initial(em) =
3117  make_constant(is_constant_int, (void *) cv)));
3118  }
3119  else {
3120  symbolic s = value_symbolic(emv);
3121  constant c = symbolic_constant(s);
3122 
3125  symbolic_constant(s) = make_constant(is_constant_int, (void *) cv);
3126  }
3127  else if(constant_unknown_p(c)) {
3128  /* The expression evaluation may have been delayed */
3132  }
3134  pips_assert("The symbolic field is consisten", symbolic_consistent_p(s));
3135  }
3136  cv++;
3137  }
3138 }
3139 
3140 entity MakeDerivedEntity(string name, list members, bool is_external, int i)
3141 {
3142  entity ent = entity_undefined;
3143  switch (i) {
3144  case is_type_struct:
3145  {
3147  entity_type(ent) = make_type_struct(members);
3148  break;
3149  }
3150  case is_type_union:
3151  {
3153  entity_type(ent) = make_type_union(members);
3154  break;
3155  }
3156  case is_type_enum:
3157  {
3159  entity_type(ent) = make_type_enum(members);
3160  break;
3161  }
3162  }
3164  /* FI: What should the initial value be? */
3168 
3169  return ent;
3170 }
3171 
3172 /******************* MISC *******************/
3173 
3174  /* The storage part should not be called twice when reparsing compilation unit.
3175  We assume that double declarations are dealt with someone else */
3176 
3177 storage MakeStorageRam(entity v, bool is_external, bool is_static)
3178 {
3179  ram r = ram_undefined;
3183  area msa = type_area(entity_type(moduleStaticArea));
3185  area gsa = type_area(entity_type(globalStaticArea));
3187  //area heap = type_area (entity_type(HeapArea));
3188  //entity m = get_current_module_entity();
3189 
3190  pips_assert("RAM Storage is used only for variables", type_variable_p(entity_type(v)));
3191 
3192  if (is_external)
3193  {
3194  if (is_static)
3195  {
3197  moduleStaticArea,
3198  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(StaticArea,e) */,
3199  NIL);
3200 
3201  /*the offset must be recomputed lately, when we know for
3202  sure the size of the variables */
3204  || !gen_in_list_p(v,area_layout(msa)))
3205  area_layout(msa) = gen_nconc(area_layout(msa), CONS(ENTITY, v, NIL));
3206  }
3207  else
3208  {
3209  /* This must be a variable, not a function/typedef/struct/union/enum.
3210  The variable is declared outside any function, and hence is global*/
3211 
3213  globalStaticArea,
3214  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(get_top_level_entity(),e) */,
3215  NIL);
3216  /* the offset must be recomputed lately, when we know for
3217  sure the size of the variable */
3218  /* Global variable can be declared in many different file */
3219  if(!gen_in_list_p(v,area_layout(gsa)))
3220  area_layout(gsa) = gen_nconc(area_layout(gsa), CONS(ENTITY, v, NIL));
3221  }
3222  }
3223  else
3224  {
3225  /* ADD BLOCK SCOPE */
3226  if (is_static)
3227  {
3229  StaticArea,
3230  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(StaticArea,e) */,
3231  NIL);
3232  /*the offset must be recomputed lately, when we know for
3233  sure the size of the variable */
3234  area_layout(lsa) = gen_nconc(area_layout(lsa), CONS(ENTITY, v, NIL));
3235  }
3236  else
3237  {
3238  int s = 0;
3239  if(!SizeOfArray(v, &s))
3240  {
3242  StackArea,
3244  NIL);
3246  }
3247  else {
3249  DynamicArea,
3250  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(DynamicArea,e) */,
3251  NIL);
3252  /* the offset must be recomputed lately, when we know for
3253  sure the size of the variable */
3254  area_layout(dsa) = gen_nconc(area_layout(dsa), CONS(ENTITY, v, NIL));
3255  }
3256  }
3257  }
3258  return make_storage_ram(r);
3259 }
3260 
3261 string CreateMemberScope(string derived, bool is_external)
3262 {
3263  /* We have to know the context :
3264  - if the struct/union is declared outside any function, its scope is the CurrentCompilationUnit
3265  - if the struct/union is declared inside a function, we have to know the CurrentBlock,
3266  which is omitted for the moment
3267  - if the function is static, its scope is CurrentCompilationUnit!CurrentModule
3268  - if the function is global, its scope is CurrentModule
3269 
3270  The name of the struct/union is then added to the field entity name, with
3271  the MEMBER_SEP_STRING */
3272 
3273  string s = string_undefined;
3274 
3275  pips_debug(3,"Struc/union name is %s\n",derived);
3276 
3277  if (is_external)
3279  else {
3280  string scope = scope_to_block_scope(GetScope());
3281 
3282  pips_assert("scope is a block scope", string_block_scope_p(scope));
3283 
3285  s = strdup(concatenate(/*compilation_unit_name,*/
3287  scope, derived, MEMBER_SEP_STRING, NULL));
3288  else
3290  scope, derived, MEMBER_SEP_STRING, NULL));
3291  }
3292 
3293  pips_debug(3,"The struct/union member's scope is %s\n",s);
3294 
3295  return s;
3296 }
3297 
3298 
3299 value MakeEnumeratorInitialValue(list enum_list, int counter)
3300 {
3301  /* The initial value = 0 if this is the first member in the enumerator list
3302  else, it is equal to : intial_value(predecessor) + 1 */
3303  value v = value_undefined;
3304  if (counter == 1)
3306  else
3307  {
3308  /* Find the predecessor of the counter-th member */
3309  entity pre = ENTITY(gen_nth(counter-1, enum_list));
3310  value vp = entity_initial(pre);
3311  if (value_constant_p(vp))
3312  {
3313  constant c = value_constant(vp);
3314  if (constant_int_p(c))
3315  {
3316  int i = constant_int(c);
3318  }
3319  }
3320  }
3321  return v;
3322 }
3323 
3325 {
3326  type ta = entity_type(a);
3327  area aa = type_area(ta);
3328  int offset = area_size(aa);
3329 
3330  pips_assert("Not used", false);
3331 
3332  /* Update the size and layout of the area aa.
3333  This function is called too earlier, we may not have the size of v.
3334  To be changed !!!
3335 
3336  FI: who wrote this? when should the offsets be computed? how do we deal with
3337  scoping?
3338  */
3339 
3340  pips_assert("Type is correctly defined", CSafeSizeOfArray(v)!=0);
3341 
3342  /* area_size(aa) = offset + 0; */
3343  area_size(aa) = offset + CSafeSizeOfArray(v);
3344  area_layout(aa) = gen_nconc(area_layout(aa), CONS(ENTITY, v, NIL));
3345  return offset;
3346 }
3347 
3349 {
3350  /* l1 is a list of parameter names and it represents the exact order in the parameter list
3351  l2 is a list of entities with their type, storage,... and the order can be different from l1
3352  In addition, l2 can be incomplete wrt l1, so other entities must be created from l1, with
3353  default type : scalar integer variable.
3354 
3355  We create the list of parameters with the order of l1, and the parameter type and mode
3356  are retrieved from l2.
3357 
3358  Since the offset of formal argument in l2 can be false, we have to update it here by using l1 */
3359  list l = NIL;
3360  int offset = 1;
3361  entity function = stack_head(FunctionStack);
3362  FOREACH(STRING, s,l1)
3363  {
3365  if (parameter_undefined_p(p))
3366  {
3367  /* s is not declared in l2, create the corresponding entity/ formal variable
3368  and add it to the declaration list, because it cannot be added with par_def in l2*/
3369  entity ent = FindOrCreateEntity(entity_user_name(function),s);
3371  entity_type(ent) = make_type_variable(v);
3373  AddToDeclarations(ent,function);
3374  p = make_parameter(entity_type(ent),
3375  make_mode_value(),
3376  make_dummy_identifier(ent)); // FI: could be unknown?
3377  }
3378  l = gen_nconc(l,CONS(PARAMETER,p,NIL));
3379  offset++;
3380  }
3381  return l;
3382 }
3383 
3385 {
3386  FOREACH(ENTITY,e,l)
3387  {
3388  const char* name = entity_user_name(e);
3389  if (strcmp(name,s)==0)
3390  {
3391  type t = entity_type(e);
3392  mode m = make_mode_value(); /* to be verified in C, when by reference, when by value*/
3393  /*
3394  What about the storage of
3395 
3396  void AMMPmonitor( vfs,ffs,nfs,op )
3397  int (*vfs[])(),(*ffs[])();
3398  int nfs;
3399  FILE *op;*/
3400 
3401  storage st = entity_storage(e);
3402  if (storage_formal_p(st))
3403  {
3404  formal f = storage_formal(st);
3405  formal_offset(f) = offset;
3406  }
3407  return make_parameter(t,m,make_dummy_identifier(e)); // FI: Could be entity_undefined
3408  }
3409  }
3410  return parameter_undefined;
3411 }
3412 
3414 {
3415  if (!intrinsic_entity_p(e))
3416  {
3417  bool already_here = false;
3418  //string n = top_level_entity_p(e)?entity_local_name(e):entity_name(e);
3419  const char* n = entity_local_name(e);
3420  MAP(STRING,s,
3421  {
3422  if (strcmp(n, s) == 0)
3423  {
3424  already_here = true;
3425  break;
3426  }
3427  }, CalledModules);
3428 
3429  if (! already_here)
3430  {
3431  pips_debug(2, "Adding %s to list of called modules\n", n);
3433  }
3434  }
3435 }
3436 
3437 
3438 
3439 /******************** STACK *******************************/
3440 
3441 /* Pop n times the stack s*/
3442 void NStackPop(stack s, int n)
3443 {
3444  while (n-->0)
3445  gen_free(stack_pop(s));
3446 }
3447 
3448 /* The OffsetStack is poped n times, where n is the number of formal arguments
3449  of the actual function */
3451 {
3452  int n = basic_int((basic) stack_head(OffsetStack));
3454 }
3455 
3456 /* The OffsetStack is pushed incrementally */
3458 {
3459  int i = basic_int((basic) stack_head(OffsetStack));
3460  stack_push((char *) make_basic_int(i+1),OffsetStack);
3461 }
3462 ␌
3463 /* Be careful if the initial value has already been set.
3464  *
3465  * Detect double definitions when possible
3466  *
3467  * Take care of the special case of pointers to functions.
3468  */
3470 {
3471  value oiv = entity_initial(v);
3472 
3473  if(!value_undefined_p(oiv) && value_unknown_p(oiv)) {
3474  free_value(oiv);
3476  oiv = value_undefined;
3477  }
3478 
3479  if(!value_undefined_p(oiv)) {
3481  /* The compilation unit has already
3482  been scanned once for
3483  declarations. Double definitions
3484  are no surprise...*/
3485  if(value_code_p(oiv)) {
3486  /* Generate initializations for pointers to functions and arrays
3487  of pointers to functions */
3488  code c = value_code(oiv);
3490 
3492  }
3493  }
3494  else {
3495  type vt = entity_type(v);
3497  : ultimate_type(entity_type(v));
3498  if(!type_undefined_p(uvt) &&
3499  ((pointer_type_p(uvt) &&
3501  || type_functional_p(uvt)) ) {
3502  /* A pointer to a function already has value code as initial
3503  value. We may not even know yet it's a pointer... */
3504  code c = value_code(oiv);
3506 
3508  //c_parser_user_warning("The initialization of a function pointer is lost\n");
3509  }
3510  else {
3512  "double definition of initial"
3513  " value for variable \"%s\"", entity_name(v));
3514 
3515  // FI: I am not sure it so good to put any junk in any format in the
3516  // Warning file. FC: Indeed:-)
3517 
3518  string initv = expression_to_string(nie);
3519  string currv;
3520  if(value_expression_p(oiv))
3521  currv = expression_to_string(value_expression(oiv));
3522  else
3523  asprintf(&currv, "value tag: %d", value_tag(entity_initial(v)));
3524 
3525  pips_user_warning("New initial value expression:\n%s"
3526  "Current initial value:\n%s",
3527  initv, currv);
3528  free(initv);
3529  free(currv);
3530  pips_internal_error("Scoping might be the reason.");
3531  }
3532  }
3533  }
3534 
3537 }
3538 
3539 /* This is designed for standard C functions, not for compilation units. */
3541 {
3542  list dl = statement_declarations(s);
3543  bool failure_p = false;
3544 
3545  FOREACH(ENTITY, e, dl) {
3546  int n = gen_occurences(e, dl);
3547  if(n>1) {
3548  /* e must be a function: they can be declared several times */
3549  type t = ultimate_type(entity_type(e));
3550 
3551  if(!type_functional_p(t)) {
3552  pips_debug(0, "Entity \"%s\" declared %d times.\n", entity_name(e), n);
3553  failure_p = true;
3554  }
3555  }
3556  }
3557  if(failure_p)
3558  pips_internal_error("Module declarations are not unique");
3559 
3560  return !failure_p;
3561 }
3562 
3563 /* if qualifier "nq" does not already belong to qualifier list "ql",
3564  * add it in front of the list. The list is probably reversed
3565  * somewhere else... for instance by the parsing grammar rules
3566  */
3568 {
3569  bool found = false; // FI: Should never be useful...
3570  list nql = ql;
3571 
3572  FOREACH(QUALIFIER, q, ql) {
3573  if(qualifier_equal_p(q, nq)) {
3574  /* FI: either the context was not
3575  stacked or it was not used and
3576  emptied... */
3577  c_parser_user_warning("Dupliquate qualifier \"%s\"\n",
3578  qualifier_to_string(q));
3579  found = true;
3580  }
3581  }
3582 
3583  if(!found)
3584  //c_parser_context_qualifiers(ycontext) =
3585  nql = CONS(QUALIFIER, nq, ql);
3586 
3587  return nql;
3588 }
3589 ␌
3590 static bool buffer_initialized_p = false;
3591 
3593 {
3594  buffer_initialized_p = false;
3595 }
3596 
3597 /* Analyze information about user line number provided by the C preprocessor
3598  * and by PIPS file splitter and return the C line number in the source file.
3599  *
3600  * We do not have specs and must evolve with C preprocessors such as cpp.
3601  *
3602  * We assume that information about the lines in the included files is
3603  * only provided for compilation unit.
3604  *
3605  * We assume that information about user line in a module is always related
3606  * to the user source file, and that the first line has been generated
3607  * by PIPS file splitter with syntax "x nnn", with no information about
3608  * the user source file name.
3609  *
3610  * See examples line00.c, line01.c, line02.c and line03.c. And do not forget
3611  * cominc02 for the compilation unit case. And missing01.c for synthesized
3612  * code.
3613  *
3614  * More examples needed for #include lines placed within a function body,
3615  * with C code or preprocessor definitions: line04 and line05.
3616  */
3618 {
3619  // In compilation units, ignore information about include files
3620  // Could be used so size "buffer", but not "init_buffer"
3621  // int s = strlen(line);
3622  char buffer[1024];
3623  static char init_buffer[1024];
3624 
3625  pips_debug(9,"Pragma-like comment %s\n",line);
3626 
3627  /* the C preprocessors, such as cpp, and PIPS file splitter provide
3628  * line information in pragmas which are not #line pragmas.
3629  *
3630  * Not too sure about C source code generated by PIPS by passes
3631  * initializer, clone, outlining, inlinging...
3632  */
3633 
3634  if(/* strstr(line, "#line")==line && */ strlen(line)>=4) {
3635  int initial_C_line_number = -1;
3636  int items = sscanf(line+1, "%d %s", &initial_C_line_number, buffer);
3637  if(items==2) {
3638  // if(C_line_number==UNDEFINED_C_LINE_NUMBER) {
3639  //if(C_line_number==FIRST_C_LINE_NUMBER) {
3640  // Local files are named either "./foo.c" or "foo.c"
3641  int skip = 0;
3642  if(buffer[1]=='.' && buffer[2]=='/') {
3643  skip = 2;
3644  buffer[2] = '"';
3645  }
3646  if(!buffer_initialized_p) {
3647  //if(strstr(buffer, ".h"))
3648  //fprintf(stderr, "Abnormal file name %s\n", buffer);
3649  buffer_initialized_p = true;
3650  C_line_number = initial_C_line_number;
3651  C_line_increment = 1;
3652  (void) strcpy(init_buffer, buffer+skip);
3653  }
3654  else if(same_string_p((string) (buffer+skip), (string) init_buffer)) {
3655  C_line_increment = 1;
3657  && C_line_number>initial_C_line_number) {
3658  int d = C_line_number-initial_C_line_number;
3660  C_line_number = initial_C_line_number;
3661  }
3662  else {
3663  /* Not to sure about this case */
3664  C_line_number = initial_C_line_number;
3665  }
3666  }
3667  else {
3668  /* The next lines have been imported from an included file.
3669  * Ignore information about include files, preserve the
3670  * current C_line_number.
3671  */
3672  C_line_increment = 0;
3673  }
3674  }
3675  else if(items==1) {
3676  /* Not to sure about this case: internal error? */
3677  C_line_number = initial_C_line_number;
3678  }
3679  else {
3680  // items==0
3681  pips_user_warning("No line number after a #: \"%s\".\n", line);
3682  CParserError("Ill. formated # pragma.\n");
3683  }
3684  }
3685  return C_line_number;
3686 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
void user_log(const char *format,...)
Definition: message.c:234
void pips_log_alist(const pips_log_t tag, const string pips_pass, const string pips_owner, const string pips_func, const string pips_file, const int pips_line, const string user_func, const string user_file, const int user_line, const int user_line2, const string stmt, const string suggestion, const string format, va_list *args)
log entry with unprocessed format/alist arguments
Definition: message.c:1200
string get_pips_current_pass_name(void)
Export this piece of information to customize warning functions in passes.
Definition: message.c:77
string get_pips_current_module(void)
Definition: message.c:82
dummy make_dummy_identifier(entity _field_)
Definition: ri.c:620
syntax make_syntax_application(application _field_)
Definition: ri.c:2512
functional make_functional(list a1, type a2)
Definition: ri.c:1109
call make_call(entity a1, list a2)
Definition: ri.c:269
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
value make_value_unknown(void)
Definition: ri.c:2847
value make_value_expression(expression _field_)
Definition: ri.c:2850
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
type make_type_union(list _field_)
Definition: ri.c:2733
application make_application(expression a1, list a2)
Definition: ri.c:56
value make_value_code(code _field_)
Definition: ri.c:2835
bool symbolic_consistent_p(symbolic p)
Definition: ri.c:2342
subscript make_subscript(expression a1, list a2)
Definition: ri.c:2327
type make_type_variable(variable _field_)
Definition: ri.c:2715
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
storage make_storage_rom(void)
Definition: ri.c:2285
value make_value_constant(constant _field_)
Definition: ri.c:2841
type copy_type(type p)
TYPE.
Definition: ri.c:2655
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
type make_type_struct(list _field_)
Definition: ri.c:2730
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
type make_type_functional(functional _field_)
Definition: ri.c:2718
type make_type_void(list _field_)
Definition: ri.c:2727
basic make_basic_pointer(type _field_)
Definition: ri.c:179
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
entity check_entity(entity p)
Definition: ri.c:2527
constant make_constant_int(intptr_t _field_)
Definition: ri.c:409
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
symbolic make_symbolic(expression a1, constant a2)
Definition: ri.c:2369
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
value copy_value(value p)
VALUE.
Definition: ri.c:2784
area make_area(intptr_t a1, list a2)
Definition: ri.c:98
code make_code(list a1, string a2, sequence a3, list a4, language a5)
Definition: ri.c:353
storage make_storage_formal(formal _field_)
Definition: ri.c:2282
void free_expression(expression p)
Definition: ri.c:853
void free_storage(storage p)
Definition: ri.c:2231
language make_language_c(void)
Definition: ri.c:1253
type make_type_unknown(void)
Definition: ri.c:2724
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
void free_type(type p)
Definition: ri.c:2658
dummy make_dummy_unknown(void)
Definition: ri.c:617
void free_basic(basic p)
Definition: ri.c:107
type make_type_enum(list _field_)
Definition: ri.c:2736
storage make_storage_ram(ram _field_)
Definition: ri.c:2279
mode make_mode_value(void)
Definition: ri.c:1353
sequence make_sequence(list a)
Definition: ri.c:2125
storage make_storage_return(entity _field_)
Definition: ri.c:2276
bool entity_consistent_p(entity p)
Definition: ri.c:2530
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
syntax make_syntax_subscript(subscript _field_)
Definition: ri.c:2509
void free_value(value p)
Definition: ri.c:2787
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
value make_value_symbolic(symbolic _field_)
Definition: ri.c:2838
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
string list_to_string(list l)
Return the malloc()ed version of the concatenation of all the strings in the list.
Definition: args.c:74
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
static list lexp
bool c_parser_error(const char *func, const char *msg)
Output a parser message error.
Definition: c_parser.c:266
list CalledModules
Definition: c_parser.c:51
string compilation_unit_name
cproto-generated files
Definition: c_parser.c:49
stack get_from_entity_type_stack_table(entity key)
Definition: c_parser.c:146
bool compilation_unit_parser_is_running_p
To pass down the information to functions used by the syntactical analyzer.
Definition: c_parser.c:541
stack OffsetStack
Definition: c_parser.c:120
stack FunctionStack
Definition: c_parser.c:118
void remove_entity_type_stack(entity e)
Definition: c_parser.c:156
void put_to_entity_type_stack_table(entity key, stack value)
Definition: c_parser.c:139
list removable_extern_entities
Definition: c_parser.c:542
string get_c_parser_current_user_input_file_name()
Definition: c_parser.c:89
void remove_entity_type_stacks(list el)
Definition: c_parser.c:179
stack FormalStack
Definition: c_parser.c:119
stack ContextStack
Definition: c_parser.c:117
string get_c_parser_current_input_file_name()
Definition: c_parser.c:58
statement ModuleStatement
Definition: c_parser.c:53
#define c_parser_context_storage(x)
#define c_parser_context_qualifiers(x)
#define c_parser_context_static(x)
#define c_parser_context_type(x)
struct _newgen_struct_type_ * type
#define c_parser_context_typedef(x)
#define c_parser_context_scope(x)
void remove_LFs_from_C_comment(int)
Remove "extra_LF" trailing LF from C_current_comment if they can be found at the end of the comment s...
Definition: clexer.c:1398
entity DynamicArea
These global variables are declared in ri-util/util.c.
Definition: area.c:57
c_parser_context GetContext(void)
Definition: cyacc.tab.c:458
entity HeapArea
Definition: area.c:59
int get_previous_c_lineno(void)
Definition: clexer.c:1115
entity StaticArea
Definition: area.c:58
#define c_parser_user_warning(...)
string get_c_parser_current_scope(void)
Definition: cyacc.tab.c:569
int get_current_C_line_number(void)
Definition: clexer.c:1146
int ScopeStackSize(void)
Definition: cyacc.tab.c:366
int C_line_increment
from "clex.l"
Definition: c_syntax.h:296
string scope_to_block_scope(string)
Allocate a new string containing only block scope information.
Definition: cyacc.tab.c:268
entity StackArea
Definition: area.c:60
string GetParentScope(void)
Definition: cyacc.tab.c:387
string pop_block_scope(string)
The scope is moved up the scope tree and a NULL is return when there are no more scope to explore.
Definition: cyacc.tab.c:235
int get_previous_C_line_number(void)
Should be called just before get_current_C_line_number.
Definition: clexer.c:1161
string GetScope(void)
Definition: cyacc.tab.c:371
int get_declaration_counter(void)
Definition: cyacc.tab.c:497
int c_lineno
the file read in by the c_lexer
Definition: c_syntax.h:293
void CCompilationUnitMemoryReallocation(entity module)
Definition: util.c:1972
void MakeCurrentCompilationUnitEntity(const char *name)
A compilation unit is also considered as a module.
Definition: util.c:328
list MakeParameterList(list l1, list l2, stack FunctionStack)
Definition: util.c:3348
string CreateMemberScope(string derived, bool is_external)
Definition: util.c:3261
void AddToDeclarations(entity e, entity mod)
FI: check the difference with AddEntityToDeclarations()
Definition: util.c:2924
bool CheckExternList()
Definition: util.c:1025
static bool declarationerror_p
Definition: util.c:1788
void c_parser_user_warning_alist(const char *pips_func, const char *pips_file, const int pips_line, const char *format, va_list *args)
Compared to pips_user_warning(), the name of the calling function is lost, which does not help mainte...
Definition: util.c:60
void c_parser_user_warning_func(const char *pips_func, const char *pips_file, const int pips_line, const char *format,...)
Definition: util.c:112
static entity CleanUpEntity(entity e)
if returned entity != original entity, e must be freed, otherwise an invalid entity is still tabulate...
Definition: util.c:2745
storage MakeStorageRam(entity v, bool is_external, bool is_static)
The storage part should not be called twice when reparsing compilation unit.
Definition: util.c:3177
void MakeTopLevelEntity()
Definition: util.c:157
static bool buffer_initialized_p
Definition: util.c:3590
expression MemberDerivedIdentifierToExpression(type t, string m)
Definition: util.c:463
entity FindEntityFromLocalNameAndPrefixAndScope(string name, string prefix, string scope)
The parameter "scope" is potentially destroyed.
Definition: util.c:850
int analyze_preprocessor_line(string line, int C_line_number)
Analyze information about user line number provided by the C preprocessor and by PIPS file splitter a...
Definition: util.c:3617
expression MakeFunctionExpression(expression e, list le)
e is now owned by returned expression and must not be used any longer
Definition: util.c:368
void CCompilationUnitMemoryAllocations(entity module, bool first_p)
This function allocates the memory to the Current Compilation Unit.
Definition: util.c:1881
entity FindOrCreateEntityFromLocalNameAndPrefix(string name, string prefix, bool is_external)
Definition: util.c:811
void CModuleMemoryAllocation(entity module)
This function is for MemoryAllocation for Module of C programs.
Definition: util.c:1979
void NStackPop(stack s, int n)
Pop n times the stack s.
Definition: util.c:3442
void UpdateArrayEntity(entity e, list lq, list le)
Definition: util.c:1514
void CCompilationUnitMemoryAllocation(entity module)
Definition: util.c:1967
expression MakeArrayExpression(expression exp, list lexp)
FI: this function is called for a bracketed comma expression.
Definition: util.c:713
void reset_preprocessor_line_analysis(void)
Definition: util.c:3592
static int get_current_dummy_parameter_number(void)
Definition: util.c:147
void ResetCurrentCompilationUnitEntity(bool is_compilation_unit_parser)
Definition: util.c:349
entity FindOrCreateCurrentEntity(string name, stack ContextStack __attribute__((__unused__)), stack FormalStack, stack FunctionStack, bool is_external)
This function finds or creates the current entity.
Definition: util.c:1088
void set_entity_initial(entity v, expression nie)
Be careful if the initial value has already been set.
Definition: util.c:3469
entity MakeDerivedEntity(string name, list members, bool is_external, int i)
Definition: util.c:3140
void put_new_typedef(const char *name)
This function is used by libraries "step"* and "task_parallelization".
Definition: util.c:1078
entity get_current_compilation_unit_entity()
Definition: util.c:320
void UseDummyArguments(entity f)
If f has regular formal parameters, destroy them.
Definition: util.c:2019
entity FindEntityFromLocalName(string name)
Definition: util.c:778
void UpdateDerivedEntity(list ld, entity e, stack ContextStack)
Definition: util.c:2942
type UpdateFinalPointer(type pt, type t)
Definition: util.c:1427
static void set_current_dummy_parameter_number(int n)
Definition: util.c:139
void UpdateEntities(list le, stack ContextStack, stack FormalStack, stack FunctionStack, stack OffsetStack, bool is_external, bool is_declaration)
Definition: util.c:2733
void StackPop(stack OffsetStack)
The OffsetStack is poped n times, where n is the number of formal arguments of the actual function.
Definition: util.c:3450
dimension MakeDimension(list le, list ql)
Definition: util.c:1389
expression MemberIdentifierToExpression(expression e, string m)
Definition: util.c:498
void UpdatePointerEntity(entity e, type pt, list lq)
Definition: util.c:1444
entity make_C_constant_entity(string name, tag bt, size_t size)
Definition: util.c:269
void InitializeEnumMemberValues(list lem)
Definition: util.c:3104
void UpdateFunctionEntity(entity oe, list la)
The parser has found out that an entity is a function and partially sets its type.
Definition: util.c:1614
void UseFormalArguments(entity f)
If f has dummy formal parameters, replace them by standard formal parameters.
Definition: util.c:2063
static void nodecl_p(entity __attribute__((unused)) module, statement stat)
Definition: util.c:1868
void CleanUpEntities(list le)
Definition: util.c:2772
entity CreateEntityFromLocalNameAndPrefix(string name, string prefix, bool is_external)
Definition: util.c:962
static bool referencenodeclfilter(reference r)
Definition: util.c:1790
entity get_top_level_entity()
Definition: util.c:152
void UpdateParenEntity(entity e, list lq)
Definition: util.c:1368
void AddToExterns(entity e, entity mod)
Definition: util.c:2898
parameter FindParameterEntity(string s, int offset, list l)
Definition: util.c:3384
void SubstituteDummyParameters(entity f, list el)
Definition: util.c:2351
static bool callnodeclfilter(call c)
Definition: util.c:1822
void RemoveFromExterns(entity e)
Definition: util.c:2884
void init_c_areas()
In C we have 4 areas.
Definition: util.c:186
static int current_dummy_parameter_number
The data structure to tackle the memory allocation problem due to reparsing of compilation unit.
Definition: util.c:137
bool check_declaration_uniqueness_p(statement s)
This is designed for standard C functions, not for compilation units.
Definition: util.c:3540
void AddToCalledModules(entity e)
Definition: util.c:3413
void init_c_implicit_variables(entity m)
Definition: util.c:277
void UpdateEntity(entity e, stack ContextStack, stack FormalStack, stack FunctionStack, stack OffsetStack, bool is_external, bool is_declaration)
Update the entity with final type, storage and initial value; and also (sometimes?...
Definition: util.c:2473
list TakeDerivedEntities(list le)
Definition: util.c:3020
int ComputeAreaOffset(entity a, entity v)
Definition: util.c:3324
value MakeEnumeratorInitialValue(list enum_list, int counter)
Definition: util.c:3299
entity FindEntityFromLocalNameAndPrefix(string name, string prefix)
Definition: util.c:877
void RemoveDummyArguments(entity f, list refs)
To chase formals in type declarations.
Definition: util.c:2224
void UpdateDerivedEntities(list ld, list le, stack ContextStack)
Definition: util.c:3097
void c_parser_put_new_typedef(const char *name)
Store named type for the lexical analyzer, which has to decide if a character string is the name of a...
Definition: util.c:1060
void CreateReturnEntity(entity f)
If necessary, create the return entity, which is a hidden variable used in PIPS internal representati...
Definition: util.c:2382
void UpdateAbstractEntity(entity e, stack ContextStack)
Definition: util.c:2842
type UpdateType(type t1, type t2)
This function replaces the undefined field in t1 by t2.
Definition: util.c:1693
#define FILE_LOCAL_USER_DEFINED_TYPES_P
void reset_current_dummy_parameter_number()
Definition: util.c:144
list insert_qualifier(list ql, qualifier nq)
if qualifier "nq" does not already belong to qualifier list "ql", add it in front of the list.
Definition: util.c:3567
expression IdentifierToExpression(string s)
Definition: util.c:650
entity FindOrCreateEntityFromLocalNameAndPrefixAndScope(string name, string prefix, string scope, bool is_external)
Definition: util.c:820
void StackPush(stack OffsetStack)
The OffsetStack is pushed incrementally.
Definition: util.c:3457
void UpdateEntity2(entity f, stack FormalStack __attribute__((__unused__)), stack OffsetStack __attribute__((__unused__)))
A subset of UpdateEntity, used when the function entity is already more defined because the return ty...
Definition: util.c:2431
entity RenameFunctionEntity(entity oe)
Rename function oe if necessary.
Definition: util.c:1556
static int C_line_number
To track the user line number, that is the one in the original user file.
Definition: clexer.c:1102
entity make_C_or_Fortran_constant_entity(const char *name, tag bt, size_t size, bool is_fortran, bool(*error_manager)(const char *, const char *))
This function creates a constant.
Definition: constant.c:148
static bool is_external
to know if the variable is declared inside or outside a function, so its scope is the current functio...
Definition: cyacc.tab.c:115
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
static Value offset
Definition: translation.c:283
bool static_module_name_p(const char *name)
Check if the given name is a static module name.
Definition: entity_names.c:122
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
bool empty_string_p(const char *s)
Definition: entity_names.c:239
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
string safe_get_line_interval(const string fn, int f, int l)
return lines f-l from file fn as a string
Definition: file.c:539
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define STRING(x)
Definition: genC.h:87
void gen_free(gen_chunk *obj)
version without shared_pointers.
Definition: genClib.c:992
void free(void *)
void CParserError(char *msg)
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
bool gen_list_cyclic_p(const list ml)
Definition: list.c:120
int gen_occurences(const void *vo, const list l)
count occurences of vo in l
Definition: list.c:746
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
statement make_expression_statement(expression)
Build a statement from a given expression.
Definition: statement.c:1308
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define asprintf
Definition: misc-local.h:225
@ warning_log
Definition: misc-local.h:34
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
static entity rank
#define BLOCK_SEP_CHAR
Definition: naming-local.h:51
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
#define MODULE_SEP
special characters to build entity names of various kinds
Definition: naming-local.h:27
#define FILE_SEP_STRING
Definition: naming-local.h:41
#define TYPEDEF_PREFIX
Definition: naming-local.h:62
#define UNION_PREFIX
Definition: naming-local.h:58
#define DUMMY_PARAMETER_PREFIX
For dmmmy parameters in functions declarations.
Definition: naming-local.h:93
#define ENUM_PREFIX
Definition: naming-local.h:60
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define STACK_AREA_LOCAL_NAME
Definition: naming-local.h:72
#define STATIC_AREA_LOCAL_NAME
Definition: naming-local.h:70
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define HEAP_AREA_LOCAL_NAME
Definition: naming-local.h:71
#define MEMBER_SEP_STRING
Definition: naming-local.h:53
#define STRUCT_PREFIX
Definition: naming-local.h:56
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
bool stack_empty_p(const stack)
stack stack_copy(const stack)
duplicate a stack with its contents.
Definition: stack.c:267
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
int stack_size(const stack)
observers
void stack_push(void *, stack)
stack use
Definition: stack.c:373
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
#define stack_undefined_p(s)
Definition: newgen_stack.h:56
int tag
TAG.
Definition: newgen_types.h:92
#define string_undefined
Definition: newgen_types.h:40
intptr_t _int
_INT
Definition: newgen_types.h:53
struct cons * list
Definition: newgen_types.h:106
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
list safe_c_words_entity(type t, list name)
list c_words_entity(type t, list name, list *ppdl)
void print_references(list rl)
Definition: expression.c:163
void print_expressions(list le)
Definition: expression.c:98
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
string expression_to_string(expression e)
Definition: expression.c:77
bool same_entity_lname_p(entity, entity)
Definition: same_names.c:64
static int tc
Internal variables
Definition: reindexing.c:107
static const char * prefix
#define ENTITY_ASSIGN_P(e)
#define ENTITY_DEREFERENCING_P(e)
#define ENTITY_PLUS_P(e)
#define DEFAULT_INTEGER_TYPE_SIZE
#define ENTITY_POINT_TO_P(e)
#define ENTITY_PRE_DECREMENT_P(e)
#define ENTITY_POST_DECREMENT_P(e)
#define DYNAMIC_RAM_OFFSET
FI: I would have assumed that it is used for the stack area, but I must be wrong.....
#define IMPLICIT_VARIABLE_NAME_1
Implicit variable names for C.
#define ENTITY_POST_INCREMENT_P(e)
#define ENTITY_CONDITIONAL_P(e)
#define UNKNOWN_RAM_OFFSET
#define ENTITY_PRE_INCREMENT_P(e)
#define UNDEFINED_RAM_OFFSET
#define entity_declarations(e)
MISC: newgen shorthands.
#define ENTITY_PLUS_C_P(e)
#define IMPLICIT_VARIABLE_NAME_2
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
#define ENTITY_MINUS_C_P(e)
#define ENTITY_ADDRESS_OF_P(e)
#define MINUS_C_OPERATOR_NAME
@ ENTITY_STATIC_AREA
@ ABSTRACT_LOCATION
@ ENTITY_DYNAMIC_AREA
@ ENTITY_STACK_AREA
@ ENTITY_HEAP_AREA
void fprint_C_environment(FILE *fd, entity m)
Definition: declarations.c:292
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool entity_list_p(list el)
Checks that el only contains entity.
Definition: entity.c:1411
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool dummy_parameter_entity_p(entity p)
is p a dummy parameter?
Definition: entity.c:1941
bool entity_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
bool string_block_scope_p(string s)
Definition: entity.c:511
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
void update_dummy_parameter(parameter p, entity ep)
Definition: entity.c:2072
string empty_scope()
Functions used to manage the block scoping in conjunction with ContextStack and yco ntext.
Definition: entity.c:498
string storage_to_string(storage s)
Definition: entity.c:2030
bool typedef_entity_p(entity e)
Definition: entity.c:1902
static string prefixes[]
Definition: entity.c:1433
string local_name_to_scope(const char *ln)
allocates a new string
Definition: entity.c:563
bool empty_scope_p(string s)
Definition: entity.c:500
void print_entities(list l)
Definition: entity.c:167
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
string safe_entity_name(entity e)
predicates and functions for entities
Definition: entity.c:433
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
bool derived_entity_p(entity e)
Definition: entity.c:1048
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
bool member_entity_p(entity e)
Definition: entity.c:1921
entity MakeCompilationUnitEntity(const char *name)
This is useful for the C language only.
Definition: entity.c:1954
list extract_references_from_declarations(list decls)
FI: this function has not yet been extended for C types!!!
Definition: entity.c:2834
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
expression reference_to_expression(reference r)
Definition: expression.c:196
expression make_unbounded_expression()
Definition: expression.c:4339
expression MakeCommaExpression(list l)
Definition: expression.c:3918
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
list module_all_declarations(entity m)
The function itself is not in its declarations.
Definition: module.c:419
bool static_module_p(entity e)
Check if the given module entity is a static module.
Definition: module.c:80
bool compilation_unit_entity_p(entity e)
Check if the given module entity is a compilation unit.
Definition: module.c:87
list declaration_supporting_references(list dl)
Find all references in the declaration list.
Definition: module.c:392
entity find_ith_parameter(entity e, int i)
Definition: util.c:93
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
type ultimate_type(type)
Definition: type.c:3466
bool call_compatible_type_p(type)
end of basic_concrete_types
Definition: type.c:3764
bool SizeOfArray(entity, int *)
This function computes the total size of a variable in bytes, ie.
Definition: size.c:87
type make_char_array_type(int)
Definition: type.c:5213
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
bool place_holder_variable_p(entity)
Definition: variable.c:2069
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
type call_to_functional_type(call, bool)
The function called can have a functional type, or a typedef type or a pointer type to a functional t...
Definition: type.c:3824
int add_C_variable_to_area(entity, entity)
Definition: variable.c:1381
string safe_type_to_string(const type)
Definition: type.c:59
bool type_equal_p(type, type)
Definition: type.c:547
type expression_to_user_type(expression)
Preserve typedef'ed types when possible.
Definition: type.c:2645
bool check_C_function_type(entity, list)
Check that an effective parameter list is compatible with a function type.
Definition: type.c:4716
type MakeIntegerResult(void)
Definition: type.c:276
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
string qualifier_to_string(qualifier)
Definition: type.c:5427
type make_scalar_integer_type(_int)
Definition: type.c:712
bool formal_parameter_p(entity)
Definition: variable.c:1489
hash_table keyword_typedef_table
Because of typedefs, the C lexers need help to decide if a character string such as toto is a type na...
Definition: static.c:253
bool bit_type_p(type)
Definition: type.c:2843
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
bool qualifier_equal_p(qualifier, qualifier)
Definition: type.c:5420
int CSafeSizeOfArray(entity)
BEGIN_EOLE.
Definition: size.c:225
#define type_functional_p(x)
Definition: ri.h:2950
#define formal_offset(x)
Definition: ri.h:1408
#define value_tag(x)
Definition: ri.h:3064
#define value_undefined_p(x)
Definition: ri.h:3017
#define dummy_identifier(x)
Definition: ri.h:1033
#define value_undefined
Definition: ri.h:3016
@ is_basic_derived
Definition: ri.h:579
@ is_basic_string
Definition: ri.h:576
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_int
Definition: ri.h:571
@ is_basic_typedef
Definition: ri.h:580
#define value_code_p(x)
Definition: ri.h:3065
#define basic_pointer(x)
Definition: ri.h:637
#define normalized_undefined
Definition: ri.h:1745
#define functional_result(x)
Definition: ri.h:1444
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
struct _newgen_struct_value_ * value
Definition: ri.h:455
#define storage_formal_p(x)
Definition: ri.h:2522
#define parameter_dummy(x)
Definition: ri.h:1823
#define parameter_type(x)
Definition: ri.h:1819
#define area_size(x)
Definition: ri.h:544
#define value_constant(x)
Definition: ri.h:3073
#define basic_int_p(x)
Definition: ri.h:614
#define syntax_reference(x)
Definition: ri.h:2730
#define type_unknown_p(x)
Definition: ri.h:2956
#define syntax_tag(x)
Definition: ri.h:2727
#define code_undefined_p(x)
Definition: ri.h:758
#define call_function(x)
Definition: ri.h:709
#define QUALIFIER(x)
QUALIFIER.
Definition: ri.h:2106
#define reference_variable(x)
Definition: ri.h:2326
#define basic_derived(x)
Definition: ri.h:640
#define code_externs(x)
Definition: ri.h:790
#define basic_int(x)
Definition: ri.h:616
#define storage_tag(x)
Definition: ri.h:2515
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define type_tag(x)
Definition: ri.h:2940
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define symbolic_constant(x)
Definition: ri.h:2599
#define constant_int(x)
Definition: ri.h:850
#define ram_undefined
Definition: ri.h:2221
#define syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define value_unknown_p(x)
Definition: ri.h:3077
#define syntax_application(x)
Definition: ri.h:2748
#define parameter_undefined
Definition: ri.h:1794
#define constant_unknown_p(x)
Definition: ri.h:863
#define dimension_lower(x)
Definition: ri.h:980
#define basic_tag(x)
Definition: ri.h:613
@ is_constant_int
Definition: ri.h:817
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define entity_storage(x)
Definition: ri.h:2794
@ is_value_code
Definition: ri.h:3031
#define code_declarations(x)
Definition: ri.h:784
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define storage_ram_p(x)
Definition: ri.h:2519
#define value_constant_p(x)
Definition: ri.h:3071
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define ram_section(x)
Definition: ri.h:2249
#define storage_formal(x)
Definition: ri.h:2524
#define value_symbolic(x)
Definition: ri.h:3070
#define basic_undefined_p(x)
Definition: ri.h:557
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define basic_typedef(x)
Definition: ri.h:643
#define type_undefined_p(x)
Definition: ri.h:2884
#define basic_undefined
Definition: ri.h:556
#define entity_undefined_p(x)
Definition: ri.h:2762
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define type_void(x)
Definition: ri.h:2961
#define constant_int_p(x)
Definition: ri.h:848
#define expression_undefined
Definition: ri.h:1223
#define value_symbolic_p(x)
Definition: ri.h:3068
#define type_void_p(x)
Definition: ri.h:2959
#define entity_name(x)
Definition: ri.h:2790
#define area_layout(x)
Definition: ri.h:546
#define ENTITY_(x)
Definition: ri.h:2758
#define functional_parameters(x)
Definition: ri.h:1442
#define code_initializations(x)
Definition: ri.h:788
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define formal_function(x)
Definition: ri.h:1406
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define syntax_call(x)
Definition: ri.h:2736
#define cast_type(x)
Definition: ri.h:745
#define variable_qualifiers(x)
Definition: ri.h:3124
#define type_area(x)
Definition: ri.h:2946
#define expression_undefined_p(x)
Definition: ri.h:1224
#define application_function(x)
Definition: ri.h:508
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_declarations(x)
Definition: ri.h:2460
#define storage_ram(x)
Definition: ri.h:2521
#define type_undefined
Definition: ri.h:2883
#define call_arguments(x)
Definition: ri.h:711
#define entity_kind(x)
Definition: ri.h:2798
@ is_type_void
Definition: ri.h:2904
@ is_type_enum
Definition: ri.h:2907
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
@ is_type_union
Definition: ri.h:2906
@ is_type_area
Definition: ri.h:2899
@ is_type_struct
Definition: ri.h:2905
#define entity_type(x)
Definition: ri.h:2792
#define parameter_undefined_p(x)
Definition: ri.h:1795
#define value_expression_p(x)
Definition: ri.h:3080
#define expression_syntax(x)
Definition: ri.h:1247
#define entity_domain_number(x)
Definition: ri.h:2788
#define storage_return_p(x)
Definition: ri.h:2516
#define dummy_identifier_p(x)
Definition: ri.h:1031
#define type_variable_p(x)
Definition: ri.h:2947
#define basic_bit_p(x)
Definition: ri.h:632
#define symbolic_expression(x)
Definition: ri.h:2597
#define value_expression(x)
Definition: ri.h:3082
#define storage_undefined_p(x)
Definition: ri.h:2477
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define variable_basic(x)
Definition: ri.h:3120
#define ram_offset(x)
Definition: ri.h:2251
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define storage_undefined
Definition: ri.h:2476
#define entity_initial(x)
Definition: ri.h:2796
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
static int line
FLEX_SCANNER.
Definition: scanner.c:852
#define ifdebug(n)
Definition: sg.c:47
#define TK_NAMED_TYPE
Definition: splitc.c:760
#define intptr_t
Definition: stdint.in.h:294
static string buffer
Definition: string.c:113
the stack head
Definition: stack.c:62
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
struct cons * cdr
The pointer to the next element.
Definition: newgen_list.h:43
gen_chunk car
The data payload of a list element.
Definition: newgen_list.h:42
Definition: delay.c:253
void gen_clear_tabulated_element(gen_chunk *obj)
GEN_CLEAR_TABULATED_ELEMENT only clears the entry for object OBJ in the gen_tabulated_ and gen_tabula...
Definition: tabulated.c:251
char * int2a(int i)
util.c
Definition: util.c:42
A gen_chunk is used to store every object.
Definition: genC.h:58
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207