PIPS
misc.c
Go to the documentation of this file.
1 /*
2 
3  $Id: misc.c 23181 2016-09-09 12:56:48Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #ifndef lint
29 char lib_ri_util_prettyprint_c_rcsid[] = "$Id: misc.c 23181 2016-09-09 12:56:48Z irigoin $";
30 #endif /* lint */
31 
32  /*
33  * Prettyprint all kinds of ri related data structures
34  *
35  * Modifications:
36  * - In order to remove the extra parentheses, I made the several changes:
37  * (1) At the intrinsic_handler, the third term is added to indicate the
38  * precendence, and accordingly words_intrinsic_precedence(obj) is built
39  * to get the precedence of the call "obj".
40  * (2) words_subexpression is created to distinguish the
41  * words_expression. It has two arguments, expression and
42  * precedence. where precedence is newly added. In case of failure
43  * of words_subexpression , that is, when
44  * syntax_call_p is false, we use words_expression instead.
45  * (3) When words_call is firstly called , we give it the lowest precedence,
46  * that is 0.
47  * Lei ZHOU Nov. 4, 1991
48  *
49  * - Addition of CMF and CRAFT prettyprints. Only text_loop() has been
50  * modified.
51  * Alexis Platonoff, Nov. 18, 1994
52 
53  * - Modifications of sentence_area to deal with the fact that
54  * " only one appearance of a symbolic name as an array name in an
55  * array declarator in a program unit is permitted."
56  * (Fortran standard, number 8.1, line 40)
57  * array declarators now only appear with the type declaration, not with the
58  * area. - BC - october 196.
59  *
60  * - Modification of text_entity_declaration to ensure that the OUTPUT of PIPS
61  * can also be used as INPUT; in particular, variable declarations must
62  * appear
63  * before common declarations. BC.
64  *
65  * - neither are DATA statements for non integers (FI/FC)
66  *
67  * - Also, EQUIVALENCE statements are not generated for the moment. BC.
68  * Thay are now??? FC?
69  *
70  * - variable pdl added in most signature to handle derived type
71  * declarations in C; it is the parser declaration list; if a derived
72  * type must be prettyprinted, it must be prettyprinted with all
73  * information if in pdl, and else it must be prettyprinted with no
74  * information. For instance, "struct m {int l; int m}" is the
75  * definition of m. Other references to the type must be
76  * prettyprinted "struct m". The PIPS internal representation does
77  * record derived type declarations. The parser declaration list is
78  * used to desambiguate between the two cases. The problem occurs
79  * in both declarations.c and prettyprint.c because types can
80  * appear in expressions thanks to the sizeof and cast operators.
81  *
82  * FI: I am changing the semantics of pdl and record the entities
83  * that have already been declared, possibly in previous
84  * statements. To update this list, a pointer to pdl, ppdl, is now
85  * passed.
86  *
87  * Data structures used:
88  *
89  * text: to produce output with multiple lines (a.k.a. "sentence")
90  * and proper indenting; this is a Newgen managed data structure
91  *
92  * words: a list of strings to produce output without any specific
93  * formatting, but text's sentences can be built with words.
94  *
95  * Call graph structure (a slice of it, for C prettyprint):
96  *
97  * text_module
98  * text_named_module
99  * text_statement
100  * text_statement_enclosed: to manage braces
101  * generic_text_statement_enclosed: to manage recursivity
102  * (proper statement or compound statement)
103  * text_instruction: to print a command
104  * c_text_related_entities: to print the declarations
105  * all variables declared share some type
106  * c_text_entities: to declare a list of variables
107  * c_text_entity: to declare a variable; may call
108  * recursively c_text_related_entities to
109  * print out, for instance, a set of membres
110  * words_variable_or_function(): words level
111  * c_words_simplified_entity()
112  * generic_c_words_simplified_entity()
113  */
114 
115 // To have asprintf:
116 #include <stdlib.h>
117 #include <stdio.h>
118 #include <string.h>
119 #include <ctype.h>
120 
121 #include "linear.h"
122 
123 #include "genC.h"
124 #include "text.h"
125 #include "text-util.h"
126 #include "ri.h"
127 #include "ri-util.h"
128 #include "workspace-util.h"
129 #include "prettyprint.h"
130 #include "effects.h"
131 
132 #include "misc.h"
133 #include "properties.h"
134 
135 
136 /* operator precedences are in the [0,100] range */
137 
138 #define MAXIMAL_PRECEDENCE 100
139 #define MINIMAL_ARITHMETIC_PRECEDENCE 19
140 
141 /* Define the markers used in the raw unstructured output when the
142  PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH property is true: */
143 #define PRETTYPRINT_UNSTRUCTURED_BEGIN_MARKER "\200Unstructured"
144 #define PRETTYPRINT_UNSTRUCTURED_END_MARKER "\201Unstructured End"
145 #define PRETTYPRINT_UNSTRUCTURED_ITEM_MARKER "\202Unstructured Item"
146 #define PRETTYPRINT_UNSTRUCTURED_SUCC_MARKER "\203Unstructured Successor ->"
147 #define PRETTYPRINT_UNREACHABLE_EXIT_MARKER "\204Unstructured Unreachable"
148 ␌
149 
150 
151 /* @brief Start a single line comment
152  * @return a string containing the begin of a comment line, language dependent
153  */
155  switch(get_prettyprint_language_tag()) {
156  case is_language_c: return "//";
157  case is_language_fortran: return "C";
158  case is_language_fortran95: return "!";
159  default: pips_internal_error("language unknown not handled"); return NULL ;
160  }
161 }
162 
163 
164 /* @brief Start a single line comment with continuation (blank spaces)
165  * @return a string containing the begin of a comment line, language dependent
166  */
168  switch(get_prettyprint_language_tag()) {
169  case is_language_c: return "// ";
170  case is_language_fortran: return "C ";
171  case is_language_fortran95: return "! ";
172  default: pips_internal_error("language unknown not handled"); return NULL ;
173  }
174 }
175 
176 
179  return 0;
180  } else {
181  return INDENTATION;
182  }
183 }
184 ␌
185 static list words_cast(cast obj, int precedence, list * ppdl);
186 static list words_sizeofexpression(sizeofexpression obj, bool in_type_declaration, list * ppdl);
189 static text text_forloop(entity module,const char* label,int margin,forloop obj,int n, list * ppdl, bool is_recursive_p);
190 
191 /* This variable is used to disable the precedence system and hence to
192  prettyprint all parentheses, which let the prettyprint reflect the
193  AST. */
194 static bool precedence_p = true;
195 /* This variable is used to print braces around all blocks including
196  blocks with only one statement. */
197 static bool prettyprint_all_c_braces_p = false;
198 /* This variable is used to gracefuly print braces around if / else
199  blocks to avoid gcc warnings */
200 static bool prettyprint_gcc_c_braces_p = false;
201 
202 /******************************************************************* STYLES */
203 
204 static bool pp_style_p(string s) {
206 }
207 
208 #define pp_hpf_style_p() pp_style_p("hpf")
209 #define pp_f90_style_p() pp_style_p("f90")
210 #define pp_craft_style_p() pp_style_p("craft")
211 #define pp_cray_style_p() pp_style_p("cray")
212 #define pp_cmf_style_p() pp_style_p("cmf")
213 #define pp_doall_style_p() pp_style_p("doall")
214 #define pp_do_style_p() pp_style_p("do")
215 #define pp_omp_style_p() pp_style_p("omp")
216 
217 /********************************************************************* MISC */
218 
220  int __attribute__ ((unused)) m,
221  statement __attribute__ ((unused)) s) {
222  return make_text(NIL);
223 }
224 
226 
227 
228 /**
229  * @brief checks that the prettyprint hook was actually reset...
230  */
231 void init_prettyprint(text(*hook)(entity, int, statement)) {
232  pips_assert("prettyprint hook not set", text_statement_hook==empty_text);
233  text_statement_hook = hook;
234 }
235 
236 
237 /**
238  * @brief because some prettyprint functions may be used for debug, so
239  * the last hook set by somebody may have stayed there although
240  * being non sense...
241  */
244 }
245 
246 
247 /**
248  * @brief True is statement "s" can be printed out without enclosing
249  * braces when it is the true branch of a test. This is a special case
250  * because of dangling else clauses.
251  */
252 /* bool one_liner_true_branch_p(statement s) */
253 /* { */
254 /* bool one_p = false; */
255 
256 /* if(!statement_test_p(s)) */
257 /* one_p = one_liner_p(s); */
258 /* else { */
259 /* test t = instruction_test(statement_instruction(s)); */
260 /* statement f = test_false(t); */
261 /* if(!(empty_statement_p(f) || nop_statement_p(f))) */
262 /* one_p = true; // No need to worry, the else clause exists */
263 /* else { */
264 /* // Make sure there is no internal dangling else... */
265 /* one_p = one_liner_test_p(t); */
266 /* } */
267 /* } */
268 /* return one_p; */
269 /* } */
270 
271 /**
272  * @brief True is test "t" contains a non-empty final "else" clause.
273  */
274 /* bool one_liner_test_p(test t) */
275 /* { */
276 /* bool one_liner_p = false; */
277 /* /\* We must make sure that the final else clause is not empty *\/ */
278 /* statement f = test_false(t); */
279 
280 /* if(empty_statement_p(f) || nop_statement_p(f)) */
281 /* one_liner_p = false; */
282 /* else if(statement_test_p(f)) { */
283 /* /\* Go down recursively for "else if" constructs. *\/ */
284 /* instruction i = statement_instruction(f); */
285 /* test ft = instruction_test(i); */
286 /* one_liner_p = one_liner_test_p(ft); */
287 /* } */
288 /* else */
289 /* one_liner_p = true; */
290 
291 /* return one_liner_p; */
292 /* } */
293 
294 /**
295  * @brief Can this statement be printed on one line, without enclosing
296  * braces, if it is embedded in a loop?
297  *
298  * Another test must be used if Statement "s" is embedded in a test a
299  * a true branch.
300  */
302 {
306  || return_instruction_p(i));
307 
308  yes = yes && ENDP(statement_declarations(s));
309 
310  if(!yes && instruction_sequence_p(i)) {
312  int sc = gen_length(sl);
313 
314  if(sc==1) {
315  /* There may be many lines hidden behind another block construct
316  when code is generated in a non canonical way as for
317  {{x=1;y=2;}} */
319 
320  if(instruction_sequence_p(ii)) {
321  /* OK, we could check deeper, but this is only useful for
322  redundant internal representations. Let's forget about
323  niceties such as skipping useless braces. */
324  yes = false;
325  }
326  else
327  yes = ENDP(statement_declarations(s));
328  }
329  else
330  yes = (sc < 1) && ENDP(statement_declarations(s));
331  }
332 
333  return yes;
334 }
335 
337 {
338  statement tb = effective_test_true(obj);
339 
340  if(one_liner_p(tb)) {
341  if (statement_test_p(tb)) {
342  test nested_test = statement_test(tb);
343  statement fb = test_false(nested_test);
344  if (!empty_statement_p(fb)) {
346  }
347  }
348  }
349  return false;
350 }
351 
352 
353 
354 /***************************************************local variables handling */
355 
357 static bool local_flg = false;
358 
359 /**
360  * @brief This function either appends the declaration to the text given as a
361  * parameter or return a new text with the declaration
362 */
363 static text insert_locals (text r) {
364  if (local_flg == true) {
365  if ((r != text_undefined) && (r != NULL)){
366  MERGE_TEXTS (r, local_var);
367  }
368  else {
369  r = local_var;
370  }
371  local_flg = false;
372  }
373  return r;
374 }
375 
376 
377 /**
378  * @brief This function returns true if BLOCK boundary markers are required.
379  * The function also creates the maker when needed.
380  */
381 static bool mark_block(unformatted *t_beg,
382  unformatted *t_end,
383  int n,
384  int margin) {
385  bool result = false;
386  if(!get_bool_property("PRETTYPRINT_FOR_FORESYS")
387  && (get_bool_property("PRETTYPRINT_ALL_EFFECTS")
388  || get_bool_property("PRETTYPRINT_BLOCKS")))
389  result = true;
390  if(result == true) {
391  list pbeg = NIL;
392  list pend = NIL;
393  // Here we need to generate block markers for later use:
394  switch(get_prettyprint_language_tag()) {
395  case is_language_fortran:
397  // Fortran case: comments at the begin of the line
398  pbeg = CHAIN_SWORD (NIL, "BEGIN BLOCK");
399  pend = CHAIN_SWORD (NIL, "END BLOCK");
401  n,
402  margin,
403  pbeg);
405  n,
406  margin,
407  pend);
408  break;
409  case is_language_c:
410  // C case: comments alligned with blocks:
413  pbeg = CHAIN_SWORD (pbeg, " BEGIN BLOCK");
414  pend = CHAIN_SWORD (pend, " END BLOCK");
415  *t_beg = make_unformatted(NULL, n, margin, pbeg);
416  *t_end = make_unformatted(NULL, n, margin, pend);
417  break;
418  default:
419  pips_internal_error("Language unknown !");
420  break;
421  }
422  }
423  return result;
424 }
425 
426 /********************************************************************* WORDS */
427 
428 static int words_intrinsic_precedence(call);
429 static int intrinsic_precedence(const char*);
430 
431 /**
432  * @brief exported for craft
433  */
435  list pc;
437 
438  pc = words_subexpression(range_lower(obj), 0, true, ppdl);
439  pc = CHAIN_SWORD(pc,", ");
440  pc = gen_nconc(pc, words_subexpression(range_upper(obj), 0, true, ppdl));
441  if (/* expression_constant_p(range_increment(obj)) && */
442  strcmp( entity_local_name(call_function(c)), "1") == 0 )
443  return(pc);
444  pc = CHAIN_SWORD(pc,", ");
445  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
446 
447  return(pc);
448 }
449 
450 
451 /**
452  * @brief Output a Fortan-like do-loop range as a C-like for-loop index part.
453  * @description Assume that the increment is an integer so we can generate the
454  * good condition. Since the do-loops are recognized in C program part only
455  * with this assumptions, it is a good assumption.
456  */
458 {
459  list pc;
460  /* call c = syntax_call(expression_syntax(range_increment(obj))); */
461 
462  /* Complete the initialization assignment */
463  pc = words_subexpression(range_lower(obj), 0, true, ppdl);
464  pc = CHAIN_SWORD(pc,"; ");
465 
466  /* Check the final bound */
467  pc = CHAIN_SWORD(pc, entity_user_name(i));
468 
469  /* Increasing or decreasing index? */
470  expression inc = range_increment(obj);
471  /* Assume the increment has an integer value with a known sign
472  If The increment is negative, that means the index is tested against
473  a lower bound
474  Else we assume to test against an upper bound
475  */
476 
477  expression ru = range_upper(obj);
478  /* check if we have something of the form exp -1 as range_upper */
480  copy_expression(ru),
482  );
483 
484  /* Additionally, we want to pretty print a strict comparison if
485  certain conditions are met. This could be the default choice ,
486  but the impact on the validation would be huge */
487  set re = get_referenced_entities(ru);
488  bool references_unsigned_entity_p = false;
489  SET_FOREACH(entity,e,re) {
490  references_unsigned_entity_p |= unsigned_type_p(ultimate_type(entity_type(e)));
491  }
492  set_free(re);
493  if( references_unsigned_entity_p ) {
494  if(positive_expression_p(inc))
495  pc = CHAIN_SWORD(pc, " < ");
496  else if(negative_expression_p(inc))
497  pc = CHAIN_SWORD(pc, " > ");
498  else {
499  //pips_internal_error("loop range cannot be prettyprinted because increment sign"
500  // " is unknown\n");
501  pips_user_warning("loop increment sign is unknown: assumed positive\n");
502  pc = CHAIN_SWORD(pc, " < ");
503  }
504  pc = gen_nconc(pc, words_subexpression(ru_minus_one, 0, true, ppdl));
505  }
506  else {
507  // FI: when inc is not a constant integer,
508  // expression_negative_integer_value_p() always return false
509  if(positive_expression_p(inc))
510  pc = CHAIN_SWORD(pc, " <= ");
511  else if(negative_expression_p(inc))
512  pc = CHAIN_SWORD(pc, " >= ");
513  else {
514  //pips_internal_error("loop range cannot be prettyprinted because increment sign"
515  // " is unknown\n");
516  pips_user_warning("loop increment sign is unknown: assumed positive\n");
517  pc = CHAIN_SWORD(pc, " <= ");
518  }
519  /* Priority for LESS, GREATER, LESS_OR_EQUAL, GREATER_OR_EQUAL: 15 */
520  pc = gen_nconc(pc, words_subexpression(ru, 15, true, ppdl));
521  }
522  free_expression(ru_minus_one);
523  pc = CHAIN_SWORD(pc,"; ");
524 
525  /* Increment the loop index */
526  pc = CHAIN_SWORD(pc, entity_user_name(i));
527  pc = CHAIN_SWORD(pc," += ");
528  pc = gen_nconc(pc, words_expression(inc, ppdl));
529  pc = CHAIN_SWORD(pc,")");
530 
531  return(pc);
532 }
533 
534 
535 /**
536  * @return a list of string
537  */
538 list words_range(range obj, list * ppdl) {
539  list pc = NIL;
540 
541  /* if undefined I print a star, why not!? */
543  pc = CONS(STRING, MAKE_SWORD("*"), NIL);
544  } else {
545  switch(get_prettyprint_language_tag()) {
546  case is_language_fortran: {
548 
549  pc = CHAIN_SWORD(pc,"(/ (I,I=");
550  pc = gen_nconc(pc, words_expression(range_lower(obj), ppdl));
551  pc = CHAIN_SWORD(pc,",");
552  pc = gen_nconc(pc, words_expression(range_upper(obj), ppdl));
553  if(strcmp(entity_local_name(call_function(c)), "1") != 0) {
554  pc = CHAIN_SWORD(pc,",");
555  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
556  }
557  pc = CHAIN_SWORD(pc,") /)") ;
558  break;
559  }
560  case is_language_fortran95: {
561  // Print the lower bound if != *
563  pc = gen_nconc(pc, words_expression(range_lower(obj), ppdl));
564  }
565 
566  // Print the upper bound if != *
567  pc = CHAIN_SWORD(pc,":");
569  pc = gen_nconc(pc, words_expression(range_upper(obj), ppdl));
570  }
571 
572  // Print the increment if != 1
574  if(strcmp(entity_local_name(call_function(c)), "1") != 0) {
575  pc = CHAIN_SWORD(pc,":");
576  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
577  }
578  break;
579  }
580  case is_language_c:
581  /* C does not include ranges, but the PIPS internal
582  representation does. For instance, constant ranges can be
583  useful to express effects or regions for intrinsics. To be
584  discussed with Beatrice: e.g. memcpy(), strncp(). Especially
585  when they are called with constant arguments. */
586 
587  // FI: we might still want a warning, but the compiler will
588  // choke anyway if this is used to prettyprint some C source code
589  // pips_internal_error("I don't know how to print a range in C !");
590 
591  // FI: copied from Fortran 95, but we may prefer to see the stars
592 
593  // Print the lower bound if != *
595  pc = gen_nconc(pc, words_expression(range_lower(obj), ppdl));
596  }
597 
598  // Print the upper bound if != *
599  pc = CHAIN_SWORD(pc,":");
601  pc = gen_nconc(pc, words_expression(range_upper(obj), ppdl));
602  }
603 
604  // Print the increment if != 1
606  if(strcmp(entity_local_name(call_function(c)), "1") != 0) {
607  pc = CHAIN_SWORD(pc,":");
608  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
609  }
610 
611  break;
612  default:
613  pips_internal_error("Language unknown !");
614  break;
615  }
616  }
617  return pc;
618 }
619 
620 
621 /**
622  * @description FI: array constructor R433, p. 37 in Fortran 90 standard, can be
623  * used anywhere in arithmetic expressions whereas the triplet notation is
624  * restricted to subscript expressions. The triplet notation is used to define
625  * array sections (see R619, p. 64).
626  *
627  * @return a list of string corresponding to the range
628 */
630  list pc = NIL;
631 
632  /* if undefined I print a star, why not!? */
634  pc = CONS(STRING, MAKE_SWORD("*"), NIL);
635  } else {
636  switch(get_prettyprint_language_tag()) {
637  case is_language_fortran: {
639 
640  pc = gen_nconc(pc, words_expression(range_lower(obj), ppdl));
641  pc = CHAIN_SWORD(pc,":");
642  pc = gen_nconc(pc, words_expression(range_upper(obj), ppdl));
643  if(strcmp(entity_local_name(call_function(c)), "1") != 0) {
644  pc = CHAIN_SWORD(pc,":");
645  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
646  }
647  break;
648  }
649  case is_language_fortran95: {
650  // Print the lower bound if != *
652  pc = gen_nconc(pc, words_expression(range_lower(obj), ppdl));
653  }
654 
655  // Print the upper bound if != *
656  pc = CHAIN_SWORD(pc,":");
658  pc = gen_nconc(pc, words_expression(range_upper(obj), ppdl));
659  }
660 
661  // Print the increment if != 1
663  if(strcmp(entity_local_name(call_function(c)), "1") != 0) {
664  pc = CHAIN_SWORD(pc,":");
665  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
666  }
667  break;
668  }
669  case is_language_c:
670  // T is no way to print range in C
671  // The notation with ":" has been chosen to simplify prettyprint
672  {
673  // Print the lower bound if != *
675  pc = gen_nconc(pc, words_expression(range_lower(obj), ppdl));
676  }
677 
678  // Print the upper bound if != *
679  pc = CHAIN_SWORD(pc,":");
681  pc = gen_nconc(pc, words_expression(range_upper(obj), ppdl));
682  }
683 
684  // Print the increment if != 1
686  if(strcmp(entity_local_name(call_function(c)), "1") != 0) {
687  pc = CHAIN_SWORD(pc,":");
688  pc = gen_nconc(pc, words_expression(range_increment(obj), ppdl));
689  }
690  break;
691  }
692  default:
693  pips_internal_error("Language unknown !");
694  break;
695  }
696  }
697  return pc;
698 }
699 
700 /* exported for expression.c
701  *
702  * Should only be used to prettyprint proper C references.
703  */
704 list words_any_reference(reference obj, list * ppdl, const char* (*enf)(entity))
705 {
706  list pc = NIL;
707  string begin_attachment;
708  entity e = reference_variable(obj);
709 
710 
712  /* We don't want to print these special entity, they are there for
713  * internal purpose only
714  */
715 
716  /* Print the entity first */
717  pc = CHAIN_SWORD(pc, (*enf)(e));
718 
719  begin_attachment = STRING(CAR(pc));
720 
721  /* Let's print the indices now */
722  if(reference_indices(obj) != NIL) {
723  switch(get_prettyprint_language_tag()) {
725  case is_language_fortran: {
726  int count = 0;
727  pc = CHAIN_SWORD(pc,"(");
729  syntax ssubscript = expression_syntax(subscript);
730  if(count > 0)
731  pc = CHAIN_SWORD(pc,",");
732  else
733  count++;
734  if(syntax_range_p(ssubscript)) {
735  pc = gen_nconc(pc,
737  ppdl));
738  } else {
739  pc = gen_nconc(pc, words_subexpression(subscript, 0, true, ppdl));
740  }
741  }
742  pc = CHAIN_SWORD(pc,")");
743  break;
744  }
745  case is_language_c: {
747  syntax ssubscript = expression_syntax(subscript);
748  pc = CHAIN_SWORD(pc, "[");
749  if(syntax_range_p(ssubscript)) {
750  pc = gen_nconc(pc,
752  ppdl));
753  } else {
754  pc = gen_nconc(pc, words_subexpression(subscript, 0, true, ppdl));
755  }
756  pc = CHAIN_SWORD(pc, "]");
757  }
758  break;
759  }
760  default:
761  pips_internal_error("Language unknown !");
762  }
763  }
764  attach_reference_to_word_list(begin_attachment,
765  STRING(CAR(gen_last(pc))),
766  obj);
767  }
768 
769 
770  return(pc);
771 }
772 
773 list Words_Any_Reference(reference obj, list pdl, const char* (*enf)(entity))
774 {
775  list npdl = pdl;
776  list pc = words_any_reference(obj, &npdl, enf);
777  gen_free_list(npdl);
778  return pc;
779 }
780 
782 {
783  return words_any_reference(obj, ppdl, entity_user_name);
784 }
785 
787 {
789 }
790 
791 /* Management of alternate returns */
792 
794 
796 {
797  ifdebug(1) {
798  pips_assert("The target list is undefined",
800  }
802 }
803 
805 {
806  ifdebug(1) {
807  pips_assert("The target list is initialized",
809  }
812 }
813 
815 {
816  ifdebug(1) {
817  pips_assert("The target list is initialized",
819  }
822 }
823 
825 {
826  text ral = text_undefined;
827 
829  list sl = NIL;
832  string str_continue = string_undefined;
833  switch (get_prettyprint_language_tag()) {
835  case is_language_fortran:
836  str_continue = CONTINUE_FUNCTION_NAME;
837  break;
838  case is_language_c:
839  str_continue = C_CONTINUE_FUNCTION_NAME;
840  break;
841  default:
842  pips_internal_error("Language unknown !");
843  break;
844  }
845  unformatted u1 =
848  0,
849  CONS(STRING, strdup(str_continue), NIL));
851  sl = gen_nconc(sl, CONS(SENTENCE, s1, NIL));
852  }
853  ral = make_text(sl);
854  }
855  else {
856  ral = make_text(NIL);
857  }
858  return ral;
859 }
860 
861 ␌
862 /* words_regular_call used for user subroutine and user function and
863  intrinsics called like user function such as MOD().
864 
865  used also by library static_controlize
866  */
867 
868 list words_regular_call(call obj, bool is_a_subroutine, list * ppdl)
869 {
870  list pc = NIL;
871 
872  entity f = call_function(obj);
873  value i = entity_initial(f);
874  type t = entity_type(f);
875  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
876 
877  if (call_arguments(obj) == NIL) {
878  if (type_statement_p(t))
879  return (CHAIN_SWORD(pc, entity_local_name(f)+sizeof(LABEL_PREFIX) -1));
880  if (value_constant_p(i) || value_symbolic_p(i)) {
881  switch (get_prettyprint_language_tag()) {
882  case is_language_fortran:
884  return (CHAIN_SWORD(pc, entity_user_name(f)));
885  break;
886  case is_language_c:
887  if (ENTITY_TRUE_P(f))
888  return (CHAIN_SWORD(pc, "true"));
889  if (ENTITY_FALSE_P(f))
890  return (CHAIN_SWORD(pc, "false"));
891  return (CHAIN_SWORD(pc, entity_user_name(f)));
892  break;
893  default:
894  pips_internal_error("Language unknown !");
895  break;
896  }
897  }
898  }
899 
901  bool function_p = type_void_p(functional_result(type_functional(calltype)));
902 
903  if (function_p) {
904  if (is_a_subroutine) {
905  switch (get_prettyprint_language_tag()) {
906  case is_language_fortran:
908  pc = CHAIN_SWORD(pc, "CALL ");
909  break;
910  case is_language_c:
911  pc = CHAIN_SWORD(pc, "");
912  break;
913  default:
914  pips_internal_error("Language unknown !");
915  break;
916  }
917  } else {
918  switch (get_prettyprint_language_tag()) {
919  case is_language_fortran:
920  pips_user_warning("subroutine '%s' used as a function.\n",
921  entity_name(f));
922  break;
923  case is_language_c:
924  // no warning in C
925  break;
927  pips_internal_error("Need to update F95 case");
928  break;
929  default:
930  pips_internal_error("Language unknown !");
931  break;
932  }
933  }
934  } else if (is_a_subroutine) {
935  switch (get_prettyprint_language_tag()) {
936  case is_language_fortran:
938  pips_user_warning("function '%s' used as a subroutine.\n",
939  entity_name(f));
940  pc = CHAIN_SWORD(pc, "CALL ");
941  break;
942  case is_language_c:
943  // no warning in C
944  pc = CHAIN_SWORD(pc, "");
945  break;
946  default:
947  pips_internal_error("Language unknown !");
948  break;
949  }
950  }
951 
952  /* special cases for stdarg builtin macros */
953  bool add_argument_count_p = false;
954  if (ENTITY_VA_END_P(f)) {
955  //pc = CHAIN_SWORD(pc, "va_end");
956  pc = CHAIN_SWORD(pc, "__builtin_va_end");
957  }
958  else if (ENTITY_VA_START_P(f)) {
959  //pc = CHAIN_SWORD(pc, "va_start");
960  pc = CHAIN_SWORD(pc, "__builtin_va_start");
961  }
962  else if (ENTITY_VA_COPY_P(f)) {
963  //pc = CHAIN_SWORD(pc, "va_copy");
964  pc = CHAIN_SWORD(pc, "__builtin_va_copy");
965  }
966 
967  /* Special cases for stdio.h */
968  /* else if (ENTITY__IO_GETC_P(f)) */
969 /* pc = CHAIN_SWORD(pc, "getc"); */
970 /* else if (ENTITY__IO_PUTC_P(f)) */
971 /* pc = CHAIN_SWORD(pc, "putc"); */
972  else if (ENTITY_ISOC99_SCANF_P(f))
974  else if (ENTITY_ISOC99_FSCANF_P(f))
976  else if (ENTITY_ISOC99_SSCANF_P(f))
978  else if (ENTITY_ISOC99_VFSCANF_P(f))
980  else if (ENTITY_ISOC99_VSCANF_P(f))
982  else if (ENTITY_ISOC99_VSSCANF_P(f))
984 
985  /* Special cases for Fortran intrinsics not available in C */
987  && !get_bool_property("PRETTYPRINT_INTERNAL_INTRINSICS")) {
988  add_argument_count_p = true;
990  }
992  && !get_bool_property("PRETTYPRINT_INTERNAL_INTRINSICS")) {
993  add_argument_count_p = true;
995  }
996 
997  /* the implied complex operator is hidden... [D]CMPLX_(x,y) -> (x,y)
998  */
1000  pc = CHAIN_SWORD(pc, entity_user_name(f));
1001 
1002 
1003  /* The corresponding formal parameter cannot be checked by
1004  formal_label_replacement_p() because the called modules may not have
1005  been parsed yet. */
1006 
1007  if(!ENDP(call_arguments(obj))) {
1008  list pa = list_undefined;
1009  pc = CHAIN_SWORD(pc, "(");
1010 
1011  if(add_argument_count_p) {
1012  int n = gen_length(call_arguments(obj));
1013  string narg;
1014  asprintf(&narg,"%d", n);
1015  pc = CHAIN_SWORD(pc, narg);
1016  pc = CHAIN_SWORD(pc, ", ");
1017  }
1018 
1019  for(pa = call_arguments(obj); !ENDP(pa); POP(pa)) {
1020  expression eap = EXPRESSION(CAR(pa));
1021  if(get_bool_property("PRETTYPRINT_REGENERATE_ALTERNATE_RETURNS")
1023  /* Alternate return actual argument have been replaced by
1024  character strings by the parser. */
1026  const char* ls = entity_local_name(cf);
1027  string ls1 = malloc(strlen(ls));
1028  /* pips_assert("ls has at least four characters", strlen(ls)>=4); */
1029 
1030  /* Get rid of initial and final quotes */
1031  ls1 = strncpy(ls1, ls+1, strlen(ls)-2);
1032  *(ls1+strlen(ls)-2) = '\000';
1033  pips_assert("eap must be a call to a constant string", expression_call_p(eap));
1034  if(strcmp(get_string_property("PARSER_SUBSTITUTE_ALTERNATE_RETURNS"), "STOP")!=0) {
1035  pc = CHAIN_SWORD(pc, ls1);
1036  /* free(ls1); */
1037  }
1038  else {
1039  /* The actual label cannot always be used because it might have been
1040  eliminated as part of dead code by PIPS since it is not used
1041  with the STOP option. */
1043  pc = CHAIN_SWORD(pc, ls1);
1044  }
1045  else {
1047 
1048  /* The assertion may be wrong if this piece of code is used to
1049  print intermediate statements */
1050  pips_assert("Label els1 has been defined although it is not used anymore",
1051  !entity_undefined_p(els1));
1052 
1053  pc = CHAIN_SWORD(pc, ls1);
1055  }
1056  }
1057  }
1058  else {
1059  /* words_expression cannot be called because of the C comma
1060  operator which require surrounding parentheses in this
1061  context. Be careful with unary minus. */
1064  true/*false*/,
1065  ppdl));
1066  }
1067  if (CDR(pa) != NIL)
1068  pc = CHAIN_SWORD(pc, space_p? ", ": ",");
1069  }
1070 
1071  pc = CHAIN_SWORD(pc, ")");
1072  }
1074  !is_a_subroutine || prettyprint_language_is_c_p()) {
1075  pc = CHAIN_SWORD(pc, "()");
1076  }
1077 
1078  return pc;
1079 }
1080 
1081 list Words_Regular_Call(call obj, bool is_a_subroutine)
1082 {
1083  list pdl = NIL;
1084  list pc = words_regular_call(obj, is_a_subroutine, &pdl);
1085  gen_free_list(pdl);
1086  return pc;
1087 }
1088 
1089 /* To deal with attachment on user module usage. */
1090 static list words_genuine_regular_call(call obj, bool is_a_subroutine, list * ppdl)
1091 {
1092  list pc = words_regular_call(obj, is_a_subroutine, ppdl);
1093 
1094  if (call_arguments(obj) != NIL) {
1095  /* The call is not used to code a constant: */
1096  //entity f = call_function(obj);
1097  //type t = entity_type(f);
1098  /* The module name is the first one except if it is a procedure CALL. */
1101  else
1103  }
1104 
1105  return pc;
1106 }
1107 
1108 list
1110  int __attribute__ ((unused)) precedence,
1111  bool __attribute__ ((unused)) leftmost,
1112  list * ppdl)
1113 {
1114  return words_regular_call(obj, true, ppdl);
1115 }
1116 
1117 static list
1119  int precedence,
1120  bool __attribute__ ((unused)) leftmost,
1121  list * ppdl)
1122 {
1123  list pc = NIL, args = call_arguments(obj);
1124  int prec = words_intrinsic_precedence(obj);
1125  const char* fun = entity_local_name(call_function(obj));
1126 
1127  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(args)), prec, true, ppdl));
1128 
1129  if (strcmp(fun, MODULO_UPDATE_OPERATOR_NAME) == 0)
1130  fun = "%=";
1131  else if (strcmp(fun, BITWISE_AND_UPDATE_OPERATOR_NAME) == 0)
1132  fun = "&=";
1133  else if (strcmp(fun, BITWISE_XOR_UPDATE_OPERATOR_NAME) == 0)
1134  fun = "^=";
1135 
1136  /* FI: space_p could be used here to control spacing around assignment */
1137  pc = CHAIN_SWORD(pc," ");
1138  pc = CHAIN_SWORD(pc, fun);
1139  pc = CHAIN_SWORD(pc," ");
1141  switch (get_prettyprint_language_tag()) {
1142  case is_language_fortran:
1143  case is_language_fortran95:
1144  exp = EXPRESSION(CAR(CDR(args)));
1145  if (expression_call_p(exp)) {
1146  /* = is not a Fortran operator. No need for parentheses ever,
1147  even with the parenthesis option */
1148  /*
1149  call c = syntax_call(expression_syntax(e));
1150  pc = gen_nconc(pc, words_call(c, 0, true, true, ppdl));
1151  */
1152  pc = gen_nconc(pc, words_syntax(expression_syntax(exp), ppdl));
1153  } else
1154  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(CDR(args))),
1155  prec,
1156  true,
1157  ppdl));
1158  break;
1159  case is_language_c:
1160  /* Brace expressions are not allowed in standard assignments */
1161  exp = EXPRESSION(CAR(CDR(args)));
1162  if (ENTITY_ASSIGN_P(call_function(obj))) {
1163  if (brace_expression_p(exp)) {
1164  // use GCC constructor extension */
1165  pips_internal_error("this should not happen: a constructor is represnetd as a cas on brace expression\n");
1166  }
1167  else {
1168  /* Be careful with expression lists, they may require
1169  surrounding parentheses. */
1170  pc = gen_nconc(pc, words_subexpression(exp, prec, true, ppdl));
1171  }
1172  } else {
1173  pc = gen_nconc(pc, words_subexpression(exp, prec, true, ppdl));
1174  }
1175  break;
1176  default:
1177  pips_internal_error("Language unknown !");
1178  break;
1179  }
1180  if (prec < precedence || (!precedence_p && precedence > 0)) {
1181  pc = CONS(STRING, MAKE_SWORD("("), pc);
1182  pc = CHAIN_SWORD(pc, ")");
1183  }
1184  return (pc);
1185 }
1186 static list
1188  int __attribute__ ((unused)) precedence,
1189  bool __attribute__ ((unused)) leftmost,
1190  list * ppdl) {
1191  /* The substring function call is reduced to a syntactic construct */
1192  list pc = NIL;
1196  /* expression e = EXPRESSION(CAR(CDR(CDR(CDR(call_arguments(obj)))))); */
1197  int prec = words_intrinsic_precedence(obj);
1198 
1199  pips_assert("words_substring_op", gen_length(call_arguments(obj)) == 3 ||
1200  gen_length(call_arguments(obj)) == 4);
1201 
1202  r = EXPRESSION(CAR(call_arguments(obj)));
1203  l = EXPRESSION(CAR(CDR(call_arguments(obj))));
1204  u = EXPRESSION(CAR(CDR(CDR(call_arguments(obj)))));
1205 
1206  pc = gen_nconc(pc, words_subexpression(r, prec, true, ppdl));
1207  pc = CHAIN_SWORD(pc, "(");
1208  pc = gen_nconc(pc, words_subexpression(l, prec, true, ppdl));
1209  pc = CHAIN_SWORD(pc, ":");
1210 
1211  /* An unknown upper bound is encoded as a call to
1212  UNBOUNDED_DIMENSION_NAME and nothing must be printed */
1216  pc = gen_nconc(pc, words_subexpression(u, prec, true, ppdl));
1217  }
1218  else {
1219  pc = gen_nconc(pc, words_subexpression(u, prec, true, ppdl));
1220  }
1221  pc = CHAIN_SWORD(pc, ")");
1222 
1223  return(pc);
1224 }
1225 
1226 static list
1228  int __attribute__ ((unused)) precedence,
1229  bool __attribute__ ((unused)) leftmost,
1230  list * ppdl)
1231 {
1232  /* The assign substring function call is reduced to a syntactic construct */
1233  list pc = NIL;
1235  int prec = words_intrinsic_precedence(obj);
1236 
1237  pips_assert("words_substring_op", gen_length(call_arguments(obj)) == 4);
1238 
1239  e = EXPRESSION(CAR(CDR(CDR(CDR(call_arguments(obj))))));
1240 
1241  pc = gen_nconc(pc, words_substring_op(obj, prec, true, ppdl));
1242  pc = CHAIN_SWORD(pc, " = ");
1243  pc = gen_nconc(pc, words_subexpression(e, prec, true, ppdl));
1244 
1245  return(pc);
1246 }
1247 
1248 /**
1249  * @return the external string representation of the operator
1250  * @param name, the pips internal representation of the operator
1251  */
1252 static const char* renamed_op_handling (const char* name) {
1253  const char* result = name;
1254 
1255  if ( strcmp(result,PLUS_C_OPERATOR_NAME) == 0 )
1256  result = "+";
1257  else if ( strcmp(result, MINUS_C_OPERATOR_NAME) == 0 )
1258  result = "-";
1259  else if ( strcmp(result,BITWISE_AND_OPERATOR_NAME) == 0 )
1260  result = "&";
1261  else if ( strcmp(result,BITWISE_XOR_OPERATOR_NAME) == 0 )
1262  result = "^";
1263  else if ( strcmp(result,C_AND_OPERATOR_NAME) == 0 )
1264  result = "&&";
1265  else if ( strcmp(result,C_NON_EQUAL_OPERATOR_NAME) == 0 )
1266  result = "!=";
1267  else if ( strcmp(result,C_MODULO_OPERATOR_NAME) == 0 )
1268  result = "%";
1269  else if (prettyprint_language_is_c_p()) {
1270  if(strcasecmp(result, GREATER_THAN_OPERATOR_NAME)==0)
1272  else if(strcasecmp(result, LESS_THAN_OPERATOR_NAME)==0)
1274  else if(strcasecmp(result,GREATER_OR_EQUAL_OPERATOR_NAME)==0)
1276  else if(strcasecmp(result,LESS_OR_EQUAL_OPERATOR_NAME)==0)
1278  else if(strcasecmp(result, EQUAL_OPERATOR_NAME) ==0)
1279  result=C_EQUAL_OPERATOR_NAME;
1280  else if(strcasecmp(result,NON_EQUAL_OPERATOR_NAME)==0)
1281  result= "!=";
1282  else if(strcasecmp(result,AND_OPERATOR_NAME)==0)
1283  result="&&";
1284  else if(strcasecmp(result, OR_OPERATOR_NAME)==0)
1285  result=C_OR_OPERATOR_NAME;
1286  }
1287  return result;
1288 }
1289 
1290 /** @return a list of string with the prettyprint of a omp reduction clause
1291  */
1292 static list
1294  int precedence __attribute__ ((unused)),
1295  bool leftmost __attribute__ ((unused)),
1296  list * ppdl)
1297 {
1298  list result = NIL;
1299  entity fct = call_function(obj);
1300  result = CHAIN_SWORD(result, entity_user_name(fct));
1301  result = CHAIN_SWORD(result, "(");
1302  // the reduction arguments as an expression list
1303  list args = call_arguments (obj);
1304  pips_assert ("no arguments for reduction clause", args != NIL);
1305  int nb_arg = 0;
1306  FOREACH (EXPRESSION, arg, args) {
1307  if (nb_arg == 0) {
1308  // the first argument is an operator and need to be handle separately
1309  // because of the intenal management of operator
1310  const char* op;
1311  syntax syn = expression_syntax (arg);
1312  pips_assert ("should be a reference", syntax_tag (syn) == is_syntax_reference);
1314  op = renamed_op_handling (op);
1315  CHAIN_SWORD(result, op);
1316  }
1317  else { // (nb_arg != 0)
1318  result = (nb_arg == 1)? CHAIN_SWORD(result,":") : CHAIN_SWORD(result,",");
1319  result = gen_nconc (result, words_expression(arg, ppdl));
1320  }
1321  nb_arg++;
1322  }
1323  pips_assert ("reduction clause has at least two arguments", nb_arg > 1);
1324  result = CHAIN_SWORD(result, ")");
1325  return result;
1326 }
1327 
1328 // Function written by C.A. Mensi to prettyprint C or Fortran code as C code
1329 static list
1331  call obj,
1332  int precedence __attribute__ ((unused)),
1333  bool leftmost __attribute__ ((unused)),
1334  list * ppdl)
1335 {
1336  list pc = NIL;
1337  list args = call_arguments(obj);
1338  entity func = call_function(obj);
1339  const char* fname = entity_local_name(func);
1340  int nargs = gen_length(args);
1341  bool parentheses_p=true;
1342 
1343  /* STOP and PAUSE and RETURN in Fortran may have 0 or 1 argument.
1344  STOP and PAUSE are prettyprinted in C using PIPS specific C functions. */
1345 
1346  if (nargs==0)
1347  {
1349  pc = CHAIN_SWORD(pc, "exit(0)");
1350  else if(same_string_p(fname,RETURN_FUNCTION_NAME)
1352  pc = CHAIN_SWORD(pc, "return");
1353  else if(same_string_p(fname,PAUSE_FUNCTION_NAME))
1354  pc = CHAIN_SWORD(pc, "_f77_intrinsics_pause_(0)");
1355  else if(same_string_p(fname,CONTINUE_FUNCTION_NAME))
1356  pc = CHAIN_SWORD(pc, "");
1357  else if ((same_string_p(fname,OMP_OMP_FUNCTION_NAME)) ||
1360  pc = CHAIN_SWORD(pc, fname);
1361  else
1362  pips_internal_error("Unknown nullary operator");
1363  }
1364  else if (nargs==1){
1365  expression e = EXPRESSION(CAR(args));
1366 
1367  if(same_string_p(fname,STOP_FUNCTION_NAME)){
1368  basic b=expression_basic(e);
1369  if(basic_int_p(b)){
1370  // Missing: declaration of exit() if Fortran code handled
1371  pc = CHAIN_SWORD(pc, "exit");
1372  }
1373  else if(basic_string_p(b)){
1374  pc = CHAIN_SWORD(pc, "_f77_intrinsics_stop_");
1375  }
1376  }
1377  else if(same_string_p(fname,RETURN_FUNCTION_NAME)
1379  pc = CHAIN_SWORD(pc, "return");
1380  parentheses_p = false;
1381  //pips_user_error("alternate returns are not supported in C\n");
1382  }
1383  else if(same_string_p(fname, PAUSE_FUNCTION_NAME)){
1384  pc = CHAIN_SWORD(pc, "_f77_intrinsics_pause_");
1385  }
1386  else {
1387  pips_internal_error("unexpected one argument");
1388  }
1389  pc = CHAIN_SWORD(pc, parentheses_p?"(":" ");
1390  pc = gen_nconc(pc, words_subexpression(e, precedence, true, ppdl));
1391  pc = CHAIN_SWORD(pc, parentheses_p?")":"");
1392  }
1393  else {
1394  // should always be an error? workaround for p4a test, FC 2015-11-27
1395  pips_user_warning("function %s: %d arguments instead of 0 or 1.",
1396  fname, nargs);
1398  pips_internal_error("unexpected %s call with %d arguments", fname, nargs);
1399  }
1400 
1401  return pc;
1402 }
1403 
1404 // function added for fortran by A. Mensi
1406  int precedence,
1407  bool __attribute__ ((unused)) leftmost,
1408  list * ppdl)
1409 {
1410  list pc = NIL;
1411  list args = call_arguments(obj);
1412  entity func = call_function(obj);
1413  const char* fname = entity_local_name(func);
1414 
1418  else if (same_string_p(fname,OMP_FOR_FUNCTION_NAME))
1419  pc = CHAIN_SWORD(pc, "do");
1420  else
1421  pc = CHAIN_SWORD(pc, fname);
1422 
1423  // STOP and PAUSE and RETURN in fortran may have 0 or 1 argument.A Mensi
1424  if(gen_length(args)==1) {
1429  expression e = EXPRESSION(CAR(args));
1430  pc = CHAIN_SWORD(pc, " ");
1431  pc = gen_nconc(pc, words_subexpression(e, precedence, true, ppdl));
1432  }
1433  else {
1434  pips_internal_error("unexpected arguments");
1435  }
1436  }
1437  else if(gen_length(args)>1) {
1438  pips_internal_error("unexpected arguments");
1439  }
1440 
1441  return(pc);
1442 }
1443 
1444 
1446  int precedence,
1447  bool __attribute__ ((unused)) leftmost,
1448  list * ppdl) {
1449  list result = NIL;
1450  switch (get_prettyprint_language_tag()) {
1451  case is_language_fortran:
1452  case is_language_fortran95:
1453  result = words_nullary_op_fortran(obj, precedence, leftmost, ppdl);
1454  break;
1455  case is_language_c:
1456  result = words_nullary_op_c(obj, precedence, leftmost, ppdl);
1457  break;
1458  default:
1459  pips_internal_error("Language unknown !");
1460  break;
1461  }
1462  return result;
1463 }
1464 
1465 
1466 static list
1468  int __attribute__ ((unused)) precedence,
1469  bool __attribute__ ((unused)) leftmost,
1470  list * ppdl)
1471 {
1472  list pc = NIL;
1473  list pio = *iol;
1474 
1475  while (pio != NIL) {
1477  call c;
1478 
1479  if (! syntax_call_p(s)) {
1480  pips_internal_error("call expected");
1481  }
1482 
1483  c = syntax_call(s);
1484 
1485  if (strcmp(entity_local_name(call_function(c)), IO_LIST_STRING_NAME) == 0) {
1486  *iol = CDR(pio);
1487  return(pc);
1488  }
1489 
1490  if (pc != NIL)
1491  pc = CHAIN_SWORD(pc, ",");
1492 
1494  pc = gen_nconc(pc, words_expression(EXPRESSION(CAR(CDR(pio))), ppdl));
1495 
1496  pio = CDR(CDR(pio));
1497  }
1498 
1499  if (pio != NIL)
1500  pips_internal_error("bad format");
1501 
1502  *iol = NIL;
1503 
1504  return(pc);
1505 }
1506 
1507 static list
1509  int __attribute__ ((unused)) precedence,
1510  bool __attribute__ ((unused)) leftmost,
1511  list * ppdl)
1512 {
1513  list pc = NIL;
1514  list pcc;
1515  expression index;
1516  syntax s;
1517  range r;
1518  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
1519 
1520  pcc = call_arguments(obj);
1521  index = EXPRESSION(CAR(pcc));
1522 
1523  pcc = CDR(pcc);
1524  s = expression_syntax(EXPRESSION(CAR(pcc)));
1525  if (! syntax_range_p(s)) {
1526  pips_internal_error("range expected");
1527  }
1528  r = syntax_range(s);
1529 
1530  pc = CHAIN_SWORD(pc, "(");
1531  MAPL(pcp, {
1532  pc = gen_nconc(pc, words_expression(EXPRESSION(CAR(pcp)), ppdl));
1533  if (CDR(pcp) != NIL)
1534  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1535  }, CDR(pcc));
1536  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1537 
1538  pc = gen_nconc(pc, words_expression(index, ppdl));
1539  pc = CHAIN_SWORD(pc, " = ");
1540  pc = gen_nconc(pc, words_loop_range(r, ppdl));
1541  pc = CHAIN_SWORD(pc, ")");
1542 
1543  return(pc);
1544 }
1545 
1546 static list
1548  int __attribute__ ((unused)) precedence,
1549  bool __attribute__ ((unused)) leftmost,
1550  list __attribute__ ((unused)) * ppdl)
1551 {
1552  list pc = NIL;
1553 
1554  pc = CHAIN_SWORD(pc, "*");
1555 
1556  return(pc);
1557 }
1558 
1559 static list
1561  int __attribute__ ((unused)) precedence,
1562  bool __attribute__ ((unused)) leftmost,
1563  list __attribute__ ((unused)) * ppdl)
1564 {
1565  list pc = NIL;
1566 
1567  pc = CHAIN_SWORD(pc, "*");
1568 
1569  return(pc);
1570 }
1571 
1572 static list
1574  int precedence, bool leftmost, list * ppdl)
1575 {
1576  list pc = NIL;
1577  list pcio = call_arguments(obj);
1578  list pio_write = pcio;
1579  bool good_fmt = false;
1580  bool good_unit = false;
1581  bool iolist_reached = false;
1582  bool complex_io_control_list = false;
1583  expression fmt_arg = expression_undefined;
1584  expression unit_arg = expression_undefined;
1585  const char* called = entity_local_name(call_function(obj));
1586  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
1587 
1588  /* AP: I try to convert WRITE to PRINT. Three conditions must be
1589  fullfilled. The first, and obvious, one, is that the function has
1590  to be WRITE. Secondly, "FMT" has to be equal to "*". Finally,
1591  "UNIT" has to be equal either to "*" or "6". In such case,
1592  "WRITE(*,*)" is replaced by "PRINT *,". */
1593  /* GO: Not anymore for UNIT=6 leave it ... */
1594  while((pio_write != NIL) && (!iolist_reached)) {
1595  syntax s = expression_syntax(EXPRESSION(CAR(pio_write)));
1596  call c;
1597  expression arg = EXPRESSION(CAR(CDR(pio_write)));
1598 
1599  if(!syntax_call_p(s)) {
1600  pips_internal_error("call expected");
1601  }
1602 
1603  c = syntax_call(s);
1604  if(strcmp(entity_local_name(call_function(c)), "FMT=") == 0) {
1605  /* Avoid to use words_expression(arg) because it set some
1606  attachments and unit_words may not be used
1607  later... RK. */
1608  entity f;
1609  /* The * format is coded as a call to
1610  "LIST_DIRECTED_FORMAT_NAME" function: */
1611  good_fmt = syntax_call_p(expression_syntax(arg))
1614  && (strcmp(entity_local_name(f), LIST_DIRECTED_FORMAT_NAME) == 0);
1615  pio_write = CDR(CDR(pio_write));
1616  /* To display the format later: */
1617  fmt_arg = arg;
1618  } else if(strcmp(entity_local_name(call_function(c)), "UNIT=") == 0) {
1619  /* Avoid to use words_expression(arg) because it set some
1620  attachments and unit_words may not be used
1621  later... RK. */
1622  entity f;
1623  /* The * format is coded as a call to
1624  "LIST_DIRECTED_FORMAT_NAME" function: */
1625  good_unit = syntax_call_p(expression_syntax(arg))
1628  && (strcmp(entity_local_name(f), LIST_DIRECTED_FORMAT_NAME) == 0);
1629  /* To display the unit later: */
1630  unit_arg = arg;
1631  pio_write = CDR(CDR(pio_write));
1632  } else if(strcmp(entity_local_name(call_function(c)), IO_LIST_STRING_NAME)
1633  == 0) {
1634  iolist_reached = true;
1635  pio_write = CDR(pio_write);
1636  } else {
1637  complex_io_control_list = true;
1638  pio_write = CDR(CDR(pio_write));
1639  }
1640  }
1641 
1642  if(good_fmt && good_unit && same_string_p(called, "WRITE")) {
1643  /* WRITE (*,*) -> PRINT * */
1644 
1645  if(pio_write != NIL) /* WRITE (*,*) pio -> PRINT *, pio */
1646  {
1647  pc = CHAIN_SWORD(pc, "PRINT *, ");
1648  } else /* WRITE (*,*) -> PRINT * */
1649  {
1650  pc = CHAIN_SWORD(pc, "PRINT * ");
1651  }
1652 
1653  pcio = pio_write;
1654  } else if(good_fmt && good_unit && same_string_p(called, "READ")) {
1655  /* READ (*,*) -> READ * */
1656 
1657  if(pio_write != NIL) /* READ (*,*) pio -> READ *, pio */
1658  {
1659  switch(get_prettyprint_language_tag()) {
1660  case is_language_fortran:
1661  case is_language_fortran95:
1662  pc = CHAIN_SWORD(pc, "READ *, ");
1663  break;
1664  case is_language_c:
1665  pc = CHAIN_SWORD(pc, "_f77_intrinsics_read_(");
1666  break;
1667  default:
1668  pips_internal_error("Language unknown !");
1669  break;
1670  }
1671  } else /* READ (*,*) -> READ * */
1672  {
1673  pc = CHAIN_SWORD(pc, "READ * ");
1674  }
1675  pcio = pio_write;
1676  } else if(!complex_io_control_list) {
1677  list unit_words = words_expression(unit_arg, ppdl);
1678  pips_assert("A unit must be defined", !ENDP(unit_words));
1680  pc = CHAIN_SWORD(pc, " (");
1681  pc = gen_nconc(pc, unit_words);
1682 
1683  if(!expression_undefined_p(fmt_arg)) {
1684  /* There is a FORMAT: */
1685  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1686  pc = gen_nconc(pc, words_expression(fmt_arg, ppdl));
1687  }
1688 
1689  pc = CHAIN_SWORD(pc, ") ");
1690  pcio = pio_write;
1691  } else {
1693  pc = CHAIN_SWORD(pc, " (");
1694  /* FI: missing argument; I use "precedence" because I've no clue;
1695  see LZ */
1696  pc = gen_nconc(pc, words_io_control(&pcio, precedence, leftmost, ppdl));
1697  pc = CHAIN_SWORD(pc, ") ");
1698  /*
1699  free_words(fmt_words);
1700  */
1701  }
1702 
1703  /* because the "IOLIST=" keyword is embedded in the list
1704  and because the first IOLIST= has already been skipped,
1705  only odd elements are printed */
1706  MAPL(pp, {
1707  pc = gen_nconc(pc, words_expression(EXPRESSION(CAR(pp)), ppdl));
1708  if (CDR(pp) != NIL) {
1709  POP(pp);
1710  if(pp==NIL)
1711  pips_internal_error("missing element in IO list");
1712  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1713  }
1714  }, pcio);
1715 
1717  pc = CHAIN_SWORD(pc, ") ");
1718 
1719  return (pc);
1720 }
1721 
1722 
1723 /**
1724  * Implemented for ALLOCATE(), but is applicable for every call to
1725  * function that take STAT= parameter
1726  */
1728  int __attribute__((unused)) precedence,
1729  bool __attribute__((unused)) leftmost,
1730  list * ppdl) {
1731  list pc = NIL;
1732  list pcio = call_arguments(obj);
1733  list pio_write = pcio;
1734  const char* called = entity_local_name(call_function(obj));
1735  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
1736 
1737  /* Write call function */
1738  pc = CHAIN_SWORD(pc, called);
1739  pc = CHAIN_SWORD(pc, " (");
1740 
1741  while ( ( pio_write != NIL ) ) {
1742  expression expr = EXPRESSION(CAR(pio_write));
1743  syntax s = expression_syntax(expr);
1744  call c;
1745 
1746  if ( syntax_call_p(s) ) { /* STAT= is a call */
1747  c = syntax_call(s);
1748  if ( strcmp( entity_local_name( call_function(c) ), "STAT=" ) == 0 ) {
1749  /* We got it ! */
1750  pc = CHAIN_SWORD(pc, strdup("STAT=")); /* FIXME : strdup ? */
1751  /* get argument */
1752  pio_write = CDR(pio_write);
1753  expression arg = EXPRESSION(CAR(pio_write));
1754  pc = gen_nconc( pc, words_expression( arg, ppdl ) );
1755  }
1756  } else { /* It's not a call */
1757  pc = gen_nconc( pc, words_expression( expr, ppdl ) );
1758  }
1759  pio_write = CDR(pio_write);
1760  if(pio_write) {
1761  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1762  }
1763  }
1764 
1765  pc = CHAIN_SWORD(pc, ") ");
1766 
1767  return ( pc );
1768 }
1769 
1770 
1771 static list
1772 null(call __attribute__ ((unused)) obj,
1773  int __attribute__ ((unused)) precedence,
1774  bool __attribute__ ((unused)) leftmost,
1775  list __attribute__ ((unused)) * ppdl)
1776 {
1777  return(NIL);
1778 }
1779 
1780 static list
1782  int precedence,
1783  bool __attribute__ ((unused)) leftmost,
1784  list * ppdl)
1785 {
1786  list pc = NIL;
1788  int prec = words_intrinsic_precedence(obj);
1789  const char* fun = entity_local_name(call_function(obj));
1790  if (strcmp(fun,PRE_INCREMENT_OPERATOR_NAME) == 0)
1791  fun = "++";
1792  else if (strcmp(fun,PRE_DECREMENT_OPERATOR_NAME) == 0)
1793  fun = "--";
1794  else if (strcmp(fun,ADDRESS_OF_OPERATOR_NAME) == 0)
1795  fun = "&";
1796  else if (strcmp(fun,C_NOT_OPERATOR_NAME) == 0)
1797  fun = "!";
1798  else if (strcmp(fun,BITWISE_NOT_OPERATOR_NAME) == 0)
1799  fun = "~";
1800  else if (strcmp(fun,DEREFERENCING_OPERATOR_NAME) == 0)
1801  /* Since we put no spaces around an operator (to not change Fortran), the blank
1802  before '*' is used to avoid the confusion in the case of divide operator, i.e
1803  d1 = 1.0 / *det in function inv_j, SPEC2000 quake benchmark.
1804 
1805  But we do not want this in a lhs and espcially with a double dereferencing. */
1806  fun = "*";
1807  else if(prettyprint_language_is_c_p()){
1808  if(strcasecmp(fun, NOT_OPERATOR_NAME)==0)
1809  fun="!";
1810  if(strcasecmp(fun, UNARY_PLUS_OPERATOR_NAME)==0) {
1811  /* You do not want to transform +1 + +1 into +1++ 1 */
1812  /* Maybe the precedence could be useful to avoid adding a
1813  useless SPACE, but unary plus is rare enough to reduce
1814  the ROI of such anoptimization to zero. */
1815  fun=" +";
1816  }
1817  }
1818 
1819  pc = CHAIN_SWORD(pc,fun);
1820  pc = gen_nconc(pc, words_subexpression(e, prec, false, ppdl));
1821 
1822  if(prec < precedence || (!precedence_p && precedence>0)) {
1823  pc = CONS(STRING, MAKE_SWORD("("), pc);
1824  pc = CHAIN_SWORD(pc, ")");
1825  }
1826 
1827  return(pc);
1828 }
1829 
1830 static list
1832  int precedence,
1833  bool __attribute__ ((unused)) leftmost,
1834  list * ppdl)
1835 {
1836  list pc = NIL;
1838  int prec = words_intrinsic_precedence(obj);
1839  const char* fun = entity_local_name(call_function(obj));
1840 
1841  pc = gen_nconc(pc, words_subexpression(e, prec, false, ppdl));
1842 
1843  if (strcmp(fun,POST_INCREMENT_OPERATOR_NAME) == 0)
1844  fun = "++";
1845  else if (strcmp(fun,POST_DECREMENT_OPERATOR_NAME) == 0)
1846  fun = "--";
1847 
1848  pc = CHAIN_SWORD(pc,fun);
1849 
1850  if(prec < precedence || (!precedence_p && precedence>0)) {
1851  pc = CONS(STRING, MAKE_SWORD("("), pc);
1852  pc = CHAIN_SWORD(pc, ")");
1853  }
1854 
1855  return(pc);
1856 }
1857 
1858 
1859 static list
1860 words_unary_minus(call obj, int precedence, bool leftmost, list * ppdl)
1861 {
1862  list pc = NIL;
1864  int prec = words_intrinsic_precedence(obj);
1865 
1866  if ( prec < precedence || !leftmost || (!precedence_p && precedence>0))
1867  pc = CHAIN_SWORD(pc, "(");
1868  /* make sure the minus can not be split apart from its argument */
1869  list sub = words_subexpression(e, prec, false, ppdl);
1870  string fst = STRING(CAR(sub));
1871  POP(sub);
1872  string nfst ;
1873  asprintf(&nfst,"-%s",fst);
1874  free(fst);
1875  sub=CONS(STRING,nfst,sub);
1876  pc = gen_nconc(pc, sub);
1877 
1878  if ( prec < precedence || !leftmost || (!precedence_p && precedence>0))
1879  pc = CHAIN_SWORD(pc, ")");
1880 
1881  return(pc);
1882 }
1883 
1884 /*
1885  The precedence of (1/x) is the same as the multiply operator
1886  (e.g. a*1/b without parentheses). Moreover, the MAXIMAL precedence is
1887  used for the (x) subterm (e.g. 1/(a*b) 1/(-2) ...). However, 1/x**2 may
1888  be a correct prettyprint in Fortran (?) */
1889 /* WARNING : the floating point division is used wether b is an int or not
1890  ! (1.0/b) -- in fact b should not be an int ! */
1891 static list /* of string */
1893  int precedence,
1894  bool __attribute__ ((unused)) leftmost,
1895  list * ppdl)
1896 {
1897  list /* of string */ pc = NIL;
1898 
1900  int prec = words_intrinsic_precedence(obj);
1901 
1902  if ( prec < precedence)
1903  pc = CHAIN_SWORD(pc, "(");
1904  pc = CHAIN_SWORD(pc, "1./");
1906  false, ppdl));
1907 
1908  if ( prec < precedence)
1909  pc = CHAIN_SWORD(pc, ")");
1910 
1911  return(pc);
1912 }
1913 
1914 /* This function is useful only for parsed codes since gotos are
1915  removed by the controlizer */
1916 list /* of string */
1917 words_goto_label(const char* tlabel)
1918 {
1919  list pc = NIL;
1920  if (strcmp(tlabel, RETURN_LABEL_NAME) == 0) {
1921  /*<<<<<<< .working
1922  switch (get_prettyprint_language_tag()) {
1923  case is_language_fortran:
1924  case is_language_fortran95:
1925  pc = CHAIN_SWORD(pc, RETURN_FUNCTION_NAME);
1926  break;
1927  case is_language_c:
1928  pc = CHAIN_SWORD(pc, C_RETURN_FUNCTION_NAME);
1929  pc = CHAIN_SWORD(pc, ";");
1930  break;
1931  default:
1932  pips_internal_error("Language unknown !");
1933  break;
1934  }
1935  =======*/
1936  switch (get_prettyprint_language_tag()) {
1937  case is_language_fortran:
1938  case is_language_fortran95:
1940  break;
1941  case is_language_c: {
1943 
1944  if(void_function_p(f)) {
1945  // FI: this hides the parsed code structure and is wrong
1946  // in C because a value may have to be returned;
1948  pc = CHAIN_SWORD(pc, ";");
1949  }
1950  else {
1952  pc = CHAIN_SWORD(pc, C_RETURN_FUNCTION_NAME" ");
1953  pc = CHAIN_SWORD(pc, entity_user_name(rv));
1954  pc = CHAIN_SWORD(pc, ";");
1955  }
1956  if(false) {
1957  // the gotos are maintained, but the final return must be printed out
1958  // FI: this would only work if the final return were printed
1959  // out for sure and with its label
1960  /* In C, a label cannot begin with a number so "l" is added
1961  for this case*/
1962  pc = CHAIN_SWORD(pc, strdup((isdigit(tlabel[0])?"goto l":"goto ")));
1963  pc = CHAIN_SWORD(pc, tlabel);
1965  }
1966  break;
1967  }
1968  default:
1969  pips_internal_error("Language unknown !");
1970  break;
1971  }
1972  //>>>>>>> .merge-right.r18859
1973  } else {
1974  switch (get_prettyprint_language_tag()) {
1975  case is_language_fortran:
1976  case is_language_fortran95:
1977  pc = CHAIN_SWORD(pc, strdup("GOTO "));
1978  pc = CHAIN_SWORD(pc, tlabel);
1979  break;
1980  case is_language_c:
1981  /* In C, a label cannot begin with a number so "l" is added
1982  for this case*/
1983  pc = CHAIN_SWORD(pc, strdup((isdigit(tlabel[0])?"goto l":"goto ")));
1984  pc = CHAIN_SWORD(pc, tlabel);
1986  break;
1987  default:
1988  pips_internal_error("Language unknown !");
1989  break;
1990  }
1991  }
1992  return pc;
1993 }
1994 
1995 static list
1997  int __attribute__ ((unused)) precedence,
1998  bool __attribute__ ((unused)) leftmost,
1999  bool isadd,
2000  list * ppdl)
2001 {
2002  list /* of strings */ pc = NIL;
2003  list /* of expressions */ args = call_arguments(obj);
2004 
2005  int prec ;
2006 
2007  /* open parenthese one */
2008  pc = CHAIN_SWORD(pc, "(");
2009 
2010  /* open parenthese two */
2011  pc = CHAIN_SWORD(pc, "(");
2012 
2013  /* get precedence for mult operator */
2014  prec = intrinsic_precedence("*");
2015 
2016  /* first argument */
2017  pc = gen_nconc(pc,words_subexpression(EXPRESSION(CAR(args)), prec, true, ppdl));
2018 
2019  /* mult operator */
2020  pc = CHAIN_SWORD(pc,"*");
2021 
2022  /* second argument */
2023  args = CDR(args);
2024  pc = gen_nconc(pc,words_subexpression(EXPRESSION(CAR(args)),prec,true, ppdl));
2025 
2026  /* close parenthese two */
2027  pc = CHAIN_SWORD(pc, ")");
2028 
2029  /* get precedence for add operator */
2030  prec = intrinsic_precedence("+");
2031 
2032  /* add/sub operator */
2033  pc = CHAIN_SWORD(pc, isadd? "+": "-");
2034 
2035  /* third argument */
2036  args = CDR(args);
2037  pc = gen_nconc(pc,words_subexpression(EXPRESSION(CAR(args)),prec,false, ppdl));
2038 
2039  /* close parenthese one */
2040  pc = CHAIN_SWORD(pc,")");
2041 
2042  return pc;
2043 }
2044 
2045 /* EOLE : The multiply-add operator is used within the optimize
2046  transformation ( JZ - sept 98) - fma(a,b,c) -> ((a*b)+c)
2047  */
2048 list /* of string */
2049 eole_fma_specific_op(call obj, int precedence, bool leftmost, list * ppdl)
2050 {
2051  return eole_fmx_specific_op(obj, precedence, leftmost, true, ppdl);
2052 }
2053 
2054 /* MULTIPLY-SUB operator */
2055 list /* of string */
2056 eole_fms_specific_op(call obj, int precedence, bool leftmost, list * ppdl)
2057 {
2058  return eole_fmx_specific_op(obj, precedence, leftmost, false, ppdl);
2059 }
2060 
2061 /* Check if the given operator is associated with a special
2062  prettyprint. For instance, n-ary add and multiply operators which are
2063  used in the EOLE project use "+" and "*" prettyprints instead of the
2064  entity_local_name (JZ - sept 98) */
2065 static const char*
2067 
2068  static struct special_operator_prettyprint {
2069  const char * name;
2070  const char * op_prettyprint;
2071  } tab_operator_prettyprint[] = {
2072  {EOLE_SUM_OPERATOR_NAME,"+"},
2074  {NULL,NULL}
2075  };
2076  int i = 0;
2077  const char* op_name;
2078 
2079  /* get the entity name */
2080  op_name = entity_local_name(call_function(obj));
2081 
2082  while (tab_operator_prettyprint[i].name) {
2083  if (!strcmp(tab_operator_prettyprint[i].name,op_name))
2084  return tab_operator_prettyprint[i].op_prettyprint;
2085  else i++;
2086  }
2087 
2088  return op_name;
2089 }
2090 
2092  int precedence __attribute__ ((unused)),
2093  bool leftmost __attribute__ ((unused)),
2094  list * ppdl)
2095 {
2097  list l = words_brace_expression(fake, ppdl);
2098  free_expression(fake);
2099  return l;
2100 }
2101 
2102 /* Extension of "words_infix_binary_op" function for nary operators used
2103  in the EOLE project - (since "nary" assumes operators with at least 2
2104  op) - JZ (Oct. 98)*/
2105 
2106 static list /* of string */
2107 words_infix_nary_op(call obj, int precedence, bool leftmost, list * ppdl)
2108 {
2109  list /*of string*/ pc = NIL;
2110  list /* of expressions */ args = call_arguments(obj);
2111 
2112  /* get current operator precedence */
2113  int prec = words_intrinsic_precedence(obj);
2114 
2115  expression exp1 = EXPRESSION(CAR(args));
2116  expression exp2;
2117 
2118  list we1 = words_subexpression(exp1, prec,
2119  prec>=MINIMAL_ARITHMETIC_PRECEDENCE? leftmost: true, ppdl);
2120  list we2;
2121 
2122  /* open parenthese if necessary */
2123  if ( prec < precedence )
2124  pc = CHAIN_SWORD(pc, "(");
2125  pc = gen_nconc(pc, we1);
2126 
2127  /* reach the second arg */
2128  args = CDR(args);
2129 
2130  for(; args; args=CDR(args)) { /* for all args */
2131  exp2 = EXPRESSION(CAR(args));
2132 
2133  /*
2134  * If the infix operator is either "-" or "/", I prefer not to delete
2135  * the parentheses of the second expression.
2136  * Ex: T = X - ( Y - Z ) and T = X / (Y*Z)
2137  *
2138  * Lei ZHOU Nov. 4 , 1991
2139  */
2140  if ( strcmp(entity_local_name(call_function(obj)), "/") == 0 ) /* divide operator */
2141  we2 = words_subexpression(exp2, MAXIMAL_PRECEDENCE, false, ppdl);
2142  else if ( strcmp(entity_local_name(call_function(obj)), "-") == 0 ) { /* minus operator */
2143  if ( expression_call_p(exp2) &&
2145  intrinsic_precedence("*") )
2146  /* precedence is greater than * or / */
2147  we2 = words_subexpression(exp2, prec, false, ppdl);
2148  else
2149  we2 = words_subexpression(exp2, MAXIMAL_PRECEDENCE, false, ppdl);
2150  }
2151  else {
2152  we2 = words_subexpression(exp2, prec,
2153  prec<MINIMAL_ARITHMETIC_PRECEDENCE, ppdl);
2154  }
2155 
2156  /* operator prettyprint */
2158 
2159  pc = gen_nconc(pc, we2);
2160  }
2161  /* close parenthese if necessary */
2162  if ( prec < precedence )
2163  pc = CHAIN_SWORD(pc, ")");
2164 
2165  return(pc);
2166 }
2167 
2168 /*
2169  * If the infix operator is either "-" or "/", I prefer not to delete
2170  * the parentheses of the second expression.
2171  * Ex: T = X - ( Y - Z ) and T = X / (Y*Z)
2172  *
2173  * Lei ZHOU Nov. 4 , 1991
2174  */
2175 static list
2176 words_infix_binary_op(call obj, int precedence, bool leftmost, list * ppdl)
2177 {
2178  list pc = NIL;
2179  list args = call_arguments(obj);
2180  int prec = words_intrinsic_precedence(obj);
2181  list we1 = words_subexpression(EXPRESSION(CAR(args)), prec,
2182  prec>=MINIMAL_ARITHMETIC_PRECEDENCE? leftmost: true, ppdl);
2183  list we2;
2184  const char* fun = entity_local_name(call_function(obj));
2185 
2186  /* handling of internally renamed operators */
2187  fun = renamed_op_handling (fun);
2188 
2189  if(strcmp(fun, DIVIDE_OPERATOR_NAME) == 0) {
2190  /* Do we want to add a space in case we2 starts with a dereferencing operator "*"?
2191  Nga suggests to look at the quake benchmark of SPEC2000. */
2192  we2 = words_subexpression(EXPRESSION(CAR(CDR(args))), MAXIMAL_PRECEDENCE, false, ppdl);
2193  }
2194  else if (strcmp(fun, MINUS_OPERATOR_NAME) == 0 ) {
2195  expression exp = EXPRESSION(CAR(CDR(args)));
2196  if(expression_call_p(exp) &&
2199  /* precedence is greater than * or / */
2200  we2 = words_subexpression(exp, prec, false, ppdl);
2201  else
2202  we2 = words_subexpression(exp, MAXIMAL_PRECEDENCE, false, ppdl);
2203  }
2204  else if(strcmp(fun, MULTIPLY_OPERATOR_NAME) == 0) {
2205  expression exp = EXPRESSION(CAR(CDR(args)));
2206  if(expression_call_p(exp) &&
2208  basic bexp = basic_of_expression(exp);
2209 
2210  if(basic_int_p(bexp)) {
2211  we2 = words_subexpression(exp, MAXIMAL_PRECEDENCE, false, ppdl);
2212  }
2213  else
2214  we2 = words_subexpression(exp, prec, false, ppdl);
2215  free_basic(bexp);
2216  }
2217  else
2218  we2 = words_subexpression(exp, prec, false, ppdl);
2219  }
2220  else {
2221  /* If the operator in the second subexpression has the same
2222  priority as the current operator, it has to be parenthesized
2223  to respect the structure imposed by the programmer. For
2224  instance, a+(b+c) does require parentheses whereas (a+b)+c is
2225  the same as a+b+c. So we1 and we2 cannot be processed exactly
2226  in the same way. */
2227  we2 = words_subexpression(EXPRESSION(CAR(CDR(args))), prec+1,
2228  prec<MINIMAL_ARITHMETIC_PRECEDENCE, ppdl);
2229  }
2230 
2231  /* Use precedence to generate or not parentheses,
2232  * unless parentheses are always required */
2233  if(prec < precedence || (!precedence_p && precedence>0)) {
2234  pc = CHAIN_SWORD(pc, "(");
2235  }
2236 
2238  && strcmp(fun, FIELD_OPERATOR_NAME) == 0) {
2239  pc = gen_nconc(pc, we1);
2240  }
2241  else if(prettyprint_language_is_c_p()) {
2242  /* Check that C ambiguities such as "a+++b" for "a++ + b" or "a +
2243  ++b" are not generated */
2244  if(strcmp(fun,"+")==0 || strcmp(fun, "-")==0) {
2245  pips_assert("left and right subexpressions are defined",
2246  !ENDP(we1) && !ENDP(we2));
2247  string l = STRING(CAR(gen_last(we1)));
2248  string f = STRING(CAR(we2));
2249  char lc = *(l+strlen(l)-1);
2250  char fc = *f;
2251  string pre = "";
2252  string post = "";
2253  if(*fun==lc)
2254  pre = " ";
2255  if(*fun==fc)
2256  post = " ";
2257  pc = gen_nconc(pc, we1);
2258  pc = CHAIN_SWORD(pc, pre);
2259  pc = CHAIN_SWORD(pc, fun);
2260  pc = CHAIN_SWORD(pc, post);
2261  pc = gen_nconc(pc, we2);
2262  }
2263  else {
2264  pc = gen_nconc(pc, we1);
2265  pc = CHAIN_SWORD(pc, fun);
2266  pc = gen_nconc(pc, we2);
2267  }
2268  }
2269  else {
2270  pc = gen_nconc(pc, we1);
2271  pc = CHAIN_SWORD(pc, fun);
2272  pc = gen_nconc(pc, we2);
2273  }
2274 
2275  if(prec < precedence || (!precedence_p && precedence>0)) {
2276  pc = CHAIN_SWORD(pc, ")");
2277  }
2278 
2279  return(pc);
2280 }
2281 
2282 /* Nga Nguyen : this case is added for comma expression in C, but I am
2283  not sure about its precedence => to be looked at more carefully */
2284 
2286  int precedence,
2287  bool __attribute__ ((unused)) leftmost,
2288  list * ppdl)
2289 {
2290  list pc = NIL, args = call_arguments(obj);
2291  int prec = words_intrinsic_precedence(obj);
2292  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
2293 
2294  if(prec < precedence || !precedence_p)
2295  pc = CHAIN_SWORD(pc,"(");
2296  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(args)), prec, true, ppdl));
2297  while (!ENDP(CDR(args)))
2298  {
2299  pc = CHAIN_SWORD(pc,space_p?", " : ",");
2300  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(CDR(args))), prec, true, ppdl));
2301  args = CDR(args);
2302  }
2303  if(prec < precedence || !precedence_p)
2304  pc = CHAIN_SWORD(pc,")");
2305  return(pc);
2306 }
2307 
2309  int precedence,
2310  bool __attribute__ ((unused)) leftmost,
2311  list * ppdl)
2312 {
2313  list pc = NIL, args = call_arguments(obj);
2314  int prec = words_intrinsic_precedence(obj);
2315 
2316  if(prec < precedence || !precedence_p)
2317  pc = CHAIN_SWORD(pc,"(");
2318  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(args)), prec, true, ppdl));
2319  pc = CHAIN_SWORD(pc,"?");
2320  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(CDR(args))), prec, true, ppdl));
2321  pc = CHAIN_SWORD(pc,":");
2322  pc = gen_nconc(pc, words_subexpression(EXPRESSION(CAR(CDR(CDR(args)))), prec, true, ppdl));
2323  if(prec < precedence || !precedence_p)
2324  pc = CHAIN_SWORD(pc,")");
2325  return(pc);
2326 }
2327 
2328 
2329 /* precedence needed here
2330  * According to the Precedence of Operators
2331  * Arithmetic > Character > Relational > Logical
2332  * Added by Lei ZHOU Nov. 4,91
2333  *
2334  * A precedence is a integer in [0..MAXIMAL_PRECEDENCE]
2335  */
2336 
2337 static struct intrinsic_handler {
2338  const char * name;
2340 } tab_intrinsic_handler[] = {
2341  {BRACE_INTRINSIC, { words_brace_op, 31 } },
2342 
2344 
2346 
2347  /* The Fortran 77 standard does not allow x*-3 or x+-3, but this is dealt
2348  * with by argument leftmost, not by prorities.
2349  */
2351  /* {"--", words_unary_minus, 19}, */
2352 
2353 
2355 
2358 
2359  /* Non-arithemtic operators have priorities lesser than
2360  * MINIMAL_ARITHMETIC_PRECEDENCE leftmost is restaured to true for
2361  * unary minus.
2362  */
2363 
2370 
2372 
2374 
2376 
2379 
2381 
2382 
2395 
2402 
2403 
2407 
2410 
2411  /* These operators are used within the optimize transformation in
2412 order to manipulate operators such as n-ary add and multiply or
2413 multiply-add operators ( JZ - sept 98) */
2420 
2421  /* show IMA/IMS */
2426 
2427  /* 05/08/2003 - Nga Nguyen - Here are C intrinsics.
2428  The precedence is computed by using Table xx, page 49, book
2429  "The C programming language" of Kernighan and Ritchie, and by
2430  taking into account the precedence value of Fortran intrinsics. */
2431 
2436 
2442  /*{"-unary", words_prefix_unary_op, 25},*/
2445 
2446  /* What is the priority for CAST? 23? */
2447 
2448 #define CAST_OPERATOR_PRECEDENCE (23)
2449 
2453 
2456 
2459 
2464 
2467 
2471 
2474 
2485 
2486  /* which precedence ? You are safe within an assignment. */
2488 
2489  /* which precedence ? You need parentheses within an assignment. */
2491 
2492  /* OMP pragma function part */
2497 
2498 
2499  {NULL, { null, 0} }
2500 };
2501 
2503 
2507  for(struct intrinsic_handler *p = &tab_intrinsic_handler[0];p->name;p++) {
2508  // no copy because the memory is static
2509  hash_put(intrinsic_handlers,p->name,&p->desc);
2510  }
2511  }
2512 }
2513 
2514 /* after this call, name and desc are owned by intrinsic_handlers, but will never be deallocated
2515  * they must point to permanent storage
2516  */
2517 void register_intrinsic_handler(const char* name,intrinsic_desc_t *desc) {
2520  }
2521  hash_put(intrinsic_handlers,name,desc);
2522 }
2523 
2524 static list
2525 words_intrinsic_call(call obj, int precedence, bool leftmost, list * ppdl)
2526 {
2529  }
2530  const char *n = entity_local_name(call_function(obj));
2532  if(d!= HASH_UNDEFINED_VALUE)
2533  return d->f(obj, precedence, leftmost, ppdl);
2534  else
2535  return words_regular_call(obj, false, ppdl);
2536 }
2537 
2538 static int
2539 intrinsic_precedence(const char* n)
2540 {
2543  }
2545  if(d!= HASH_UNDEFINED_VALUE)
2546  return d->prec;
2547  else
2548  return 0;
2549 }
2550 
2551 static int
2553 {
2554  const char *n = entity_local_name(call_function(obj));
2555  return intrinsic_precedence(n);
2556 }
2557 
2558 static list words_va_arg(list obj, list * ppdl)
2559 {
2560  list pc = NIL;
2563  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
2564 
2565  pc = CHAIN_SWORD(pc,"va_arg(");
2566  pc = gen_nconc(pc, words_expression(e1, ppdl));
2567  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
2568  pc = gen_nconc(pc, words_type(t2, ppdl, false));
2569  pc = CHAIN_SWORD(pc,")");
2570  return pc;
2571 }
2572 
2573 /* exported for cmfortran.c
2574  */
2576  call obj,
2577  int precedence,
2578  bool leftmost,
2579  bool is_a_subroutine,
2580  list * ppdl)
2581 {
2582  list pc;
2583  entity f = call_function(obj);
2584  value i = entity_initial(f);
2585 
2586  if(value_intrinsic_p(i)) {
2587  int effective_precedence = (precedence_p||precedence<=1)?
2588  precedence : MAXIMAL_PRECEDENCE;
2589 
2590  pc = words_intrinsic_call(obj, effective_precedence, leftmost, ppdl);
2591  }
2592  else
2593  pc = words_genuine_regular_call(obj, is_a_subroutine, ppdl);
2594  return pc;
2595 }
2596 
2598  call obj,
2599  int precedence,
2600  bool leftmost,
2601  bool is_a_subroutine)
2602 {
2603  list npdl = NIL;
2604  list pc = words_call(obj, precedence, leftmost, is_a_subroutine, &npdl);
2605  gen_free_list(npdl);
2606  return pc;
2607 }
2608 
2609 /* This one is exported. Outer parentheses are never useful. ppdl can
2610  point to an empty list, but it must be free on return*/
2611 list /* of string */ words_expression(expression obj, list * ppdl)
2612 {
2613  return words_syntax(expression_syntax(obj), ppdl);
2614 }
2615 
2616 list /* of string */ Words_Expression(expression obj)
2617 {
2618  return Words_Syntax(expression_syntax(obj));
2619 }
2620 
2621 /* exported for expression.c
2622  */
2624 {
2625  list pc = NIL;
2626 
2627  switch (syntax_tag(obj)) {
2628  case is_syntax_reference :
2629  pc = words_reference(syntax_reference(obj), ppdl);
2630  break;
2631  case is_syntax_range:
2632  pc = words_range(syntax_range(obj), ppdl);
2633  break;
2634  case is_syntax_call:
2635  pc = words_call(syntax_call(obj), 0, true, false, ppdl);
2636  break;
2637  case is_syntax_cast:
2638  pc = words_cast(syntax_cast(obj), 0, ppdl);
2639  break;
2641  /* FI->SG: I do not know if in_type_declaration is true, false
2642  or a formal parameter */
2643  bool in_type_declaration = true;
2645  in_type_declaration, ppdl);
2646  break;
2647  }
2648  case is_syntax_subscript:
2649  pc = words_subscript(syntax_subscript(obj), ppdl);
2650  break;
2651  case is_syntax_application:
2652  pc = words_application(syntax_application(obj), ppdl);
2653  break;
2654  case is_syntax_va_arg:
2655  pc = words_va_arg(syntax_va_arg(obj), ppdl);
2656  break;
2657  default:
2658  pips_internal_error("unexpected tag");
2659  }
2660 
2661  return(pc);
2662 }
2663 
2665 {
2666  list npdl = NIL;
2667  list pc = words_syntax(obj, &npdl);
2668  gen_free_list(npdl);
2669  return pc;
2670 }
2671 
2672 /* exported for cmfortran.c
2673  */
2675  expression obj,
2676  int precedence,
2677  bool leftmost,
2678  list * ppdl)
2679 {
2680  list pc;
2681 
2682  if ( expression_call_p(obj) )
2684  precedence, leftmost, false, ppdl);
2685  else if(expression_cast_p(obj)) {
2686  cast c = expression_cast(obj);
2687  pc = words_cast(c, precedence, ppdl);
2688  }
2689  else
2690  pc = words_syntax(expression_syntax(obj), ppdl);
2691 
2692  return pc;
2693 }
2694 
2696  expression obj,
2697  int precedence,
2698  bool leftmost)
2699 {
2700  list pdl = NIL;
2701  list pc = words_subexpression(obj, precedence, leftmost, &pdl);
2702  gen_free_list(pdl);
2703  return pc;
2704 }
2705 
2706 
2707 /**************************************************************** SENTENCE */
2708 
2709 static sentence
2711 {
2712  sentence result = sentence_undefined;
2713  switch(get_prettyprint_language_tag()) {
2714  case is_language_fortran:
2715  result = MAKE_ONE_WORD_SENTENCE(0, "END");
2716  break;
2717  case is_language_c:
2718  result = MAKE_ONE_WORD_SENTENCE(0, "}");
2719  break;
2720  case is_language_fortran95: {
2721  /* In fortran 95, we want the end to be followed by the type of construct
2722  * and its name.
2723  */
2724  list pc = NIL;
2725  type te = entity_type(e);
2726  functional fe;
2727  type tr;
2728 
2729  pc = CHAIN_SWORD(pc,"END ");
2730 
2731  pips_assert("is functionnal", type_functional_p(te));
2732 
2733  if (static_module_p(e))
2734  pc = CHAIN_SWORD(pc,"static ");
2735 
2736  fe = type_functional(te);
2737  tr = functional_result(fe);
2738 
2739  switch(type_tag(tr)) {
2740  case is_type_void:
2741  if (entity_main_module_p(e))
2742  pc = CHAIN_SWORD(pc,"PROGRAM ");
2743  else {
2744  if (entity_blockdata_p(e))
2745  pc = CHAIN_SWORD(pc, "BLOCKDATA ");
2746  else if (entity_f95module_p(e))
2747  pc = CHAIN_SWORD(pc, "MODULE ");
2748  else
2749  pc = CHAIN_SWORD(pc,"SUBROUTINE ");
2750  }
2751  break;
2752  case is_type_variable: {
2753  pc = CHAIN_SWORD(pc,"FUNCTION ");
2754  break;
2755  }
2756  case is_type_unknown:
2757  /*
2758  * For C functions with no return type.
2759  * It can be treated as of type int, but we keep it unknown
2760  * for the moment, to make the differences and to regenerate initial code
2761  */
2762  break;
2763  default:
2764  pips_internal_error("unexpected type for result");
2765  }
2766 
2767  pc = CHAIN_SWORD(pc, entity_user_name(e));
2769  0,
2770  0,
2771  pc));
2772  break;
2773  }
2774  default:
2775  pips_internal_error("Language unknown !");
2776  break;
2777  }
2778 
2779  return result;
2780 }
2781 
2782 /* exported for unstructured.c */
2783 sentence
2785  entity __attribute__ ((unused)) module,
2786  const char* label,
2787  int margin,
2788  const char* tlabel,
2789  int n)
2790 {
2791  list pc = words_goto_label(tlabel);
2792 
2794  make_unformatted(label?strdup(label):NULL, n, margin, pc)));
2795 }
2796 
2798  const char* label,
2799  int margin,
2800  statement obj,
2801  int n) {
2802  const char* tlabel = entity_local_name(statement_label(obj)) +
2803  sizeof(LABEL_PREFIX) -1;
2804  pips_assert("Legal label required", strlen(tlabel)!=0);
2805  return sentence_goto_label(module, label, margin, tlabel, n);
2806 }
2807 
2808 /* Build the text of a code block (a list of statements)
2809 
2810  @module is the module entity the code to display belong to
2811 
2812  @label is the label associated to the block
2813 
2814  @param margin is the indentation level
2815 
2816  @param objs is the list of statements in the sequence to display
2817 
2818  @param n is the statement number of the sequence
2819 
2820  @pdl is the parser declaration list to track type declaration display
2821  in C
2822 
2823  @return the text of the block
2824 */
2825 static text
2827  const char* label,
2828  int margin,
2829  list objs,
2830  int n,
2831  list * ppdl)
2832 {
2833  text r = make_text(NIL);
2834 
2835  if (ENDP(objs)
2836  && ! (get_bool_property("PRETTYPRINT_EMPTY_BLOCKS")
2837  || get_bool_property("PRETTYPRINT_ALL_C_BLOCKS")))
2838  return(r);
2839 
2840  if(!empty_string_p(label)) {
2841  pips_user_warning("Illegal label \"%s\". "
2842  "Blocks cannot carry a label\n",
2843  label);
2844  }
2845 
2846  /* "Unformatted" to be added at the beginning and at the end of a block: */
2847  unformatted bm_beg = NULL;
2848  unformatted bm_end = NULL;
2849  // Test if block markers are required and set them:
2850  bool flg_marker = mark_block(&bm_beg, &bm_end, n, margin);
2851 
2852  // Print the begin block marker(s) if needed:
2853  if (flg_marker == true)
2855  else if ((get_bool_property("PRETTYPRINT_ALL_EFFECTS")
2856  || get_bool_property("PRETTYPRINT_BLOCKS"))
2857  && get_bool_property("PRETTYPRINT_FOR_FORESYS"))
2859  strdup("C$BB\n")));
2860 
2861  if (get_bool_property("PRETTYPRINT_ALL_C_BLOCKS")) {
2862  /* Since we generate new { }, we increment the margin for the nested
2863  statements: */
2864  margin -= INDENTATION;
2865  if (margin < 0)
2866  margin = 0;
2867  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin, "{{"));
2868  margin += INDENTATION;
2869  }
2870 
2871  // Append local variables if any:
2872  r = insert_locals (r);
2873 
2874  /* Now begin block markers and declarations have been printed, so print
2875  the block instructions: */
2876  for (; objs != NIL; objs = CDR(objs)) {
2877  statement s = STATEMENT(CAR(objs));
2878 
2879  text t = text_statement_enclosed(module, margin, s, false, true, ppdl);
2881  text_sentences(t) = NIL;
2882  free_text(t);
2883  }
2884 
2885  if (get_bool_property("PRETTYPRINT_ALL_C_BLOCKS")) {
2886  /* Get back to previous indentation: */
2887  margin -= INDENTATION;
2888  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin, "}}"));
2889  margin += INDENTATION;
2890  }
2891 
2892  // Print the end block marker(s) if needed:
2893  if (flg_marker == true)
2895 
2896  return r;
2897 }
2898 
2899 /* @return a list of string with the variable that need to be private in the
2900  * current context. The context takes care of the kind of output. For example
2901  * in the case of open mp the variables would be encapsulated into
2902  * the private() clause like this: private (a,b).
2903  * @param obj the loop to look at.
2904  */
2905 static list /* of string */
2907 {
2908  bool all_private = get_bool_property("PRETTYPRINT_ALL_PRIVATE_VARIABLES"),
2909  hpf_private = pp_hpf_style_p(), omp_private = pp_omp_style_p(),
2910  some_before = false;
2911  list l = NIL;
2912 
2913  // list of local entities
2914  // In case of openmp the variable declared in the loop body should
2915  // not be made private, so ask for removing them from the list of locals.
2916  // If all_private is false -> remove loop indice from the list of locals.
2918  omp_private,
2919  !all_private);
2920 
2921  pips_debug(5, "#printed %zd/%zd\n", gen_length(l),
2922  gen_length(loop_locals(obj)));
2923 
2924  /* stuff around if not empty
2925  */
2926  if (locals) {
2927  string private = string_undefined;
2928  if (hpf_private) {
2929  private = "NEW(";
2930  } else if (omp_private) {
2931  switch (get_prettyprint_language_tag()) {
2932  case is_language_fortran:
2933  private = "PRIVATE(";
2934  break;
2935  case is_language_c:
2936  private = "private(";
2937  break;
2938  case is_language_fortran95:
2939  pips_internal_error("Need to update F95 case");
2940  break;
2941  default:
2942  pips_internal_error("Language unknown !");
2943  break;
2944  }
2946  /* This is debugging way to print out code. I do not know which
2947  Fortran parser takes this language extension. */
2948  private = "PRIVATE ";
2949  }
2950  else {
2951  /* In C case, it might be a good idea to re-declare the private
2952  variables in the loop body, exceot for outer loop indices,
2953  but this is not easy here. PIPS data structures should be
2954  updated because loop_private is somehow redundant with
2955  statement declarations. */
2956  pips_user_warning("Privatized variables are ignored with the "
2957  "current prettyprinter options.\n");
2958  }
2959 
2960  if(!string_undefined_p(private)) {
2961  /* comma-separated list of private variables.
2962  * built in reverse order to avoid adding at the end...
2963  */
2964  FOREACH (ENTITY, p, locals) {
2965  if (some_before)
2966  l = CHAIN_SWORD(l, ",");
2967  else
2968  some_before = true; /* from now on commas, triggered... */
2969  l = gen_nconc(l, words_declaration(p, true, ppdl));
2970  }
2971 
2972  gen_free_list(locals);
2973 
2974  l = CONS(STRING, MAKE_SWORD(private), l);
2975  if (hpf_private || omp_private)
2976  CHAIN_SWORD(l, ")");
2977  }
2978  }
2979 
2980  return l;
2981 }
2982 
2983 /* returns a formatted text for the HPF independent and new directive
2984  * well, no continuations and so, but the directives do not fit the
2985  * unformatted domain, because the directive prolog would not be well
2986  * managed there.
2987  */
2988 static string
2990  string prefix,
2991  int margin)
2992 {
2993  int len = strlen(prefix), i;
2994  string result = (string) malloc(strlen(prefix)+margin+1);
2995  strcpy(result, prefix);
2997  for (i=len; margin-->0;) {
2998  result[i++] = ' '; result[i]='\0';
2999  }
3000  }
3001  return result;
3002 }
3003 
3004 
3005 static text text_directive(loop obj, /* the loop we're interested in */
3006  int margin,
3007  string basic_directive,
3008  string basic_continuation,
3009  string parallel,
3010  list * ppdl) {
3011  string dir = marged(basic_directive, margin), cont =
3012  marged(basic_continuation, margin);
3013  text t = make_text(NIL);
3014  char buffer[100]; /* ??? */
3015  list /* of string */l = NIL;
3016  bool is_hpf = pp_hpf_style_p(), is_omp = pp_omp_style_p();
3017  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
3018 
3019  /* start buffer */
3020  buffer[0] = '\0';
3021 
3023  add_to_current_line(buffer, dir, cont, t);
3024  add_to_current_line(buffer, parallel, cont, t);
3025  l = loop_private_variables(obj, ppdl);
3026  if (l && is_hpf)
3027  add_to_current_line(buffer, space_p ? ", " : ",", cont, t);
3028  } else if (get_bool_property("PRETTYPRINT_ALL_PRIVATE_VARIABLES")) {
3029  l = loop_private_variables(obj, ppdl);
3030  if (l) {
3031  add_to_current_line(buffer, dir, cont, t);
3032  if (is_omp) {
3033  switch (get_prettyprint_language_tag()) {
3034  case is_language_fortran:
3035  case is_language_fortran95:
3036  add_to_current_line(buffer, "DO ", cont, t);
3037  break;
3038  case is_language_c:
3039  add_to_current_line(buffer, "for ", cont, t);
3040  break;
3041  default:
3042  pips_internal_error("Language unknown !");
3043  break;
3044  }
3045  }
3046  }
3047  }
3048 
3049  if (strlen(buffer) > 0)
3050  MAP(STRING, s, add_to_current_line(buffer, s, cont, t), l);
3051 
3052  /* what about reductions? should be associated to the ri somewhere.
3053  */
3054 
3055  close_current_line(buffer, t, cont);
3056  free(dir);
3057  free(cont);
3058  return t;
3059 }
3060 
3061 #define HPF_SENTINEL "!HPF$"
3062 #define HPF_DIRECTIVE HPF_SENTINEL " "
3063 #define HPF_CONTINUATION HPF_SENTINEL "x"
3064 #define HPF_INDEPENDENT "INDEPENDENT"
3065 
3066 static text text_hpf_directive(loop l, int m)
3067 {
3068  list pdl = NIL; // pdl is useless in Fortran
3070  HPF_INDEPENDENT, &pdl);
3071  return t;
3072 }
3073 
3074 #define OMP_SENTINEL "!$OMP"
3075 #define OMP_DIRECTIVE OMP_SENTINEL " "
3076 #define OMP_CONTINUATION OMP_SENTINEL "x"
3077 #define OMP_PARALLELDO "PARALLEL DO "
3078 #define OMP_C_SENTINEL "#pragma omp"
3079 #define OMP_C_DIRECTIVE OMP_C_SENTINEL " "
3080 #define OMP_C_CONTINUATION OMP_C_SENTINEL "x"
3081 #define OMP_C_PARALLELDO "parallel for "
3082 
3083 text
3085 {
3086  list pdl = NIL; // pdl is useless in Fortran
3087  text t = text_undefined;
3088 
3089  switch(get_prettyprint_language_tag()) {
3090  case is_language_fortran:
3091  case is_language_fortran95:
3092  t = text_directive(l,
3093  m,
3094  "\n" OMP_DIRECTIVE,
3097  &pdl);
3098  break;
3099  case is_language_c:
3100  // text_directive function takes care of private variables
3101  // More should be done to take care of shared variables, reductions
3102  // and other specific omp clause like lastprivate, copyin ...
3103  t = text_directive(l,
3104  m,
3108  &pdl);
3109  break;
3110  default:
3111  pips_internal_error("Language unknown !");
3112  break;
3113  }
3114  return t;
3115 }
3116 
3117 /* exported for fortran90.c */
3119  const char* label,
3120  int margin,
3121  loop obj,
3122  int n,
3123  list * ppdl,
3124  bool is_recursive_p) {
3125  list pc = NIL;
3126  sentence first_sentence = sentence_undefined;
3127  unformatted u;
3128  text r = make_text(NIL);
3129  statement body = loop_body( obj );
3130  entity the_label = loop_label(obj);
3131  const char* do_label = entity_local_name(the_label) + sizeof(LABEL_PREFIX) -1;
3132  bool structured_do = entity_empty_label_p(the_label);
3133  bool doall_loop_p = false;
3134  bool hpf_prettyprint = pp_hpf_style_p();
3135  bool do_enddo_p = get_bool_property("PRETTYPRINT_DO_LABEL_AS_COMMENT");
3136  bool all_private = get_bool_property("PRETTYPRINT_ALL_PRIVATE_VARIABLES");
3137  bool braces_p = !one_liner_p(body) || prettyprint_all_c_braces_p;
3138 
3140  doall_loop_p = false;
3141  } else {
3142  doall_loop_p = pp_doall_style_p();
3143  }
3144 
3145  /* HPF directives before the loop if required (INDEPENDENT and NEW) */
3146  if (hpf_prettyprint)
3147  MERGE_TEXTS(r, text_hpf_directive(obj, margin));
3148  /* idem if Open MP directives are required */
3149  if (pp_omp_style_p())
3150  MERGE_TEXTS(r, text_omp_directive(obj, margin));
3151 
3152  /* LOOP prologue.
3153  */
3154  switch (get_prettyprint_language_tag()) {
3155  case is_language_fortran:
3156  case is_language_fortran95:
3157  pc = CHAIN_SWORD(NIL, (doall_loop_p) ? "DOALL " : "DO " );
3158  if (!structured_do && !doall_loop_p && !do_enddo_p) {
3159  pc = CHAIN_SWORD(pc, concatenate(do_label, " ", NULL));
3160  }
3161  break;
3162  case is_language_c:
3163  pc = CHAIN_SWORD(NIL, (doall_loop_p) ? "forall(" : "for(" );
3164  break;
3165  default:
3166  pips_internal_error("Language unknown !");
3167  break;
3168  }
3169 
3170  //pc = CHAIN_SWORD(pc, entity_local_name(loop_index(obj)));
3171  pc = CHAIN_SWORD(pc, entity_user_name(loop_index(obj)));
3172  pc = CHAIN_SWORD(pc, " = ");
3173 
3174  switch (get_prettyprint_language_tag()) {
3175  case is_language_fortran:
3176  case is_language_fortran95:
3177  pc = gen_nconc(pc, words_loop_range(loop_range(obj), ppdl));
3178  u = make_unformatted(strdup(label), n, margin, pc);
3179  ADD_SENTENCE_TO_TEXT(r, first_sentence =
3181  break;
3182  case is_language_c:
3183  pc = gen_nconc(pc, C_loop_range(loop_range(obj), loop_index(obj), ppdl));
3184  if (braces_p)
3185  pc = CHAIN_SWORD(pc," {");
3186  if ((label != NULL) && (label[0] != '\0')) {
3187  pips_debug(9, "the label %s need to be print for a for C loop", label);
3188  u = make_unformatted(strdup(label), 0, 0, NULL);
3189  ADD_SENTENCE_TO_TEXT(r, first_sentence =
3191  }
3192  u = make_unformatted(NULL, n, margin, pc);
3194  break;
3195  default:
3196  pips_internal_error("Language tag unknown!");
3197  break;
3198  }
3199 
3200  if(is_recursive_p) {
3201  /* builds the PRIVATE scalar declaration if required
3202  */
3203  if (!ENDP(loop_locals(obj)) && (doall_loop_p || all_private)
3204  && !hpf_prettyprint) {
3205  list /* of string */lp = loop_private_variables(obj, ppdl);
3206 
3207  // initialize the local variable text if needed
3208  if ((local_flg == false) && (lp)) {
3209  local_flg = true;
3210  local_var = make_text(NIL);
3211  }
3212 
3213  if (lp)
3214  /* local_var is a global variable which is exploited
3215  later... */
3216  /* FI: I do not understand why the local declarations were
3217  not added right away. I hope my change (simplification)
3218  does not break something else that is not tested by our
3219  non-regression suite. */
3220  if (!pp_omp_style_p()) {
3222  // ( local_var,
3223  ( r,
3225  make_unformatted(NULL, 0, margin+INDENTATION, lp)));
3226  }
3227  }
3228 
3229  /* loop BODY
3230  */
3232  margin+INDENTATION,
3233  body,
3234  !one_liner_p(body),
3235  !one_liner_p(body),
3236  ppdl));
3237 
3238  /* LOOP postlogue
3239  */
3240  switch (get_prettyprint_language_tag()) {
3241  case is_language_fortran:
3242  case is_language_fortran95:
3243  if (structured_do || doall_loop_p || do_enddo_p || pp_cray_style_p()
3244  || pp_craft_style_p() || pp_cmf_style_p()) {
3245  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin,"ENDDO"));
3246  }
3247  break;
3248  case is_language_c:
3249  if (braces_p)
3251  break;
3252  default:
3253  pips_internal_error("Language unknown !");
3254  break;
3255  }
3256 
3257  attach_loop_to_sentence_up_to_end_of_text(first_sentence, r, obj);
3258  }
3259 
3260  return r;
3261 }
3262 
3263 /* exported for conversion/look_for_nested_loops.c */
3265  entity module,
3266  const char* label,
3267  int margin,
3268  loop obj,
3269  int n,
3270  list * ppdl,
3271  bool is_recursive_p)
3272 {
3273  text r = make_text(NIL);
3274  statement body = loop_body( obj ) ;
3275  entity the_label = loop_label(obj);
3276  const char* do_label = entity_local_name(the_label)+sizeof(LABEL_PREFIX) -1;
3277  bool structured_do = entity_empty_label_p(the_label);
3278  bool do_enddo_p = get_bool_property("PRETTYPRINT_DO_LABEL_AS_COMMENT");
3279 
3280  /* small hack to show the initial label of the loop to name it...
3281  */
3282  if(!structured_do && do_enddo_p)
3283  {
3285  strdup(concatenate("! INITIALLY: DO ", do_label, "\n", NULL))));
3286  }
3287 
3288  /* quite ugly management of other prettyprints...
3289  */
3290  switch(execution_tag(loop_execution(obj)) ) {
3292  MERGE_TEXTS(r, text_loop_default(module, label, margin, obj, n, ppdl, is_recursive_p));
3293  break ;
3294  case is_execution_parallel:
3295  if (pp_cmf_style_p()) {
3296  text aux_r;
3297  if((aux_r = text_loop_cmf(module, label, margin, obj, n, NIL, NIL))
3298  != text_undefined) {
3299  MERGE_TEXTS(r, aux_r);
3300  }
3301  }
3302  else if (pp_craft_style_p()) {
3303  text aux_r;
3304  if((aux_r = text_loop_craft(module, label, margin, obj, n, NIL, NIL))
3305  != text_undefined) {
3306  MERGE_TEXTS(r, aux_r);
3307  }
3308  }
3309  else if (pp_f90_style_p()) {
3310  instruction bi = statement_instruction(body); // body instruction
3311  bool success_p = false;
3312  if(instruction_assign_p(bi) ) {
3313  MERGE_TEXTS(r, text_loop_90(module, label, margin, obj, n));
3314  success_p = true;
3315  }
3316  else if(instruction_sequence_p(bi)) {
3318  if(gen_length(sl)==1) {
3319  statement ibs = STATEMENT(CAR(sl));
3321  if(instruction_assign_p(ibi) ) {
3322  MERGE_TEXTS(r, text_loop_90(module, label, margin, obj, n));
3323  success_p = true;
3324  }
3325  }
3326  }
3327  if(!success_p) {
3328  MERGE_TEXTS(r, text_loop_default(module, label, margin, obj, n, ppdl, is_recursive_p));
3329  }
3330  }
3331  else {
3332  MERGE_TEXTS(r, text_loop_default(module, label, margin, obj, n, ppdl, is_recursive_p));
3333  }
3334  break ;
3335  default:
3336  pips_internal_error("Unknown \"execution\" tag") ;
3337  }
3338  return r;
3339 }
3340 
3342  const char* label,
3343  int margin,
3344  whileloop obj,
3345  int n,
3346  list * ppdl,
3347  bool is_recursive_p) {
3348  list pc = NIL;
3349  sentence first_sentence;
3350  unformatted u;
3351  text r = make_text(NIL);
3352  statement body = whileloop_body( obj );
3353  entity the_label = whileloop_label(obj);
3354  const char* do_label = entity_local_name(the_label) + sizeof(LABEL_PREFIX) -1;
3355  bool structured_do = entity_empty_label_p(the_label);
3356  bool do_enddo_p = get_bool_property("PRETTYPRINT_DO_LABEL_AS_COMMENT");
3357 
3359 
3360  /* Show the initial label of the loop to name it...
3361  * FI: I believe this is useless for while loops since they cannot
3362  * be parallelized.
3363  */
3364  if(!structured_do && do_enddo_p) {
3366  strdup(concatenate("! INITIALLY: DO ", do_label, "\n", NULL))));
3367  }
3368 
3369  if(evaluation_before_p(eval)) {
3370  switch(get_prettyprint_language_tag()) {
3371  case is_language_fortran:
3372  case is_language_fortran95:
3373  /* LOOP prologue.
3374  */
3375  pc = CHAIN_SWORD(NIL, "DO " );
3376 
3377  if(!structured_do && !do_enddo_p) {
3378  pc = CHAIN_SWORD(pc, concatenate(do_label, " ", NULL));
3379  }
3380  pc = CHAIN_SWORD(pc, "WHILE (");
3381  pc = gen_nconc(pc, words_expression(whileloop_condition(obj), ppdl));
3382  pc = CHAIN_SWORD(pc, ")");
3383  u = make_unformatted(strdup(label), n, margin, pc);
3384  ADD_SENTENCE_TO_TEXT(r, first_sentence =
3386 
3387  if(is_recursive_p) {
3388  /* loop BODY
3389  */
3390  MERGE_TEXTS(r, text_statement(module, margin+INDENTATION, body, ppdl));
3391 
3392  /* LOOP postlogue
3393  */
3394  if(structured_do) {
3395  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin,"ENDDO"));
3396  }
3397  }
3398  break;
3399  case is_language_c:
3400  {
3401  bool braces_p = !one_liner_p(body) || prettyprint_all_c_braces_p;
3402  if(!braces_p) {
3403  pc = CHAIN_SWORD(NIL,"while (");
3404  pc = gen_nconc(pc, words_expression(whileloop_condition(obj), ppdl));
3405  pc = CHAIN_SWORD(pc,")");
3406  u = make_unformatted(strdup(label), n, margin, pc);
3408  if(is_recursive_p) {
3410  margin+INDENTATION,
3411  body,
3412  !one_liner_p(body),
3413  !one_liner_p(body),
3414  ppdl));
3415 
3416  //if (structured_do)
3417  //ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin,"}"));
3418  }
3419  } else {
3420  pc = CHAIN_SWORD(NIL,"while (");
3421  pc = gen_nconc(pc, words_expression(whileloop_condition(obj), ppdl));
3422  pc = CHAIN_SWORD(pc,") {");
3423  u = make_unformatted(strdup(label), n, margin, pc);
3425  if(is_recursive_p) {
3426  MERGE_TEXTS(r, text_statement(module, margin+INDENTATION, body, ppdl));
3427  if(structured_do)
3429  }
3430  }
3431  }
3432  break;
3433  default:
3434  pips_internal_error("Language unknown !");
3435  break;
3436  }
3437  } else {
3438  pips_assert ("Only C language is managed here",
3440  /* C do { s; } while (cond); loop*/
3441  if(is_recursive_p) {
3442  pc = CHAIN_SWORD(NIL,"do {");
3443  u = make_unformatted(strdup(label), n, margin, pc);
3445  MERGE_TEXTS(r, text_statement(module, margin+INDENTATION, body, ppdl));
3447  }
3448  pc = CHAIN_SWORD(NIL,"while (");
3449  pc = gen_nconc(pc, words_expression(whileloop_condition(obj), ppdl));
3450  pc = CHAIN_SWORD(pc, ");");
3451  u = make_unformatted(NULL, n, margin, pc);
3453  }
3454 
3455  /* attach_loop_to_sentence_up_to_end_of_text(first_sentence, r, obj); */
3456  return r;
3457 }
3458 
3459 /* exported for unstructured.c
3460  */
3461 text
3463  entity module,
3464  int margin,
3465  statement obj)
3466 {
3468  text r;
3469 
3470  if (get_bool_property("PRETTYPRINT_ALL_EFFECTS")
3471  || !((instruction_block_p(i) &&
3472  !get_bool_property("PRETTYPRINT_BLOCKS")) ||
3474  !get_bool_property("PRETTYPRINT_UNSTRUCTURED")))) {
3475  /* FI: before calling the hook,
3476  * statement_ordering(obj) should be checked */
3477  r = (*text_statement_hook)( module, margin, obj );
3480  }
3481  else
3482  r = make_text( NIL ) ;
3483 
3484  if (get_bool_property("PRETTYPRINT_ALL_EFFECTS") ||
3485  get_bool_property("PRETTYPRINT_STATEMENT_ORDERING")) {
3486  char *buffer;
3487  int so = statement_ordering(obj) ;
3488 
3490  (! get_bool_property("PRETTYPRINT_BLOCKS")))) {
3491  if (so != STATEMENT_ORDERING_UNDEFINED)
3492  asprintf(&buffer, "%s (%d,%d)\n", get_comment_sentinel(),
3494  else
3495  asprintf(&buffer, "%s (statement ordering unavailable)\n",
3498  buffer));
3499  }
3500  }
3501  return( r ) ;
3502 }
3503 
3505  const char* label,
3506  int margin,
3507  test obj,
3508  int n,
3509  list * ppdl,
3510  bool is_recursive_p) {
3511  text r = make_text(NIL);
3512  list pc = NIL;
3513  statement tb = test_true(obj);
3514 
3515  switch(get_prettyprint_language_tag()) {
3516  case is_language_fortran:
3517  case is_language_fortran95:
3518  pc = CHAIN_SWORD(pc, strdup("IF ("));
3519  break;
3520  case is_language_c:
3521  pc = CHAIN_SWORD(pc, strdup("if ("));
3522  break;
3523  default:
3524  pips_internal_error("Language unknown !");
3525  break;
3526  }
3527 
3528  pc = gen_nconc(pc, words_expression(test_condition(obj), ppdl));
3530  call c = call_undefined;
3531  text t = text_undefined;
3532  switch (get_prettyprint_language_tag()) {
3533  case is_language_fortran:
3534  case is_language_fortran95:
3535  pc = CHAIN_SWORD(pc, ") ");
3536  if(is_recursive_p) {
3537  ti = statement_instruction(tb);
3538  c = instruction_call(ti);
3539  pc = gen_nconc(pc, words_call(c, 0, true, true, ppdl));
3540  }
3543  make_unformatted(strdup(label), n,
3544  margin, pc)));
3545  break;
3546  case is_language_c:
3547  pc = CHAIN_SWORD(pc, ")"); // Do not add a useless SPACE
3550  make_unformatted(strdup(label), n,
3551  margin, pc)));
3552  if(is_recursive_p) {
3553  t = text_statement(module, margin + INDENTATION, tb, ppdl);
3555  text_sentences(t) = NIL;
3556  free_text(t);
3557  }
3558  break;
3559  default:
3560  pips_internal_error("Language unknown !");
3561  break;
3562  }
3563 
3564  ifdebug(8) {
3565  fprintf(stderr, "logical_if=================================\n");
3566  print_text(stderr, r);
3567  fprintf(stderr, "==============================\n");
3568  }
3569  return (r);
3570 }
3571 
3573 {
3574  bool no_else_p = true;
3576  no_else_p = false;
3577  else {
3578  statement fs = test_false(t);
3579  if(statement_test_p(fs)) // Go down recursively
3580  no_else_p = test_with_no_else_clause_p(statement_test(fs));
3581  else
3582  no_else_p = true;
3583  }
3584  return no_else_p;
3585 }
3586 
3587 /* Some code shared by text_block_if and text_block_ifthen */
3589 {
3590  statement fb = test_false(t);
3591  bool outer_else_p = !nop_statement_p(fb); // obj contains a non-empty else clause
3592  /* Do we have a test as a true branch, a test with no else clause? */
3594  bool inner_test_p = statement_test_p(ts);
3595  bool inner_else_p = inner_test_p?
3597  bool dangling_else_p = inner_test_p && outer_else_p && !inner_else_p;
3598 
3599  return dangling_else_p;
3600 }
3601 
3602 /* Prettyprint if clause of a test */
3604  const char* label,
3605  int margin,
3606  test obj,
3607  int n,
3608  list * ppdl,
3609  bool is_recursive_p) {
3610  text r = make_text(NIL);
3611  list pc = NIL;
3612  statement tb = test_true(obj);
3613  bool one_liner_true_statement_p = one_liner_p(tb);
3614  bool dangling_else_p = test_with_dangling_else_p(obj);
3615  bool gcc_braces_p = gcc_if_block_braces_required_p(obj);
3616  bool braces_p =
3617  !one_liner_true_statement_p // several statement in the true branch
3618  || prettyprint_all_c_braces_p // use request for braces
3619  || dangling_else_p // else clause would be associated to the wrong if
3620  || gcc_braces_p; // gcc warning [-Wparentheses]
3621 
3622  switch (get_prettyprint_language_tag()) {
3623  case is_language_fortran:
3624  case is_language_fortran95:
3625  pc = CHAIN_SWORD(pc, "IF (");
3626  pc = gen_nconc(pc, words_expression(test_condition(obj), ppdl));
3627  pc = CHAIN_SWORD(pc, ") THEN");
3628  break;
3629  case is_language_c:
3630  pc = CHAIN_SWORD(pc, "if (");
3631  pc = gen_nconc(pc, words_expression(test_condition(obj), ppdl));
3632  pc = CHAIN_SWORD(pc, (!braces_p?")":") {"));
3633  break;
3634  default:
3635  pips_internal_error("Language unknown !");
3636  break;
3637  }
3638 
3641  make_unformatted(strdup(label), n,
3642  margin, pc)));
3643  if(is_recursive_p) {
3645  margin+INDENTATION,
3646  tb,
3647  braces_p,
3648  braces_p,
3649  ppdl));
3651  && braces_p)
3653  }
3654 
3655  ifdebug(8) {
3656  fprintf(stderr, "if=================================\n");
3657  print_text(stderr, r);
3658  fprintf(stderr, "==============================\n");
3659  }
3660  return (r);
3661 }
3662 
3663 
3665  const char * label __attribute__ ((unused)),
3666  int margin,
3667  statement stmt,
3668  int n __attribute__ ((unused)),
3669  list * ppdl)
3670 {
3671  text r = make_text(NIL);
3672 
3675  (empty_statement_p(stmt) && ( get_bool_property("PRETTYPRINT_EMPTY_BLOCKS") )) ||
3676  (continue_statement_p(stmt) && ( get_bool_property("PRETTYPRINT_ALL_LABELS") ))
3677  )
3678  {
3679  switch (get_prettyprint_language_tag()) {
3680  case is_language_fortran:
3681  case is_language_fortran95:
3682  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin, "ELSE"));
3683  MERGE_TEXTS(r, text_statement(module, margin+INDENTATION, stmt, ppdl));
3684  break;
3685  case is_language_c:
3687  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin,"else"));
3689  margin+INDENTATION,
3690  stmt,
3691  false,
3692  false,
3693  ppdl));
3694  } else {
3695  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin, "else {"));
3696  MERGE_TEXTS(r, text_statement(module, margin+INDENTATION, stmt, ppdl));
3698  }
3699  break;
3700  default:
3701  pips_internal_error("Language unknown !");
3702  break;
3703  }
3704  }
3705 
3706  ifdebug(8) {
3707  fprintf(stderr, "else=================================\n");
3708  print_text(stderr, r);
3709  fprintf(stderr, "==============================\n");
3710  }
3711  return r;
3712 }
3713 
3714 
3716  const char* label,
3717  int margin,
3718  test obj,
3719  int n,
3720  list * ppdl) {
3721  text r = make_text(NIL);
3722  list pc = NIL;
3723  statement tb = test_true(obj);
3724  statement fb = test_false(obj);
3725  bool braces_p = !one_liner_p(tb) || prettyprint_all_c_braces_p;
3726 
3727  switch (get_prettyprint_language_tag()) {
3728  case is_language_fortran:
3729  case is_language_fortran95:
3730  pc = CHAIN_SWORD(pc, strdup("ELSEIF ("));
3731  pc = gen_nconc(pc, words_expression(test_condition(obj), ppdl));
3732  pc = CHAIN_SWORD(pc, strdup(") THEN"));
3733  break;
3734  case is_language_c:
3735  pc = CHAIN_SWORD(pc, strdup("else if ("));
3736  pc = gen_nconc(pc, words_expression(test_condition(obj), ppdl));
3737  pc = CHAIN_SWORD(pc, (!braces_p?")":") {"));
3738  break;
3739  default:
3740  pips_internal_error("Language unknown !");
3741  break;
3742  }
3743 
3746  make_unformatted(strdup(label), n,
3747  margin, pc)));
3748 
3750  margin+INDENTATION,
3751  tb,
3752  braces_p,
3753  braces_p,
3754  ppdl));
3755 
3757  && braces_p) {
3759  }
3760 
3765  margin,
3766  statement_test(fb), n, ppdl));
3767 
3768  } else {
3769  MERGE_TEXTS(r, text_block_else(module, label, margin, fb, n, ppdl));
3770  }
3771 
3772  ifdebug(8) {
3773  fprintf(stderr, "elseif=================================\n");
3774  print_text(stderr, r);
3775  fprintf(stderr, "==============================\n");
3776  }
3777  return (r);
3778 }
3779 
3780 
3781 /* Prettyprint the condition, the true and, possibly, the false branch.
3782  *
3783  * Manage redundant braces in C according to either the standard, or
3784  * gcc guidelines or a request to print them all.
3785  *
3786  * Brace management is a bit complex because the clausing brace of the
3787  * true block may be printed with the else branch or as a final brace
3788  * when the else branch is empty.
3789  *
3790  * Braces are now managed by text_block_ifthen, text_block_elseif or
3791  * text_block_else to factorize the work and facilitate the engineering.
3792  * A difference on the output code can be to not put "}" and else
3793  * in the same line?
3794  */
3796  const char* label,
3797  int margin,
3798  test obj,
3799  int n,
3800  list *ppdl,
3801  bool is_recursive_p)
3802 {
3803  text r = make_text(NIL);
3804 
3805  /* Prettyprint the true branch */
3806  r = text_block_ifthen(module, label, margin, obj, n, ppdl, is_recursive_p);
3807 
3808  if(is_recursive_p) {
3809  /* Prettyprint the false branch if it is useful */
3810  statement test_false_obj = test_false(obj);
3811  if(statement_undefined_p(test_false_obj)) {
3812  pips_internal_error("undefined statement");
3813  }
3814  /* one test in the false branch => "ELSEIF" Fortran block
3815  * or "else if" C construct */
3816  else if (statement_test_p(test_false_obj)
3817  && empty_comments_p(statement_comments(test_false_obj))
3818  && entity_empty_label_p(statement_label(test_false_obj))
3819  && !get_bool_property("PRETTYPRINT_BLOCK_IF_ONLY")) {
3820  MERGE_TEXTS(r,
3822  label_local_name(statement_label(test_false_obj)),
3823  margin, statement_test(test_false_obj), n, ppdl));
3824  }
3825  else {
3826  MERGE_TEXTS(r,
3827  text_block_else(module, label, margin, test_false_obj, n, ppdl));
3828  }
3829 
3830  /* Prettyprint the closing of the test */
3831  switch (get_prettyprint_language_tag()) {
3832  case is_language_fortran:
3833  case is_language_fortran95:
3834  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin,strdup("ENDIF")));
3835  break;
3836  case is_language_c:
3837  //nothing to do in C
3838  /* management of braces are take into account inside
3839  * text_block_ifthen
3840  * text_block_elseif
3841  * text_block_else
3842  */
3843  break;
3844  default:
3845  pips_internal_error("Language unknown !");
3846  break;
3847  }
3848  }
3849 
3850  ifdebug(8) {
3851  fprintf(stderr, "text_block_if=================================\n");
3852  print_text(stderr, r);
3853  fprintf(stderr, "==============================\n");
3854  }
3855  return (r);
3856 }
3857 
3858 
3860  const char* label,
3861  int margin,
3862  test obj,
3863  int n,
3864  list * ppdl) {
3865  text r = make_text(NIL);
3866  list pc = NIL;
3867 
3868  if (!empty_statement_p(test_true(obj))) {
3870  char* strglab= label_local_name + 1;
3871 
3872  r = make_text(CONS(SENTENCE,
3873  sentence_goto_label(module, label, margin,
3874  strglab, n),
3875  NIL));
3876 
3879  make_unformatted(strdup(label), n,
3880  margin, pc)));
3881  MERGE_TEXTS(r, text_statement(module, margin,
3882  test_true(obj), ppdl));
3883  string str = string_undefined;
3884  switch (get_prettyprint_language_tag()) {
3885  case is_language_fortran:
3887  break;
3888  case is_language_c:
3890  break;
3891  case is_language_fortran95:
3892  pips_internal_error("Need to update F95 case");
3893  break;
3894  default:
3895  pips_internal_error("Language unknown !");
3896  break;
3897  }
3898 
3900  make_unformatted(strdup(strglab), n, margin,
3901  CONS(STRING, str, NIL))));
3903  }
3904 
3905  if (!empty_statement_p(test_false(obj)))
3906  MERGE_TEXTS(r, text_statement(module, margin,
3907  test_false(obj), ppdl));
3908 
3909  return (r);
3910 }
3911 
3912 
3914  const char* label,
3915  int margin,
3916  test obj,
3917  int n,
3918  list * ppdl,
3919  bool is_recursive_p) {
3920  text r = text_undefined;
3921  statement tb = test_true(obj);
3922  statement fb = test_false(obj);
3923 
3924  /* 1st case: one statement in the true branch => Fortran logical IF
3925  or no braces in C */
3926  if (nop_statement_p(fb)
3927  && statement_call_p(tb)
3930  && !continue_statement_p(tb)
3931  && !get_bool_property("PRETTYPRINT_BLOCK_IF_ONLY")
3933  && get_bool_property("PRETTYPRINT_REGENERATE_ALTERNATE_RETURNS") )
3935  {
3936  r = text_logical_if(module, label, margin, obj, n, ppdl, is_recursive_p);
3937  }
3938  else {
3940 
3941  if (syntax_reference_p(c)
3943  && !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS"))
3944  r = text_io_block_if(module, label, margin, obj, n, ppdl);
3945  else
3946  r = text_block_if(module, label, margin, obj, n, ppdl, is_recursive_p);
3947  }
3948 
3949  ifdebug(8) {
3950  fprintf(stderr, "text_test=================================\n");
3951  print_text(stderr, r);
3952  fprintf(stderr, "==============================\n");
3953  }
3954  return r;
3955 }
3956 
3957 
3958 /* hook for adding something in the head. used by hpfc.
3959  * done so to avoid hpfc->prettyprint dependence in the libs.
3960  * FC. 29/12/95.
3961  */
3962 static string (*head_hook)(entity) = NULL;
3965 
3967  const char* label,
3968  int margin,
3969  instruction obj,
3970  int n,
3971  list * ppdl,
3972  bool is_recursive_p) {
3973  text r = text_undefined;
3974 
3975  switch(instruction_tag(obj)) {
3976  case is_instruction_block: {
3977  r = text_block(module, label, margin, instruction_block(obj), n, ppdl);
3978  break;
3979  }
3980  case is_instruction_test: {
3981  r = text_test(module, label, margin, instruction_test(obj), n, ppdl, is_recursive_p);
3982  break;
3983  }
3984  case is_instruction_loop: {
3985  r = text_loop(module, label, margin, instruction_loop(obj), n, ppdl, is_recursive_p);
3986  break;
3987  }
3988  case is_instruction_whileloop: {
3989  r = text_whileloop(module,
3990  label,
3991  margin,
3992  instruction_whileloop(obj),
3993  n,
3994  ppdl,
3995  is_recursive_p);
3996  break;
3997  }
3998  case is_instruction_goto: {
3999  r = make_text(CONS(SENTENCE,
4000  sentence_goto(module, label, margin,
4001  instruction_goto(obj), n), NIL));
4002  break;
4003  }
4004  case is_instruction_call: {
4005  unformatted u;
4006  sentence s;
4007  /* FI: in C at least, this has already been decided by the
4008  caller, text_statement_enclosed(); but apparently not in
4009  Fortran. Also, the source code may be in Fortran, but the
4010  user wants it prettyprinted as C. */
4012  && instruction_continue_p(obj) && empty_string_p(label)
4013  && !get_bool_property("PRETTYPRINT_ALL_LABELS")) {
4014  pips_debug(5, "useless Fortran CONTINUE not printed\n");
4015  r = make_text(NIL);
4016  } else {
4017  switch (get_prettyprint_language_tag()) {
4018  case is_language_fortran:
4019  case is_language_fortran95:
4020  u = make_unformatted(strdup(label),
4021  n,
4022  margin,
4024  0,
4025  true,
4026  true,
4027  ppdl));
4028  break;
4029  case is_language_c:
4030  u = make_unformatted(strdup(label),
4031  n,
4032  margin,
4034  0, true, true, ppdl),
4036  break;
4037  default:
4038  pips_internal_error("Language unknown !");
4040  break;
4041  }
4043  r = make_text(CONS(SENTENCE, s, NIL));
4044  }
4045  break;
4046  }
4048  // append local variables if there is some.
4049  // local variable need to be inserted before diging the
4050  // unstructured graph.
4051  r = insert_locals(r);
4052 
4053  text tmp = text_undefined;
4054  tmp = text_unstructured(module,
4055  label,
4056  margin,
4058  n,
4059  ppdl);
4060 
4061  // append the unstructured to the current text if it exists
4062  if ((r != text_undefined) && (r != NULL)) {
4063  MERGE_TEXTS (r, tmp);
4064  } else {
4065  r = tmp;
4066  }
4067 
4068  break;
4069  }
4070  case is_instruction_forloop: {
4071  r = text_forloop(module, label, margin, instruction_forloop(obj), n, ppdl, is_recursive_p);
4072  break;
4073  }
4075  list pc = words_expression(instruction_expression(obj), ppdl);
4076  unformatted u;
4078  u = make_unformatted(strdup(label), n, margin, pc);
4079  r = make_text(CONS(SENTENCE,
4081  NIL));
4082  break;
4083  }
4084  default: {
4085  pips_internal_error("unexpected tag");
4086  }
4087  }
4088  return (r);
4089 }
4090 
4091 
4092 /* In case the input code is not C code, non-standard comments have to
4093  be detected */
4094 bool C_comment_p(string c){
4095  bool is_C_comment=true;
4096  char * ccp=c;
4097  char cc=' ';
4098 
4099  init:
4100  cc=*ccp++;
4101  if(cc==' '|| cc=='\t' || cc=='\n')
4102  goto init;
4103  else if( cc=='/')
4104  goto slash;
4105  else if(cc=='\000')
4106  goto end;
4107  else {
4108  is_C_comment=false;
4109  goto end;
4110  }
4111 
4112  slash:
4113  cc=*ccp++;
4114  if(cc=='*')
4115  goto slash_star;
4116  else if(cc=='/')
4117  goto slash_slash;
4118  else{
4119  is_C_comment=false;
4120  goto end;
4121  }
4122 
4123  slash_star:
4124  cc=*ccp++;
4125  if(cc=='*')
4126  goto slash_star_star;
4127  else if(cc=='\0'){
4128  is_C_comment=false;
4129  goto end;
4130  }
4131  else
4132  goto slash_star;
4133 
4134  slash_slash:
4135  cc=*ccp++;
4136  if(cc=='\n')
4137  goto init;
4138  if(cc=='\0') // The comment may not end first with a '\n'
4139  goto end;
4140  else
4141  goto slash_slash;
4142 
4143  slash_star_star:
4144  cc=*ccp++;
4145  if(cc=='/')
4146  goto init;
4147  else if(cc=='*')
4148  goto slash_star_star;
4149  else if(cc=='\0'){
4150  is_C_comment=false;
4151  goto end;
4152  }
4153  else
4154  goto slash_star;
4155 
4156  end : return is_C_comment;
4157 }
4158 
4159 /* In case comments are not formatted according to C rules, e.g. when
4160  * prettyprinting Fortran code as C code, add // at beginning of lines
4161  *
4162  * Note: this is supposed to have been dealt with by another function
4163  * called before, ensure_comment_consistency()
4164  */
4165 text C_any_comment_to_text(int r_margin, string c)
4166 {
4167  string lb = c; /* line beginning */
4168  string le = c; /* line end */
4169  string cp = c; /* current position, pointer in comments */
4170  text ct = make_text(NIL);
4171  bool is_C_comment = C_comment_p(c);
4172  int e_margin = r_margin;
4173 
4174  /* We do not need spaces before a line feed */
4175  if(strcmp(c, "\n")==0)
4176  e_margin = 0;
4177 
4178  if(strlen(c)>0) {
4179  for(;*cp!='\0';cp++) {
4180  if(*cp=='\n') {
4181  if(cp!=c || true){ // Do not skip \n
4182  string cl = gen_strndup0(lb, le-lb);
4184  if(is_C_comment)
4185  s = MAKE_ONE_WORD_SENTENCE(e_margin, cl);
4186  else if(strlen(cl)>0){
4187  list pc = CHAIN_SWORD(NIL, cl); // cl is uselessly duplicated
4188  pc = CONS(STRING, MAKE_SWORD("//"), pc);
4190  make_unformatted((char *) NULL, 0, e_margin, pc));
4191  }
4192  else {
4193  s = MAKE_ONE_WORD_SENTENCE(0, cl);
4194  }
4195  ADD_SENTENCE_TO_TEXT(ct, s);
4196  free(cl);
4197  }
4198  lb = cp+1;
4199  le = cp+1;
4200  }
4201  else
4202  le++;
4203  }
4204  // Final \n has been removed in the parser presumably by Ronan
4205  // But this is also useful when non-standard comments are added,
4206  // for instance by phase "comment_prepend"
4207  if(lb<cp){
4209  string sl = gen_strndup0(lb,le-lb);
4210  if(is_C_comment) {
4211  s = MAKE_ONE_WORD_SENTENCE(e_margin,sl);
4212  }
4213  else {
4214  list pc = CHAIN_SWORD(NIL, sl); // sl is uselessly duplicated
4215  pc = CONS(STRING, MAKE_SWORD("//"), pc);
4217  make_unformatted((char *) NULL, 0, e_margin, pc));
4218  }
4219  ADD_SENTENCE_TO_TEXT(ct,s);
4220  free(sl);
4221  } else{
4222  //ADD_SENTENCE_TO_TEXT(ct,MAKE_ONE_WORD_SENTENCE(0,""));
4223  ;
4224  }
4225  }
4226  else{// Final \n has been removed by Ronan
4227  //ADD_SENTENCE_TO_TEXT(ct,MAKE_ONE_WORD_SENTENCE(0,""));
4228  ;
4229  }
4230 
4231  return ct;
4232 }
4233 
4234 // Ronan's improved version is bugged. It returns many lines for a
4235 // unique \n because le is not updated before looping. Has this code
4236 // been validated?
4238 {
4239  string line;
4240  string le = comment; /* position of a line end */
4241  text ct = make_text(NIL);
4242 
4243  do {
4244  /* Find the first end of line: */
4245  le = strchr(comment, '\n');
4246  if (le == NULL)
4247  /* No end-of-line, so use all the rest of the comment: */
4248  line = strdup(comment);
4249  else {
4250  /* Skip the '\n' at the end since the line concept is the notion of
4251  sentence */
4252  line = gen_strndup0(comment, le - comment);
4253  /* Analyze the next line: */
4254  comment = le + 1;
4255  }
4256  /* Do not indent if the line is empty */
4258  MAKE_ONE_WORD_SENTENCE(line[0] == '\0' ? 0 : margin,
4259  line));
4260  } while (le != NULL);
4261  return ct;
4262 }
4263 
4264 /* Special handling for C comments with each line indented according to
4265  the context.
4266 
4267  I do not see the interest if the user code is already indented... RK
4268  OK, since the blanks outside the comments are removed by the parser.
4269 */
4270 text C_comment_to_text(int margin, string comment)
4271 {
4272  text ct = text_undefined;
4273 
4274  if(C_comment_p(comment))
4275  //ct = C_standard_comment_to_text(margin, comment);
4276  ct = C_any_comment_to_text(margin, comment);
4277  else
4278  ct = C_any_comment_to_text(margin, comment);
4279  return ct;
4280 }
4281 
4282 /* Split string into a list of strings according to a separator, delim
4283  *
4284  * Note that the final LF is dropped in C comments
4285  */
4286 static list cstrsplit(const char * s, char delim) {
4287  list out = NIL;
4288  const char *b=s,*e=s;
4289  while(*e) {
4290  while(*e && *e!=delim) ++e;
4291  char * word = strndup(b,e-b);
4292  out=CONS(STRING,word,out);
4293  if(*e) {
4294  ++e;
4295  b=e;
4296  }
4297  // This looks necessary for decl64-65.c (1 and 2 empty lines),
4298  // but is impossible for comment14.c (3 empty lines)
4299  /* if(delim=='\n' && *(e-1)=='\n' && *e=='\000') */
4300  /* out=CONS(STRING,strdup(""),out); */
4301  }
4302  return gen_nreverse(out);
4303 }
4304 
4305 /* return a formatted comment, that takes care of adding the relevant // or C
4306  * depending on output language, except for empty lines in C
4307  */
4308 static string ensure_comment_consistency(const char * i_comments, language l) {
4309  string comments;
4310  /* Special handling of comments linked to declarations and to the
4311  poor job of the lexical analyzer as regards C comments:
4312  failure. */
4313  if(empty_comments_p(i_comments)) {
4314  comments = strdup("");
4315  }
4316  else {
4317  if(get_bool_property("PRETTYPRINT_CHECK_COMMENTS")) {
4318  char * patterns [] = { NULL, NULL, NULL, NULL, NULL, NULL };
4319  char prefix[3]= { 0,0,0 };
4320  if(language_c_p(l)) {
4321  patterns[0] = "//";
4322  patterns[1] = "/*";
4323  strcat(prefix,"//");
4324  }
4325  else if(language_fortran95_p(l) || language_fortran_p(l)) {
4326  patterns[0]= "C";
4327  patterns[1]= "!";
4328  patterns[2]= "*";
4329  patterns[3]= "c";
4330  patterns[4]= "#"; // a single test case in PIPS validation forces me to do this (Syntax/sharpcomment)
4331  if(language_fortran95_p(l))
4332  strcat(prefix,"! ");
4333  else
4334  strcat(prefix,"C ");//to keep consistency with old fashioned code
4335  }
4336  // be multi-line comments compliant
4337  list lines = cstrsplit(i_comments,'\n');
4338  list lcomments = NIL;
4339  for(list liter=lines;!ENDP(liter);POP(liter)){
4340  string line = STRING(CAR(liter));
4341  bool comment_ok =false;
4342  char *iter =line;
4343  while(*iter && isspace(*iter)) iter++;
4344  if(*iter) {
4345  for(char **piter=&patterns[0];*piter;piter++) {
4346  if((comment_ok=(strncmp(iter,*piter,strlen(*piter))==0)))
4347  break;
4348  }
4349  if(!comment_ok)
4350  asprintf(&comments,"%s%s",prefix,line);
4351  else
4352  comments=strdup(line);
4353  }
4354  else /*blank line */
4355  comments=strdup(line);
4356  if(language_c_p(l) && strncmp(iter,"/*",2)==0 ){ // multi-line comment started, assume it's ok now
4357  lcomments=gen_nconc(lcomments,gen_copy_string_list(liter));
4358  break; // so bad if we close the multi-line comment and keep commenting afterwards ...
4359  }
4360  else
4361  lcomments=gen_nconc(lcomments,CONS(STRING,comments,NIL));
4362  }
4363  comments=words_join(lcomments,"\n");
4364  gen_free_string_list(lcomments);
4366  }
4367  else
4368  return strdup(i_comments);
4369 
4370 #if 0
4371 
4373  /* LF interspersed within C struct or union or initialization
4374  declarations may damage the user comment. However, there is no
4375  way no know if the LF are valid because thay are located
4376  between two statements or invalid because they are located
4377  within one statement. The information is lost by the lexer and
4378  the parser. */
4379  //comments = string_strip_final_linefeeds(strdup(i_comments));
4380  //comments = string_fuse_final_linefeeds(strdup(i_comments));
4381  comments = strdup(i_comments);
4382  }
4383  else {
4384  comments = strdup(i_comments);
4385  }
4386 #endif
4387  }
4388  return comments;
4389 
4390 }
4391 
4392 ␌
4393 /* Build the text of a statement
4394 
4395  @param module: the module containing the statement
4396 
4397  @param imargin: current tabulation
4398 
4399  @param stmt: the statement to print
4400 
4401  @param braces_p: the statement is within a block; this has an impact of
4402  the print-out of continue statements in C, ";"
4403 
4404  @param drop_continue_p: another condition to control the print-out of
4405  ";" or not;
4406 
4407  @param ppdl: pointer to the previous declaration list; list of
4408  entities that have already been declared and should not be
4409  redeclared; this is required for struct and union which may be
4410  declared independently or in a nested way. See C_syntax/struct03,
4411  04, 05, etc...
4412 
4413  @return the text of the statement
4414 
4415  Notes:
4416 
4417  - in simple tests, the statement ";" may be mandatory or not.
4418 
4419  - continue may be used to preserve comments and then the ";" may be
4420  dropped
4421 
4422  - source fidelity would be easier if a new NOP statement that is
4423  never printed out were used.
4424 */
4426  entity module,
4427  int imargin,
4428  statement stmt,
4429  bool braces_p,
4430  bool drop_continue_p,
4431  list * ppdl,
4432  bool is_recursive_p,
4433  bool with_comments)
4434 {
4436  //synchronization sync = statement_synchronization(stmt);
4437  text r= make_text(NIL);
4438  text temp;
4439  string i_comments = with_comments? statement_comments(stmt): string_undefined;
4440  string comments = string_undefined;
4441  bool braces_added = false;
4442  int nmargin = imargin;
4443 
4444  // To ease breakpoint setting
4445  //pips_assert("Blocks have no comments", !instruction_block_p(i)||empty_comments_p(comments));
4446  if(instruction_block_p(i) && !empty_comments_p(i_comments)) {
4447  pips_internal_error("Blocks should have no comments");
4448  }
4449 
4450  comments = ensure_comment_consistency(i_comments,get_prettyprint_language());
4451 
4455  {
4456  string ext = extensions_to_string(statement_extensions (stmt), true);
4457  if (ext != string_undefined) {
4459  braces_added = true;
4461  MAKE_ONE_WORD_SENTENCE(imargin, "{"));
4462  nmargin += INDENTATION;
4463  }
4464  }
4465 
4466  // Generate text for local declarations
4467  // NN: Code added for C, because a statement can have its own declarations
4469 
4470  // FI: consistency check - incompatible with unfolding and C parser...
4471  ifdebug(1) {
4472  /* The real check is that dl and idl are equal, that is
4473  ENDP(gen_list_and_not(dl,idl)) && ENDP(gen_list_and_not(idl,dl)),
4474  except for the side effects of gen_list_and_not(), so dl and idl
4475  should be copied first. */
4476  if(statement_block_p(stmt)) {
4478  if(ENDP(dl) && !ENDP(idl)) {
4479  /* This may occur when declaration statements are added using
4480  subsequences by somebody forgetfull of scope issues */
4481  // Do not forget: the error is detected within the prettyprinter...
4482  //print_statement(stmt);
4483  print_entities(idl);
4484  pips_internal_error("A block statement with no declarations"
4485  " contains declarations\n");
4486  }
4487  else if(gen_length(dl)!=gen_length(idl)) {
4488  print_entities(dl);
4489  fprintf(stderr, "\n"); // FI, OK a fputc might do as well
4490  print_entities(idl);
4491  fprintf(stderr, "\n");
4492  pips_internal_error("A block statement with %d declarations"
4493  " contains %d declarations in its statements\n",
4494  gen_length(dl), gen_length(idl));
4495  }
4496  else
4497  gen_free_list(idl);
4498  }
4499  if(statement_block_p(stmt) && !ENDP(dl)) {
4500  /* See for instance
4501  Transformations/Simplify_control.sub/sequence01 */
4502  list sl = statement_block(stmt);
4503  if(ENDP(sl)) {
4504  pips_internal_error("A block statement with declarations"
4505  " contains no declaration statements\n");
4506  }
4507  }
4508  }
4509 
4510  if (!ENDP(dl) && prettyprint_language_is_c_p()) {
4511  if(statement_block_p(stmt)) {
4512  if(!braces_p && !braces_added) {
4513  braces_added = true;
4515  MAKE_ONE_WORD_SENTENCE(imargin, "{"));
4516  nmargin += INDENTATION;
4517  }
4518  }
4519  else {
4520  pips_assert("declarations are carried by continue statements",
4522  }
4523  // initialize the local variable text if needed
4524  if (local_flg == false) {
4525  local_flg = true;
4526  local_var = make_text(NIL);
4527  }
4529  int sn = statement_number(stmt);
4532  c_text_related_entities(module,dl,nmargin,sn,ppdl,il));
4533  //c_text_related_entities(module,dl,nmargin,sn,dl,il));
4534  }
4535  else {
4536  //MERGE_TEXTS(local_var, c_text_entities(module,l,nmargin));
4537  // Do nothing and rely on CONTINUE statements...
4538  ;
4539  }
4540  }
4541 
4542  pips_debug(2, "Begin for statement %s with braces_p=%d\n",
4543  statement_identification(stmt),braces_p);
4544  pips_debug(9, "statement_comments: --%s--\n",
4545  string_undefined_p(comments)? "<undef>": comments);
4546 
4549  /* we are in trouble with some kind of dead (?) code...
4550  but we might as well be dealing with some parsed_code */
4551  pips_debug(1, "I unexpectedly bumped into dead code?\n");
4552  }
4553 
4554  const char* label;
4555 
4556  bool pragma_before_label_in_C = prettyprint_language_is_c_p()
4558 
4559  if (pragma_before_label_in_C)
4560  /* We are in trouble because a pragma in C should appear after the label but
4561  the Fortran-oriented prettyprinter is to prettyprint a label and an
4562  instruction in block. So we print the instruction without the label
4563  that is to be added in another way afterwards */
4564  label = "";
4565  else
4567 
4569  pips_assert("Statement with return label must be a return statement",
4571 
4572  /* do not add a redundant RETURN before an END, unless
4573  requested or unless needed because a value must be returned
4574  in C */
4575  extern bool last_statement_p(statement);
4576 
4577  if (get_bool_property("PRETTYPRINT_FINAL_RETURN") ||
4578  !last_statement_p(stmt) ||
4580  {
4584  || fortran_module_p(module)) {
4585  s = MAKE_ONE_WORD_SENTENCE(nmargin,
4589  }
4590  else {
4591  // Must be a non void C function
4593  list pc = NIL;
4595  pc = CHAIN_SWORD(pc, " ");
4596  pc = CHAIN_SWORD(pc, entity_user_name(rv));
4598  unformatted u = make_unformatted((char *) NULL, 0, nmargin, pc);
4600  }
4601  temp = make_text(CONS(SENTENCE, s, NIL));
4602  }
4603  else {
4604  temp = make_text(NIL);
4605  }
4606  }
4607  else
4608  {
4611  : module;
4612 
4613  if (true || !compilation_unit_p(entity_name(m))) {
4614  // Do we need to print this CONTINUE statement in C?
4615  string cs = statement_comments(stmt);
4616 
4618  && (braces_p || drop_continue_p)
4620  && instruction_continue_p(i)) {
4622  /* The declarations will be printed, no need for anything else */
4623  temp = make_text(NIL);
4624  }
4625  else if(string_undefined_p(cs) || cs == NULL || strcmp(cs, "")==0) {
4626  sentence s = MAKE_ONE_WORD_SENTENCE(0, "");
4627  temp = make_text(CONS(SENTENCE, s, NIL));
4628  //temp = make_text(NIL);
4629  }
4630  else if(strcmp(cs, "\n")==0) {
4631  // MAKE_ONE_WORD_SENTENCE already implies a '\n'
4632  sentence s = MAKE_ONE_WORD_SENTENCE(0, "");
4633  temp = make_text(CONS(SENTENCE, s, NIL));
4634  }
4635  else
4636  temp = text_instruction(module, label, nmargin, i,
4637  statement_number(stmt), ppdl,
4638  is_recursive_p);
4639  }
4640  else
4641  temp = text_instruction(module, label, nmargin, i,
4642  statement_number(stmt), ppdl,
4643  is_recursive_p);
4644  }
4645  else
4646  temp = make_text(NIL);
4647  }
4648 
4649  // Take care of comments and of analysis results printed as comments
4650  // Note about comments: they are duplicated here, but I'm pretty
4651  // sure that the free is NEVER performed as it should. FC.
4652  if (!ENDP(text_sentences(temp))) {
4653  // There is something to output for the instruction...
4654  MERGE_TEXTS(r, init_text_statement(module, nmargin, stmt));
4655  if (! empty_comments_p(comments)) {
4656  switch(get_prettyprint_language_tag()) {
4657  case is_language_fortran:
4658  case is_language_fortran95:
4660  strdup(comments)));
4661  break;
4662  case is_language_c: {
4663  text ct = C_comment_to_text(nmargin, comments);
4664  MERGE_TEXTS(r, ct);
4665  }
4666  break;
4667  default:
4668  pips_internal_error("Language unknown !");
4669  break;
4670  }
4671  }
4672  }
4673  else {
4674  /* There is nothing to output for the instruction itself.
4675 
4676  Preserve comments and empty C instruction */
4677  if (! empty_comments_p(comments)) {
4678  text ct = text_undefined;
4679  switch (get_prettyprint_language_tag()) {
4680  case is_language_fortran:
4681  case is_language_fortran95:
4683  strdup(comments)));
4684  break;
4685  case is_language_c:
4686  ct = C_comment_to_text(nmargin, comments);
4687  MERGE_TEXTS(r, ct);
4688  MERGE_TEXTS(r, init_text_statement(module, nmargin, stmt));
4689  break;
4690  default:
4691  pips_internal_error("Language unknown !");
4692  break;
4693  }
4694  }
4695  else if(prettyprint_language_is_c_p() &&
4696  !braces_p && !braces_added &&ENDP(dl)) {
4697  // Because C braces can be eliminated and hence semi-colon
4698  // may be mandatory in a test branch or in a loop body.
4699  // A. Mensi
4700  sentence s = MAKE_ONE_WORD_SENTENCE(nmargin,
4702  ADD_SENTENCE_TO_TEXT(r, s);
4703  }
4704  else if(!ENDP(dl)) {
4705  MERGE_TEXTS(r, init_text_statement(module, nmargin, stmt));
4706  }
4707  }
4708 
4709  /* Add the label if not already done, in the case we want it before a
4710  extension/pragma: */
4711  if (pragma_before_label_in_C)
4715  0,
4716  NULL)));
4717 
4719  /* Append the extensions after comments: */
4720  string ext = extensions_to_string(statement_extensions (stmt), true);
4721  if (ext != string_undefined) {
4723  }
4724  }
4725 
4726  /* Then add any instruction text: */
4727  MERGE_TEXTS(r, temp);
4728 
4729  /* append local variables that might have not been inserted
4730  previously
4731 
4732  FI: this seems to be quite late and might explain the problem
4733  with local variables of Fortran do loops. Might, because I've
4734  never managed to figure out exactly what happens...
4735  */
4736  r = insert_locals (r);
4737 
4738  if (braces_added) {
4739  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(imargin, "}"));
4740  }
4742 
4743  // the last thing to do is to close the extension
4744  string close = close_extensions (statement_extensions (stmt), true);
4745  if (close != string_undefined) {
4747  }
4748 
4749  ifdebug(1) {
4750  if (instruction_sequence_p(i)) {
4754  user_log("Block statement %s\n"
4755  "Block number=%d, Block label=\"%s\", block comment=\"%s\"\n",
4759  pips_internal_error("This block statement should be labelless,"
4760  " numberless and commentless.\n");
4761  }
4762  }
4763  }
4764  ifdebug(8){
4765  fprintf(stderr,"text_statement_enclosed=================================\n");
4766  print_text(stderr,r);
4767  fprintf(stderr,"==============================\n");
4768  }
4769 
4770  free(comments);
4771 
4772  pips_debug(2, "End for statement %s\n", statement_identification(stmt));
4773 
4774  return(r);
4775 }
4776 
4777 /* Build the text of a statement recursively
4778 
4779  @param module: the module containing the statement
4780 
4781  @param imargin: current tabulation
4782 
4783  @param stmt: the statement to print
4784 
4785  @param braces_p: the statement is within a block; this has an impact of
4786  the print-out of continue statements in C, ";"
4787 
4788  @param drop_continue_p: another condition to control the print-out of
4789  ";" or not;
4790 
4791  @param ppdl: pointer to the previous declaration list; list of
4792  entities that have already been declared and should not be
4793  redeclared; this is required for struct and union which may be
4794  declared independently or in a nested way. See C_syntax/struct03,
4795  04, 05, etc...
4796 
4797  @return the text of the statement
4798 
4799  Notes:
4800 
4801  - in simple tests, the statement ";" may be mandatory or not.
4802 
4803  - continue may be used to preserve comments and then the ";" may be
4804  dropped
4805 
4806  - source fidelity would be easier if a new NOP statement that is
4807  never printed out were used.
4808 */
4810  int imargin,
4811  statement stmt,
4812  bool braces_p,
4813  bool drop_continue_p,
4814  list * ppdl)
4815 {
4817  module, imargin, stmt, braces_p, drop_continue_p, ppdl, true, true);
4818 }
4819 
4821  int imargin,
4822  statement stmt,
4823  bool braces_p,
4824  bool drop_continue_p)
4825 {
4826  list npdl = NIL;
4827  text t = text_statement_enclosed(module, imargin, stmt, braces_p, drop_continue_p, &npdl);
4828  gen_free_list(npdl);
4829  return t;
4830 }
4831 
4832 /* Handles all statements but tests that are nodes of an unstructured.
4833  Those are handled by text_control.
4834 
4835  @param module: the module containing the statement
4836 
4837  @param margin: current tabulation
4838 
4839  @param stmt: the statement to print
4840 
4841  @param ppdl: pointer to the previous declaration list; list of
4842  entities that have already been declared and should not be
4843  redeclared; this is required for struct and union which may be
4844  declared independently or in a nested way. See C_syntax/struct03,
4845  04, 05, etc...
4846 
4847  @return the text of the statement
4848  */
4850  entity module,
4851  int margin,
4852  statement stmt,
4853  list * ppdl)
4854 {
4855  return text_statement_enclosed(module, margin, stmt, true, true, ppdl);
4856 }
4857 
4859  entity module,
4860  int margin,
4861  statement stmt)
4862 {
4863  return Text_Statement_Enclosed(module, margin, stmt, true, true);
4864 }
4865 
4867  entity module,
4868  int margin,
4869  statement stmt)
4870 {
4871  list npdl = NIL;
4873  module, margin, stmt, true, true, &npdl, false, false);
4874  gen_free_list(npdl);
4875  return t;
4876 }
4877 
4878 /* return a string from a statement, or NULL if undefined
4879  */
4881 {
4882  if (cs == NULL || statement_undefined_p(cs))
4883  return NULL;
4884 
4886  string s = text_to_string_nl(t);
4887  free_text(t);
4888  return s;
4889 }
4890 
4891 /* Keep track of the last statement to decide if a final return can be
4892  * omitted or not. If no last statement can be found for sure, for
4893  * instance because it depends on the prettyprinter, last_statement_found is
4894  * set to statement_undefined which is safe.
4895  *
4896  * FI: for purposes unrelated to prettyprint, see
4897  * last_statement(). This function is part of the prettyprinter and
4898  * probably only useful for Fortran code.
4899  */
4900 static statement last_statement_found = statement_undefined;
4901 
4903 {
4905 
4906  pips_assert("statement is defined", !statement_undefined_p(s));
4907 
4908  if(statement_sequence_p(s)) {
4910 
4911  last = (ENDP(ls)? statement_undefined : STATEMENT(CAR(gen_last(ls))));
4912  }
4913  else if(statement_unstructured_p(s)) {
4915  list trail = unstructured_to_trail(u);
4916 
4917  last = control_statement(CONTROL(CAR(trail)));
4918 
4919  gen_free_list(trail);
4920  }
4921  else if(statement_call_p(s)) {
4922  /* Hopefully it is a return statement.
4923  * Since the semantics of STOP is ignored by the parser, a
4924  * final STOp should be followed by a RETURN.
4925  */
4926  last = s;
4927  }
4928  else {
4929  /* loop or test cannot be last statements of a module */
4930  last = statement_undefined;
4931  }
4932 
4933  /* recursive call */
4934  if(!statement_undefined_p(last)
4935  && (statement_sequence_p(last) || statement_unstructured_p(last))) {
4936  last = find_last_statement(last);
4937  }
4938 
4939  /* Too many program transformations and syntheses violate the
4940  following assert */
4941  if(!(statement_undefined_p(last)
4942  || !statement_sequence_p(s)
4943  || return_statement_p(last))) {
4944  switch(get_prettyprint_language_tag()) {
4945  case is_language_fortran:
4946  case is_language_fortran95:
4947  pips_user_warning("Last statement is not a RETURN!\n");
4948  break;
4949  case is_language_c:
4950  /* No warning needed for C, is it right for C ?*/
4951  break;
4952  default:
4953  pips_internal_error("Language unknown !");
4954  break;
4955  }
4956  last = statement_undefined;
4957  }
4958 
4959  /* I had a lot of trouble writing the condition for this assert... */
4960  pips_assert("Last statement is either undefined or a call to return",
4961  statement_undefined_p(last) /* let's give up: it's always safe */
4962  || !statement_sequence_p(s) /* not a block: any kind of statement... */
4963  || return_statement_p(last)); /* if a block, then a return */
4964 
4965  return last;
4966 }
4967 
4969 {
4971  pips_assert("last statement is undefined",
4972  statement_undefined_p(last_statement_found));
4973  ls = find_last_statement(s);
4974  last_statement_found = ls;
4975 }
4976 
4977 void reset_last_statement()
4978 {
4979  last_statement_found = statement_undefined;
4980 }
4981 
4982 bool last_statement_p(statement s) {
4983  pips_assert("statement is defined\n", !statement_undefined_p(s));
4984  return s == last_statement_found;
4985 }
4986 
4987 /* adds a RETURN statement to *ps if necessary
4988  */
4989 void
4991  entity module,
4992  statement *ps)
4993 {
4994  statement last = find_last_statement(*ps);
4995  if (statement_undefined_p(last) || !return_statement_p(last))
4996  {
4998  if (statement_block_p(*ps))
4999  {
5001  statement_instruction(*ps))) =
5003  statement_instruction(*ps))),
5004  CONS(STATEMENT, ret, NIL));
5005  }
5006  else
5007  {
5008  *ps = make_block_statement(CONS(STATEMENT, *ps,
5009  CONS(STATEMENT, ret, NIL)));
5010  }
5011  }
5012 }
5013 ␌
5014 /* Reuse all declarations of the compilation unit, although some
5015  * may occur after the module definition.
5016  */
5018 {
5019  list pdl = NIL;
5022 
5023  if(entity_undefined_p(cu)) {
5024  pips_user_warning("A C source code is prettyprinted without using definitions placed in its compilation unit.\nThe resulting source code may not be meaningfull.\n");
5025  type t = entity_type(module);
5026  pdl = NIL;
5027  /* all types and derived entities used to define the formal
5028  * parameters must be predefined, or they are local to the
5029  * formal scope and useless.
5030  */
5031  pdl = type_supporting_entities(pdl, t);
5032  }
5033  else {
5034  code cuc = value_code(entity_initial(cu));
5035  pdl = gen_copy_seq(code_declarations(cuc));
5036  }
5037  }
5038  return pdl;
5039 }
5040 ␌
5041 /* Build the text of a module.
5042 
5043  The original text of the declarations is used if possible in
5044  Fortran. Otherwise, the function text_declaration is called.
5045  */
5047  entity name, /**< the name of the module */
5048  entity module,
5049  statement stat)
5050 {
5051  text r = make_text(NIL);
5052  code c = entity_code(module);
5053  string s = code_decls_text(c);
5054  text ral = text_undefined;
5055 
5056  debug_on("PRETTYPRINT_DEBUG_LEVEL");
5057 
5058  /* Set the prettyprint language */
5060 
5061  /* This guard is correct but could be removed if find_last_statement()
5062  * were robust and/or if the internal representations were always "correct".
5063  * See also the guard for reset_last_statement()
5064  */
5065  if(!get_bool_property("PRETTYPRINT_FINAL_RETURN"))
5066  set_last_statement(stat);
5067 
5068  precedence_p = !get_bool_property("PRETTYPRINT_ALL_PARENTHESES");
5069  prettyprint_all_c_braces_p = get_bool_property("PRETTYPRINT_ALL_C_BRACES");
5070  prettyprint_gcc_c_braces_p = get_bool_property("PRETTYPRINT_GCC_C_BRACES");
5071  list l = NIL;
5072  switch(get_prettyprint_language_tag()) {
5073  case is_language_fortran:
5074  case is_language_fortran95:
5075  if(strcmp(s, "") == 0
5076  || get_bool_property("PRETTYPRINT_ALL_DECLARATIONS")) {
5077  if(get_bool_property("PRETTYPRINT_HEADER_COMMENTS"))
5078  /* Add the original header comments if any: */
5080 
5081  list pdl = NIL;
5084  gen_free_list(pdl);
5085  if(head_hook)
5087  head_hook(module)));
5088 
5089  if(get_bool_property("PRETTYPRINT_HEADER_COMMENTS"))
5090  /* Add the original header comments if any: */
5092 
5095  } else {
5098  strdup(s)),
5099  module));
5100  }
5101  break;
5102  case is_language_c:
5103  /* C prettyprinter */
5104  pips_debug(3,"Prettyprint function %s\n",entity_name(name));
5105  if(!compilation_unit_p(entity_name(name))) {
5106  /* Print function header if the current module is not a compilation unit*/
5108 
5111  /* get the declarations for Fortran codes prettyrinted as C,
5112  as the declarations are not located in the module
5113  statement. A.Mensi */
5117  }
5118  /* Declarations linked to formal parameters are performed in a
5119  different scope and do not have to be propagated. */
5120  gen_free_list(pdl);
5121  }
5122  break;
5123  default:
5124  pips_internal_error("Language unknown !");
5125  break;
5126  }
5127 
5130 
5131  if (stat != statement_undefined) {
5132  // Prevously declared entity list
5134 
5135  switch(get_prettyprint_language_tag()) {
5136  case is_language_fortran:
5137  case is_language_fortran95:
5140  stat,
5141  &pdl));
5142  break;
5143  case is_language_c:
5144  MERGE_TEXTS(r,
5147  stat, &pdl));
5148  break;
5149  default:
5150  pips_internal_error("Language unknown !");
5151  break;
5152  }
5153  gen_free_list(pdl);
5154  }
5155 
5158  MERGE_TEXTS(r, ral);
5159 
5160  if(!compilation_unit_p(entity_name(name))
5162  /* No need to print TAIL (}) if the current module is a C compilation unit*/
5164  }
5165 
5166  if(!get_bool_property("PRETTYPRINT_FINAL_RETURN"))
5168 
5169  debug_off();
5170  return(r);
5171 }
5172 
5173 
5175  return text_named_module(module, module, stat);
5176 }
5177 
5178 text text_graph(), text_control() ;
5179 string control_slabel() ;
5180 
5181 
5182 /* The node itentifiers are generated from the ordering, more stable than
5183  the control node address: */
5184 void
5187  add_one_unformated_printf_to_text(r, "c_%d_%d",
5188  ORDERING_NUMBER(so),
5189  ORDERING_STATEMENT(so));
5190 }
5191 
5193  entity module,
5194  int margin,
5195  control c)
5196 {
5197  list pdl = NIL; // FI: I have no idea how to initialize it in this context...
5198 
5203 
5204  if (get_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH_VERBOSE")) {
5205  add_one_unformated_printf_to_text(r, "C Unstructured node %p ->", c);
5206  MAP(CONTROL, a_successor,
5207  add_one_unformated_printf_to_text(r, " %p", a_successor),
5208  control_successors(c));
5210  }
5211 
5213  margin,
5214  control_statement(c),
5215  &pdl));
5216 
5217 
5220  MAP(CONTROL, a_successor,
5221  {
5223  add_control_node_identifier_to_text(r, a_successor);
5224  },
5225  control_successors(c));
5227 }
5228 
5229 
5231  entity module,
5232  int margin,
5233  control begin_control,
5234  control exit_control)
5235 {
5236  bool exit_node_has_been_displayed = false;
5237  list blocs = NIL;
5238 
5239  CONTROL_MAP(c,
5240  {
5241  /* Display the statements of each node followed by
5242  the list of its successors if any: */
5244  module,
5245  margin,
5246  c);
5247  if (c == exit_control)
5248  exit_node_has_been_displayed = true;
5249  },
5250  begin_control,
5251  blocs);
5252  gen_free_list(blocs);
5253 
5254  return exit_node_has_been_displayed;
5255 }
5256 
5258  entity module,
5259  const char * label __attribute__ ((unused)),
5260  int margin,
5261  unstructured u,
5262  int __attribute__ ((unused)) num)
5263 {
5264  bool exit_node_has_been_displayed = false;
5265  control begin_control = unstructured_control(u);
5266  control end_control = unstructured_exit(u);
5267 
5270  add_control_node_identifier_to_text(r, begin_control);
5271  add_one_unformated_printf_to_text(r, " end: ");
5272  add_control_node_identifier_to_text(r, end_control);
5274 
5275  exit_node_has_been_displayed =
5277  module,
5278  margin,
5279  begin_control,
5280  end_control);
5281 
5282  /* If we have not displayed the exit node, that mean that it is not
5283  connex with the entry node and so the code is
5284  unreachable. Anyway, it has to be displayed as for the classical
5285  Sequential View: */
5286  if (! exit_node_has_been_displayed) {
5287  /* Note that since the controlizer adds a dummy successor to the
5288  exit node, use
5289  output_a_graph_view_of_the_unstructured_from_a_control()
5290  instead of
5291  output_a_graph_view_of_the_unstructured_successors(): */
5293  module,
5294  margin,
5295  end_control,
5296  end_control);
5297  /* Even if the code is unreachable, add the fact that the
5298  control above is semantically related to the entry node. Add
5299  a dash arrow from the entry node to the exit node in daVinci,
5300  for example: */
5303  add_control_node_identifier_to_text(r, begin_control);
5305  add_control_node_identifier_to_text(r, end_control);
5307  if (get_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH_VERBOSE"))
5308  add_one_unformated_printf_to_text(r, "C Unreachable exit node (%p -> %p)\n",
5309  begin_control,
5310  end_control);
5311  }
5312 
5315  add_control_node_identifier_to_text(r, begin_control);
5316  add_one_unformated_printf_to_text(r, " end: ");
5317  add_control_node_identifier_to_text(r, end_control);
5319 }
5320 
5321 
5322 /* ================C prettyprinter functions================= */
5323 
5324 static list words_cast(cast obj, int precedence, list * ppdl)
5325 {
5326  list pc = NIL;
5327  type t = cast_type(obj);
5329  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
5330 
5331  pc = CHAIN_SWORD(pc,"(");
5332  pc = gen_nconc(pc, c_words_entity(t, NIL, ppdl));
5333  pc = CHAIN_SWORD(pc, space_p? ") " : ")");
5335  if(get_bool_property("PRETTYPRINT_ALL_PARENTHESES") || precedence >= 25) {
5336  pc = CONS(STRING, strdup("("),
5337  gen_nconc(pc,CONS(STRING, strdup(")"), NIL)));
5338  }
5339  return pc;
5340 }
5341 
5343  bool in_type_declaration,
5344  list * ppdl)
5345 {
5346  list pc = NIL;
5347  switch(get_prettyprint_language_tag()) {
5348  case is_language_fortran:
5349  case is_language_fortran95:
5350  pips_user_warning("generating FORTRAN 2008 function call defined in the the module ISO_C_BINDING\n");
5351  pc = CHAIN_SWORD(pc,"c_sizeof(");
5352  break;
5353  case is_language_c:
5354  pc = CHAIN_SWORD(pc,"sizeof(");
5355  break;
5356  default:
5357  pips_internal_error("Language unknown !");
5358  break;
5359  }
5360  if (sizeofexpression_type_p(obj)) {
5361  type t = sizeofexpression_type(obj);
5362  /* FI: the test used below is probably too strict I believe, because
5363  dimensions are not allowed, but I may be wrong*/
5364  if(derived_type_p(t)) {
5366  if(gen_in_list_p((void *) te, *ppdl)) {
5367  list pca = words_type(sizeofexpression_type(obj), ppdl, false);
5368  pc = gen_nconc(pc, pca);
5369  }
5370  else {
5371  /* The type must be fully declared: see struct15.c */
5372  list pct = c_words_simplified_entity(t, NIL, true, in_type_declaration, ppdl);
5373  pc = gen_nconc(pc, pct);
5374  *ppdl = gen_once((void *) te, *ppdl);
5375  }
5376  }
5377  else {
5378  list pca = words_type(sizeofexpression_type(obj), ppdl, false);
5379  pc = gen_nconc(pc, pca);
5380  }
5381  }
5382  else
5384  pc = CHAIN_SWORD(pc,")");
5385  return pc;
5386 }
5387 
5388 static list words_subscript(subscript s, list * ppdl)
5389 {
5390  list pc = NIL;
5391  expression a = subscript_array(s);
5393  bool first = true;
5394 
5395  /* Parentheses must be added for array expression
5396  * like __ctype+1 in (__ctype+1)[*np]
5397  */
5398 
5399  /* Here we differentiate the indices parenthesis syntax */
5400  switch(get_prettyprint_language_tag()) {
5401  case is_language_fortran:
5402  pips_internal_error("We don't know how to prettyprint a subscript in "
5403  "Fortran, aborting");
5404  case is_language_fortran95: {
5405  bool allocatable_p = expression_allocatable_data_access_p(a);
5406  pips_assert("We don't know how to prettyprint a subscript in Fortran95 "
5407  "and it's not an allocatable",
5408  allocatable_p );
5409  pc = gen_nconc(pc, words_expression(a, ppdl));
5410  if(!ENDP(lexp)) {
5411  pc = CHAIN_SWORD(pc,"(");
5412  }
5413  break;
5414  }
5415  case is_language_c:
5416  pc = CHAIN_SWORD(pc,"(");
5417  pc = gen_nconc(pc, words_expression(a, ppdl));
5418  pc = CHAIN_SWORD(pc,")");
5419  if(!ENDP(lexp)) {
5420  pc = CHAIN_SWORD(pc,"[");
5421  }
5422  break;
5423  default:
5424  pips_internal_error("Language unknown !");
5425  break;
5426  }
5427 
5428  /* Print now the indices list */
5430  if(!first) {
5431  switch(get_prettyprint_language_tag()) {
5432  case is_language_fortran:
5433  case is_language_fortran95:
5434  pc = CHAIN_SWORD(pc, ",");
5435  break;
5436  case is_language_c:
5437  pc = CHAIN_SWORD(pc,"][");
5438  break;
5439  default:
5440  pips_internal_error("Language unknown !");
5441  break;
5442  }
5443  }
5444  pc = gen_nconc(pc, words_expression(exp, ppdl));
5445  first = false;
5446  }
5447 
5448  /* Here we differentiate the indices syntax */
5449  switch(get_prettyprint_language_tag()) {
5450  case is_language_fortran:
5451  case is_language_fortran95:
5452  if(!ENDP(lexp)) {
5453  pc = CHAIN_SWORD(pc,")");
5454  }
5455  break;
5456  case is_language_c:
5457  if(!ENDP(lexp)) {
5458  pc = CHAIN_SWORD(pc,"]");
5459  }
5460  break;
5461  default:
5462  pips_internal_error("Language unknown !");
5463  break;
5464  }
5465 
5466 
5467  return pc;
5468 }
5469 
5470 static list words_application(application a, list * ppdl)
5471 {
5472  list pc = NIL;
5475  bool first = true;
5476  /* Parentheses must be added for function expression */
5477  pc = CHAIN_SWORD(pc,"(");
5478  pc = gen_nconc(pc, words_expression(f, ppdl));
5479  pc = CHAIN_SWORD(pc,")(");
5480  MAP(EXPRESSION,exp,
5481  {
5482  if (!first)
5483  pc = CHAIN_SWORD(pc,",");
5484  pc = gen_nconc(pc, words_expression(exp, ppdl));
5485  first = false;
5486  },lexp);
5487  pc = CHAIN_SWORD(pc,")");
5488  return pc;
5489 }
5490 
5492  const char* label,
5493  int margin,
5494  forloop obj,
5495  int n,
5496  list * ppdl,
5497  bool is_recursive_p)
5498 {
5499  list pc = NIL;
5500  unformatted u;
5501  text r = make_text(NIL);
5502  statement body = forloop_body(obj) ;
5503  //instruction i = statement_instruction(body);
5504  bool braces_p = !one_liner_p(body) || prettyprint_all_c_braces_p;
5505 
5506  pc = CHAIN_SWORD(pc,"for (");
5508  pc = gen_nconc(pc, words_expression(forloop_initialization(obj), ppdl));
5511  /* To restitute for(;;) */
5512  expression cond = forloop_condition(obj);
5513  if(!expression_one_p(cond))
5514  pc = gen_nconc(pc, words_expression(forloop_condition(obj), ppdl));
5515  }
5518  pc = gen_nconc(pc, words_expression(forloop_increment(obj), ppdl));
5519  pc = CHAIN_SWORD(pc,!braces_p?")":") {");
5520  u = make_unformatted(strdup(label), n, margin, pc) ;
5522 
5523  if(is_recursive_p) {
5524  if(!braces_p) {
5526  margin+INDENTATION,
5527  body,
5528  !one_liner_p(body),
5529  !one_liner_p(body),
5530  ppdl));
5531  }
5532  else {
5533  // ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin,"{"));
5534  MERGE_TEXTS(r, text_statement(module, margin+INDENTATION, body, ppdl));
5536  }
5537  }
5538 
5539  return r;
5540 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
void user_log(const char *format,...)
Definition: message.c:234
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
call copy_call(call p)
CALL.
Definition: ri.c:233
void free_expression(expression p)
Definition: ri.c:853
void free_basic(basic p)
Definition: ri.c:107
unformatted make_unformatted(string a1, intptr_t a2, intptr_t a3, list a4)
Definition: text.c:149
sentence make_sentence_unformatted(unformatted _field_)
Definition: text.c:65
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
text make_text(list a)
Definition: text.c:107
void free_text(text p)
Definition: text.c:74
static int count
Definition: SDG.c:519
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static FILE * out
Definition: alias_check.c:128
void const char const char const int
static list lexp
sentence attach_head_to_sentence(sentence s, entity module)
Attach the PROGRAM/FUNCTION head:
void attach_decoration_to_text(text t)
Attach a decoration:
void attach_reference_to_word_list(string begin_word, string end_word, reference r)
Attach a module usage (CALL or function call):
void attach_regular_call_to_word(string word, call c)
Attach a reference:
void attach_statement_information_to_text(text t, statement s)
Attach some statement information to text:
void attach_loop_to_sentence_up_to_end_of_text(sentence s, text t, loop l)
The user interface:
static int num
Definition: bourdoncle.c:137
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
text text_loop_cmf(entity module, const char *label, int margin, loop obj, int n, list lr, list lidx)
=====================================================================
Definition: cmfortran.c:66
text text_loop_craft(entity module, const char *label, int margin, loop obj, int n, list lr, list lidx)
=====================================================================
Definition: craft.c:92
text text_initializations(entity m)
text text_declaration(entity module)
exported for hpfc.
#define ret(why, what)
true if not a remapping for old.
Definition: dynamic.c:986
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
bool empty_string_p(const char *s)
Definition: entity_names.c:239
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....
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
#define STRING(x)
Definition: genC.h:87
void * malloc(YYSIZE_T)
void free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool instruction_assign_p(instruction i)
Test if an instruction is an assignment.
Definition: instruction.c:164
bool instruction_continue_p(instruction i)
Test if an instruction is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: instruction.c:173
bool return_instruction_p(instruction i)
Test if an instruction is a C or Fortran "return".
Definition: instruction.c:185
list loop_private_variables_as_entites(loop obj, bool local, bool index)
Get the variables local or private to a loop.
Definition: loop.c:338
#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
#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
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list l)
Definition: list.c:150
void gen_free_string_list(list ls)
Definition: list.c:564
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#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
list gen_copy_string_list(list ls)
of string
Definition: list.c:556
#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
statement effective_test_true(test)
returns the effective true branch of a test by skipping a possible sequence of one element.
Definition: statement.c:1358
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
test statement_test(statement)
Get the test of a statement.
Definition: statement.c:1348
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
unstructured statement_unstructured(statement stat)
Get the unstructured of a statement.
Definition: statement.c:1416
bool unlabelled_statement_p(statement)
Definition: statement.c:402
bool statement_test_p(statement)
Definition: statement.c:343
bool statement_call_p(statement)
Definition: statement.c:364
bool nop_statement_p(statement)
Definition: statement.c:407
bool empty_statement_p(statement)
Test if a statement is empty.
Definition: statement.c:391
bool statement_sequence_p(statement)
Statement classes induced from instruction type.
Definition: statement.c:335
bool statement_unstructured_p(statement)
Definition: statement.c:369
string statement_identification(statement)
Like external_statement_identification(), but with internal information, the hexadecimal address of t...
Definition: statement.c:1700
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
bool statement_with_pragma_p(statement)
Test if a statement has some pragma.
Definition: statement.c:3836
list statement_to_direct_declarations(statement)
Returns the declarations contained directly in a statement s.
Definition: statement.c:3366
bool continue_statement_p(statement)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
statement make_return_statement(entity)
Definition: statement.c:779
list declaration_statement_to_initializations(statement)
Definition: statement.c:1128
bool empty_comments_p(const char *)
Definition: statement.c:107
bool statement_with_empty_comment_p(statement)
Return true if the statement has an empty statement:
Definition: statement.c:126
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
static GtkWidget * lines[HELP_LINES]
Definition: gtk_help.c:47
char end
Definition: gtk_status.c:82
static Value eval(Pvecteur pv, Value val, Variable var)
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
bool prettyprint_language_is_fortran95_p()
Definition: language.c:83
void set_prettyprint_language_from_property(enum language_utype native)
set the prettyprint language according to the property PRETTYPRINT_LANGUAGE @description If the prope...
Definition: language.c:103
language get_prettyprint_language()
please avoid using this function directly, use predicate instead (see below)
Definition: language.c:57
bool prettyprint_language_is_c_p()
Definition: language.c:91
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
bool prettyprint_language_is_fortran_p()
Definition: language.c:75
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define asprintf
Definition: misc-local.h:225
#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 debug_off()
Definition: misc-local.h:160
#define LABEL_PREFIX
Definition: naming-local.h:31
#define RETURN_LABEL_NAME
Definition: naming-local.h:106
#define LIST_DIRECTED_FORMAT_NAME
Definition: naming-local.h:97
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
string gen_strndup0(string, size_t)
Like strdup() but copy at most n characters.
Definition: string.c:83
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ hash_string
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
#define same_string_p(s1, s2)
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
void set_free(set)
Definition: set.c:332
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define string_undefined_p(s)
Definition: newgen_types.h:41
intptr_t _int
_INT
Definition: newgen_types.h:53
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
text c_text_related_entities(entity module, list del, int margin, int sn, list *ppdl, list cl)
It is assumed that all entities in list el can be declared by an unique statement,...
text c_text_entities(entity module, list ldecl, int margin, list *ppdl)
Generate declarations for a list of entities belonging to the same statement declaration.
list c_words_simplified_entity(type t, list name, bool is_first, bool in_type_declaration, list *ppdl)
The declaration list pointer ppdl is passed down to determine if an internal derived type must be ful...
list words_declaration(entity e, bool prettyprint_common_variable_dimensions_p, list *ppdl)
some compilers don't like dimensions that are declared twice.
Definition: declarations.c:277
sentence sentence_head(entity e, list *ppdl)
We have no way to distinguish between the SUBROUTINE and PROGRAM They two have almost the same proper...
Definition: declarations.c:601
list words_type(type obj, list *ppdl, bool argument_p)
obj is the type to describe
Definition: declarations.c:821
list c_words_entity(type t, list name, list *ppdl)
list words_brace_expression(expression exp, list *ppdl)
Definition: declarations.c:910
string close_extensions(extensions es, bool nl)
Definition: extension.c:58
string extensions_to_string(extensions es, bool nl)
return a new allocated string with the string representation of the extensions.
Definition: extension.c:111
text text_loop_90(entity module, const char *label, int margin, loop obj, int n)
Generate range subscript for simple loop with only one assignment.
Definition: fortran90.c:77
list C_loop_range(range obj, entity i, list *ppdl)
Output a Fortan-like do-loop range as a C-like for-loop index part.
Definition: misc.c:457
#define CAST_OPERATOR_PRECEDENCE
static text text_hpf_directive(loop l, int m)
Definition: misc.c:3066
static bool pp_style_p(string s)
Definition: misc.c:204
static sentence sentence_tail(entity e)
Definition: misc.c:2710
list Words_Any_Reference(reference obj, list pdl, const char *(*enf)(entity))
Definition: misc.c:773
static list words_assign_substring_op(call obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1227
static text text_block(entity module, const char *label, int margin, list objs, int n, list *ppdl)
Build the text of a code block (a list of statements)
Definition: misc.c:2826
static list words_brace_op(call obj, int precedence __attribute__((unused)), bool leftmost __attribute__((unused)), list *ppdl)
Definition: misc.c:2091
#define pp_cray_style_p()
Definition: misc.c:211
#define OMP_CONTINUATION
Definition: misc.c:3076
static list words_nullary_op_c(call obj, int precedence __attribute__((unused)), bool leftmost __attribute__((unused)), list *ppdl)
Definition: misc.c:1330
static list words_sizeofexpression(sizeofexpression obj, bool in_type_declaration, list *ppdl)
static bool precedence_p
This variable is used to disable the precedence system and hence to prettyprint all parentheses,...
Definition: misc.c:194
static text text_directive(loop obj, int margin, string basic_directive, string basic_continuation, string parallel, list *ppdl)
Definition: misc.c:3005
static struct intrinsic_handler tab_intrinsic_handler[]
static hash_table intrinsic_handlers
Definition: misc.c:2502
static list words_omp_red(call obj, int precedence __attribute__((unused)), bool leftmost __attribute__((unused)), list *ppdl)
Definition: misc.c:1293
list eole_fms_specific_op(call obj, int precedence, bool leftmost, list *ppdl)
MULTIPLY-SUB operator.
Definition: misc.c:2056
#define pp_cmf_style_p()
Definition: misc.c:212
static text text_block_elseif(entity module, const char *label, int margin, test obj, int n, list *ppdl)
Definition: misc.c:3715
list eole_fma_specific_op(call obj, int precedence, bool leftmost, list *ppdl)
EOLE : The multiply-add operator is used within the optimize transformation ( JZ - sept 98) - fma(a,...
Definition: misc.c:2049
list words_subscript_range(range obj, list *ppdl)
@description FI: array constructor R433, p.
Definition: misc.c:629
char lib_ri_util_prettyprint_c_rcsid[]
misc.c
Definition: misc.c:29
list words_subexpression(expression obj, int precedence, bool leftmost, list *ppdl)
exported for cmfortran.c
Definition: misc.c:2674
static list words_nullary_op_fortran(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1405
static list eole_fmx_specific_op(call obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, bool isadd, list *ppdl)
Definition: misc.c:1996
static list words_io_inst(call obj, int precedence, bool leftmost, list *ppdl)
Definition: misc.c:1573
#define HPF_INDEPENDENT
Definition: misc.c:3064
#define PRETTYPRINT_UNREACHABLE_EXIT_MARKER
Definition: misc.c:147
string get_comment_sentinel()
Start a single line comment.
Definition: misc.c:154
static bool test_with_no_else_clause_p(test t)
Definition: misc.c:3572
static list words_cast(cast obj, int precedence, list *ppdl)
#define pp_doall_style_p()
Definition: misc.c:213
static list words_intrinsic_call(call obj, int precedence, bool leftmost, list *ppdl)
Definition: misc.c:2525
list words_goto_label(const char *tlabel)
This function is useful only for parsed codes since gotos are removed by the controlizer.
Definition: misc.c:1917
void set_alternate_return_set()
Definition: misc.c:795
list words_any_reference(reference obj, list *ppdl, const char *(*enf)(entity))
exported for expression.c
Definition: misc.c:704
void reset_prettyprinter_head_hook()
Definition: misc.c:3964
#define pp_craft_style_p()
Definition: misc.c:210
list Words_Subexpression(expression obj, int precedence, bool leftmost)
Definition: misc.c:2695
#define MAXIMAL_PRECEDENCE
lint
Definition: misc.c:138
list words_call_intrinsic(call obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1109
#define PRETTYPRINT_UNSTRUCTURED_SUCC_MARKER
Definition: misc.c:146
text empty_text(entity __attribute__((unused)) e, int __attribute__((unused)) m, statement __attribute__((unused)) s)
Definition: misc.c:219
string get_comment_continuation()
Start a single line comment with continuation (blank spaces)
Definition: misc.c:167
list words_syntax(syntax obj, list *ppdl)
exported for expression.c
Definition: misc.c:2623
#define PRETTYPRINT_UNSTRUCTURED_ITEM_MARKER
Definition: misc.c:145
void reset_alternate_return_set()
Definition: misc.c:804
static void init_intrinsic_handlers()
Definition: misc.c:2504
text text_loop(entity module, const char *label, int margin, loop obj, int n, list *ppdl, bool is_recursive_p)
exported for conversion/look_for_nested_loops.c
Definition: misc.c:3264
static string marged(string prefix, int margin)
returns a formatted text for the HPF independent and new directive well, no continuations and so,...
Definition: misc.c:2989
bool gcc_if_block_braces_required_p(test obj)
Definition: misc.c:336
#define HPF_CONTINUATION
Definition: misc.c:3063
#define OMP_C_CONTINUATION
Definition: misc.c:3080
#define HPF_DIRECTIVE
Definition: misc.c:3062
unsigned int get_prettyprint_indentation()
Definition: misc.c:177
static list words_infix_binary_op(call obj, int precedence, bool leftmost, list *ppdl)
Definition: misc.c:2176
static text text_io_block_if(entity module, const char *label, int margin, test obj, int n, list *ppdl)
Definition: misc.c:3859
void close_prettyprint()
because some prettyprint functions may be used for debug, so the last hook set by somebody may have s...
Definition: misc.c:242
#define pp_f90_style_p()
Definition: misc.c:209
static list loop_private_variables(loop obj, list *ppdl)
of string
Definition: misc.c:2906
list Words_Call(call obj, int precedence, bool leftmost, bool is_a_subroutine)
Definition: misc.c:2597
static const char * get_special_prettyprint_for_operator(call obj)
Check if the given operator is associated with a special prettyprint.
Definition: misc.c:2066
static list words_substring_op(call obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1187
static text text_logical_if(entity __attribute__((unused)) module, const char *label, int margin, test obj, int n, list *ppdl, bool is_recursive_p)
Definition: misc.c:3504
static sentence sentence_goto(entity module, const char *label, int margin, statement obj, int n)
Definition: misc.c:2797
static text text_test(entity module, const char *label, int margin, test obj, int n, list *ppdl, bool is_recursive_p)
Definition: misc.c:3913
static list set_of_labels_required_for_alternate_returns
Management of alternate returns.
Definition: misc.c:793
static text local_var
Definition: misc.c:356
static list words_unbounded_dimension(call __attribute__((unused)) obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list __attribute__((unused)) *ppdl)
Definition: misc.c:1547
static list words_infix_nary_op(call obj, int precedence, bool leftmost, list *ppdl)
Extension of "words_infix_binary_op" function for nary operators used in the EOLE project - (since "n...
Definition: misc.c:2107
static string ensure_comment_consistency(const char *i_comments, language l)
return a formatted comment, that takes care of adding the relevant // or C depending on output langua...
Definition: misc.c:4308
#define PRETTYPRINT_UNSTRUCTURED_BEGIN_MARKER
Define the markers used in the raw unstructured output when the PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH p...
Definition: misc.c:143
list words_range(range obj, list *ppdl)
Definition: misc.c:538
#define pp_hpf_style_p()
Definition: misc.c:208
bool one_liner_p(statement s)
True is statement "s" can be printed out without enclosing braces when it is the true branch of a tes...
Definition: misc.c:301
static list words_list_directed(call __attribute__((unused)) obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list __attribute__((unused)) *ppdl)
Definition: misc.c:1560
static text text_block_if(entity module, const char *label, int margin, test obj, int n, list *ppdl, bool is_recursive_p)
Prettyprint the condition, the true and, possibly, the false branch.
Definition: misc.c:3795
list words_call(call obj, int precedence, bool leftmost, bool is_a_subroutine, list *ppdl)
exported for cmfortran.c
Definition: misc.c:2575
static list words_application(application a, list *ppdl)
bool C_comment_p(string c)
In case the input code is not C code, non-standard comments have to be detected.
Definition: misc.c:4094
static string(* head_hook)(entity)
hook for adding something in the head.
Definition: misc.c:3962
static text text_block_else(entity module, const char *label __attribute__((unused)), int margin, statement stmt, int n __attribute__((unused)), list *ppdl)
Definition: misc.c:3664
static list words_assign_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1118
static list words_prefix_unary_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1781
void set_prettyprinter_head_hook(string(*f)(entity))
Definition: misc.c:3963
static text text_block_ifthen(entity module, const char *label, int margin, test obj, int n, list *ppdl, bool is_recursive_p)
Prettyprint if clause of a test.
Definition: misc.c:3603
static text text_whileloop(entity module, const char *label, int margin, whileloop obj, int n, list *ppdl, bool is_recursive_p)
Definition: misc.c:3341
static text insert_locals(text r)
This function either appends the declaration to the text given as a parameter or return a new text wi...
Definition: misc.c:363
text text_loop_default(entity module, const char *label, int margin, loop obj, int n, list *ppdl, bool is_recursive_p)
exported for fortran90.c
Definition: misc.c:3118
static bool prettyprint_gcc_c_braces_p
This variable is used to gracefuly print braces around if / else blocks to avoid gcc warnings.
Definition: misc.c:200
text C_any_comment_to_text(int r_margin, string c)
In case comments are not formatted according to C rules, e.g.
Definition: misc.c:4165
text generate_alternate_return_targets()
Definition: misc.c:824
static list words_subscript(subscript s, list *ppdl)
static bool local_flg
Definition: misc.c:357
text text_omp_directive(loop l, int m)
Definition: misc.c:3084
#define pp_omp_style_p()
Definition: misc.c:215
static list words_genuine_regular_call(call obj, bool is_a_subroutine, list *ppdl)
To deal with attachment on user module usage.
Definition: misc.c:1090
static int words_intrinsic_precedence(call)
Definition: misc.c:2552
#define PRETTYPRINT_UNSTRUCTURED_END_MARKER
Definition: misc.c:144
static list words_inverse_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
WARNING : the floating point division is used wether b is an int or not ! (1.0/b) – in fact b should ...
Definition: misc.c:1892
static list words_comma_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Nga Nguyen : this case is added for comma expression in C, but I am not sure about its precedence => ...
Definition: misc.c:2285
static list words_va_arg(list obj, list *ppdl)
Definition: misc.c:2558
list Words_Regular_Call(call obj, bool is_a_subroutine)
Definition: misc.c:1081
list Words_Syntax(syntax obj)
Definition: misc.c:2664
static list cstrsplit(const char *s, char delim)
Split string into a list of strings according to a separator, delim.
Definition: misc.c:4286
list words_expression(expression obj, list *ppdl)
This one is exported.
Definition: misc.c:2611
static text text_instruction(entity module, const char *label, int margin, instruction obj, int n, list *ppdl, bool is_recursive_p)
Definition: misc.c:3966
list words_regular_call(call obj, bool is_a_subroutine, list *ppdl)
words_regular_call used for user subroutine and user function and intrinsics called like user functio...
Definition: misc.c:868
list Words_Expression(expression obj)
of string
Definition: misc.c:2616
list words_loop_range(range obj, list *ppdl)
exported for craft
Definition: misc.c:434
void register_intrinsic_handler(const char *name, intrinsic_desc_t *desc)
after this call, name and desc are owned by intrinsic_handlers, but will never be deallocated they mu...
Definition: misc.c:2517
static list words_conditional_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:2308
text init_text_statement(entity module, int margin, statement obj)
exported for unstructured.c
Definition: misc.c:3462
void init_prettyprint(text(*hook)(entity, int, statement))
checks that the prettyprint hook was actually reset...
Definition: misc.c:231
#define OMP_C_DIRECTIVE
Definition: misc.c:3079
static bool test_with_dangling_else_p(test t)
Some code shared by text_block_if and text_block_ifthen.
Definition: misc.c:3588
static int intrinsic_precedence(const char *)
Definition: misc.c:2539
static text(* text_statement_hook)(entity, int, statement)
Definition: misc.c:225
#define MINIMAL_ARITHMETIC_PRECEDENCE
Definition: misc.c:139
text C_comment_to_text(int margin, string comment)
Special handling for C comments with each line indented according to the context.
Definition: misc.c:4270
static list words_nullary_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1445
static const char * renamed_op_handling(const char *name)
Definition: misc.c:1252
static list words_unary_minus(call obj, int precedence, bool leftmost, list *ppdl)
Definition: misc.c:1860
#define OMP_PARALLELDO
Definition: misc.c:3077
static text text_forloop(entity module, const char *label, int margin, forloop obj, int n, list *ppdl, bool is_recursive_p)
#define OMP_C_PARALLELDO
Definition: misc.c:3081
static bool mark_block(unformatted *t_beg, unformatted *t_end, int n, int margin)
This function returns true if BLOCK boundary markers are required.
Definition: misc.c:381
list Words_Reference(reference obj)
Definition: misc.c:786
list words_reference(reference obj, list *ppdl)
Definition: misc.c:781
sentence sentence_goto_label(entity __attribute__((unused)) module, const char *label, int margin, const char *tlabel, int n)
exported for unstructured.c
Definition: misc.c:2784
static list words_io_control(list *iol, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1467
static bool prettyprint_all_c_braces_p
This variable is used to print braces around all blocks including blocks with only one statement.
Definition: misc.c:197
static list words_stat_io_inst(call obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Implemented for ALLOCATE(), but is applicable for every call to function that take STAT= parameter.
Definition: misc.c:1727
static list words_implied_do(call obj, int __attribute__((unused)) precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1508
void add_target_to_alternate_return_set(entity l)
Definition: misc.c:814
text C_standard_comment_to_text(int margin, string comment)
Definition: misc.c:4237
static list words_postfix_unary_op(call obj, int precedence, bool __attribute__((unused)) leftmost, list *ppdl)
Definition: misc.c:1831
#define OMP_DIRECTIVE
Definition: misc.c:3075
text generic_text_statement_enclosed(entity, int, statement, bool, bool, list *, bool, bool)
text text_named_module(entity, entity, statement)
text Text_Statement(entity, int, statement)
text text_module(entity, statement)
statement find_last_statement(statement)
list initialize_previously_declared_entities(entity)
text text_statement(entity, int, statement, list *)
text text_unstructured(entity, const char *, int, unstructured, int, list *)
unstructured.c
Definition: unstructured.c:55
string proper_statement_to_string(statement)
void add_control_node_identifier_to_text(text, control)
void output_a_graph_view_of_the_unstructured(text, entity, const char *, int, unstructured, int)
text text_statement_enclosed(entity, int, statement, bool, bool, list *)
bool last_statement_p(statement)
void reset_last_statement(void)
text Text_Proper_Statement(entity, int, statement)
text Text_Statement_Enclosed(entity, int, statement, bool, bool)
void output_a_graph_view_of_the_unstructured_successors(text, entity, int, control)
list unstructured_to_trail(unstructured)
Definition: unstructured.c:240
void insure_return_as_last_statement(entity, statement *)
bool output_a_graph_view_of_the_unstructured_from_a_control(text, entity, int, control, control)
void set_last_statement(statement)
#define PRETTYPRINT_PARALLEL
static const char * prefix
#define UNBOUNDED_DIMENSION_NAME
Definition: ri-util-local.h:74
#define C_STATEMENT_END_STRING
#define BITWISE_OR_OPERATOR_NAME
#define POWER_OPERATOR_NAME
#define ISOC99_VFSCANF_USER_FUNCTION_NAME
#define POST_DECREMENT_OPERATOR_NAME
Definition: ri-util-local.h:98
#define PRINT_FUNCTION_NAME
#define ENTITY_DIVIDE_P(e)
#define BITWISE_XOR_OPERATOR_NAME
#define C_LESS_OR_EQUAL_OPERATOR_NAME
#define ENTITY_ALLOCATABLE_BOUND_P(e)
#define instruction_block_p(i)
#define ENTITY_ISOC99_VFSCANF_P(e)
#define READ_FUNCTION_NAME
#define C_AND_OPERATOR_NAME
#define GREATER_THAN_OPERATOR_NAME
#define ENDFILE_FUNCTION_NAME
#define C_GREATER_OR_EQUAL_OPERATOR_NAME
#define BITWISE_OR_UPDATE_OPERATOR_NAME
#define SUBSTRING_FUNCTION_NAME
#define EOLE_FMA_OPERATOR_NAME
These operators are used within the optimize transformation in order to manipulate operators such as ...
#define C_CONTINUE_FUNCTION_NAME
#define ENTITY_ASSIGN_P(e)
#define C_GREATER_THAN_OPERATOR_NAME
#define C_MODULO_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define LESS_THAN_OPERATOR_NAME
#define ENTITY_IMPLIED_DCMPLX_P(e)
#define EQUIV_OPERATOR_NAME
#define DIVIDE_UPDATE_OPERATOR_NAME
#define ISOC99_SSCANF_USER_FUNCTION_NAME
#define COMMA_OPERATOR_NAME
#define MODULO_UPDATE_OPERATOR_NAME
#define POINT_TO_OPERATOR_NAME
Definition: ri-util-local.h:92
#define PLUS_OPERATOR_NAME
#define ENTITY_TRUE_P(e)
#define ORDERING_NUMBER(o)
#define ENTITY_ISOC99_SSCANF_P(e)
#define ORDERING_STATEMENT(o)
#define EQUAL_OPERATOR_NAME
#define ISOC99_VSCANF_USER_FUNCTION_NAME
#define statement_block_p(stat)
#define RETURN_FUNCTION_NAME
#define BACKSPACE_FUNCTION_NAME
#define DEREFERENCING_OPERATOR_NAME
Definition: ri-util-local.h:93
#define PIPS_C_MAX_OPERATOR_NAME
#define FIELD_OPERATOR_NAME
Definition: ri-util-local.h:91
#define NON_EQUIV_OPERATOR_NAME
#define C_NON_EQUAL_OPERATOR_NAME
#define LEFT_SHIFT_UPDATE_OPERATOR_NAME
#define IMS_OPERATOR_NAME
#define ISOC99_VSSCANF_USER_FUNCTION_NAME
#define ISOC99_FSCANF_USER_FUNCTION_NAME
#define REWIND_FUNCTION_NAME
#define STATEMENT_NUMBER_UNDEFINED
default values
#define MULTIPLY_UPDATE_OPERATOR_NAME
#define ENTITY_ISOC99_SCANF_P(e)
#define OPEN_FUNCTION_NAME
#define END_FUNCTION_NAME
#define INVERSE_OPERATOR_NAME
#define LEFT_SHIFT_OPERATOR_NAME
#define CONDITIONAL_OPERATOR_NAME
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define C_RETURN_FUNCTION_NAME
#define AND_OPERATOR_NAME
FI: intrinsics are defined at a third place after bootstrap and effects! I guess the name should be d...
#define MINUS_UPDATE_OPERATOR_NAME
#define EOLE_FMS_OPERATOR_NAME
#define C_NOT_OPERATOR_NAME
#define OMP_FOR_FUNCTION_NAME
#define is_instruction_block
soft block->sequence transition
#define ENTITY_MAX_P(e)
#define CONTINUE_FUNCTION_NAME
#define ALLOCATE_FUNCTION_NAME
F95.
#define ADDRESS_OF_OPERATOR_NAME
#define ENTITY_VA_END_P(e)
Defined elsewhere: #define ENTITY_ADDRESS_OF_P(e) entity_an_operator_p(e, ADDRESS_OF)
#define PRE_DECREMENT_OPERATOR_NAME
#define ENTITY_VA_START_P(e)
#define OMP_OMP_FUNCTION_NAME
#define OMP_PARALLEL_FUNCTION_NAME
#define DIVIDE_OPERATOR_NAME
#define WRITE_FUNCTION_NAME
#define CLOSE_FUNCTION_NAME
#define UNARY_MINUS_OPERATOR_NAME
#define BITWISE_XOR_UPDATE_OPERATOR_NAME
#define CONCATENATION_FUNCTION_NAME
#define EOLE_PROD_OPERATOR_NAME
#define PIPS_C_MIN_OPERATOR_NAME
PIPS run-time support for C code generation.
#define IMA_OPERATOR_NAME
Integer Multiply Add and Sub, FC 27/10/2005 for FI.
#define UNARY_PLUS_OPERATOR_NAME
#define BRACE_INTRINSIC
Definition: ri-util-local.h:85
#define RIGHT_SHIFT_UPDATE_OPERATOR_NAME
#define INDENTATION
#define C_LESS_THAN_OPERATOR_NAME
#define BITWISE_NOT_OPERATOR_NAME
#define ENTITY_MIN_P(e)
#define ENTITY_ISOC99_FSCANF_P(e)
#define GREATER_OR_EQUAL_OPERATOR_NAME
#define STOP_FUNCTION_NAME
#define PRE_INCREMENT_OPERATOR_NAME
Definition: ri-util-local.h:99
#define EOLE_SUM_OPERATOR_NAME
#define ENTITY_VA_COPY_P(e)
#define POST_INCREMENT_OPERATOR_NAME
Definition: ri-util-local.h:97
#define ASSIGN_OPERATOR_PRECEDENCE
Definition: ri-util-local.h:96
#define ENTITY_ISOC99_VSSCANF_P(e)
#define ENTITY_IMPLIED_CMPLX_P(e)
#define PLUS_UPDATE_OPERATOR_NAME
#define ENTITY_ISOC99_VSCANF_P(e)
#define instruction_block(i)
#define PAUSE_FUNCTION_NAME
#define FORMAT_FUNCTION_NAME
#define IO_LIST_STRING_NAME
Definition: ri-util-local.h:82
#define ENTITY_FALSE_P(e)
#define MINUS_C_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
#define BITWISE_AND_UPDATE_OPERATOR_NAME
#define LESS_OR_EQUAL_OPERATOR_NAME
#define C_OR_OPERATOR_NAME
#define BITWISE_AND_OPERATOR_NAME
#define OMP_REDUCTION_FUNCTION_NAME
#define RIGHT_SHIFT_OPERATOR_NAME
#define DEALLOCATE_FUNCTION_NAME
#define INQUIRE_FUNCTION_NAME
#define NOT_OPERATOR_NAME
#define IMPLIED_DO_FUNCTION_NAME
Definition: ri-util-local.h:76
#define ISOC99_SCANF_USER_FUNCTION_NAME
#define ASSIGN_SUBSTRING_FUNCTION_NAME
#define OR_OPERATOR_NAME
#define NON_EQUAL_OPERATOR_NAME
#define C_EQUAL_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
#define PLUS_C_OPERATOR_NAME
bool expression_allocatable_data_access_p(expression e)
Check if an expression is a reference to an allocatable array.
Definition: allocatable.c:95
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
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
bool entity_return_label_p(entity e)
Definition: entity.c:673
char * new_label_local_name(entity module)
Definition: entity.c:326
bool label_string_defined_in_current_module_p(string ls)
Definition: entity.c:407
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
code entity_code(entity e)
Definition: entity.c:1098
bool entity_main_module_p(entity e)
Definition: entity.c:700
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
void print_entities(list l)
Definition: entity.c:167
bool entity_blockdata_p(entity e)
Definition: entity.c:712
bool entity_empty_label_p(entity e)
Definition: entity.c:666
bool io_entity_p(entity e)
Several implicit entities are declared to define the implicit effects of IO statements.
Definition: entity.c:1139
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
bool entity_f95module_p(entity e)
Definition: entity.c:707
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
void reset_label_counter()
Definition: entity.c:322
set get_referenced_entities(void *elem)
retrieves the set of entities used in elem beware that this entities may be formal parameters,...
Definition: entity.c:3063
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
bool positive_expression_p(expression e)
Use constants and type information to decide if the value of sigma(e) is always positive,...
Definition: eval.c:826
bool negative_expression_p(expression e)
Use constants and type information to decide if the value of sigma(e) is always negative,...
Definition: eval.c:896
bool expression_one_p(expression exp)
Definition: expression.c:2591
bool expression_call_p(expression e)
Definition: expression.c:415
bool expression_cast_p(expression e)
Definition: expression.c:450
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
cast expression_cast(expression e)
Definition: expression.c:455
bool brace_expression_p(expression e)
Return bool indicating if expression e is a brace expression.
Definition: expression.c:3384
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
bool empty_extensions_p(extensions es)
Definition: extension.c:50
sentence get_header_comments(entity module)
Get the header comments (before PROGRAM, FUNCTION,...) from the text declaration:
Definition: module.c:254
bool static_module_p(entity e)
Check if the given module entity is a static module.
Definition: module.c:80
bool void_function_p(entity m)
Check if m is a C void function or a Fortran subroutine.
Definition: module.c:538
entity function_to_return_value(entity m)
Returns the entity rv that carries the value returned by module m, when m is not a C void function or...
Definition: module.c:509
sentence get_declaration_comments(entity module)
Get all the declaration comments, that are comments from the PROGRAM, FUNCTION,...
Definition: module.c:275
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
type ultimate_type(type)
Definition: type.c:3466
type call_compatible_type(type)
returns the type necessary to generate or check a call to an object of type t.
Definition: type.c:3791
bool actual_label_replacement_p(expression)
Assumes that eap is a call.
Definition: variable.c:1811
list type_supporting_entities(list, type)
Definition: type.c:4347
bool unsigned_type_p(type)
Predicates on types.
Definition: type.c:2821
bool derived_type_p(type)
Returns true if t is of type struct, union or enum.
Definition: type.c:3104
bool call_contains_alternate_returns_p(call)
Definition: variable.c:1835
entity find_label_entity(const char *, const char *)
util.c
Definition: util.c:43
basic expression_basic(expression)
Definition: type.c:1115
#define type_functional_p(x)
Definition: ri.h:2950
#define execution_tag(x)
Definition: ri.h:1207
#define loop_body(x)
Definition: ri.h:1644
#define syntax_reference_p(x)
Definition: ri.h:2728
#define functional_result(x)
Definition: ri.h:1444
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define loop_execution(x)
Definition: ri.h:1648
#define basic_int_p(x)
Definition: ri.h:614
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define forloop_initialization(x)
Definition: ri.h:1366
#define instruction_loop_p(x)
Definition: ri.h:1518
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define basic_derived(x)
Definition: ri.h:640
#define SIZEOFEXPRESSION(x)
SIZEOFEXPRESSION.
Definition: ri.h:2364
#define sizeofexpression_type(x)
Definition: ri.h:2406
#define range_upper(x)
Definition: ri.h:2290
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define type_tag(x)
Definition: ri.h:2940
#define forloop_increment(x)
Definition: ri.h:1370
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define instruction_goto(x)
Definition: ri.h:1526
#define syntax_application(x)
Definition: ri.h:2748
#define test_false(x)
Definition: ri.h:2837
#define syntax_va_arg(x)
Definition: ri.h:2751
#define whileloop_evaluation(x)
Definition: ri.h:3166
#define type_variable(x)
Definition: ri.h:2949
#define type_statement_p(x)
Definition: ri.h:2941
#define code_declarations(x)
Definition: ri.h:784
#define syntax_range(x)
Definition: ri.h:2733
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define range_increment(x)
Definition: ri.h:2292
#define value_constant_p(x)
Definition: ri.h:3071
#define language_fortran95_p(x)
Definition: ri.h:1597
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define application_arguments(x)
Definition: ri.h:510
#define instruction_forloop_p(x)
Definition: ri.h:1536
#define subscript_indices(x)
Definition: ri.h:2563
#define instruction_undefined
Definition: ri.h:1454
#define statement_label(x)
Definition: ri.h:2450
#define entity_undefined_p(x)
Definition: ri.h:2762
#define language_c_p(x)
Definition: ri.h:1594
#define entity_undefined
Definition: ri.h:2761
#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_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define whileloop_label(x)
Definition: ri.h:3164
#define execution_sequential_p(x)
Definition: ri.h:1208
#define value_symbolic_p(x)
Definition: ri.h:3068
#define type_void_p(x)
Definition: ri.h:2959
#define entity_name(x)
Definition: ri.h:2790
#define test_true(x)
Definition: ri.h:2835
#define sequence_statements(x)
Definition: ri.h:2360
#define reference_indices(x)
Definition: ri.h:2328
#define statement_extensions(x)
Definition: ri.h:2464
#define syntax_sizeofexpression(x)
Definition: ri.h:2742
#define value_code(x)
Definition: ri.h:3067
#define instruction_sequence(x)
Definition: ri.h:1514
#define sizeofexpression_type_p(x)
Definition: ri.h:2404
#define instruction_forloop(x)
Definition: ri.h:1538
#define syntax_call(x)
Definition: ri.h:2736
#define control_successors(x)
Definition: ri.h:945
#define cast_type(x)
Definition: ri.h:745
#define loop_label(x)
Definition: ri.h:1646
#define unstructured_exit(x)
Definition: ri.h:3006
#define instruction_unstructured_p(x)
Definition: ri.h:1530
#define instruction_call_p(x)
Definition: ri.h:1527
#define loop_locals(x)
Definition: ri.h:1650
#define instruction_expression(x)
Definition: ri.h:1541
#define expression_undefined_p(x)
Definition: ri.h:1224
#define test_condition(x)
Definition: ri.h:2833
#define subscript_array(x)
Definition: ri.h:2561
#define instruction_whileloop(x)
Definition: ri.h:1523
#define application_function(x)
Definition: ri.h:508
#define range_lower(x)
Definition: ri.h:2288
#define whileloop_body(x)
Definition: ri.h:3162
#define code_decls_text(x)
Definition: ri.h:786
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_comments(x)
Definition: ri.h:2456
#define instruction_whileloop_p(x)
Definition: ri.h:1521
#define instruction_call(x)
Definition: ri.h:1529
#define syntax_subscript(x)
Definition: ri.h:2745
#define loop_range(x)
Definition: ri.h:1642
#define forloop_condition(x)
Definition: ri.h:1368
@ is_execution_parallel
Definition: ri.h:1190
@ is_execution_sequential
Definition: ri.h:1189
#define instruction_test_p(x)
Definition: ri.h:1515
#define call_arguments(x)
Definition: ri.h:711
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define statement_undefined_p(x)
Definition: ri.h:2420
@ is_type_void
Definition: ri.h:2904
@ is_type_variable
Definition: ri.h:2900
@ is_type_unknown
Definition: ri.h:2903
#define whileloop_condition(x)
Definition: ri.h:3160
#define syntax_range_p(x)
Definition: ri.h:2731
#define basic_string_p(x)
Definition: ri.h:629
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define statement_number(x)
Definition: ri.h:2452
#define code_language(x)
Definition: ri.h:792
#define instruction_goto_p(x)
Definition: ri.h:1524
#define expression_syntax(x)
Definition: ri.h:1247
#define language_fortran_p(x)
Definition: ri.h:1591
#define execution_parallel_p(x)
Definition: ri.h:1211
#define language_tag(x)
Definition: ri.h:1590
#define evaluation_before_p(x)
Definition: ri.h:1159
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567
#define loop_index(x)
Definition: ri.h:1640
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define instruction_expression_p(x)
Definition: ri.h:1539
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
static int line
FLEX_SCANNER.
Definition: scanner.c:852
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
static string buffer
Definition: string.c:113
char * strndup(char const *s, size_t n)
A replacement function, for systems that lack strndup.
Definition: strndup.c:26
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
for intrinsic registration
list(* f)(call, int, bool, list *)
precedence needed here According to the Precedence of Operators Arithmetic > Character > Relational >...
Definition: misc.c:2337
const char * name
Definition: misc.c:2338
intrinsic_desc_t desc
Definition: misc.c:2339
Definition: statement.c:54
#define CHAIN_SWORD(l, s)
#define MERGE_TEXTS(r, t)
#define MAKE_ONE_WORD_SENTENCE(m, s)
#define ADD_SENTENCE_TO_TEXT(t, p)
#define MAKE_SWORD(s)
void print_text(FILE *fd, text t)
Definition: print.c:195
void close_current_line(string, text, string)
Definition: util.c:235
void add_one_unformated_printf_to_text(text, string,...)
Definition: util.c:59
string words_join(list, const char *)
Definition: text_print.c:385
void add_to_current_line(string, const char *, string, text)
Definition: util.c:140
string text_to_string_nl(text)
Definition: text_print.c:455
#define sentence_undefined
Definition: text.h:42
#define unformatted_undefined
Definition: text.h:123
struct _newgen_struct_text_ * text
Definition: text.h:23
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define text_undefined
Definition: text.h:91
#define text_sentences(x)
Definition: text.h:113
@ is_sentence_formatted
Definition: text.h:57
@ is_sentence_unformatted
Definition: text.h:58
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
entity module_entity_to_compilation_unit_entity(entity m)
Retrieve the compilation unit containing a module definition.
Definition: module.c:116
static Menu_item close
Definition: xv_log.c:66