PIPS
procedure.c
Go to the documentation of this file.
1 /*
2 
3  $Id: procedure.c 23065 2016-03-02 09:05:50Z coelho $
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 
36 #include "misc.h"
37 #include "properties.h"
38 #include "pipsdbm.h"
39 
40 #include "ri-util.h"
41 #include "workspace-util.h"
42 
43 #include "control.h"
44 // for make_text_resource_and_free() (only?!)
45 // ??? could/should it be removed
46 #include "prettyprint.h"
47 
48 // To be able to test which controlizer is currently used
49 #include "phases.h"
50 #include "pipsmake.h"
51 
52 #include "syntax.h"
53 #include "parser_private.h"
54 #include "syn_yacc.h"
55 
56 /* list of called subroutines or functions */
58 
59 /* statement of current function */
61 
62 /*********************************************************** GHOST VARIABLES */
63 
64 /* list of potential local or top-level variables
65  * that turned out to be useless.
66  */
68 
70 {
73 }
74 
76  expression expr,
77  entity v,
78  entity f)
79 {
80  /* It is assumed that v and f are defined entities and that v is of
81  type variable and f of type functional. */
82  syntax s = expression_syntax(expr);
84  range rng = range_undefined;
85  call c = call_undefined;
86 
87  ifdebug(8) {
88  pips_debug(8, "Begin for expression: ");
89  print_expression(expr);
90  }
91 
92  switch(syntax_tag(s)) {
94  ref = syntax_reference(s);
95  if(reference_variable(ref)==v) {
96  pips_debug(1,
97  "Reference to formal functional entity %s to be substituted\n",
98  entity_name(f));
99  /* ParserError() is going to request ghost variable
100  substitution recursively and we do not want this to happen
101  because it is going to fail again. Well, substitution won't be
102  tried from AbortOfProcedure()... */
103  /* ghost_variable_entities = NIL; */
105  "Functional variable %s is used as an actual argument\n"
106  "This is not yet fully supported by PIPS.\n",
108  /* ParserError("substitute_ghost_variable_in_expression",
109  "Functional parameters are not (yet) supported by PIPS\n"); */
111  }
112  MAP(EXPRESSION, e, {
114  }, reference_indices(ref));
115  break;
116  case is_syntax_range:
117  rng = syntax_range(s);
121  break;
122  case is_syntax_call:
123  c = syntax_call(s);
124  pips_assert("Called entities are not substituted", call_function(c)!= v);
125  MAP(EXPRESSION, e, {
127  }, call_arguments(c));
128  break;
129  default:
130  break;
131  }
132 
133  ifdebug(8) {
134  pips_debug(8, "End for expression: ");
135  print_expression(expr);
136  }
137 }
138 
140  statement stmt,
141  entity v,
142  entity f)
143 {
144  /* It is assumed that v and f are defined entities and that v is of
145  type variable and f of type functional. */
146 
147  /* gen_recurse() is not used to control the context better */
148 
151  loop l = loop_undefined;
153  test t = test_undefined;
154  call c = call_undefined;
155  /* unstructured u = unstructured_undefined; */
156 
157  pips_assert("Labels are not substituted", sl!= v);
158 
159  switch(instruction_tag(i)) {
161  MAP(STATEMENT, s, {
163  }, instruction_block(i));
164  break;
165  case is_instruction_loop:
166  l = instruction_loop(i);
167  pips_assert("Loop indices are not substituted", loop_index(l)!= v);
168  pips_assert("Loop labels are not substituted", loop_label(l)!= v);
173  /* Local variables should also be checked */
174  break;
176  w = instruction_whileloop(i);
177  pips_assert("WHILE loop labels are not substituted", whileloop_label(w)!= v);
180  /* Local variables should also be checked */
181  break;
182  case is_instruction_test:
183  t = instruction_test(i);
187  break;
188  case is_instruction_goto:
189  /* nothing to do */
190  break;
191  case is_instruction_call:
192  c = instruction_call(i);
193  pips_assert("Called entities are not substituted", call_function(c)!= v);
194  MAP(EXPRESSION, e, {
196  }, call_arguments(c));
197  break;
199  pips_assert("The parser should not have to know about unstructured\n", false);
200  break;
201  default:
202  FatalError("substitute_ghost_variable_in_statement", "Unexpected instruction tag");
203  }
204 }
205 
206 void remove_ghost_variable_entities(bool substitute_p)
207 {
209  MAP(ENTITY, e,
210  {
211  /* The debugging message must use the variable name before it is freed
212  */
213  pips_debug(1, "entity '%s'\n", entity_name(e));
214  pips_assert("Entity e is defined and has type \"variable\" if substitution is required\n",
215  !substitute_p
216  || (!entity_undefined_p(e)
219  user_warning("remove_ghost_variable_entities",
220  "Entity \"%s\" does not really exist but appears"
221  " in an equivalence chain!\n",
222  entity_name(e));
223  if(!ParserError("remove_ghost_variable_entities",
224  "Cannot remove still accessible ghost variable\n")) {
225  /* We already are in ParserError()! Too bad for the memory leak */
227  return;
228  }
229  }
230  else {
232 
233  if(entity_undefined_p(fe)) {
234  pips_assert("Entity fe cannot be undefined", false);
235  }
236  else if(type_undefined_p(entity_type(fe))) {
237  pips_assert("Type for entity fe cannot be undefined", false);
238  }
239  else if(type_functional_p(entity_type(fe))) {
241 
242 
243  /*
244  if(intrinsic_entity_p(fe)) {
245  user_warning("remove_ghost_variable_entities",
246  "Intrinsic %s is probably declared in a strange useless way\n",
247  module_local_name(fe));
248  }
249  */
250 
251 
252  if(substitute_p) {
253  pips_debug(1,
254  "Start substitution of variable %s by module %s\n",
255  entity_name(e), entity_name(fe));
257  pips_debug(1,
258  "End for substitution of variable %s by module %s\n",
259  entity_name(e), entity_name(fe));
260  }
261  }
262  else {
263  pips_assert("Type t for entity fe should be functional", false);
264  }
265 
267  }
268  pips_debug(1, "destroyed\n");
269  },
271 
273 }
274 
276 {
279 }
280 
281 /* It is possible to change one's mind and effectively use an entity which was
282  * previously assumed useless
283  */
285 {
289 }
290 
291 bool
293 {
295 
297 }
298 
299 ␌
300 /* this function is called each time a new procedure is encountered. */
302 {
303  /* reset_current_module_entity(); */
304  InitImplicit();
306 }
307 
309 entity e;
310 {
311  bool already_here = false;
312  const char* n = entity_local_name(e);
313  string nom;
315 
316  /* Self recursive calls are not allowed */
317  if(e==cm) {
318  pips_user_warning("Recursive call from %s to %s\n",
320  ParserError("update_called_modules",
321  "Recursive call are not supported\n");
322  }
323 
324  /* do not count intrinsics; user function should not be named
325  like intrinsics */
328  if(entity_initial(e) == value_undefined) {
329  /* FI, 20/01/92: maybe, initializations of global entities
330  should be more precise (storage, initial value, etc...);
331  for the time being, I choose to ignore the potential
332  problems with other executions of the parser and the linker */
333  /* pips_internal_error("unexpected case"); */
334  }
335  else if(value_intrinsic_p(entity_initial(e)))
336  return;
337  }
338 
339  MAPL(ps, {
340  if (strcmp(n, STRING(CAR(ps))) == 0) {
341  already_here = true;
342  break;
343  }
344  }, called_modules);
345 
346  if (! already_here) {
347  pips_debug(1, "adding %s\n", n);
349  }
350 }
351 
352 /* macros are added, although they should not have been.
353  */
355 {
356  bool found = false;
357  list l = called_modules;
358  const char* name = module_local_name(e);
359 
360  if (!called_modules) return;
361 
362  if (same_string_p(name, STRING(CAR(called_modules)))) {
364  found = true;
365  } else {
366  list lp = called_modules;
367  l = CDR(called_modules);
368 
369  for(; !ENDP(l); POP(l), POP(lp)) {
370  if (same_string_p(name, STRING(CAR(l)))) {
371  CDR(lp) = CDR(l);
372  found = true;
373  break;
374  }
375  }
376  }
377 
378  if (found) {
379  pips_debug(3, "removing %s from callees\n", entity_name(e));
380  CDR(l) = NIL;
381  free(STRING(CAR(l)));
382  gen_free_list(l);
383  }
384 }
385 
387 {
388  /* get rid of ghost variable entities */
391 
392  (void) ResetBlockStack() ;
393 }
394 ␌
396 
398 {
399  entity idf = call_function(c);
400 
401  if(ENTITY_IMPLIEDDO_P(idf)) {
405  }
406  return true;
407 }
408 
409 static bool fix_storage(reference r)
410 {
411  entity v = reference_variable(r);
412 
413  /*
414  if(entity_variable_p(v)) {
415  if(!gen_in_list_p(v, implicit_do_index_set)) {
416  save_initialized_variable(v);
417  }
418  }
419  */
420 
422  pips_debug(8, "Storage for entity %s must be static or made static\n",
423  entity_name(v));
424 
426  entity_storage(v) =
429  StaticArea,
431  NIL)));
432  }
433  else if(storage_ram_p(entity_storage(v))) {
436 
437  if(dynamic_area_p(s)) {
438  if(entity_blockdata_p(m)) {
440  ("Variable %s is declared dynamic in a BLOCKDATA\n",
441  entity_local_name(v));
442  ParserError("fix_storage",
443  "No dynamic variables in BLOCKDATA\n");
444  }
445  else {
446  SaveEntity(v);
447  }
448  }
449  else {
450  /* Variable is in static area or in a user declared common */
451  if(entity_blockdata_p(m)) {
452  /* Variable must be in a user declared common */
453  if(static_area_p(s)) {
455  ("DATA for variable %s declared is impossible:"
456  " it should be declared in a COMMON instead\n",
457  entity_local_name(v));
458  ParserError("fix_storage",
459  "Improper DATA declaration in BLOCKDATA");
460  }
461  }
462  else {
463  /* Variable must be in static area */
464  if(!static_area_p(s)) {
466  ("DATA for variable %s declared in COMMON %s:"
467  " not standard compliant,"
468  " use a BLOCKDATA\n",
470  if(!get_bool_property("PARSER_ACCEPT_ANSI_EXTENSIONS")) {
471  ParserError("fix_storage",
472  "Improper DATA declaration, use a BLOCKDATA"
473  " or set property PARSER_ACCEPT_ANSI_EXTENSIONS");
474  }
475  }
476  }
477  }
478  }
479  else {
480  pips_user_warning("DATA initialization for non RAM variable %s "
481  "(storage tag = %d)\n",
483  ParserError("fix_storage",
484  "DATA statement initializes non RAM variable\n");
485  }
486  }
487  /* No need to go down */
488  return false;
489 }
490 
491 /* forward declaration */
493 
495 {
496  int nvp = 0; /* Number of Value Positions */
497 
498  pips_debug(2, "Begin\n");
499 
500  if(expression_reference_p(e)) {
502 
503  if(entity_scalar_p(v)) {
504  /* A scalar is referenced */
505  pips_user_warning("Scalar variable %s initialized by an DATA implied do",
506  entity_local_name(v));
507  ParserError("expression_reference_number",
508  "Scalar variable initialized by an DATA implied do");
509  }
511  /* An array element is referenced */
512  nvp++;
513  }
514  else {
515  /* A whole array is initialized */
516  int ne = -1;
518 
520  pips_user_warning("Varying size of array \"%s\"\n", entity_name(v));
521  ParserError("expression_reference_number",
522  "Fortran standard prohibit varying size array in DATA statements.\n");
523  }
524  nvp += ne;
525  }
526  }
527  else if(expression_call_p(e)) {
529 
530  if(strcmp(entity_local_name(f), IMPLIED_DO_NAME)==0) {
531  int lvp = implied_do_reference_number(e);
532 
533  if(lvp<=0) {
534  pips_user_warning("Cannot deal with non-constant loop bounds\n");
535  }
536 
537  nvp += lvp;
538  }
539  else if(strcmp(entity_local_name(f), SUBSTRING_FUNCTION_NAME)==0) {
540  /* substring is equivalent to one reference */
541  nvp++;
542  }
543  else if(strcmp(entity_local_name(f), IO_LIST_STRING_NAME)==0) {
544  /* substring is equivalent to one reference */
545  nvp=0;
546  }
547  else {
548  pips_user_warning("Unexpected call to function %s\n", entity_module_name(f));
549  ParserError("expression_reference_number", "Unexpected function call");
550  }
551  }
552  else {
553  ParserError("expression_reference_number", "Unexpected range");
554  }
555 
556  pips_debug(2, "End with nvp = %d\n", nvp);
557 
558  return nvp;
559 }
560 
562 {
563  /* Must be an implied DO */
566  int lvp = 0; /* local value position */
567 
568  pips_debug(2, "Begin\n");
569 
570  pips_assert("This is an implied DO", (strcmp(entity_local_name(f), IMPLIED_DO_NAME)==0));
571  pips_assert("This is an implied DO", gen_length(args)>=3);
572 
573  MAP(EXPRESSION, se, {
574  int llvp = -1;
575 
576  llvp = expression_reference_number(se);
577 
578  if(llvp>0) {
579  lvp += llvp;
580  }
581  else {
582  lvp = -1;
583  break;
584  }
585  }, CDR(CDR(args)));
586 
587  if(lvp>0) {
588  expression re = EXPRESSION(CAR(CDR(args)));
590  intptr_t c = -1;
591 
592  ifdebug(2)
593  pips_assert("The second argument of an implied do is a range",
595 
596  if(range_count(r, &c)) {
597  lvp *= c;
598  }
599  else {
600  pips_user_warning("Between line %d and %d:\n"
601  "Only constant loop bounds with non-zero increment"
602  " are supported by the PIPS parser in DATA statement\n",
603  line_b_I, line_e_I);
604  lvp = -1;
605  }
606  }
607 
608  pips_debug(2, "End with lvp = %d\n", lvp);
609 
610  return lvp;
611 }
612 
613 static list find_target_position(list cvl, int ctp, int * pmin_cp, int * pmax_cp, expression * pcve)
614 {
615  list lcvl = cvl; /* Local Current Value expression List*/
616 
617  pips_debug(2, "Begin for target ctp=%d with window [%d, %d]\n", ctp, *pmin_cp, *pmax_cp);
618  pips_debug(2, "and with %zd value sets\n", gen_length(cvl));
619 
620  while(ctp > *pmax_cp) {
621  expression vs = expression_undefined; /* Value Set */
622 
623  pips_debug(2, "Iterate for target ctp=%d with window [%d, %d]\n", ctp, *pmin_cp, *pmax_cp);
624 
625  if(ENDP(lcvl)) {
626  pips_user_warning("Looking for %dth value, could find only %d\n",
627  ctp, *pmax_cp);
628  ParserError("find_target_position", "Not enough values in DATA statement");
629  }
630 
631  vs = EXPRESSION(CAR(lcvl)); /* Value Set */
632 
633  POP(lcvl);
634  *pmin_cp = *pmax_cp+1;
635 
636  if(expression_call_p(vs)) {
637  /* Find the repeat factor */
639  entity rf = call_function(c);
640  list args = call_arguments(c);
641  expression rfe = expression_undefined; /* Repeat Factor Expression */
642  expression cve = expression_undefined; /* Constant Value Expression */
643  int n = 1; /* Default repeat factor */
644 
645  if(ENTITY_REPEAT_VALUE_P(rf)) {
646  /* pips_assert("The repeat function is called", ENTITY_REPEAT_VALUE_P(rf)); */
647  pips_assert("The repeat function is called with two arguments", gen_length(args)==2);
648 
649  rfe = EXPRESSION(CAR(args));
650  cve = EXPRESSION(CAR(CDR(args)));
651  n = expression_to_int(rfe);
652  }
653  else {
654  cve = vs;
655  }
656 
657  pips_assert("A constant value expression is a call", expression_call_p(cve));
658  *pcve = cve;
659  *pmax_cp += n;
660  }
661  else {
662  pips_internal_error("Call expression expected");
663  }
664  pips_debug(2, "ctp=%d, *pmin_cp=%d, *pmax_cp=%d\n", ctp, *pmin_cp, *pmax_cp);
665  }
666 
667  pips_debug(2, "End for target ctp=%d with window [%d, %d]\n", ctp, *pmin_cp, *pmax_cp);
668 
669  return lcvl;
670 }
671 
672 /* Integer and bool initial values are stored as int, float, string and
673 maybe complex initial values are stored as entities. Type coercion should
674 be implemented as required in the Fortran standard. */
675 static void store_initial_value(entity var, expression val)
676 {
677  type var_t = entity_type(var);
678  /* type val_t = type_of_expression(val); */
679  variable var_vt = type_variable(var_t);
680  basic var_bt = variable_basic(var_vt);
681  /* variable val_vt = type_variable(val_t); */
682  expression coerced_val = expression_undefined;
683  basic val_bt = basic_of_expression(val); /* to be freed */
684  value fv = value_undefined;
685 
686  ifdebug(2) {
687  pips_debug(2, "Begin for variable %s and expression\n",
688  entity_local_name(var));
689  print_expression(val);
690 
691  pips_assert("var is a scalar variable", entity_scalar_p(var));
692  /* The semantics of expression_constant_p() is a call to a constant
693  entity and not a constant expression(), i.e. an expression whose
694  terms are all recursively constant */
695  /* pips_assert("val is a constant expression", expression_constant_p(val)); */
696  }
697 
698  /* return; */
699 
700  /* Type coercion */
701  if(!basic_equal_p(var_bt, val_bt)) {
702  pips_user_warning("Type coercion needed for variable %s and its DATA expression value\n",
703  entity_local_name(var));
704  print_expression(val);
705  coerced_val = expression_undefined;
706  /* Voir avec Fabien les procedures de Son, type_this_chunk() et typing_of_expressions() */
707  }
708  else {
709  coerced_val = val;
710  }
711 
712  /* Has an initialization already been defined for var? */
713  if(!value_unknown_p(entity_initial(var))) {
714  value v = entity_initial(var);
715  constant c = value_constant(v);
716 
717  pips_assert("value must be constant", value_constant_p(v));
718  pips_assert("constant must be int or call",
720  pips_user_warning("Redefinition of the DATA value for variable %s\n",
721  entity_local_name(var));
722  pips_user_warning("Defined with value %s and redefined by expression\n",
723  constant_int_p(c)?
724  i2a(constant_int(c))
726  print_expression(val);
727  ParserError("store_initial_value", "Conflicting DATA statements");
728  }
729  else {
732  }
733 
734  /* An evaluation function should evaluate any well-typed expression and
735  return a value. Find below a very limited evaluation procedure for
736  backward compatibility with PIPS previous implementation for integer
737  expressions */
738 
739  /* Storage if a proper initial value has been found */
740  if(!expression_undefined_p(coerced_val)) {
741  _int b = -1;
742  int sign = 1;
743  call c = syntax_call(expression_syntax(coerced_val));
744  entity f = call_function(c);
745 
746  pips_assert("The constant value expression is a CALL",
747  expression_call_p(coerced_val));
748 
749  /* Is there a leading unary minus? */
750  if(ENTITY_UNARY_MINUS_P(f)) {
751  sign = -1;
752  coerced_val = EXPRESSION(CAR(call_arguments(c)));
753  pips_assert("The constant value expression is still a CALL",
754  expression_call_p(coerced_val));
755  c = syntax_call(expression_syntax(coerced_val));
756  f = call_function(c);
757  }
758 
759  switch(basic_tag(var_bt)) {
760  case is_basic_int:
761  sscanf(entity_local_name(f), "%td", &b);
763  make_constant(is_constant_int, (value *) (sign*b)));
764  break;
765  case is_basic_logical:
766  if(ENTITY_TRUE_P(f)) {
767  b = 1;
768  }
769  else if(ENTITY_FALSE_P(f)) {
770  b = 0;
771  }
772  else{
773  pips_user_warning("LOGICAL variable %s cannot be initialized with expression",
774  entity_local_name(var));
775  print_expression(coerced_val);
776  ParserError("store_initial_value", "Illegal initialization of a LOGICAL variable");
777  }
780  break;
781  case is_basic_float:
782  case is_basic_complex:
783  case is_basic_string:
784  if(sign==1) {
787  }
788  else {
789  /* For real and complex, I should allocate "-f" and forget about
790  calls to unary minus */
792  }
793  break;
794  case is_basic_overloaded:
795  pips_internal_error("A Fortran variable cannot have the OVERLOADED internal type");
796  break;
797  default:
798  pips_internal_error("Unexpected basic tag=%d", basic_tag(var_bt));
799  break;
800  }
801  }
802  else {
804  }
805  entity_initial(var) = fv;
806  free_basic(val_bt);
807 }
808 
809 static void process_value_list(list vl, list isvs, list svps)
810 {
811  /* Find a value in vl at the monotonically increasing position given in
812  svps for the variable in isvs. All lists are assumed non-empty. */
813  int ctp = -1; /* current target position */
814  /* The current position is a window because of the repeat operator */
815  int min_cp = -1; /* minimal current position */
816  int max_cp = -1; /* maximal current position */
817  list cvp = list_undefined;
818  list cvl = vl; /* Current Value List */
819  list civl = list_undefined; /* Current Initialized Variable List */
820  expression cve = expression_undefined; /* Current Value Expression */
821 
822  for(cvp=svps, civl = isvs;!ENDP(cvp);POP(cvp), POP(civl)) {
823  entity cvar = ENTITY(CAR(civl));
824  ctp = INT(CAR(cvp));
825 
826  if(ctp>max_cp) {
827  cvl = find_target_position(cvl, ctp, &min_cp, &max_cp, &cve);
828  pips_assert("The value window is not empty", min_cp<=max_cp);
829  if(ctp>=min_cp && ctp <= max_cp) {
830  /* Store value */
831  store_initial_value(cvar, cve);
832  }
833  else {
834  /* Not enough values in vl */
835  pips_user_warning("No value in value list for variable %s and the following ones.\n",
836  entity_local_name(cvar));
837  ParserError("process_value_list", "Not enough values for reference list");
838  }
839  }
840  else if(ctp>=min_cp) {
841  /* reuse the same value cve*/
842  /* Store value */
843  store_initial_value(cvar, cve);
844  }
845  else {
846  pips_internal_error("ctp is smaller than the current value window,"
847  " it should have been satisfied earlier\n");
848  }
849  }
850 }
851 
853 {
854  entity ife = call_function(c);
855  list args = call_arguments(c);
856  list isvs = NIL; /* Initialized Scalar VariableS */
857  list svps = NIL; /* Scalar Value PositionS */
858  _int cvp = 0; /* Current Variable Position */
859  list al = args; /* Value list from the second element on */
860  list rl = list_undefined; /* Reference list, hanging from call to DATA LIST function */
861  entity rlf = entity_undefined; /* DATA LIST function */
862  expression rle = expression_undefined; /* reference list expression, with call to DATA LIST */
863  list vl = list_undefined; /* Value List, with repeat operator */
864 
865  pips_debug(2, "Begin with %zd arguments\n", gen_length(args));
866 
867  pips_assert("This is a call to the static initialization function",
869 
870  /* Look for initialized scalar variables and for their positions in the reference list */
871  rle = EXPRESSION(CAR(al));
872  vl = CDR(al); /* Move al to the first value, passing the reference list */
873  pips_assert("The first argument is a call", expression_call_p(rle));
875  pips_assert("This is the DATA LIST function", ENTITY_DATA_LIST_P(rlf));
877 
878  for(; !ENDP(rl); POP(rl)) {
879  int nr = -1;
880  expression e = EXPRESSION(CAR(rl));
881  if(expression_reference_p(e)) {
883 
884  if(entity_scalar_p(v)) {
885  /* A scalar is referenced */
886  if(gen_in_list_p(v, isvs)) {
887  pips_user_warning("Variable %s appears twice in a DATA statement",
888  entity_local_name(v));
889  ParserError("", "Redundant/Conflicting initialization");
890  }
891  nr = 1;
892  pips_debug(2, "Variable %s with value at position %td\n",
893  entity_local_name(v), cvp);
894  isvs = gen_nconc(isvs, CONS(ENTITY, v, NIL));
895  svps = gen_nconc(svps, CONS(INT,cvp, NIL));
896  }
897  else {
899  }
900  }
901  else {
903  }
904  if(nr>=0) { /* 0 is returned for call to IO LIST */
905  cvp += nr;
906  }
907  else {
908  cvp = -1;
909  break;
910  }
911  }
912 
913  ifdebug(2) {
914  list lp = svps;
915  pips_assert("The variable and positions lists have the same length",
916  gen_length(isvs)==gen_length(svps));
917  if(gen_length(isvs)>0) {
918  pips_debug(2, "List of initialized scalar variables with value positions:\n");
919  MAP(ENTITY, v, {
920  int pos = INT(CAR(lp));
921  fprintf(stderr, "Variable %s has value at position %d\n",
922  entity_local_name(v), pos);
923  POP(lp);
924  }, isvs);
925  }
926  pips_debug(2, "The DATA statement is %s decoded (cvp=%td)\n",
927  ((gen_length(isvs)==0)? "not" : ((cvp==-1)? "partially" : "fully")), cvp);
928  }
929 
930  /* Process the value list */
931 
932  if(!ENDP(isvs)) {
933  if(ENDP(vl)) {
934  ParserError("process_static_initialization",
935  "Empty value list in DATA statement\n");
936  }
937  else {
938  process_value_list(vl, isvs, svps);
939  }
940  }
941 
942  pips_debug(2, "End\n");
943 }
944 
946 {
947  sequence iseq =
949 
950  /* Variables appearing in a static initialization cannot be in the
951  dynamic area, nor in the heap_area nor in the stack_area. They must
952  be moved to the static area if this happens unless they are implied
953  do indices. */
959 
960  MAP(STATEMENT, is, {
961  if(statement_call_p(is)) {
962  call c = statement_call(is);
964  }
965  else {
966  pips_internal_error("Initialization statements are call statements");
967  }
968  }, sequence_statements(iseq));
969 
970 }
971 ␌
972 /* This function is called when the parsing of a procedure is completed.
973  * It performs a few calculations which cannot be done on the fly such
974  * as address computations for static and dynamic areas and commons.
975  *
976  * And it writes the internal representation of the CurrentFunction with a
977  * call to gen_free (?). */
978 
980 {
981  entity CurrentFunction = get_current_module_entity();
982 
983  pips_debug(8, "Begin for module %s\n",
984  entity_name(CurrentFunction));
985 
986  pips_debug(8, "checking code consistency = %d\n",
988 
989  ifdebug(8) {
990  pips_debug(8, "Declarations inherited from module %s:\n",
991  module_local_name(CurrentFunction));
992  dump_arguments(entity_declarations(CurrentFunction));
993  }
994 
995  /* get rid of ghost variable entities and substitute them if necessary */
997 
998  /* we generate the last statement to carry a label or a comment */
999  if (strlen(lab_I) != 0 /* || iPrevComm != 0 */ ) {
1001  }
1002 
1003  /* we generate statement last+1 to eliminate returns */
1004  GenerateReturn();
1005 
1006  uses_alternate_return(false);
1009 
1010  /* Check the block stack */
1011  (void) PopBlock() ;
1012  if (!IsBlockStackEmpty())
1013  ParserError("EndOfProcedure",
1014  "bad program structure: missing ENDDO and/or ENDIF\n");
1015 
1016  /* are there undefined gotos ? */
1018 
1019  /* The following calls could be located in check_first_statement()
1020  * which is called when the first executable statement is
1021  * encountered. At that point, many declaration related
1022  * problems should be fixed or fixeable. But additional
1023  * undeclared variables will be added to the dynamic area
1024  * and their addresses must be computed. At least, ComputeAddresses()
1025  * must stay here.. so I keep all these calls together.
1026  */
1027  UpdateFunctionalType(CurrentFunction,
1029 
1031 
1032  /* Must be performed before equivalence resolution, for user declared
1033  commons whose declarations are stronger than equivalences */
1034  update_user_common_layouts(CurrentFunction);
1035 
1037  /* Use equivalence chains to update storages of equivalenced and of
1038  variables implicitly declared in DynamicArea, or implicitly thru
1039  DATA or explicitly thru SAVE declared in StaticArea */
1040  ComputeAddresses();
1041 
1042  /* Initialize the shared field in ram storage */
1043  SaveChains();
1044 
1045  /* Now that retyping and equivalences have been taken into account: */
1047 
1048  /* Why keep it in (apparent) declaration order rather than
1049  alphabetical order? Because some later processing may be based on
1050  this assumption. Sort can be performed before printouts. */
1051  code_declarations(EntityCode(CurrentFunction)) =
1052  gen_nreverse(code_declarations(EntityCode(CurrentFunction))) ;
1053 
1054  if (get_bool_property("PARSER_DUMP_SYMBOL_TABLE"))
1055  fprint_environment(stderr, CurrentFunction);
1056 
1057  ifdebug(5){
1058  fprintf(stderr, "Parser: checking callees consistency = %d\n",
1060  }
1061 
1062  /* remove hpfc special routines if required.
1063  */
1064  if (get_bool_property("HPFC_FILTER_CALLEES"))
1065  {
1066  list l = NIL;
1067  string s;
1068 
1069  MAPL(cs,
1070  {
1071  s = STRING(CAR(cs));
1072 
1074  {
1075  pips_debug(3, "ignoring %s\n", s);
1076  }
1077  else
1078  l = CONS(STRING, s, l);
1079  },
1080  called_modules);
1081 
1083  called_modules = l;
1084  }
1085 
1086  /* done here. affects callees and code. FC.
1087  */
1090 
1091  if(!EmptyEntryListsP()) {
1093  ProcessEntries();
1095  }
1096 
1098 
1099  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES,
1100  module_local_name(CurrentFunction),
1101  (char*) make_callees(called_modules));
1102 
1103  pips_debug(5, "checking code consistency = %d\n",
1105 
1106  DB_PUT_MEMORY_RESOURCE(DBR_PARSED_CODE,
1107  module_local_name(CurrentFunction),
1108  (char *)function_body);
1109 
1110  /* the current package is re-initialized */
1112  ResetChains();
1116 
1117  pips_debug(5, "checking code consistency after resettings = %d\n",
1119 
1120  pips_debug(8, "End for module %s\n", entity_name(CurrentFunction));
1121 }
1122 
1123 
1124 
1125 /* This function analyzes the CurrentFunction formal parameter list to
1126  * determine the CurrentFunction functional type. l is this list.
1127  *
1128  * It is called by EndOfProcedure().
1129  */
1130 
1132  entity f,
1133  list l)
1134 {
1135  cons *pc;
1136  parameter p;
1137  functional ft;
1138  entity CurrentFunction = f;
1139  type t = entity_type(CurrentFunction);
1140 
1141  ifdebug(8) {
1142  pips_debug(8, "Begin for %s with type ",
1143  module_local_name(CurrentFunction));
1144  fprint_functional(stderr, type_functional(t));
1145  (void) fprintf(stderr, "\n");
1146  }
1147 
1148  pips_assert("A module type should be functional", type_functional_p(t));
1149 
1150  ft = type_functional(t);
1151 
1152  /* FI: I do not understand this assert... at least now that
1153  * functions may be typed at call sites. I do not understand why this
1154  * assert has not made more damage. Only OVL in APSI (Spec-cfp95)
1155  * generates a core dump. To be studied more!
1156  *
1157  * This assert is guaranteed by MakeCurrentFunction() but not by
1158  * retype_formal_parameters() which is called in case an intrinsic
1159  * statement is encountered. It is not guaranteed by MakeExternalFunction()
1160  * which uses the actual parameter list to estimate a functional type
1161  */
1162  pips_assert("Parameter type list should be empty",
1164 
1165  for (pc = l; pc != NULL; pc = CDR(pc)) {
1166  entity fp = ENTITY(CAR(pc));
1167  type fpt = entity_type(fp);
1168 
1169  if(type_undefined_p(fpt)) {
1170  entity_type(fp) = ImplicitType(fp);
1171  }
1172 
1173  p = make_parameter((entity_type(fp)),
1175  functional_parameters(ft) =
1177  CONS(PARAMETER, p, NIL));
1178  }
1179 
1180  ifdebug(8) {
1181  pips_debug(8, "End for %s with type ",
1182  module_local_name(CurrentFunction));
1183  fprint_functional(stderr, type_functional(t));
1184  (void) fprintf(stderr, "\n");
1185  }
1186 }
1187 
1189 {
1190  /* It is assumed that neither variables nor areas have been declared in m
1191  * but that m may have been declared by EXTERNAL in other modules.
1192  */
1193  gen_array_t modules = db_get_module_list();
1194  int module_list_length = gen_array_nitems(modules);
1195  int i = 0;
1196 
1197  for(i = 0; i < module_list_length; i++) {
1199 
1200  if(!entity_undefined_p(om)) {
1201  value v = entity_initial(om);
1202 
1203  if(!value_undefined_p(v) && !value_unknown_p(v)) {
1204  code c = value_code(v);
1205 
1206  if(!code_undefined_p(c)) {
1207  ifdebug(1) {
1208  if(gen_in_list_p(m, code_declarations(c))) {
1209  pips_debug(1,
1210  "Declaration of module %s removed from %s's declarations",
1211  entity_name(m), entity_name(om));
1212  }
1213  }
1214  gen_remove(&code_declarations(c), m);
1215  }
1216  }
1217  }
1218  }
1219  gen_array_full_free(modules);
1220  free_entity(m);
1221 }
1222 
1223 /* this function creates one entity cf that represents the Fortran
1224  function f being analyzed. if f is a Fortran FUNCTION, a second
1225  entity is created; this entity represents the variable that is used
1226  in the function body to return a value. both entities share the
1227  same name and the type of the result entity is equal to the type of
1228  cf's result.
1229 
1230  t is the type of the function result if it has been given by the
1231  programmer as in INTEGER FUNCTION F(A,B,C)
1232 
1233  msf indicates if f is a main, a subroutine or a function.
1234 
1235  cf is the current function
1236 
1237  lfp is the list of formal parameters
1238 */
1240  int msf,
1241  const char* cfn,
1242  list lfp)
1243 {
1244  entity cf = entity_undefined; /* current function */
1245  instruction icf; /* the body of the current function */
1246  entity result; /* the second entity, used to store the function result */
1247  /* to split the entity name space between mains, commons, blockdatas and regular modules */
1248  string prefix = string_undefined;
1249  string fcfn = string_undefined; /* full current function name */
1250  entity ce = entity_undefined; /* global entity with conflicting name */
1251 
1252  /* Check that there is no such common: This test is obsolete because
1253  * the standard does not prohibit the use of the same name for a
1254  * common and a function. However, it is not a good programming practice
1255  */
1258  COMMON_PREFIX, cfn, NULL),
1260  {
1261  pips_user_warning("global name %s used for a module and for a common\n",
1262  cfn);
1263  /*
1264  ParserError("MakeCurrentFunction",
1265  "Name conflict between a "
1266  "subroutine and/or a function and/or a common\n");
1267  */
1268  }
1269 
1270  if(msf==TK_PROGRAM) {
1271  prefix = MAIN_PREFIX;
1272  }
1273  else if(msf==TK_BLOCKDATA) {
1275  }
1276  else {
1277  prefix = "";
1278  }
1279  fcfn = strdup(concatenate(prefix, cfn, NULL));
1281  free(fcfn);
1282 
1283  /* if(!type_undefined_p(entity_type(cf))
1284  || ! storage_undefined_p(entity_storage(cf))
1285  || !value_undefined_p(entity_initial(cf))) */
1286 
1287  if(!value_undefined_p(entity_initial(cf))) {
1288  if(value_code_p(entity_initial(cf))) {
1289  code c = value_code(entity_initial(cf));
1290  if(!code_undefined_p(c) && !ENDP(code_declarations(c))) {
1291  /* Clean up existing local entities in case of a recompilation. */
1292  CleanLocalEntities(cf);
1293  }
1294  }
1295  }
1296 
1297  ce = FindEntity(TOP_LEVEL_MODULE_NAME, cfn);
1298  if(!entity_undefined_p(ce) && ce!=cf) {
1299  if(!value_undefined_p(entity_initial(cf)) || msf!=TK_BLOCKDATA) {
1300  user_warning("MakeCurrentFunction", "Global name %s used for a function or subroutine"
1301  " and for a %s\n", cfn, msf==TK_BLOCKDATA? "blockdata" : "main");
1302  ParserError("MakeCurrentFunction", "Name conflict\n");
1303  }
1304  else {
1305  /* A block data may be declared in an EXTERNAL statement, see Standard 8-9 */
1306  pips_debug(1, "Entity \"%s\" does not really exist."
1307  " A blockdata is declared in an EXTERNAL statement.",
1308  entity_name(ce));
1309  /* remove_variable_entity(ce); */
1311  }
1312  }
1313 
1314  /* Let's hope cf is not an intrinsic */
1315  if( entity_type(cf) != type_undefined
1316  && intrinsic_entity_p(cf) ) {
1317  user_warning("MakeCurrentFunction",
1318  "Intrinsic %s redefined.\n"
1319  "This is not supported by PIPS. Please rename %s\n",
1321  /* Unfortunately, an intrinsics cannot be redefined, just like a user function
1322  * or subroutine after editing because intrinsics are not handled like
1323  * user functions or subroutines. They are not added to the called_modules
1324  * list of other modules, unless the redefining module is parsed FIRST.
1325  * There is not mechanism in PIPS to control the parsing order.
1326  */
1327  ParserError("MakeCurrentFunction",
1328  "Name conflict between a "
1329  "subroutine and/or a function and an intrinsic\n");
1330  }
1331 
1332  /* set ghost variable entities to NIL */
1333  /* This procedure is called when the whole module declaration
1334  statement has been parsed. The formal parameters have already been
1335  declared and the ghost variables checked. The call was moved in
1336  gram.y, reduction rule for psf_keyword. */
1337  /* init_ghost_variable_entities(); */
1338 
1339  /* initialize equivalence chain lists to NIL */
1340  SetChains();
1341 
1342  if (msf == TK_FUNCTION) {
1343  if (t == type_undefined) {
1344  t = ImplicitType(cf);
1345  }
1346  }
1347  else {
1348  if (t == type_undefined) {
1349  t = make_type(is_type_void, UU);
1350  }
1351  else {
1352  /* the intended result type t for a main or a subroutine should be undefined */
1353  FatalError("MakeCurrentFunction", "bad type\n");
1354  }
1355  }
1356 
1357  /* The parameters part of cf's functional type is not created because
1358  the types of formal parameters are not known yet. This is performed
1359  later by UpdateFunctionalType().
1360 
1361  If a call to the function has been encountered before, it's already
1362  typed. However, this information is discarded. */
1363  if(!type_undefined_p(entity_type(cf))) {
1364  free_type(entity_type(cf));
1365  }
1367 
1368  /* a function has a rom storage */
1370 
1371  /* a function has an initial value 'code' that contains an empty block */
1372  icf = MakeEmptyInstructionBlock();
1373 
1374  /* FI: This NULL string is a catastrophy for the strcmp used later
1375  * to check the content of the stack. Any string, including
1376  * the empty string "", would be better. icf is used to link new
1377  * instructions/statement to the current block. Only the first
1378  * block is not pushed for syntactic reasons. The later blocks
1379  * will be pushed for DO's and IF's.
1380  */
1381  /* PushBlock(icf, (string) NULL); */
1382  PushBlock(icf, "INITIAL");
1383 
1385  entity_initial(cf) =
1387  make_code(NIL, NULL, make_sequence(NIL),NIL,
1389 
1391 
1392  /* No common has yet been declared */
1394 
1395  /* Generic areas are created for memory allocation. */
1396  InitAreas();
1397 
1398  /* Formal parameters are created. Alternate returns can be ignored
1399  * or substituted.
1400  */
1402  (get_string_property("PARSER_SUBSTITUTE_ALTERNATE_RETURNS"));
1404 
1405  if (msf == TK_FUNCTION) {
1406  /* a result entity is created */
1407  /*result = FindOrCreateEntity(CurrentPackage, entity_local_name(cf));*/
1408  /*
1409  result = make_entity(strdup(concatenate(CurrentPackage,
1410  MODULE_SEP_STRING,
1411  module_local_name(cf),
1412  NULL)),
1413  type_undefined,
1414  storage_undefined,
1415  value_undefined);
1416  */
1417  /* CleanLocalEntities() does not remove any entity */
1419  module_local_name(cf));
1421  value_undefined);
1422  AddEntityToDeclarations(result, cf);
1423  }
1424 }
1425 ␌
1426 /* Processing of entries: when an ENTRY statement is encountered, it is
1427  * replaced by a labelled CONTINUE and the entry is declared as function
1428  * or a subroutine, depending on its type. The label and the module entity
1429  * which are created are stored in two static lists, entry_labels and
1430  * entry_entities, for later processing. When the current module has been
1431  * fully parsed, the two entry lists are scanned together. The current
1432  * module code is duplicated for each entry, a GOTO the proper entry label
1433  * is added, the code is controlized to get rid of the unwanted pieces of
1434  * code, and:
1435  *
1436  * - either all references are translated into the entry
1437  * reference. The entry declarations are then initialized.
1438  *
1439  * - or the controlized code is prettyprinted as SOURCE_FILE and parser
1440  * again to avoid the translation issue.
1441  *
1442  * The second approach was selected. The current .f file is overwritten
1443  * when the parser is called for the code of an entry.
1444  *
1445  * Further problems are created by entries in fsplit which creates a
1446  * .f_initial file for each entry and in the parser which may not produce
1447  * the expected PARSED_CODE when it is called for an ENTRY. A recursive
1448  * call to the parser is executed to parse the .f file just produced by
1449  * the first call. This scheme was designed to make entries unvisible from
1450  * pipsmake.
1451  * */
1452 
1457 
1459 {
1461  entry_labels = NIL;
1462 
1464  entry_targets = NIL;
1465 
1467  entry_entities = NIL;
1468 
1471 }
1472 
1474 {
1475  /* Useless entities should be reset */
1476 
1477  MAP(ENTITY, el, {
1478  free_entity(el);
1479  }, entry_labels);
1481  entry_labels = NIL;
1482 
1483  MAP(ENTITY, et, {
1484  free_entity(et);
1485  }, entry_targets);
1487  entry_targets = NIL;
1488 
1489  MAP(ENTITY, ee, {
1490  CleanLocalEntities(ee);
1491  free_entity(ee);
1492  }, entry_entities);
1494  entry_entities = NIL;
1495 
1496  MAP(ENTITY, efp, {
1497  free_entity(efp);
1498  }, entry_targets);
1501 
1502  /* the current module statement is used when processing entries */
1504 }
1505 
1507 {
1508  bool empty = ((entry_labels==NIL) && (entry_entities==NIL));
1509 
1510  return empty;
1511 }
1512 
1514 {
1516 }
1517 
1519 {
1521 }
1522 
1524 {
1526 }
1527 
1528 /* Keep track of the formal parameters for the current module */
1530 {
1532 }
1533 
1535 {
1537 }
1538 
1540  entity e, /* entry e */
1541  list lfp) /* list of formal parameters wrongly declared in current module */
1542 {
1543  list lefp = NIL; /* list of effective formal parameters lefp for entry e */
1544 
1545  ifdebug(1) {
1546  pips_debug(1, "Begin with lfp = ");
1547  dump_arguments(lfp);
1548  }
1549 
1550  MAP(ENTITY, fp, {
1552  entity_type(efp) = copy_type(entity_type(fp));
1553  /* the storage is not recoverable */
1555  lefp = gen_nconc(lefp, CONS(ENTITY, efp, NIL));
1556  }, lfp);
1557 
1558  ifdebug(1) {
1559  pips_debug(1, "\nEnd with lefp = ");
1560  dump_arguments(lefp);
1561  }
1562 
1563  return lefp;
1564 }
1565 
1566 /* Static variables in a module with entries must be redeclared as stored
1567  * in a common in order to be accessible from all modules derived from the
1568  * entries. This may create a problem for variables initialized with a DATA
1569  * for compilers that do not accept multiple initializations of a common
1570  * variable.
1571  */
1572 
1573 static void MakeEntryCommon(
1574  entity m,
1575  entity a)
1576 {
1577  /* FI: the prefix used to be "_ENTRY_" but this seems to be refused by f77 3.3.5 */
1578  string c_name = strdup(concatenate(COMMON_PREFIX, "ENTRY_",
1579  module_local_name(m), NULL));
1581  area aa = type_area(entity_type(a));
1582  area ac = area_undefined;
1583  list members = list_undefined;
1584 
1585  pips_debug(1, "Begin for static area %s in module %s\n",
1586  entity_name(a), entity_name(m));
1587 
1588  if(ENDP(area_layout(aa))) {
1589  pips_debug(1, "End: no static variables in module %s\n",
1590  entity_name(m));
1591  return;
1592  }
1593 
1594  members = common_members_of_module(a, m, false);
1595  if(ENDP(members)) {
1596  pips_internal_error("No local static variables in module %s: impossible!",
1597  entity_name(m));
1598  }
1599  gen_free_list(members);
1600 
1601  ifdebug(1) {
1602  pips_debug(1, "Static area %s without aliasing in module %s\n",
1603  entity_name(a), entity_name(m));
1604  print_common_layout(stderr, a, true);
1605  pips_debug(1, "Static area %s with aliasing in module %s\n",
1606  entity_name(a), entity_name(m));
1607  print_common_layout(stderr, a, false);
1608  }
1609 
1610  /* Make sure that no static variables are aliased because this special
1611  cases has not been implemented */
1612  MAP(ENTITY, v, {
1613  storage vs = entity_storage(v);
1614 
1615  pips_assert("storage is ram", storage_ram_p(vs));
1616  pips_assert("storage is static", ram_section(storage_ram(vs)) == a);
1617  if(!ENDP(ram_shared(storage_ram(vs)) )) {
1618  pips_user_warning("Static variable %s is aliased with ",
1619  entity_local_name(v));
1621  ParserError("MakeEntryCommon",
1622  "Entries with aliased static variables not yet supported by PIPS\n");
1623  }
1624  }, area_layout(aa));
1625 
1626  if(entity_undefined_p(c)) {
1628  c = MakeCommon(c);
1629  ac = type_area(entity_type(c));
1630  }
1631  else {
1632  pips_internal_error("The scheme to generate a new common name %s"
1633  " for entries in module %s failed",
1634  c_name, module_local_name(m));
1635  }
1636  free(c_name);
1637 
1638  /* Process all variables in a's layout and declare them stored in c */
1639  MAP(ENTITY, v, {
1640  storage vs = entity_storage(v);
1641 
1642  if(value_constant(entity_initial(v))) {
1643  pips_debug(1,
1644  "Initialized variable %s\n", entity_local_name(v));
1645  /* A variable in a common cannot be initialized more than once */
1646  /*
1647  free_value(entity_initial(v));
1648  entity_initial(v) = make_value(is_value_unknown, UU);
1649  */
1650  }
1651 
1652  ram_section(storage_ram(vs)) = c;
1653  }, area_layout(aa));
1654 
1655  /* Copy a's area in c's area */
1656  area_layout(ac) = area_layout(aa);
1657  /* Do not sort by name or the offset increasing implicit rule is
1658  broken: sort_list_of_entities(area_layout(ac)); */
1659  area_size(ac) = area_size(aa);
1660 
1661  /* Reset a's area */
1662  area_layout(aa) = NIL;
1663  area_size(aa) = 0;
1664 
1665  ifdebug(1) {
1666  pips_debug(1, "New common %s for static area %s in module %s\n",
1667  entity_name(c), entity_name(a), entity_name(m));
1668  print_common_layout(stderr, c, true);
1669  }
1670 
1671  pips_debug(1, "End for static area %s in module %s\n",
1672  entity_name(a), entity_name(m));
1673 }
1674 
1675 /* A local entity might have been created but found out later to be
1676  * global, depending on the order of declaration statements (see
1677  * MakeExternalFunction()). The local entity e is (marked as) destroyed
1678  * and replaced by functional entity fe.
1679  */
1680 
1682 {
1683  entity fe = entity_undefined;
1684 
1685  if(!top_level_entity_p(e)) {
1686  storage s = entity_storage(e);
1687  if(s == storage_undefined || storage_ram_p(s)) {
1688 
1690  entity_local_name(e));
1693  }
1694  else if(!storage_rom_p(entity_storage(fe))) {
1695  FatalError("SafeLocalToGlobal",
1696  "Unexpected storage class for top level entity\n");
1697  }
1699  /* Should we anticipate the value code, since we know it has
1700  to be a value code for a function and it may be tested
1701  later after the parsing phase of the caller but before
1702  the parsing phase of the callee, or should we wait till
1703  the code is really known? */
1704  /* entity_initial(fe) = make_value(is_value_unknown, UU); */
1708  }
1709 
1710  pips_debug(1, "external function %s re-declared as %s\n",
1711  entity_name(e), entity_name(fe));
1712  /* FI: I need to destroy a virtual entity which does not
1713  * appear in the program and wich was temporarily created by
1714  * the parser when it recognized a name; however, I've no way
1715  * to know if the same entity does not appear for good
1716  * somewhere else in the code; does the Fortran standard let
1717  * you write: LOG = LOG(3.) If yes, PIPS will core dump...
1718  * PIPS also core dumps with ALOG(ALOG(X))... (8 July 1993) */
1719  /* remove_variable_entity(e); */
1720  if(type_undefined_p(r)) {
1722  pips_debug(1, "entity %s to be destroyed\n", entity_name(e));
1723  }
1724  else {
1725  pips_debug(1, "entity %s to be preserved to carry function result\n",
1726  entity_name(e));
1727  }
1728  }
1729  else if(storage_formal_p(s)){
1730  pips_user_warning("Variable %s is a formal functional parameter.\n"
1731  "They are not (yet) supported by PIPS.\n",
1732  entity_name(e));
1733  /* ParserError("LocalToGlobal",
1734  "Formal functional parameters are not supported "
1735  "by PIPS.\n"); */
1736  fe = e;
1737  }
1738  else {
1739  pips_internal_error("entity %s has an unexpected storage %d",
1740  entity_name(e), storage_tag(s));
1741  }
1742  }
1743  else {
1744  fe = e;
1745  }
1746  pips_assert("Entity is global or it is a formal functional parameter",
1748  return fe;
1749 }
1750 
1751 /* The result type of a function may be carried by e, by r or be implicit.
1752  * A new type structure is allocated, unless r is used as new result type.
1753  */
1755  entity e,
1756  type r)
1757 {
1758  type te = entity_type(e);
1759  type new_r = type_undefined;
1760 
1761  if (te != type_undefined) {
1762  if (type_variable_p(te)) {
1763  /* e is a function that was implicitly declared as a variable.
1764  this may happen in Fortran. */
1765  pips_debug(2, "variable --> fonction\n");
1766  /* pips_assert("undefined type", r == type_undefined); */
1767  if(type_undefined_p(r))
1768  new_r = copy_type(te);
1769  else {
1770  /* The variable may have been typed, for instance
1771  implicitly, but then it appears in a CALL statement and
1772  its new type is void. Added for formal parameters. */
1773  pips_assert("The new result type is void", type_void_p(r));
1774  new_r = r;
1775  }
1776  }
1777  else if (type_functional_p(te)) {
1778  /* Well... this should be useless because e is already typed.
1779  * FI: I do not believe copy_type() is necessary in spite of
1780  * the non orthogonality...
1781  */
1782  new_r = functional_result(type_functional(te));
1783  }
1784  else {
1785  pips_internal_error("Unexpected type %s for entity %s",
1786  type_to_string(te), entity_name(e));
1787  }
1788  }
1789  else {
1790  if(type_undefined_p(r)) {
1791  new_r = ImplicitType(e);
1792  }
1793  else {
1794  new_r = r;
1795  }
1796  }
1797  pips_assert("type new_r is defined", !type_undefined_p(new_r));
1798  return new_r;
1799 }
1800 
1802 {
1803  return SafeLocalToGlobal(e, type_undefined);
1804 }
1805 
1806 /* An ENTRY statement is substituted by a labelled continue. The ENTRY
1807  * entity is created as in MakeExternalFunction() and MakeCurrentFunction().
1808  */
1809 
1811  entity e, /* entry, local to retrieve potential explicit typing */
1812  list lfp) /* list of formal parameters */
1813 {
1814  entity cm = get_current_module_entity(); /* current module cm */
1815  entity l = make_new_label(cm);
1817  /* The parser expects an instruction and not a statement. I use
1818  * a block wrapping to avoid tampering with lab_I.
1819  */
1821  /* entity e = FindOrCreateEntity(cmn, en); */
1822  entity fe = entity_undefined;
1823  bool is_a_function = entity_function_p(get_current_module_entity());
1824  type rt = type_undefined; /* result type */
1825  list cc = list_undefined; /* current chunk (temporary) */
1826  list lefp = list_undefined; /* list of effective formal parameters */
1827 
1828  pips_debug(1, "Begin for entry %s\n", entity_name(e));
1829 
1830  /* Name conflicts could be checked here as in MakeCurrentFunction() */
1831 
1832  /* Keep track of the effective formal parameters of the current module cm
1833  * at the first call to MakeEntry and reallocate static variables.
1834  */
1835  if(EmptyEntryListsP()) {
1836  MAP(ENTITY, fp, {
1840  }, entity_declarations(cm));
1841 
1842  /* Check if the static area is empty and define a specific common
1843  * if not.
1844  */
1845  /* Too early: StaticArea is not defined yet. Postpone to ProcessEntry.
1846  if(area_size(type_area(entity_type(StaticArea)))!=0) {
1847  MakeEntryCommon(cm, StaticArea);
1848  }
1849  */
1850  }
1851 
1852  /* Compute the result type and make sure a functional entity is being
1853  * used.
1854  */
1855  if(is_a_function) {
1856  rt = MakeResultType(e, type_undefined);
1857  /* In case of previous declaration in the current module */
1858  /* Entity e must not be destroyed if fe is a function because e
1859  * must carry the result.
1860  */
1861  fe = SafeLocalToGlobal(e, rt);
1862  }
1863  else {
1864  rt = make_type(is_type_void, UU);
1865  /* In case of previous declaration in the current module */
1866  fe = LocalToGlobal(e);
1867  }
1868 
1869  lefp = TranslateEntryFormals(fe, lfp);
1870  UpdateFormalStorages(fe, lefp);
1871 
1872  /* Entry fe may have been encountered earlier and typed from the
1873  parameter list */
1874  if(!type_undefined_p(entity_type(fe))) {
1875  free_type(entity_type(fe));
1877  }
1878  TypeFunctionalEntity(fe, rt);
1879  UpdateFunctionalType(fe, lefp);
1880 
1881  /* This depends on what has been done in LocalToGlobal and SafeLocalToGlobal */
1884  }
1885  else {
1886  pips_assert("storage must be rom", storage_rom_p(entity_storage(fe)));
1887  }
1888 
1889  /* This depends on what has been done in LocalToGlobal and SafeLocalToGlobal */
1892  }
1893  else {
1894  value val = entity_initial(fe);
1895  code c = code_undefined;
1896 
1897  if(value_unknown_p(val)) {
1898  /* A call site for fe has been encountered in another module */
1901  }
1902  else {
1903  pips_assert("value is code", value_code_p(val));
1904  c = value_code(entity_initial(fe));
1905  if(code_undefined_p(c)) {
1907  }
1908  else if(ENDP(code_declarations(c))) {
1909  /* Should now be the normal case... */
1910  code_declarations(c) = lefp;
1911  }
1912  else {
1913  pips_internal_error("Code should not (yet) be defined for entry fe...");
1914  }
1915  }
1916  }
1917 
1918  /* The entry formal parameters should be removed if they are not
1919  * formal parameters of the current module... but they are referenced.
1920  * They cannot be preserved although useless because they may be
1921  * dimensionned by expressions legal for this entry but not for the
1922  * current module. They should be removed later when dead code elimination
1923  * let us know which variables are used by each entry.
1924  *
1925  * Temporarily, the formal parameters of entry fe are declared in cm
1926  * to keep the code consistent but they are supposedly not added to
1927  * cm's declarations... because FindOrCreateEntity() does not update
1928  * declarations. MakeAtom() does not redeclare formal parameters.
1929  */
1930  for(cc = lfp; !ENDP(cc); POP(cc)) {
1931  entity fp = ENTITY(CAR(cc));
1932  storage fps = entity_storage(fp);
1933 
1934  if(storage_undefined_p(fps) || !storage_formal_p(fps)) {
1935  /* Let's assume it works for undefined storages.. */
1936  free_storage(fps);
1938  make_formal(cm, 0));
1939  /* Should it really be officially declared? */
1940  if(!IsEffectiveFormalParameterP(fp)) {
1941  /* Remove it from the declaration list */
1942  /*
1943  entity_declarations(cm) =
1944  arguments_rm_entity(entity_declarations(cm), fp);
1945  */
1947  pips_debug(1, "Entity %s removed from declarations for %s\n",
1948  entity_name(fp), module_local_name(cm));
1949  gen_remove(&entity_declarations(cm), fp);
1950  pips_user_warning("Variable %s seems to be used before it is declared"
1951  " as a formal parameter for entry %s. It is legal "
1952  "if it only appears in a type statement.\n",
1953  entity_local_name(fp), entity_name(e));
1954  /* fp may appear in a type statement and/or an
1955  executable statement: the information is now
1956  lost. */
1957  /*
1958  ParserError("MakeEntry",
1959  "Formal parameters of entries cannot appear textually"
1960  " in executable statements before they are declared"
1961  " (Fortran 77 Standard, 15.7.4, pp. 15-13)");
1962  */
1963  }
1964  }
1965  }
1966  }
1967 
1968  /* Request some post-processing */
1969  AddEntryLabel(l);
1970  AddEntryTarget(s);
1971  AddEntryEntity(fe);
1972 
1973  ifdebug(2) {
1974  (void) fprintf(stderr, "Declarations of formal parameters for entry %s:\n",
1975  entity_name(fe));
1977  (void) fprintf(stderr, "Declarations for current module %s:\n",
1978  entity_name(cm));
1980  }
1981 
1982  pips_debug(1, "End for entry %s\n", entity_name(fe));
1983 
1984  return i;
1985 }
1986 
1987 /* Build an entry version of the current module statement. */
1988 
1990  entity cm,
1991  entity e,
1992  statement t)
1993 {
1996  /* The copy_statement() is not consistent with the use of statement t.
1997  * You have to free s in a very careful way
1998  */
1999  statement cms = get_current_module_statement(); /* current module statement */
2000  statement es = statement_undefined; /* statement for entry e */
2001  list l = NIL; /* temporary statement list */
2002 
2003  pips_debug(1, "Begin for entry %s in module %s\n",
2004  entity_name(e), entity_name(cm));
2005 
2006  pips_assert("jump consistent", statement_consistent_p(jump));
2007  pips_assert("cms consistent", statement_consistent_p(cms));
2008 
2010  CONS(STATEMENT, jump,
2011  CONS(STATEMENT, cms,
2012  NIL)));
2013  es = copy_statement(s);
2014 
2015  pips_assert("s consistent", statement_consistent_p(s));
2016  pips_assert("es consistent", statement_consistent_p(es));
2017 
2018  /* Let's get rid of s without destroying cms: do not forget the goto t! */
2020  pips_assert("cms is the second statement of the block",
2021  STATEMENT(CAR(CDR(l))) == cms);
2025  free_statement(s);
2026 
2027  pips_assert("es is still consistent", statement_consistent_p(es));
2028  pips_assert("cms is still consistent", statement_consistent_p(cms));
2029 
2030  pips_debug(1, "End for entry %s in module %s\n",
2031  entity_name(e), entity_name(cm));
2032 
2033  return es;
2034 }
2035 
2036 static void ProcessEntry(
2037  entity cm,
2038  entity e,
2039  statement t)
2040 {
2041  statement es = statement_undefined; /* so as not to compute
2042  anything before the
2043  debugging message is
2044  printed out */
2046  list decls = list_undefined;
2048  text txt = text_undefined;
2049  bool line_numbering_p = false;
2050 
2051  pips_debug(1, "Begin for entry %s of module %s\n",
2052  entity_name(e), module_local_name(cm));
2053 
2056  }
2057 
2058  es = BuildStatementForEntry(cm, e, t);
2059 
2060  /* Compute the proper declaration list, without formal parameters from cm
2061  * and with formal parameters from e
2062  */
2063 
2064  /* Collect local and global variables of cm that may be visible from entry e */
2065  decls = NIL;
2066  MAP(ENTITY, v, {
2067  if(!storage_formal_p(entity_storage(v))) {
2068  decls = arguments_add_entity(decls, v);
2069  }
2070  }, entity_declarations(cm));
2071 
2072  ifdebug(2) {
2073  (void) fprintf(stderr, "Declarations inherited from module %s:\n",
2074  module_local_name(cm));
2076  (void) fprintf(stderr, "Declarations of formal parameters for entry %s:\n",
2077  module_local_name(e));
2079  }
2080 
2081  /* Try to get rid of unreachable statements which may contain references
2082  * to formal parameters undeclared in the current entry an obtain a clean
2083  * entry statement (ces).
2084  */
2085  /* By default we use the controlizer that is activated according to
2086  pipsmake... */
2087  bool use_new_controlizer_p =
2088 #ifdef BUILDER_NEW_CONTROLIZER
2089  active_phase_p(BUILDER_NEW_CONTROLIZER);
2090 #else
2091  false;
2092 #endif // BUILDER_NEW_CONTROLIZER
2093  /* ...but we can change it according to special environment variables if
2094  they are defined: */
2095  use_new_controlizer_p |=
2096  (getenv(USE_NEW_CONTROLIZER_ENV_VAR_NAME) != NULL);
2097  use_new_controlizer_p &=
2098  (getenv(USE_OLD_CONTROLIZER_ENV_VAR_NAME) == NULL);
2099 
2100  if (use_new_controlizer_p)
2101  ces = hcfg(es);
2102  else
2105  MAKE_ORDERING(0,1),
2108  control_graph(es)),
2111 
2112  /* Compute an external representation of entry statement es for entry e.
2113  * Cheat with the declarations because of text_named_module().
2114  */
2116  decls = list_undefined;
2117 
2118  ifdebug(2) {
2119  (void) fprintf(stderr, "Declarations of all variables for entry %s:\n",
2120  module_local_name(e));
2122  }
2123 
2124  decls = entity_declarations(cm);
2126  /* DATA statements should not be replicated in each entry code */
2129 
2130  ifdebug(1) {
2131  fprint_environment(stderr, cm);
2132  }
2133 
2134  line_numbering_p = get_bool_property("PRETTYPRINT_STATEMENT_NUMBER");
2135  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", false);
2136  txt = text_named_module(e, cm, ces);
2137  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", line_numbering_p);
2138 
2139  entity_declarations(cm) = decls;
2140  decls = list_undefined;
2143 
2144  pips_assert("statement ces is consistent", statement_consistent_p(ces));
2145 
2146  pips_assert("statement for cm is consistent",
2148 
2149  /* */
2150  make_text_resource_and_free(module_local_name(e), DBR_SOURCE_FILE, ".f",
2151  txt);
2152 
2153  pips_assert("statement for cm is consistent",
2155 
2156  free_statement(ces);
2157 
2158  /* give the entry a user file.
2159  */
2160  DB_PUT_MEMORY_RESOURCE(DBR_USER_FILE, module_local_name(e),
2161  strdup(db_get_memory_resource(DBR_USER_FILE, module_local_name(cm), true)));
2162 
2163  pips_assert("statement for cm is consistent",
2165 
2166  pips_debug(1, "End for entry %s of module %s\n",
2167  entity_name(e), module_local_name(cm));
2168 
2169 }
2170 
2172 {
2174  code c = entity_code(cm);
2175  list ce = NIL;
2176  list cl = NIL;
2177  list ct = NIL;
2178  text txt = text_undefined;
2179  bool line_numbering_p = get_bool_property("PRETTYPRINT_STATEMENT_NUMBER");
2180  bool data_statements_p = get_bool_property("PRETTYPRINT_DATA_STATEMENTS");
2181  /* To avoid an include of the prettyprint library and/or a
2182  compiler warning. */
2183  /* The declarations for cm are likely to be incorrect. They must be
2184  * synthesized by the prettyprinter.
2185  */
2186  free(code_decls_text(c));
2187  code_decls_text(c) = strdup("");
2188  /* Regenerate a SOURCE_FILE .f without entries for the module itself */
2189  /* To avoid warnings about column 73 when the code is parsed again */
2190  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", false);
2192  make_text_resource_and_free(module_local_name(cm), DBR_SOURCE_FILE, ".f",
2193  txt);
2194 
2195  /* Not ot duplicate DATA statements for static variables and
2196  common variables in every entry */
2197  set_bool_property("PRETTYPRINT_DATA_STATEMENTS", false);
2198 
2199  /* Process each entry */
2200  for(ce = entry_entities, cl = entry_labels, ct = entry_targets;
2201  !ENDP(ce) && !ENDP(cl) && !ENDP(ct); POP(ce), POP(cl), POP(ct)) {
2202  entity e = ENTITY(CAR(ce));
2203  entity l = ENTITY(CAR(cl));
2204  statement t = STATEMENT(CAR(ct));
2205 
2206  pips_assert("Target and label match", l==statement_label(t));
2207 
2208  ProcessEntry(cm, e, t);
2209  }
2210  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", line_numbering_p);
2211  set_bool_property("PRETTYPRINT_DATA_STATEMENTS", data_statements_p);
2212  /* Postponed to the_actual_parser() which needs to know entries were
2213  encountered */
2214  /* ResetEntries(); */
2215 }
2216 ␌
2218 {
2221  BLOCKDATA_PREFIX, name, NULL),
2222  entity_domain);
2223 
2224  if(entity_undefined_p(f)) {
2227  entity_domain);
2228 
2229  /* Ignore ghost variables, they are *not* in the current scope */
2231 
2232  if(entity_undefined_p(f)) {
2234  }
2237  /* The functional entity must be a formal parameter */
2238  ;
2239  }
2240  else if(storage_undefined_p(entity_storage(f))) {
2241  /* The current declaration is wrong and should be fixed
2242  * later, i.e. by MakeExternalFunction() or MakeCallInst()
2243  */
2244  ;
2245  }
2246  else {
2247  pips_assert("Unexpected kind of functional entity!", true);
2248  }
2249  }
2250  else {
2251  /* It is the name of a blockdata */
2252  ;
2253  }
2254  return f;
2255 }
2256 
2258  type r)
2259 {
2260  type tfe = entity_type(fe);
2261 
2262  if(tfe == type_undefined) {
2263  /* this is wrong, because we do not know if we are handling
2264  an EXTERNAL declaration, in which case the result type
2265  is type_undefined, or a function call appearing somewhere,
2266  in which case the ImplicitType should be used;
2267  maybe the unknown type should be used? */
2270  (r == type_undefined) ?
2271  ImplicitType(fe) :
2272  r));
2273  }
2274  else if (type_functional_p(tfe))
2275  {
2277  if(r != type_undefined && !type_equal_p(tr, r)) {
2278 
2279  /* a bug is detected here: MakeExternalFunction, as its name
2280  implies, always makes a FUNCTION, even when the symbol
2281  appears in an EXTERNAL statement; the result type is
2282  infered from ImplicitType() - see just above -;
2283  let's use implicit_type_p() again, whereas the unknown type
2284  should have been used
2285  */
2286  if(intrinsic_entity_p(fe)) {
2287  /* ignore r */
2288  } else if (type_void_p(tr)) {
2289  /* someone used a subroutine as a function.
2290  * this happens in hpfc for declaring "pure" routines.
2291  * thus I make this case being ignored. warning? FC.
2292  */
2293  } else if (implicit_type_p(fe) || overloaded_type_p(tr)) {
2294  /* memory leak of tr */
2296  } else {
2297  user_warning("TypeFunctionalEntity",
2298  "Type redefinition of result for function %s\n",
2299  entity_name(fe));
2300  if(type_variable_p(tr)) {
2301  user_warning("TypeFunctionalEntity",
2302  "Currently declared result is %s\n",
2304  }
2305  if(type_variable_p(r)) {
2306  user_warning("TypeFunctionalEntity",
2307  "Redeclared result is %s\n",
2309  }
2310  ParserError("TypeFunctionalEntity",
2311  "Functional type redefinition.\n");
2312  }
2313  }
2314  } else if (type_variable_p(tfe)) {
2315  /* This may be an undeclared formal functional argument, initially
2316  assumed to be a variable. Since it is not declared as an array
2317  but appears with arguments, it must be a functional entity. */
2318  storage sfe = entity_storage(fe);
2319 
2320  if(storage_formal_p(sfe)) {
2321  /* I do not know how to get the argument types. Let's hope it's
2322  performed later...*/
2323  free_type(entity_type(fe));
2325  make_functional(NIL, r));
2326  }
2327  else {
2328  pips_internal_error("Fortran does not support global variables");
2329  }
2330  } else {
2331  pips_internal_error("Unexpected type for a global name %s",
2332  entity_name(fe));
2333  }
2334 }
2335 
2336 /*
2337  * This function creates an external function. It may happen in
2338  * Fortran that a function is declared as if it were a variable; example:
2339  *
2340  * INTEGER*4 F
2341  * ...
2342  * I = F(9)
2343  *
2344  * or:
2345  *
2346  * SUBROUTINE FOO(F)
2347  * ...
2348  * CALL F(9)
2349  *
2350  * in these cases, the initial declaration must be updated,
2351  * ie. the variable declaration must be
2352  * deleted and replaced by a function declaration.
2353  *
2354  * This function is called when an EXTERNAL or a CALL statement is
2355  * analyzed.
2356  *
2357  * See DeclareVariable for other combination based on EXTERNAL
2358  *
2359  * Modifications:
2360  * - to perform link edition at parse time, returns a new entity when
2361  * e is not a TOP-LEVEL entity; this changes the function a lot;
2362  * Francois Irigoin, 9 March 1992;
2363  * - introduction of fe and tfe to clean up the relationship between e
2364  * and the new TOP-LEVEL entity; formal functional parameters were
2365  * no more recognized as a bug because of the previous modification;
2366  * Francois Irigoin, 11 July 1992;
2367  * - remove_variable_entity() added to avoid problems in semantics analysis
2368  * with an inexisting variable, FI, June 1993;
2369  * - a BLOCKDATA can be declared EXTERNAL, FI, May 1998
2370  */
2371 
2373  entity e, /* entity to be turned into external function */
2374  type r /* type of result */)
2375 {
2376  entity fe = entity_undefined;
2377  type new_r = type_undefined;
2378 
2379  pips_debug(8, "Begin for %s\n", entity_name(e));
2380 
2381  if(entity_blockdata_p(e)) {
2382  pips_debug(8, "End for blockdata %s\n", entity_name(e));
2383  return e;
2384  }
2385 
2386  new_r = MakeResultType(e, r);
2387 
2388  pips_debug(9, "external function %s declared\n", entity_name(e));
2389 
2390  fe = LocalToGlobal(e);
2391 
2392  /* Assertion: fe is a (functional) global entity and the type of its
2393  result is new_r, or it is a formal functional parameter */
2394 
2395  TypeFunctionalEntity(fe, new_r);
2396 
2397  /* a function has a rom storage, except for formal functions */
2398 
2401  else
2402  if (! storage_formal_p(entity_storage(e)))
2404  else {
2405  pips_user_warning("unsupported formal function %s\n",
2406  entity_name(fe));
2407  /*
2408  ParserError("MakeExternalFunction",
2409  "Formal functions are not supported by PIPS.\n"); */
2410  }
2411 
2412  /* an external function has an unknown initial value, else code would
2413  * be temporarily undefined which is avoided (theoretically forbidden)
2414  * in PIPS. */
2415  if(entity_initial(fe) == value_undefined)
2417 
2418  /* fe is added to CurrentFunction's entities */
2420 
2421  pips_debug(8, "End for %s\n", entity_name(fe));
2422 
2423  return fe;
2424 }
2425 
2427  entity e /* entity to be turned into external function or subroutine,
2428  except if it is a formal functional parameter. */)
2429 {
2430  entity fe = entity_undefined;
2431 
2436  fe = e;
2437  }
2438  else {
2439  /* It might be better to declare an unknown type as result type but I
2440  decided to fix the problem later. When a call is later encountered,
2441  the result type is set to void. */
2443 
2446  "Name conflict between user declared module %s and intrinsic %s\n",
2448  ParserError("DeclareExternalFunction",
2449  "Name conflict with intrinsic because PIPS does not support"
2450  " a specific name space for intrinsics. "
2451  "Please change your function or subroutine name.");
2452  }
2453  }
2454 
2455  return fe;
2456 }
2457 
2458 /* This function transforms an untyped entity into a formal parameter.
2459  * fp is an entity generated by FindOrCreateEntity() for instance,
2460  * and nfp is its rank in the formal parameter list.
2461  *
2462  * A specific type is used for the return code variable which may be
2463  * adde by the parser to handle alternate returns. See return.c
2464  */
2465 
2467  entity m, /* module of formal parameter */
2468  entity fp, /* formal parameter */
2469  int nfp) /* offset (i.e. rank) of formal parameter */
2470 {
2471  // pips_assert("type is undefined", entity_type(fp) == type_undefined);
2472  if(!type_undefined_p(entity_type(fp))) {
2473  pips_user_warning("Formal parameter \"%s\" may be used several times\n",
2474  entity_local_name(fp));
2475  ParserError("MakeFormalParameter",
2476  "formal parameter should not be already typed");
2477  }
2478 
2482  make_value_unknown()),
2483  NIL,NIL));
2484  }
2487  }
2488  else {
2489  entity_type(fp) = ImplicitType(fp);
2490  }
2491 
2492  entity_storage(fp) =
2494 
2496 }
2497 
2498 
2499 
2500 /* this function scans the formal parameter list. each formal parameter
2501 is created with an implicit type, and then is added to CurrentFunction's
2502 declarations. */
2504 {
2505  list pc;
2506  entity fp; /* le parametre formel */
2507  int nfp; /* son rang dans la liste */
2508 
2509  FormalParameters = l;
2510 
2511  for (pc = l, nfp = 1; pc != NULL; pc = CDR(pc), nfp += 1) {
2512  fp = ENTITY(CAR(pc));
2513 
2514  MakeFormalParameter(m, fp, nfp);
2515 
2516  AddEntityToDeclarations(fp, m);
2517  }
2518 }
2519 
2520 /* this function check and set if necessary the storage of formal
2521  parameters in lfp. */
2523  entity m,
2524  list lfp)
2525 {
2526  list fpc; /* formal parameter chunk */
2527  int fpo; /* formal parameter offset */
2528 
2529  for (fpc = lfp, fpo = 1; !ENDP(fpc); POP(fpc), fpo += 1) {
2530  entity fp = ENTITY(CAR(fpc));
2531  storage fps = entity_storage(fp);
2532 
2533  pips_assert("Formal parameter fp must be in scope of module m",
2535 
2536  if(storage_undefined_p(fps)) {
2538  make_formal(m, fpo));
2539  }
2540  else if(storage_ram_p(fps)){
2541  /* Oupss... the associated area should be cleaned up... but
2542  * it should ony occur in EndOfProcedure() when all implictly
2543  * declared variables have been encountered...
2544  */
2545  free_storage(fps);
2547  make_formal(m, fpo));
2548  }
2549  else if(storage_formal_p(fps)){
2550  pips_assert("Consistent Offset",
2551  fpo==formal_offset(storage_formal(fps)));
2552  }
2553  else {
2554  pips_internal_error("Unexpected storage for entity %s",
2555  entity_name(fp));
2556  }
2557  }
2558 }
dummy make_dummy_identifier(entity _field_)
Definition: ri.c:620
functional make_functional(list a1, type a2)
Definition: ri.c:1109
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
value make_value_unknown(void)
Definition: ri.c:2847
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
language make_language_fortran(void)
Definition: ri.c:1250
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
storage make_storage_rom(void)
Definition: ri.c:2285
void free_entity(entity p)
Definition: ri.c:2524
type copy_type(type p)
TYPE.
Definition: ri.c:2655
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
bool statement_consistent_p(statement p)
Definition: ri.c:2195
bool storage_defined_p(storage p)
Definition: ri.c:2241
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
value copy_value(value p)
VALUE.
Definition: ri.c:2784
code make_code(list a1, string a2, sequence a3, list a4, language a5)
Definition: ri.c:353
void free_storage(storage p)
Definition: ri.c:2231
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
void free_type(type p)
Definition: ri.c:2658
synchronization make_synchronization_none(void)
Definition: ri.c:2424
void free_basic(basic p)
Definition: ri.c:107
sequence make_sequence(list a)
Definition: ri.c:2125
void free_statement(statement p)
Definition: ri.c:2189
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
callees make_callees(list a)
Definition: ri.c:227
void free_value(value p)
Definition: ri.c:2787
bool callees_consistent_p(callees p)
Definition: ri.c:200
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
bool active_phase_p(const char *phase)
Definition: activate.c:80
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
cons * arguments_rm_entity(cons *a, entity e)
Definition: arguments.c:94
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void gen_array_full_free(gen_array_t a)
Definition: array.c:77
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
@ INT
Definition: atomic.c:48
entity DynamicArea
These global variables are declared in ri-util/util.c.
Definition: area.c:57
entity StaticArea
Definition: area.c:58
void CleanLocalEntities(entity function)
Fortran version.
Definition: clean.c:140
#define USE_OLD_CONTROLIZER_ENV_VAR_NAME
The name of the one to force the use of the old controlizer:
Definition: control-local.h:35
#define USE_NEW_CONTROLIZER_ENV_VAR_NAME
– control.h
Definition: control-local.h:33
void unspaghettify_statement(statement)
The real entry point of unspaghettify:
void InitImplicit()
this function initializes the data structure used to compute implicit types
Definition: declaration.c:1271
void update_user_common_layouts(entity m)
Check...
Definition: declaration.c:1670
void InitAreas()
Definition: declaration.c:100
void update_common_sizes(void)
Definition: declaration.c:1215
void reset_common_size_map()
Definition: declaration.c:954
void DeclareVariable(entity e, type t, list d, storage s, value v)
void DeclareVariable(e, t, d, s, v): update entity e description as declaration statements are encoun...
Definition: declaration.c:670
void SaveEntity(entity e)
These two functions transform a dynamic variable into a static one.
Definition: declaration.c:178
bool implicit_type_p(entity e)
This function checks that entity e has an undefined or an implicit type which can be superseded by an...
Definition: declaration.c:1358
entity MakeCommon(entity e)
MakeCommon: This function creates a common block.
Definition: declaration.c:1047
type ImplicitType(entity e)
This function computes the Fortran implicit type of entity e.
Definition: declaration.c:1311
void initialize_common_size_map()
Definition: declaration.c:947
void SaveChains()
Initialize the shared fields of aliased variables.
Definition: equivalence.c:859
bool entity_in_equivalence_chains_p(entity e)
Definition: equivalence.c:403
void SetChains()
initialize chains before each call to the parser
Definition: equivalence.c:76
void ResetChains()
undefine chains between two successives calls to parser
Definition: equivalence.c:65
void ComputeEquivalences()
This function merges all the equivalence chains to take into account equivalences due to transitivity...
Definition: equivalence.c:215
void ComputeAddresses()
This function computes an address for every variable.
Definition: equivalence.c:503
char * get_string_property(const char *)
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
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
unstructured control_graph(statement)
CONTROL_GRAPH returns the control graph of the statement ST.
statement hcfg(statement)
Compute the hierarchical control flow graph (HCFG) of a statement.
Definition: controlizer.c:2621
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
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_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
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
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
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
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#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
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
gen_array_t db_get_module_list(void)
Get an array of all the modules (functions, procedures and compilation units) of a workspace.
Definition: database.c:1266
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364
statement make_continue_statement(entity)
Definition: statement.c:953
void parser_substitute_all_macros(statement s)
Definition: macros.c:294
void parser_close_macros_support(void)
Definition: macros.c:72
#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 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
#define user_warning(fn,...)
Definition: misc-local.h:262
static statement init_stmt
#define COMMON_PREFIX
Definition: naming-local.h:34
#define MAIN_PREFIX
Definition: naming-local.h:32
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define BLOCKDATA_PREFIX
Definition: naming-local.h:35
#define MODULE_SEP_STRING
Definition: naming-local.h:30
void print_arguments(list args)
Definition: naming.c:228
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121
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
#define string_undefined
Definition: newgen_types.h:40
intptr_t _int
_INT
Definition: newgen_types.h:53
#define UU
Definition: newgen_types.h:98
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
text text_named_module(entity, entity, statement)
bool make_text_resource_and_free(const char *, const char *, const char *, text)
Definition: print.c:82
string basic_to_string(basic)
Definition: type.c:87
void AddEntryLabel(entity l)
Definition: procedure.c:1513
type MakeResultType(entity e, type r)
The result type of a function may be carried by e, by r or be implicit.
Definition: procedure.c:1754
void substitute_ghost_variable_in_expression(expression expr, entity v, entity f)
Definition: procedure.c:75
entity SafeLocalToGlobal(entity e, type r)
A local entity might have been created but found out later to be global, depending on the order of de...
Definition: procedure.c:1681
entity LocalToGlobal(entity e)
Definition: procedure.c:1801
bool IsEffectiveFormalParameterP(entity f)
Definition: procedure.c:1534
void ScanFormalParameters(entity m, list l)
this function scans the formal parameter list.
Definition: procedure.c:2503
entity MakeExternalFunction(entity e, type r)
Definition: procedure.c:2372
void remove_from_called_modules(entity e)
macros are added, although they should not have been.
Definition: procedure.c:354
void MakeCurrentFunction(type t, int msf, const char *cfn, list lfp)
this function creates one entity cf that represents the Fortran function f being analyzed.
Definition: procedure.c:1239
static void process_static_initialization(call c)
Definition: procedure.c:852
void add_ghost_variable_entity(entity e)
Definition: procedure.c:275
void ProcessEntries()
Definition: procedure.c:2171
void AddEntryTarget(statement s)
Definition: procedure.c:1518
bool ghost_variable_entity_p(entity e)
Definition: procedure.c:292
static void ProcessEntry(entity cm, entity e, statement t)
Definition: procedure.c:2036
void EndOfProcedure()
This function is called when the parsing of a procedure is completed.
Definition: procedure.c:979
void BeginingOfProcedure()
this function is called each time a new procedure is encountered.
Definition: procedure.c:301
void update_called_modules(entity e)
Definition: procedure.c:308
void init_ghost_variable_entities()
procedure.c
Definition: procedure.c:69
static void store_initial_value(entity var, expression val)
Integer and bool initial values are stored as int, float, string and maybe complex initial values are...
Definition: procedure.c:675
static list entry_entities
Definition: procedure.c:1455
void AddEffectiveFormalParameter(entity f)
Keep track of the formal parameters for the current module.
Definition: procedure.c:1529
static statement function_body
statement of current function
Definition: procedure.c:60
entity DeclareExternalFunction(entity e)
Definition: procedure.c:2426
static list effective_formal_parameters
Definition: procedure.c:1456
static int expression_reference_number(expression e)
Definition: procedure.c:494
static list ghost_variable_entities
list of potential local or top-level variables that turned out to be useless.
Definition: procedure.c:67
static statement BuildStatementForEntry(entity cm, entity e, statement t)
Build an entry version of the current module statement.
Definition: procedure.c:1989
static void process_static_initializations()
Definition: procedure.c:945
void AbortEntries()
Definition: procedure.c:1473
static list implicit_do_index_set
Definition: procedure.c:395
static void process_value_list(list vl, list isvs, list svps)
Definition: procedure.c:809
static list find_target_position(list cvl, int ctp, int *pmin_cp, int *pmax_cp, expression *pcve)
Definition: procedure.c:613
static list TranslateEntryFormals(entity e, list lfp)
list of formal parameters wrongly declared in current module
Definition: procedure.c:1539
static int implied_do_reference_number(expression)
forward declaration
Definition: procedure.c:561
void UpdateFormalStorages(entity m, list lfp)
this function check and set if necessary the storage of formal parameters in lfp.
Definition: procedure.c:2522
static list entry_labels
Processing of entries: when an ENTRY statement is encountered, it is replaced by a labelled CONTINUE ...
Definition: procedure.c:1453
void ResetEntries()
Definition: procedure.c:1458
void reify_ghost_variable_entity(entity e)
It is possible to change one's mind and effectively use an entity which was previously assumed useles...
Definition: procedure.c:284
instruction MakeEntry(entity e, list lfp)
An ENTRY statement is substituted by a labelled continue.
Definition: procedure.c:1810
void MakeFormalParameter(entity m, entity fp, int nfp)
This function transforms an untyped entity into a formal parameter.
Definition: procedure.c:2466
static bool fix_storage(reference r)
Definition: procedure.c:409
void AddEntryEntity(entity e)
Definition: procedure.c:1523
void substitute_ghost_variable_in_statement(statement stmt, entity v, entity f)
Definition: procedure.c:139
entity NameToFunctionalEntity(string name)
Definition: procedure.c:2217
bool EmptyEntryListsP()
Definition: procedure.c:1506
static list called_modules
list of called subroutines or functions
Definition: procedure.c:57
void remove_module_entity(entity m)
Definition: procedure.c:1188
void remove_ghost_variable_entities(bool substitute_p)
Definition: procedure.c:206
static bool gather_implicit_indices(call c)
Definition: procedure.c:397
static list entry_targets
Definition: procedure.c:1454
void UpdateFunctionalType(entity f, list l)
This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction fun...
Definition: procedure.c:1131
static void MakeEntryCommon(entity m, entity a)
Static variables in a module with entries must be redeclared as stored in a common in order to be acc...
Definition: procedure.c:1573
void TypeFunctionalEntity(entity fe, type r)
Definition: procedure.c:2257
void AbortOfProcedure()
Definition: procedure.c:386
void set_bool_property(const char *, bool)
static const char * prefix
#define SUBSTRING_FUNCTION_NAME
#define ENTITY_UNARY_MINUS_P(e)
#define ENTITY_IMPLIEDDO_P(e)
#define ENTITY_TRUE_P(e)
#define UNKNOWN_RAM_OFFSET
#define STATEMENT_NUMBER_UNDEFINED
default values
#define ENTITY_STATIC_INITIALIZATION_P(e)
Fortran DATA management.
#define IMPLIED_DO_NAME
Definition: ri-util-local.h:75
#define entity_declarations(e)
MISC: newgen shorthands.
#define ENTITY_REPEAT_VALUE_P(e)
#define MAKE_ORDERING(u, s)
On devrait utiliser Newgen pour cela, mais comme on ne doit pas les utiliser directement (mais via st...
#define instruction_block(i)
#define empty_comments
Empty comments (i.e.
#define IO_LIST_STRING_NAME
Definition: ri-util-local.h:82
#define ENTITY_FALSE_P(e)
#define ENTITY_DATA_LIST_P(e)
bool dynamic_area_p(entity aire)
Definition: area.c:68
void print_common_layout(FILE *fd, entity c, bool debug_p)
Definition: area.c:207
bool static_area_p(entity aire)
Definition: area.c:77
void fprint_functional(FILE *fd, functional f)
This function is called from c_parse() via ResetCurrentModule() and fprint_environment()
Definition: declarations.c:227
void fprint_environment(FILE *fd, entity m)
Definition: declarations.c:287
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 intrinsic_entity_p(entity e)
Definition: entity.c:1272
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
code entity_code(entity e)
Definition: entity.c:1098
bool entity_function_p(entity e)
Definition: entity.c:724
entity entity_empty_label(void)
Definition: entity.c:1105
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool entity_blockdata_p(entity e)
Definition: entity.c:712
code EntityCode(entity e)
this function checks that e has an initial value code.
Definition: entity.c:301
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
entity make_new_label(entity module)
This function returns a new label.
Definition: entity.c:357
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
list common_members_of_module(entity common, entity module, bool only_primary)
returns the list of entity to appear in the common declaration.
Definition: entity.c:1741
bool range_count(range r, intptr_t *pcount)
The range count only can be evaluated if the three range expressions are constant and if the incremen...
Definition: eval.c:979
bool expression_call_p(expression e)
Definition: expression.c:415
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
bool hpf_directive_string_p(const char *s)
recognize an hpf directive special entity.
Definition: hpfc.c:51
bool keep_directive_in_code_p(const char *s)
whether an entity must be kept in the code.
Definition: hpfc.c:101
bool formal_label_replacement_p(entity)
Definition: variable.c:1797
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
void remove_variable_entity(entity)
Definition: variable.c:1306
void error_reset_current_module_statement(void)
To be called by an error management routine only.
Definition: static.c:234
bool NumberOfElements(basic, list, int *)
Definition: size.c:403
mode MakeModeReference(void)
Definition: type.c:82
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
bool type_equal_p(type, type)
Definition: type.c:547
bool basic_equal_p(basic, basic)
Definition: type.c:927
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
type MakeTypeVariable(basic, cons *)
BEGIN_EOLE.
Definition: type.c:116
string type_to_string(const type)
type.c
Definition: type.c:51
#define type_functional_p(x)
Definition: ri.h:2950
#define formal_offset(x)
Definition: ri.h:1408
#define STATEMENT_(x)
Definition: ri.h:2416
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_undefined
Definition: ri.h:3016
#define loop_body(x)
Definition: ri.h:1644
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_int
Definition: ri.h:571
@ is_basic_logical
Definition: ri.h:573
@ is_basic_complex
Definition: ri.h:575
#define value_code_p(x)
Definition: ri.h:3065
#define functional_result(x)
Definition: ri.h:1444
#define code_undefined
Definition: ri.h:757
#define storage_formal_p(x)
Definition: ri.h:2522
#define area_size(x)
Definition: ri.h:544
#define value_constant(x)
Definition: ri.h:3073
#define loop_undefined
Definition: ri.h:1612
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_undefined
Definition: ri.h:2302
#define code_undefined_p(x)
Definition: ri.h:758
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define range_upper(x)
Definition: ri.h:2290
#define storage_tag(x)
Definition: ri.h:2515
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define constant_int(x)
Definition: ri.h:850
#define test_undefined
Definition: ri.h:2808
#define instruction_loop(x)
Definition: ri.h:1520
#define type_functional(x)
Definition: ri.h:2952
#define instruction_goto(x)
Definition: ri.h:1526
#define value_unknown_p(x)
Definition: ri.h:3077
#define test_false(x)
Definition: ri.h:2837
#define range_undefined
Definition: ri.h:2263
#define basic_tag(x)
Definition: ri.h:613
@ is_constant_int
Definition: ri.h:817
@ is_constant_call
Definition: ri.h:821
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
#define code_declarations(x)
Definition: ri.h:784
#define syntax_range(x)
Definition: ri.h:2733
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define range_increment(x)
Definition: ri.h:2292
#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 EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define statement_label(x)
Definition: ri.h:2450
@ is_storage_rom
Definition: ri.h:2494
@ is_storage_return
Definition: ri.h:2491
@ is_storage_ram
Definition: ri.h:2492
@ is_storage_formal
Definition: ri.h:2493
#define type_undefined_p(x)
Definition: ri.h:2884
#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 constant_int_p(x)
Definition: ri.h:848
#define expression_undefined
Definition: ri.h:1223
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define whileloop_label(x)
Definition: ri.h:3164
#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 functional_parameters(x)
Definition: ri.h:1442
#define code_initializations(x)
Definition: ri.h:788
#define test_true(x)
Definition: ri.h:2835
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define sequence_statements(x)
Definition: ri.h:2360
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define constant_call_p(x)
Definition: ri.h:860
#define syntax_call(x)
Definition: ri.h:2736
#define loop_label(x)
Definition: ri.h:1646
#define type_area(x)
Definition: ri.h:2946
#define expression_undefined_p(x)
Definition: ri.h:1224
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define range_lower(x)
Definition: ri.h:2288
#define variable_dimensions(x)
Definition: ri.h:3122
#define whileloop_body(x)
Definition: ri.h:3162
#define code_decls_text(x)
Definition: ri.h:786
#define statement_instruction(x)
Definition: ri.h:2458
#define storage_ram(x)
Definition: ri.h:2521
#define type_undefined
Definition: ri.h:2883
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
#define storage_rom_p(x)
Definition: ri.h:2525
#define call_arguments(x)
Definition: ri.h:711
#define instruction_test(x)
Definition: ri.h:1517
@ is_type_void
Definition: ri.h:2904
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
#define whileloop_condition(x)
Definition: ri.h:3160
#define syntax_range_p(x)
Definition: ri.h:2731
#define entity_type(x)
Definition: ri.h:2792
#define constant_call(x)
Definition: ri.h:862
#define call_undefined
Definition: ri.h:685
#define ram_shared(x)
Definition: ri.h:2253
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define storage_undefined_p(x)
Definition: ri.h:2477
#define whileloop_undefined
Definition: ri.h:3134
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define loop_index(x)
Definition: ri.h:1640
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define storage_undefined
Definition: ri.h:2476
#define entity_initial(x)
Definition: ri.h:2796
#define area_undefined
Definition: ri.h:520
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
int var_t
Type of variables.
#define ifdebug(n)
Definition: sg.c:47
#define intptr_t
Definition: stdint.in.h:294
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
#define TK_FUNCTION
Definition: syn_yacc.c:310
#define TK_PROGRAM
Definition: syn_yacc.c:325
#define TK_BLOCKDATA
Definition: syn_yacc.c:284
#define FatalError(f, m)
Definition: syntax-local.h:56
cons * FormalParameters
the current function
Definition: parser.c:55
int line_e_I
Definition: parser.c:68
int line_b_I
Indicates where the current instruction (in fact statement) starts and ends in the input file and giv...
Definition: parser.c:68
char lab_I[6]
Definition: parser.c:69
bool ParserError(const char *f, const char *m)
Definition: parser.c:116
const char * CurrentPackage
the name of the current package, i.e.
Definition: parser.c:58
void SubstituteAlternateReturns(const char *option)
return.c
Definition: return.c:59
bool SubstituteAlternateReturnsP()
Definition: return.c:81
void uses_alternate_return(bool use)
Definition: return.c:171
list add_formal_return_code(list fpl)
Update the formal and actual parameter lists by adding the return code variable as last argument.
Definition: return.c:209
void ResetReturnCodeVariable()
Definition: return.c:151
void GenerateReturn()
Generate a unique call to RETURN per module.
Definition: return.c:499
bool ReturnCodeVariableP(entity rcv)
Definition: return.c:145
void PushBlock(instruction i, string l)
Definition: statement.c:221
void ResetBlockStack()
Definition: statement.c:203
bool IsBlockStackEmpty()
Definition: statement.c:209
instruction MakeEmptyInstructionBlock()
this function creates an empty block
Definition: statement.c:654
void CheckAndInitializeStmt(void)
this function looks for undefined labels.
Definition: statement.c:113
void LinkInstToCurrentBlock(instruction i, bool number_it)
this function links the instruction i to the current block of statements.
Definition: statement.c:529
instruction PopBlock()
Definition: statement.c:238
#define text_undefined
Definition: text.h:91
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64