PIPS
statement.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "parser_private.h"
#include "c_syntax.h"
#include "resources.h"
#include "database.h"
#include "misc.h"
#include "text-util.h"
#include "prettyprint.h"
#include "properties.h"
#include "alias_private.h"
+ Include dependency graph for statement.c:

Go to the source code of this file.

Functions

void MakeCurrentModule (entity e)
 is used for switch statements also, because we do not distinguish a break in a loop or a switch More...
 
void ResetCurrentModule ()
 
void InitializeBlock ()
 
statement MakeBlock (list stmts)
 Create a block statement. More...
 
statement FindStatementFromLabel (entity l)
 
statement MakeLabeledStatement (string label, statement s, string comment)
 Construct a new statement from. More...
 
statement MakeGotoStatement (string label)
 
entity MakeCLabel (string s)
 
statement MakeWhileLoop (list lexp, statement s, bool before)
 
statement MakeForloop (expression e1, expression e2, expression e3, statement body)
 Create a for-loop statement with some parser-specific characteristics. More...
 
static forloop find_forloop_in_statement (statement s)
 Because a break in the forloop requires the generation of an extra label statement after the forloop. More...
 
statement MakeForloopWithIndexDeclaration (list decls, expression e2, expression e3, statement body)
 Create a C99 for-loop statement with a declaration as first parameter in the for clause, with some parser-specific characteristics. More...
 
statement MakeSwitchStatement (statement s)
 
statement MakeCaseStatement (expression e)
 Transform. More...
 
statement MakeDefaultStatement ()
 
statement MakeBreakStatement (string cmt)
 
statement MakeContinueStatement (string cmt)
 
statement ExpressionToStatement (expression e)
 e is now owned by returned statement More...
 
list add_prettyprint_control_list_to_declaration_statement (statement s, list initialization_expressions)
 The control list is hidden as arguments to the call to CONTROL in the declaration statement s. More...
 
void set_prettyprint_control_list_to_extern (void)
 
bool extern_prettyprint_control_list_p (void)
 void reset_prettyprint_control_list_to_extern(void) More...
 
void set_prettyprint_control_list_to_dummy (void)
 
bool dummy_prettyprint_control_list_p (void)
 Provide the information only once. More...
 

Variables

stack BlockStack
 Attention, the null statement in C is represented as the continue statement in Fortran (make_continue_statement means make_null_statement) More...
 
list LabeledStatements
 BlockStack is used to handle block scope. More...
 
stack SwitchGotoStack = stack_undefined
 list of labeled statements of the current module More...
 
stack SwitchControllerStack = stack_undefined
 
stack LoopStack = stack_undefined
 
static bool extern_declaration_p = false
 Force declaration statement s to be an extern declaration. More...
 
static bool dummy_declaration_p = false
 void set_prettyprint_control_list_to_extern(statement s) More...
 

Function Documentation

◆ add_prettyprint_control_list_to_declaration_statement()

list add_prettyprint_control_list_to_declaration_statement ( statement  s,
list  initialization_expressions 
)

The control list is hidden as arguments to the call to CONTROL in the declaration statement s.

It is made of 0 and 1 constant expressions.

The first element tells the prettyprinter if the "extern" keyword must be printed out.

The next expressions tells the prettyprinter which variables should be initialized by this statement.

The control list for the initializations is built by the C parser, cyacc.y.

This is only useful for global variables which can be declared multiple times in multiple files and in multiple ways. See Prettyprint/double_declaration01-14.c.

The parser generated the initialization control list backwards

Try to patch the initialization list for derived entities assuming that derived entities are located anywhere in the declaration list. See decl64-65 and struct14-15.c

Place holder variables have been removed. Even if a compilation unit is being parsed, initialization_expressions should have no impact.

The initialization list is OK

We could assert here than in = dn, but this is asserted below with more explanations. However, only in debug mode 8.

Preserve the "extern" information right away before the C parser updates it each time it encounters a global declaration.

An extern declaration?

Provide debugging information

Build the prettyprint control list: extern first and the initializations

Update the declaration statement

Parameters
initialization_expressionsnitialization_expressions

Definition at line 919 of file statement.c.

921 {
922  list dl = statement_declarations(s); // declaration list
923 
924  if(ENDP(dl)) {
926  // FI: Well, the parser has declared fields for instance...
927  return NIL;
928  }
929  else {
930  pips_internal_error("Not expected\n");
932  }
933  }
934  else {
935  /* The parser generated the initialization control list backwards */
937 
938  int dn = (int) gen_length(dl); // declaration number
939  int in = (int) gen_length(iel); // initialization number
940  entity first = ENTITY(CAR(dl));
941 
942  list niel = NIL;
943 
944  /* Try to patch the initialization list for derived entities
945  * assuming that derived entities are located anywhere in the
946  * declaration list. See decl64-65 and struct14-15.c
947  */
948 
949  if(dn<in) {
950  /* Place holder variables have been removed. Even if a
951  * compilation unit is being parsed, initialization_expressions
952  * should have no impact.
953  */
954  list ciel = iel;
955  int i;
956  for(i=0;i<dn-1;i++) {
957  ciel = CDR(ciel);
958  }
959  list liel = CDR(ciel);
960  CDR(ciel) = NIL;
961  gen_full_free_list(liel);
962  niel = iel;
963  pips_assert("Same number of elements in both lists",
964  (int) gen_length(niel)==dn);
965  }
966  else if(dn>in) {
967  list ciel = iel;
968  FOREACH(ENTITY, e, dl) {
969  // FI: we could instead check variable_entity_p()?
970  if(derived_entity_p(e) || typedef_entity_p(e)) {
971  niel = CONS(EXPRESSION, int_to_expression(0), niel);
972  in++;
973  }
974  else {
975  niel = CONS(EXPRESSION, EXPRESSION(CAR(ciel)), niel);
976  POP(ciel);
977  }
978  }
979  niel = gen_nreverse(niel);
980  gen_free_list(iel); // initialization_expressions is dead
981  }
982  else {
983  /* The initialization list is OK */
984  niel = iel;
985  }
986 
987 
988  /* We could assert here than in = dn, but this is asserted below
989  * with more explanations. However, only in debug mode 8. */
990 
991  /* Preserve the "extern" information right away before the C parser
992  updates it each time it encounters a global declaration. */
993 
994  /* An extern declaration? */
995 
996  bool is_extern_statement_p = extern_prettyprint_control_list_p();
997  bool is_dummy_statement_p = dummy_prettyprint_control_list_p();
999  int_to_expression((is_extern_statement_p? 1 : 0) +
1000  (is_dummy_statement_p? 2 : 0));
1001 
1002  /* Provide debugging information */
1003 
1004  ifdebug(8) {
1005  fprintf(stderr, "Variable \"%s\" is %sdeclared EXTERN.\n", entity_user_name(first), is_extern_statement_p? "" : "not ");
1006  fprintf(stderr, "Number of declared variables: %d\n", dn);
1007  print_entities(dl);
1008  fprintf(stderr, "Number of initialization expressions: %d\n", in);
1009 
1010  // For debugging
1011  extern void print_expressions(list);
1012  print_expressions(niel);
1013  //printf("\nis_external = %s\n", bool_to_string(is_external));
1014  }
1015 
1016  /* Build the prettyprint control list: extern first and the initializations */
1017  list cel = CONS(EXPRESSION, extern_declaration_p, niel); // control expression list
1018 
1019  ifdebug(8) {
1020  fprintf(stderr, "Number of control expressions: %d\n", (int) gen_length(cel));
1021  print_expressions(cel);
1022  if(gen_length(dl)!=gen_length(niel)) {
1023  print_entities(dl);
1024  pips_assert("The number of variables declared is equal to the number of expressions", gen_length(dl)==gen_length(niel));
1025  }
1026  fprintf(stderr, "**************************\n");
1027  }
1028 
1029  /* Update the declaration statement */
1030 
1032 
1033  // reset the initialization_expressions list in the caller
1034  // initialization_expressions = NIL;
1035  return NIL;
1036  }
1037 }
void const char const char const int
bool extern_prettyprint_control_list_p(void)
void reset_prettyprint_control_list_to_extern(void)
Definition: statement.c:1053
bool dummy_prettyprint_control_list_p(void)
Provide the information only once.
Definition: statement.c:1090
static bool extern_declaration_p
Force declaration statement s to be an extern declaration.
Definition: statement.c:1040
static list initialization_expressions
to preserve information about the declarations for the prettyprinter, especially for the global varia...
Definition: cyacc.tab.c:120
void gen_full_free_list(list l)
Definition: genClib.c:1023
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
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
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#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
#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
statement add_initialization_information_to_declaration_statement(statement s, list iel)
The initialization expression list is integrated into the internal representation as an argument list...
Definition: statement.c:1119
#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
void print_expressions(list le)
Definition: expression.c:98
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool typedef_entity_p(entity e)
Definition: entity.c:1902
void print_entities(list l)
Definition: entity.c:167
bool derived_entity_p(entity e)
Definition: entity.c:1048
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
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define statement_declarations(x)
Definition: ri.h:2460
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References add_initialization_information_to_declaration_statement(), CAR, CDR, CONS, derived_entity_p(), dummy_prettyprint_control_list_p(), ENDP, ENTITY, entity_user_name(), EXPRESSION, extern_declaration_p, extern_prettyprint_control_list_p(), FOREACH, fprintf(), gen_free_list(), gen_full_free_list(), gen_length(), gen_nreverse(), ifdebug, initialization_expressions, int, int_to_expression(), NIL, pips_assert, pips_internal_error, POP, print_entities(), print_expressions(), statement_declarations, and typedef_entity_p().

+ Here is the call graph for this function:

◆ dummy_prettyprint_control_list_p()

bool dummy_prettyprint_control_list_p ( void  )

Provide the information only once.

Definition at line 1090 of file statement.c.

1091 {
1092  bool b = dummy_declaration_p;
1093  dummy_declaration_p = false;
1094  return b;
1095 }
static bool dummy_declaration_p
void set_prettyprint_control_list_to_extern(statement s)
Definition: statement.c:1082

References dummy_declaration_p.

Referenced by add_prettyprint_control_list_to_declaration_statement().

+ Here is the caller graph for this function:

◆ ExpressionToStatement()

statement ExpressionToStatement ( expression  e)

e is now owned by returned statement

Definition at line 880 of file statement.c.

881 {
882  syntax s = expression_syntax(e);
884  string c = get_current_C_comment();
885 
886  if (syntax_call_p(s)) {
889  free_expression(e);
890  }
891  else
893 
895  if(!string_undefined_p(c)) {
896  statement_comments(st) = c;
897  }
898 
899  return st;
900 }
instruction make_instruction_expression(expression _field_)
Definition: ri.c:1196
void free_expression(expression p)
Definition: ri.c:853
string get_current_C_comment(void)
Return the current comment as a string to be freed by the caller and reset the current comment.
Definition: clexer.c:1282
int get_current_C_line_number(void)
Definition: clexer.c:1146
statement instruction_to_statement(instruction instr)
Build a statement from a give instruction.
Definition: statement.c:597
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define call_to_statement(c)
#define syntax_call_p(x)
Definition: ri.h:2734
#define syntax_call(x)
Definition: ri.h:2736
#define statement_comments(x)
Definition: ri.h:2456
#define call_undefined
Definition: ri.h:685
#define statement_number(x)
Definition: ri.h:2452
#define expression_syntax(x)
Definition: ri.h:1247
#define statement_undefined
Definition: ri.h:2419

References call_to_statement, call_undefined, expression_syntax, free_expression(), get_current_C_comment(), get_current_C_line_number(), instruction_to_statement(), make_instruction_expression(), statement_comments, statement_number, statement_undefined, string_undefined_p, syntax_call, and syntax_call_p.

+ Here is the call graph for this function:

◆ extern_prettyprint_control_list_p()

bool extern_prettyprint_control_list_p ( void  )

void reset_prettyprint_control_list_to_extern(void)

{ extern_declaration_p = false; } Provide the information only once

Definition at line 1053 of file statement.c.

1054 {
1055  bool b = extern_declaration_p;
1056  extern_declaration_p = false;
1057  return b;
1058 }

References extern_declaration_p.

Referenced by add_prettyprint_control_list_to_declaration_statement().

+ Here is the caller graph for this function:

◆ find_forloop_in_statement()

static forloop find_forloop_in_statement ( statement  s)
static

Because a break in the forloop requires the generation of an extra label statement after the forloop.

See MakeForLoop().

Definition at line 465 of file statement.c.

466 {
468  if(statement_forloop_p(s))
469  fl = statement_forloop(s);
470  else if(statement_block_p(s)) {
471  list sl = statement_block(s);
472  statement fs = STATEMENT(CAR(CDR(sl)));
473  if(statement_forloop_p(fs))
474  fl = statement_forloop(fs);
475  }
476  if(forloop_undefined_p(fl))
477  pips_internal_error("Unexpected forloop encoding\n");
478  return fl;
479 }
list statement_block(statement s)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
forloop statement_forloop(statement s)
Get the forloop of a statement.
Definition: statement.c:1426
bool statement_forloop_p(statement s)
Definition: statement.c:374
#define statement_block_p(stat)
#define forloop_undefined_p(x)
Definition: ri.h:1341
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define forloop_undefined
Definition: ri.h:1340

References CAR, CDR, forloop_undefined, forloop_undefined_p, pips_internal_error, STATEMENT, statement_block(), statement_block_p, statement_forloop(), and statement_forloop_p().

Referenced by MakeForloopWithIndexDeclaration().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FindStatementFromLabel()

statement FindStatementFromLabel ( entity  l)

Definition at line 189 of file statement.c.

190 {
191  MAP(STATEMENT,s,
192  {
193  if (statement_label(s) == l)
194  return s;
196  return statement_undefined;
197 }
list LabeledStatements
BlockStack is used to handle block scope.
Definition: statement.c:60
#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
#define statement_label(x)
Definition: ri.h:2450

References LabeledStatements, MAP, STATEMENT, statement_label, and statement_undefined.

Referenced by MakeForloop(), MakeGotoStatement(), MakeLabeledStatement(), MakeSwitchStatement(), and MakeWhileLoop().

+ Here is the caller graph for this function:

◆ InitializeBlock()

void InitializeBlock ( void  )

Definition at line 143 of file statement.c.

144 {
146 }
stack BlockStack
Attention, the null statement in C is represented as the continue statement in Fortran (make_continue...
Definition: statement.c:58
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References BlockStack, stack_make(), and statement_domain.

+ Here is the call graph for this function:

◆ MakeBlock()

statement MakeBlock ( list  stmts)

Create a block statement.

It also gather all the declarations in the statements and declare them in the block sequence.

To please to current RI choices about Fortran, blocks cannot carry line numbers nor comments

Anyway, it might be much too late to retrieve the comment associated to the beginning of the block. The lost comment appears after the last statement of the block. To save it, as is done in Fortran, an empty statement should be added at the end of the sequence.

get_current_C_line_number()

get_current_C_comment()

Parameters
stmtstmts

Definition at line 153 of file statement.c.

154 {
155  /* To please to current RI choices about Fortran, blocks cannot carry
156  line numbers nor comments */
157  /* Anyway, it might be much too late to retrieve the comment
158  associated to the beginning of the block. The lost comment
159  appears after the last statement of the block. To save it, as is
160  done in Fortran, an empty statement should be added at the end of
161  the sequence. */
162  // Gather all the direct declaration entities from the statements:
164 
166  STATEMENT_NUMBER_UNDEFINED /* get_current_C_line_number() */,
168  empty_comments /* get_current_C_comment() */,
171 
173 
174  ifdebug(1) {
175  fprintf(stderr, "Declaration list: ");
177  fprintf(stderr, "NONE\n");
178  else {
180  fprintf(stderr, "\n");
181  }
182  }
183 
184  pips_assert("Block statement is consistent",statement_consistent_p(s));
185  return s;
186 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
instruction make_instruction_sequence(sequence _field_)
Definition: ri.c:1169
synchronization make_synchronization_none(void)
Definition: ri.c:2424
sequence make_sequence(list a)
Definition: ri.c:2125
void discard_C_comment(void)
Discard a C comment because we don't know how to deal with it.
Definition: clexer.c:1426
list statements_to_direct_declarations(list sl)
Returns the declarations contained directly in the declaration statements of a list of statements.
Definition: statement.c:3334
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define string_undefined
Definition: newgen_types.h:40
#define STATEMENT_NUMBER_UNDEFINED
default values
#define empty_comments
Empty comments (i.e.
entity entity_empty_label(void)
Definition: entity.c:1105
extensions empty_extensions(void)
extension.c
Definition: extension.c:43

References discard_C_comment(), empty_comments, empty_extensions(), ENDP, entity_empty_label(), fprintf(), ifdebug, make_instruction_sequence(), make_sequence(), make_statement(), make_synchronization_none(), pips_assert, print_entities(), statement_consistent_p(), statement_declarations, STATEMENT_NUMBER_UNDEFINED, STATEMENT_ORDERING_UNDEFINED, statements_to_direct_declarations(), and string_undefined.

+ Here is the call graph for this function:

◆ MakeBreakStatement()

statement MakeBreakStatement ( string  cmt)

NN : I did not add a bool variable to distinguish between loop and switch statements :-( FI: Also, there is no protection in case the same label has been used by the programmer...

Parameters
cmtmt

Definition at line 849 of file statement.c.

850 {
851  /* NN : I did not add a bool variable to distinguish between loop
852  and switch statements :-( FI: Also, there is no protection in case
853  the same label has been used by the programmer... */
854  int i = basic_int((basic) stack_head(LoopStack));
855  string lab;
856  asprintf(&lab,"%sbreak_%d", get_label_prefix(), i);
857  statement bs = MakeGotoStatement(lab);
858  free(lab);
859 
860  statement_comments(bs) = cmt;
861 
862  return bs;
863 }
#define get_label_prefix()
The labels in C have function scope...
stack LoopStack
Definition: statement.c:64
statement MakeGotoStatement(string label)
Definition: statement.c:254
void free(void *)
#define asprintf
Definition: misc-local.h:225
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
#define basic_int(x)
Definition: ri.h:616

References asprintf, basic_int, free(), get_label_prefix, LoopStack, MakeGotoStatement(), stack_head(), and statement_comments.

Referenced by MakeSwitchStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MakeCaseStatement()

statement MakeCaseStatement ( expression  e)

Transform.

case e:

to

switch_xxx_case_e: ;

and generate

if (c == e) goto switch_xxx_case_e

where c is retrieved from SwitchControllerStack xxx is unique from LoopStack

Before the code can be generated, expression e must be statically evaluated, transformer into a character string, and this character string must be made compatible with C constraints for labels.

It might be easier to evaluate e since e must be evaluable at compile time... And it is necessary if e contains operators whose name cannot be part of a label: see switch04

We chose to ignore the impact of casts

You must evaluate the constant expression. Hopefully it is an integer expression...

The expression may be a character

remove the quotes

Make sure "restr" only contains C characters valid for a label if a character constant is used: is_letter || is_digit || '_'.

illegal characters such as '?' or ',' or '.' must be converted as well as octal constant such as '\001' and special characters such as '
'

Must be an illegal character for a label

FI: not too safe to make it octal among decimal because it can generate a label conflict.

octal character

hexadecimal character, unicode character

FI: let's deal with special cases such as
, \r, \t,... The initialization to zero is meaningless but avoids a warning.

Definition at line 712 of file statement.c.

713 {
714  int i = basic_int((basic) stack_head(LoopStack));
715  string lab = NULL;
716  /* It might be easier to evaluate e since e must be evaluable at
717  compile time... And it is necessary if e contains operators whose
718  name cannot be part of a label: see switch04 */
719  string estr = string_undefined;
720  expression ne = e;
721 
722  /* We chose to ignore the impact of casts */
723  if(expression_cast_p(e)) {
724  cast c = expression_cast(e);
725  ne = cast_expression(c);
726  }
727 
728  if(expression_constant_p(ne)) {
729  estr = expression_to_string(ne);
730  }
731  else {
732  /* You must evaluate the constant expression. Hopefully it is an
733  integer expression... */
734  intptr_t val;
735  if(expression_integer_value(ne, &val)) {
736  asprintf(&estr, "%lld", (long long int) val);
737  }
738  else {
740  c_parser_user_warning("Expression \"%s\" not supported as case expression.\n",
742  CParserError("Unsupported case expression\n");
743  }
744  }
745 
746  string restr = estr;
747 
748  /* The expression may be a character */
749  if(*estr=='\'') {
750  /* remove the quotes */
751  restr++;
752  *(estr+strlen(estr)-1) = '\000';
753  }
754 
755  /* Make sure "restr" only contains C characters valid for a label if
756  a character constant is used: is_letter || is_digit || '_'. */
757  if(strspn(restr,
758  "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_abcdefghijklmnopqrstuvwxyz")!=strlen(restr) && *estr=='\'') {
759  /* illegal characters such as '?' or ',' or '.' must be converted
760  as well as octal constant such as '\001' and special
761  characters such as '\n' */
762  if(strlen(restr)==1) {
763  /* Must be an illegal character for a label */
764  /* FI: not too safe to make it octal among decimal because it
765  can generate a label conflict. */
766  asprintf(&lab,"%sswitch_%d_case_%hhd",get_label_prefix(),i,*restr);
767  }
768  else if(*restr=='\\') {
769  if(*(restr+1)=='0'||*(restr+1)=='1'||*(restr+1)=='2'||*(restr+1)=='3')
770  /* octal character */
771  asprintf(&lab,"%sswitch_%d_case_o%s",get_label_prefix(),i,restr+1);
772  else if(*(restr+1)=='x'||*(restr+1)=='u'||*(restr+1)=='U')
773  /* hexadecimal character, unicode character */
774  asprintf(&lab,"%sswitch_%d_case_%s",get_label_prefix(),i,restr+1);
775  else {
776  /* FI: let's deal with special cases such as \n, \r, \t,...
777  * The initialization to zero is meaningless but avoids a warning.
778  */
779  char labc = 0; // A string would carry more ASCII information
780  if(*(restr+1)=='a') // bell
781  labc = '\a'; // "BEL"
782  else if(*(restr+1)=='b') // backspace
783  labc = '\b'; // "BS"
784  else if(*(restr+1)=='f') // form feed
785  labc = '\f'; // "FF"
786  else if(*(restr+1)=='n') // new line
787  labc = '\n'; // "LF"
788  else if(*(restr+1)=='t') // horizontal tab
789  labc = '\t'; // "HT"
790  else if(*(restr+1)=='r') // carriage return
791  labc = '\r'; // "CR"
792  else if(*(restr+1)=='v') // vertical tab
793  labc = '\v'; // "VT"
794  else if(*(restr+1)=='\'') // quote
795  labc = '\''; //
796  else if(*(restr+1)=='\"') // double quote
797  labc = '\"'; //
798  else if(*(restr+1)=='\\') // backslash
799  labc = '\\'; //
800  else if(*(restr+1)=='\?') // question mark
801  labc = '\?'; //
802  else
803  pips_internal_error("Unexpected case. %s\n", (restr));
804  asprintf(&lab,"%sswitch_%d_case_%hhd",get_label_prefix(),i,labc);
805  }
806  }
807  }
808  else
809  asprintf(&lab,"%sswitch_%d_case_%s",get_label_prefix(),i,restr);
810 
811  free(estr);
812 
818  CONS(EXPRESSION, e, NIL))));
820  sequence CurrentSwitchGotoStack = stack_head(SwitchGotoStack);
821  sequence_statements(CurrentSwitchGotoStack) = gen_nconc(sequence_statements(CurrentSwitchGotoStack),
822  CONS(STATEMENT,test_to_statement(t),NULL));
823 
824  return s;
825 }
call make_call(entity a1, list a2)
Definition: ri.c:269
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
#define c_parser_user_warning(...)
stack SwitchControllerStack
Definition: statement.c:63
stack SwitchGotoStack
list of labeled statements of the current module
Definition: statement.c:62
statement MakeLabeledStatement(string label, statement s, string comment)
Construct a new statement from.
Definition: statement.c:204
void CParserError(char *msg)
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
statement make_continue_statement(entity l)
Definition: statement.c:953
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
void set_prettyprint_language_tag(enum language_utype lang)
set the prettyprint language from a language_utype argument
Definition: language.c:143
string expression_to_string(expression e)
Definition: expression.c:77
#define test_to_statement(t)
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool expression_cast_p(expression e)
Definition: expression.c:450
cast expression_cast(expression e)
Definition: expression.c:455
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
#define cast_expression(x)
Definition: ri.h:747
#define entity_undefined
Definition: ri.h:2761
#define sequence_statements(x)
Definition: ri.h:2360
@ is_language_c
Definition: ri.h:1567
#define intptr_t
Definition: stdint.in.h:294

References asprintf, basic_int, c_parser_user_warning, call_to_expression(), cast_expression, CONS, CParserError(), entity_empty_label(), entity_intrinsic(), entity_undefined, EXPRESSION, expression_cast(), expression_cast_p(), expression_constant_p(), expression_integer_value(), expression_to_string(), free(), gen_nconc(), get_current_C_comment(), get_label_prefix, intptr_t, is_language_c, LoopStack, make_call(), make_continue_statement(), make_test(), MakeGotoStatement(), MakeLabeledStatement(), NIL, pips_internal_error, sequence_statements, set_prettyprint_language_tag(), stack_head(), STATEMENT, string_undefined, SwitchControllerStack, SwitchGotoStack, and test_to_statement.

+ Here is the call graph for this function:

◆ MakeCLabel()

entity MakeCLabel ( string  s)

Definition at line 278 of file statement.c.

279 {
280  string ename = strdup(concatenate(LABEL_PREFIX,s,NULL));
282  free(ename);
283  if (entity_type(l) == type_undefined)
284  {
285  pips_debug(7,"Label %s\n", s);
290  }
291  else
292  pips_debug(7, "Label %s already exists\n", s);
293  return(l);
294 }
storage make_storage_rom(void)
Definition: ri.c:2285
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
constant make_constant_litteral(void)
Definition: ri.c:418
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define LABEL_PREFIX
Definition: naming-local.h:31
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
type MakeTypeStatement(void)
Definition: type.c:92
#define entity_storage(x)
Definition: ri.h:2794
@ is_value_constant
Definition: ri.h:3033
#define type_undefined
Definition: ri.h:2883
#define entity_type(x)
Definition: ri.h:2792
#define entity_initial(x)
Definition: ri.h:2796
char * strdup()

References concatenate(), entity_initial, entity_storage, entity_type, FindOrCreateEntity(), free(), get_current_module_name(), is_value_constant, LABEL_PREFIX, make_constant_litteral(), make_storage_rom(), make_value(), MakeTypeStatement(), pips_debug, strdup(), and type_undefined.

Referenced by MakeForloop(), MakeGotoStatement(), MakeLabeledStatement(), MakeSwitchStatement(), and MakeWhileLoop().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MakeContinueStatement()

statement MakeContinueStatement ( string  cmt)

Unique label with the LoopStack

Parameters
cmtmt

Definition at line 865 of file statement.c.

866 {
867  /* Unique label with the LoopStack */
868  int i = basic_int((basic) stack_head(LoopStack));
869  string lab;
870  asprintf(&lab, "%sloop_end_%d", get_label_prefix(), i);
871  statement cs = MakeGotoStatement(lab);
872  free(lab);
873 
874  statement_comments(cs) = cmt;
875 
876  return cs;
877 }

References asprintf, basic_int, free(), get_label_prefix, LoopStack, MakeGotoStatement(), stack_head(), and statement_comments.

+ Here is the call graph for this function:

◆ MakeCurrentModule()

void MakeCurrentModule ( entity  e)

is used for switch statements also, because we do not distinguish a break in a loop or a switch

This must be changed later, the storage is of type return and we have to create a new entity

make_storage_return(e)

code_declaration to be updated : only need formal parameters, because the others are added in block statement declaration ?

The next two tests are replicated from the Fortran parser, Syntax/procedure.c, MakeCurrentFunction()

In case the module is parsed a second time, clean up the symbol table to avoid variable redefinition warnings and errors

Clean up existing local entities in case of a recompilation.

Let's hope cf is not an intrinsic: name conflict (the problem may have been detected earlier in UpdateEntity() if there are arguments)

Unfortunately, an intrinsics cannot be redefined, just like a user function or subroutine after editing because intrinsics are not handled like user functions or subroutines. They are not added to the called_modules list of other modules, unless the redefining module is parsed FIRST. There is not mechanism in PIPS to control the parsing order.

Definition at line 67 of file statement.c.

68 {
69  /* This must be changed later, the storage is of type return and we
70  have to create a new entity*/
71  entity_storage(e) = make_storage_rom() /* make_storage_return(e) */;
74  make_code(NIL,strdup(""),
76  NIL,
77  make_language_c()));
78  /* code_declaration to be updated : only need formal parameters, because the others are added in
79  block statement declaration ? */
80  pips_debug(4,"Set current module entity %s\n",entity_user_name(e));
81 
82  /* The next two tests are replicated from the Fortran parser,
83  Syntax/procedure.c, MakeCurrentFunction() */
84 
85  /* In case the module is parsed a second time, clean up the symbol
86  table to avoid variable redefinition warnings and errors */
90  if(!code_undefined_p(c) && !ENDP(code_declarations(c))) {
91  /* Clean up existing local entities in case of a recompilation. */
93  }
94  }
95  }
96 
97  /* Let's hope cf is not an intrinsic: name conflict (the problem may
98  have been detected earlier in UpdateEntity() if there are
99  arguments) */
100  if( entity_type(e) != type_undefined
101  && intrinsic_entity_p(e) ) {
102  pips_user_warning("Intrinsic %s redefined.\n"
103  "This is not supported by PIPS. Please rename %s\n",
105  /* Unfortunately, an intrinsics cannot be redefined, just like a user function
106  * or subroutine after editing because intrinsics are not handled like
107  * user functions or subroutines. They are not added to the called_modules
108  * list of other modules, unless the redefining module is parsed FIRST.
109  * There is not mechanism in PIPS to control the parsing order.
110  */
111  CParserError("Name conflict between a "
112  "function and an intrinsic\n");
113  }
114 
115 
117  init_c_areas();
123 }
code make_code(list a1, string a2, sequence a3, list a4, language a5)
Definition: ri.c:353
language make_language_c(void)
Definition: ri.c:1253
void init_c_areas(void)
In C we have 4 areas.
Definition: util.c:186
void init_c_implicit_variables(entity)
Definition: util.c:277
void CCleanLocalEntities(entity function)
C language version.
Definition: clean.c:146
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
#define pips_user_warning
Definition: misc-local.h:146
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 intrinsic_entity_p(entity e)
Definition: entity.c:1272
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_code_p(x)
Definition: ri.h:3065
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define code_undefined_p(x)
Definition: ri.h:758
@ is_value_code
Definition: ri.h:3031
#define code_declarations(x)
Definition: ri.h:784
#define basic_domain
newgen_area_domain_defined
Definition: ri.h:42
#define value_code(x)
Definition: ri.h:3067
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346

References basic_domain, CCleanLocalEntities(), code_declarations, code_undefined_p, CParserError(), ENDP, entity_initial, entity_local_name(), entity_storage, entity_type, entity_user_name(), expression_domain, init_c_areas(), init_c_implicit_variables(), intrinsic_entity_p(), is_value_code, LabeledStatements, LoopStack, make_code(), make_language_c(), make_sequence(), make_storage_rom(), make_value(), NIL, pips_debug, pips_user_warning, sequence_domain, set_current_module_entity(), stack_make(), strdup(), SwitchControllerStack, SwitchGotoStack, type_undefined, value_code, value_code_p, and value_undefined_p.

+ Here is the call graph for this function:

◆ MakeDefaultStatement()

statement MakeDefaultStatement ( void  )

Return the labeled statement switch_xxx_default: ; and add goto switch_xxx_default; to the switch header

If the default case is not last, it must be moved later in the sequence_statements(CurrentSwitchGoto)

Definition at line 827 of file statement.c.

828 {
829  /* Return the labeled statement
830  switch_xxx_default: ;
831  and add
832  goto switch_xxx_default;
833  to the switch header */
834  int i = basic_int((basic) stack_head(LoopStack));
835  string lab;
836  asprintf(&lab,"%sswitch_%d_default", get_label_prefix(), i);
840  sequence CurrentSwitchGoto = stack_head(SwitchGotoStack);
841  /* If the default case is not last, it must be moved later in the
842  sequence_statements(CurrentSwitchGoto) */
843  sequence_statements(CurrentSwitchGoto) = gen_nconc(sequence_statements(CurrentSwitchGoto),
844  CONS(STATEMENT,MakeGotoStatement(lab),NULL));
845  free(lab);
846  return s;
847 }

References asprintf, basic_int, CONS, entity_empty_label(), free(), gen_nconc(), get_current_C_comment(), get_label_prefix, LoopStack, make_continue_statement(), MakeGotoStatement(), MakeLabeledStatement(), sequence_statements, stack_head(), STATEMENT, and SwitchGotoStack.

+ Here is the call graph for this function:

◆ MakeForloop()

statement MakeForloop ( expression  e1,
expression  e2,
expression  e3,
statement  body 
)

Create a for-loop statement with some parser-specific characteristics.

A more generic implementation would have been in ri-util instead.

There are assumptions that 2 comments have been pushed in the parser before.

Parameters
[in]e1is the init part of the for
[in]e2is the conditional part of the for
[in]e3is the increment part of the for
[in]bodyis the loop body statement
Returns
a statement with the for

Beware that a block is returned instead of a forloop when a break has been processed. The forloop is somewhere in there...

A bool C constant cannot be used because stdbool.h may not be included

cond = make_call_expression(MakeConstant(TRUE_OPERATOR_NAME,

is_basic_logical),

NIL);

Create some land-pad labels to deal with break and continue.

Looks like some memory leaks if no break or continue...

What happens if this label is already used by the programmer? If I increment i, the label may not be retrieved when needed... unless LoopStack is updated...

This loop has a continue statement which has been transformed to goto.

Add the labeled statement at the end of loop body

The for clause may contain declarations

This loop has a break statement which has been transformed to goto Add the labeled statement after the loop

ifdebug(5) {

printf("For loop statement: \n");

print_statement(smt);

}

Parameters
e11
e22
e33
bodyody

Definition at line 358 of file statement.c.

361  {
362  forloop f;
363  statement smt;
364  // Assume this push have been done in the parser:
365  int sn = pop_current_C_line_number();
366  expression init = e1;
367  expression cond = e2;
368  expression inc = e3;
369 
370  pips_assert("For loop body consistent",statement_consistent_p(body));
371 
374  NIL);
375  else
377 
378  if(expression_undefined_p(cond))
379  /* A bool C constant cannot be used
380  because stdbool.h may not be
381  included */
382  /* cond = make_call_expression(MakeConstant(TRUE_OPERATOR_NAME, */
383  /* is_basic_logical), */
384  /* NIL); */
385  cond = int_to_expression(1);
386  else
387  simplify_C_expression(cond);
388 
389  if(expression_undefined_p(inc))
391  NIL);
392  else
394 
395  int i = basic_int((basic) stack_head(LoopStack));
396  /* Create some land-pad labels to deal with break and continue.
397 
398  Looks like some memory leaks if no break or continue...
399 
400  What happens if this label is already used by the programmer? If
401  I increment i, the label may not be retrieved when
402  needed... unless LoopStack is updated...
403  */
404  string lab1 = string_undefined;
405  //do {
406  //if(!string_undefined_p(lab1)) free(lab1);
407  asprintf(&lab1, "%s%s%d", get_label_prefix(), "loop_end_", i);
408  //i++;
409  //} while(label_string_defined_in_current_module_p(lab1)()
411  free(lab1);
412 
413  string lab2 = string_undefined;
414  //do {
415  //if(!string_undefined_p(lab2)) free(lab2);
416  asprintf(&lab2, "%s%s%d", get_label_prefix(), "break_", i);
417  //i++;
418  //} while(label_string_defined_in_current_module_p(lab1)()
420  free(lab2);
421 
423  /* This loop has a continue statement which has been transformed to goto.
424 
425  Add the labeled statement at the end of loop body*/
426  insert_statement(body, s1, false);
427 
428  /* The for clause may contain declarations*/
429  f = make_forloop(init, cond, inc, body);
437 
438  if (!statement_undefined_p(s2))
439  /* This loop has a break statement which has been transformed to goto
440  Add the labeled statement after the loop */
441  insert_statement(smt, s2, false);
442 
443  // Assume these 2 push have been done in the parser:
444  string comment_after_for_clause = pop_current_C_comment();
445  string comment_before_for_clause = pop_current_C_comment();
446  string sc = strdup(concatenate(comment_before_for_clause,
447  comment_after_for_clause,
448  NULL));
449  free(comment_after_for_clause);
450  free(comment_before_for_clause);
451  smt = add_comment_and_line_number(smt, sc, sn);
453  pips_assert("For loop consistent", statement_consistent_p(smt));
454 
455  pips_assert("For loop is consistent", forloop_consistent_p(f));
456  /* ifdebug(5) { */
457  /* printf("For loop statement: \n"); */
458  /* print_statement(smt); */
459  /* } */
460  return smt;
461 }
instruction make_instruction_forloop(forloop _field_)
Definition: ri.c:1193
bool forloop_consistent_p(forloop p)
Definition: ri.c:998
forloop make_forloop(expression a1, expression a2, expression a3, statement a4)
Definition: ri.c:1025
string pop_current_C_comment(void)
Pop the current comment.
Definition: clexer.c:1352
int pop_current_C_line_number(void)
Definition: clexer.c:1202
entity MakeCLabel(string s)
Definition: statement.c:278
statement FindStatementFromLabel(entity l)
Definition: statement.c:189
statement add_comment_and_line_number(statement s, string sc, int sn)
Since block cannot carry comments nor line numbers, they must be moved to an internal continue statem...
Definition: statement.c:1980
void insert_statement(statement s, statement s1, bool before)
This is the normal entry point.
Definition: statement.c:2570
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define CONTINUE_FUNCTION_NAME
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
bool simplify_C_expression(expression e)
Replace C operators "+C" and "-C" which can handle pointers by arithmetic operators "+" and "-" when ...
Definition: expression.c:2814
#define expression_undefined_p(x)
Definition: ri.h:1224
#define statement_undefined_p(x)
Definition: ri.h:2420
s1
Definition: set.c:247

References add_comment_and_line_number(), asprintf, basic_int, concatenate(), CONTINUE_FUNCTION_NAME, empty_extensions(), entity_empty_label(), entity_intrinsic(), expression_undefined_p, f(), FindStatementFromLabel(), forloop_consistent_p(), free(), get_current_C_line_number(), get_label_prefix, init, insert_statement(), int_to_expression(), LoopStack, make_call_expression(), make_forloop(), make_instruction_forloop(), make_statement(), make_synchronization_none(), MakeCLabel(), NIL, pips_assert, pop_current_C_comment(), pop_current_C_line_number(), s1, simplify_C_expression(), stack_head(), stack_pop(), statement_consistent_p(), STATEMENT_ORDERING_UNDEFINED, statement_undefined_p, strdup(), and string_undefined.

Referenced by MakeForloopWithIndexDeclaration().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MakeForloopWithIndexDeclaration()

statement MakeForloopWithIndexDeclaration ( list  decls,
expression  e2,
expression  e3,
statement  body 
)

Create a C99 for-loop statement with a declaration as first parameter in the for clause, with some parser-specific characteristics.

To represent for(int i = a;...;...) we generate instead: { int i; for(int i = a;...;...) }

The for could be generated back into the original form by the prettyprinter. To differentiate between such a C99 for loop or a for-loop that was really written with the i declaration just before, west may mark the for loop with an extension here so that the prettyprinter could use this hint to know if it has to do some resugaring or not.

Parameters
[in,out]declsis the init part of the for. It is a declaration statement list
[in]e2is the conditional part of the for
[in]e3is the increment part of the for
[in]bodyis the loop body statement
Returns
a statement that contains the declaration and the for

ifdebug(6) {

printf("For loop statement declarations: \n");

print_statements(decls);

}

First generate naive but more robust version in the RI, such as:

{ int i = a; for(;...;...) }

We inject the for in its declaration statement to have the naive representation:

We try to refine to inject back an initialization in the for-clause.

Note split_initializations_in_statemen() works only on a block

We are interested in solving the simple case when there are 3 statements because we should be in the form of: int i; i = a; for(;...;...)

We need to remove the decl block statement and move the index declaration directly in the for statement.

Not yet implemented because it needs to extend declaration_statement_p for any kind of loops, the loop restructurers...

Parameters
declsecls
e22
e33
bodyody

Definition at line 508 of file statement.c.

511  {
512  /* ifdebug(6) { */
513  /* printf("For loop statement declarations: \n"); */
514  /* print_statements(decls); */
515  /* } */
516  // FI: modified because insert_statement() should not be used with
517  // declaration statements although it would be OK in this special case
518  // statement decl = make_statement_from_statement_list_or_empty_block(decls);
519  statement decl = make_block_statement(decls);
520  /* First generate naive but more robust version in the RI, such as:
521 
522  {
523  int i = a;
524  for(;...;...)
525  }
526  */
527  statement for_s = MakeForloop(expression_undefined, e2, e3, body);
528  /* We inject the for in its declaration statement to have the naive
529  representation: */
530  // insert_statement(decl, for_s, false);
532  // Gather all the direct declarations from the statements in the block
534  // to put them on the block statement:
535  statement_declarations(decl) = dl;
536 
537  if (!get_bool_property("C_PARSER_GENERATE_NAIVE_C99_FOR_LOOP_DECLARATION")) {
538  /* We try to refine to inject back an initialization in the for-clause.
539 
540  Note split_initializations_in_statemen() works only on a block */
542  list l = statement_block(decl);
543  size_t len = gen_length(l);
544  ifdebug(6)
545  printf("Number of statements in the block: %zd\n", len);
546  if (len == 3) {
547  /* We are interested in solving the simple case when there are 3
548  statements because we should be in the form of:
549  int i;
550  i = a;
551  for(;...;...)
552  */
553  // So we pick the initialization part which is the second statement:
554  statement init = STATEMENT(gen_nth(1, l));
555  // Remove it from the enclosing declaration statement:
556  gen_remove(&l, init);
557  // Get the assignment:
558  call c = statement_call(init);
559  // Housekeeping: first protect what we want to keep somewhere else...
561  // ... and free the now useless container:
563  // Make from it an expression that can appear inside the for clause:
565  // Get the for-loop:
567  // Remove the default-generated initialization expression:
569  // Put the new one instead:
571  if (get_bool_property("C_PARSER_GENERATE_COMPACT_C99_FOR_LOOP_DECLARATION")) {
572  /* We need to remove the decl block statement and move the index
573  declaration directly in the for statement. */
574 
575  /* Not yet implemented because it needs to extend
576  declaration_statement_p for any kind of loops, the loop
577  restructurers... */
578  ;
579  }
580  }
581  }
582  return decl;
583 }
void free_statement(statement p)
Definition: ri.c:2189
static forloop find_forloop_in_statement(statement s)
Because a break in the forloop requires the generation of an extra label statement after the forloop.
Definition: statement.c:465
statement MakeForloop(expression e1, expression e2, expression e3, statement body)
Create a for-loop statement with some parser-specific characteristics.
Definition: statement.c:358
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
if(!(yy_init))
Definition: genread_lex.c:1029
statement make_block_statement(list body)
Make a block statement from a list of statement.
Definition: statement.c:616
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
call statement_call(statement s)
Get the call of a statement.
Definition: statement.c:1406
void append_statement_to_block_statement(statement b, statement s)
Definition: statement.c:2586
void split_initializations_in_statement(statement s)
Transform a declaration with an initialization statement into 2 parts, a declaration statement and an...
Definition: declarations.c:437
#define forloop_initialization(x)
Definition: ri.h:1366
#define expression_undefined
Definition: ri.h:1223
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
int printf()

References append_statement_to_block_statement(), call_to_expression(), call_undefined, expression_undefined, f(), find_forloop_in_statement(), forloop_initialization, free_expression(), free_statement(), gen_length(), gen_nth(), gen_remove(), get_bool_property(), ifdebug, init, instruction_call, make_block_statement(), MakeForloop(), printf(), split_initializations_in_statement(), STATEMENT, statement_block(), statement_call(), statement_declarations, statement_instruction, and statements_to_direct_declarations().

+ Here is the call graph for this function:

◆ MakeGotoStatement()

statement MakeGotoStatement ( string  label)

Find the corresponding statement from its label, if not found, create a pseudo one, which will be replaced lately when we see the statement (label: statement)

Parameters
labelabel

Definition at line 254 of file statement.c.

255 {
256  entity l = MakeCLabel(label);
258 
259  /* Find the corresponding statement from its label,
260  if not found, create a pseudo one, which will be replaced lately when
261  we see the statement (label: statement) */
262 
264  if (s == statement_undefined) {
267  }
274 
275  return gts;
276 }
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
@ is_instruction_goto
Definition: ri.h:1473

References CONS, empty_extensions(), entity_empty_label(), FindStatementFromLabel(), get_current_C_comment(), get_current_C_line_number(), is_instruction_goto, LabeledStatements, make_continue_statement(), make_instruction(), make_statement(), make_synchronization_none(), MakeCLabel(), NIL, STATEMENT, STATEMENT_ORDERING_UNDEFINED, and statement_undefined.

Referenced by MakeBreakStatement(), MakeCaseStatement(), MakeContinueStatement(), and MakeDefaultStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MakeLabeledStatement()

statement MakeLabeledStatement ( string  label,
statement  s,
string  comment 
)

Construct a new statement from.

Parameters
sby adding a
labeland a
comment.If it is possible to do it without creating a new statement, retun the old one modified according to.

There is no other statement already associated with this label...

Add a label and deal all the gory details about the PIPS internal representation:

There is already a statement stub smt associated to this label with some gotos pointing to it, so keep it as the labeled target.

The statement does not have a label and can accept one, so patch in place smt:

The statement can not accept a label or another one, just keep the previous label in front:

Parameters
labelabel
commentomment

Definition at line 204 of file statement.c.

204  {
205  entity l = MakeCLabel(label);
206  statement labeled_statement;
207  // Get the statement with the l label, if any:
209  if (smt == statement_undefined) {
210  /* There is no other statement already associated with this
211  label... */
212  /* Add a label and deal all the gory details about the PIPS internal
213  representation: */
214  s = add_label_to_statement(l, s, &labeled_statement);
215  // Keep a track of this statement associated to a label:
216  LabeledStatements = CONS(STATEMENT, labeled_statement, LabeledStatements);
217  }
218  else {
219  /* There is already a statement stub smt associated to this label with
220  some gotos pointing to it, so keep it as the labeled target. */
222  && unlabelled_statement_p(s)) {
223  /* The statement does not have a label and can accept one, so
224  patch in place smt: */
227  // Discard the old statement:
230  free_statement(s);
231  // And keep the old one:
232  s = smt;
233  labeled_statement = s;
234  }
235  else {
236  /* The statement can not accept a label or another one, just keep
237  the previous label in front: */
238  list stmts = gen_statement_cons(s, NIL);
239  stmts = gen_statement_cons(smt, stmts);
240  statement seq = make_block_statement(stmts);
241  labeled_statement = smt;
242  s = seq;
243  }
244  }
245  // Associate the current comment to the statement with the label:
246  if (comment != string_undefined) {
247  insert_comments_to_statement(labeled_statement, comment);
248  free(comment);
249  }
250  return s;
251 }
list gen_statement_cons(statement p, list l)
Definition: ri.c:2202
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
bool unlabelled_statement_p(statement st)
Definition: statement.c:402
void insert_comments_to_statement(statement s, const char *the_comments)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
statement add_label_to_statement(entity label, statement s, statement *labeled_statement)
Add a label to a statement.
Definition: statement.c:2158
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define instruction_undefined
Definition: ri.h:1454

References add_label_to_statement(), comment(), CONS, FindStatementFromLabel(), free(), free_statement(), gen_statement_cons(), insert_comments_to_statement(), instruction_sequence_p, instruction_undefined, LabeledStatements, make_block_statement(), MakeCLabel(), NIL, STATEMENT, statement_comments, statement_instruction, statement_undefined, string_undefined, and unlabelled_statement_p().

Referenced by MakeCaseStatement(), and MakeDefaultStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MakeSwitchStatement()

statement MakeSwitchStatement ( statement  s)

Transform a switch statement to if - else - goto. Example:

switch (c) { case 1: s1; case 2: s2; default: sd; }

if (c==1) goto switch_xxx_case_1; if (c==2) goto switch_xxx_case_2; goto switch_xxx_default; switch_xxx_case_1: ; s1; switch_xxx_case_2: ; s2; switch_xxx_default: ; sd;

In si, we can have goto break_xxx; (which was a break)

and break_xxx: ; is inserted at the end of the switch statement

The statement s corresponds to the body

switch_xxx_case_1: ; s1; switch_xxx_case_2: ; s2; switch_xxx_default: ; sd;

we have to insert

if (c==1) goto switch_xxx_case_1; if (c==2) goto switch_xxx_case_2; goto switch_xxx_default;

before s and return the inserted statement.

For the time being, the switch comment is lost. It should already be included in the argument,s

pop_current_C_comment();

Make sure the default case is the last one in the test sequence

Keep the cases in the user order. Tobe checked at the pARSED_PRINTED_FILE level.

no default case, jump out of the switch control structure

trdup("")

This switch has a break statement which has been transformed to goto Add the labeled statement after the switch

ifdebug(5)

{

printf("Switch statement: \n");

print_statement(s);

}

Definition at line 586 of file statement.c.

587 {
588  /* Transform a switch statement to if - else - goto. Example:
589 
590  switch (c) {
591  case 1:
592  s1;
593  case 2:
594  s2;
595  default:
596  sd;
597  }
598 
599  if (c==1) goto switch_xxx_case_1;
600  if (c==2) goto switch_xxx_case_2;
601  goto switch_xxx_default;
602  switch_xxx_case_1: ;
603  s1;
604  switch_xxx_case_2: ;
605  s2;
606  switch_xxx_default: ;
607  sd;
608 
609  In si, we can have goto break_xxx; (which was a break)
610 
611  and break_xxx: ; is inserted at the end of the switch statement
612 
613  The statement s corresponds to the body
614 
615  switch_xxx_case_1: ;
616  s1;
617  switch_xxx_case_2: ;
618  s2;
619  switch_xxx_default: ;
620  sd;
621 
622  we have to insert
623 
624  if (c==1) goto switch_xxx_case_1;
625  if (c==2) goto switch_xxx_case_2;
626  goto switch_xxx_default;
627 
628 
629  before s and return the inserted statement. */
630  int i = basic_int((basic) stack_head(LoopStack));
631  string lab ;
632  asprintf(&lab, "%sbreak_%d", get_label_prefix(), i);
636  list tl = sequence_statements(oseq);
637  list ct = list_undefined;
638  list ntl = NIL;
640 
641  ifdebug(8) {
642  pips_debug(8, "tl=%p\n", tl);
643  }
644 
645  /* For the time being, the switch comment is lost. It should already
646  be included in the argument,s */
647  /* pop_current_C_comment(); */
648 
649  /* Make sure the default case is the last one in the test sequence */
650  for(ct=tl;!ENDP(ct); POP(ct)) {
651  statement s = STATEMENT(CAR(ct));
652 
654  ds = s;
655  }
656  else {
657  /* Keep the cases in the user order. Tobe checked at the
658  pARSED_PRINTED_FILE level. */
659  ntl = gen_nconc(ntl, CONS(STATEMENT,s,NIL));
660  //ntl = CONS(STATEMENT,s,ntl);
661  }
662  }
663  if(statement_undefined_p(ds)) {
664  /* no default case, jump out of the switch control structure */
665  ds = MakeBreakStatement(string_undefined /*strdup("")*/);
666  }
667  ntl = gen_nconc(ntl, CONS(STATEMENT,ds,NIL));
668  gen_free_list(tl);
669  sequence_statements(oseq)=NIL;
670  free_sequence(oseq);
672  //seq = instruction_to_statement(make_instruction_sequence(make_sequence(tl)));
673 
674  insert_statement(s,seq,true);
675 
677  free(lab);
678  if (!statement_undefined_p(smt))
679  {
680  /* This switch has a break statement which has been transformed to goto
681  Add the labeled statement after the switch */
682  insert_statement(s,smt,false);
683  }
684  pips_assert("Switch is consistent",statement_consistent_p(s));
685  /* ifdebug(5) */
686  /* { */
687  /* printf("Switch statement: \n"); */
688  /* print_statement(s); */
689  /* } */
690  return s;
691 }
void free_sequence(sequence p)
Definition: ri.c:2092
statement MakeBreakStatement(string cmt)
Definition: statement.c:849
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
struct _newgen_struct_sequence_ * sequence
Definition: ri.h:351
#define instruction_goto_p(x)
Definition: ri.h:1524

References asprintf, basic_int, CAR, CONS, ENDP, FindStatementFromLabel(), free(), free_sequence(), gen_free_list(), gen_nconc(), get_label_prefix, ifdebug, insert_statement(), instruction_goto_p, instruction_to_statement(), list_undefined, LoopStack, make_instruction_sequence(), make_sequence(), MakeBreakStatement(), MakeCLabel(), NIL, pips_assert, pips_debug, POP, sequence_statements, stack_head(), STATEMENT, statement_consistent_p(), statement_instruction, statement_undefined, statement_undefined_p, string_undefined, and SwitchGotoStack.

+ Here is the call graph for this function:

◆ MakeWhileLoop()

statement MakeWhileLoop ( list  lexp,
statement  s,
bool  before 
)

This loop has a continue statement which has been transformed to goto Add the labeled statement at the end of loop body

This loop has a break statement which has been transformed to goto Add the labeled statement after the loop

ifdebug(5)

{

printf("While loop statement: \n");

print_statement(smt);

}

Parameters
lexpexp
beforeefore

Definition at line 297 of file statement.c.

298 {
299  statement smt;
300  int i = basic_int((basic) stack_head(LoopStack));
301  string lab1;
302  asprintf(&lab1,"%s%s%d", get_label_prefix(), "loop_end_", i);
304  free(lab1);
305  string lab2;
306  asprintf(&lab2,"%s%s%d", get_label_prefix(), "break_", i);
308  free(lab2);
309 
311  {
312  /* This loop has a continue statement which has been transformed to goto
313  Add the labeled statement at the end of loop body*/
314  insert_statement(s,s1,false);
315  }
316 
318  s,
320  before);
321  if (!statement_undefined_p(s2))
322  {
323  /* This loop has a break statement which has been transformed to goto
324  Add the labeled statement after the loop */
325  insert_statement(smt,s2,false);
326  }
327 
328  pips_assert("While loop is consistent",statement_consistent_p(smt));
329  /* ifdebug(5) */
330  /* { */
331  /* printf("While loop statement: \n"); */
332  /* print_statement(smt); */
333  /* } */
334  return smt;
335 }
static list lexp
statement make_whileloop_statement(expression condition, statement body, int line_number, bool before)
Build a while loop statement.
Definition: statement.c:1150
expression MakeCommaExpression(list l)
Definition: expression.c:3918

References asprintf, basic_int, FindStatementFromLabel(), free(), get_current_C_line_number(), get_label_prefix, insert_statement(), lexp, LoopStack, make_whileloop_statement(), MakeCLabel(), MakeCommaExpression(), pips_assert, s1, stack_head(), statement_consistent_p(), and statement_undefined_p.

+ Here is the call graph for this function:

◆ ResetCurrentModule()

void ResetCurrentModule ( void  )

Reset them to stack_undefined_p instead of STACK_NULL

Definition at line 125 of file statement.c.

126 {
128  if (get_bool_property("PARSER_DUMP_SYMBOL_TABLE"))
130  pips_debug(4,"Reset current module entity %s\n",get_current_module_name());
136  /* Reset them to stack_undefined_p instead of STACK_NULL */
141 }
void CModuleMemoryAllocation(entity)
This function is for MemoryAllocation for Module of C programs.
Definition: util.c:1979
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define stack_undefined
Definition: newgen_stack.h:55
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
void fprint_C_environment(FILE *fd, entity m)
Definition: declarations.c:292

References BlockStack, CModuleMemoryAllocation(), fprint_C_environment(), get_bool_property(), get_current_module_entity(), get_current_module_name(), LoopStack, pips_debug, reset_current_module_entity(), stack_free(), stack_undefined, SwitchControllerStack, and SwitchGotoStack.

+ Here is the call graph for this function:

◆ set_prettyprint_control_list_to_dummy()

void set_prettyprint_control_list_to_dummy ( void  )

Definition at line 1084 of file statement.c.

1085 {
1086  dummy_declaration_p = true;
1087 }

References dummy_declaration_p.

◆ set_prettyprint_control_list_to_extern()

void set_prettyprint_control_list_to_extern ( void  )

Definition at line 1042 of file statement.c.

1043 {
1044  extern_declaration_p = true;
1045 }

References extern_declaration_p.

Variable Documentation

◆ BlockStack

stack BlockStack

Attention, the null statement in C is represented as the continue statement in Fortran (make_continue_statement means make_null_statement)

statement.c

Definition at line 58 of file statement.c.

Referenced by InitializeBlock(), LinkInstToCurrentBlock(), MakeBlockIfInst(), MakeElseInst(), MakeEnddoInst(), MakeEndifInst(), PopBlock(), PushBlock(), and ResetCurrentModule().

◆ dummy_declaration_p

bool dummy_declaration_p = false
static

void set_prettyprint_control_list_to_extern(statement s)

{ // pips_assert("s is a declaration statement", declaration_statement_p(s)); call c = statement_call(s); list cel = call_arguments(c); if(ENDP(cel)) { cel = CONS(EXPRESSION, int_to_expression(1), NIL); } else { expression ce = EXPRESSION(CAR(cel)); int extern_p = integer_constant_expression_value(ce); if(!extern_p) { EXPRESSION_(CAR(cel)) = int_to_expression(1); free_expression(ce); } } call_arguments(c) = cel; } Force declaration statement s to be a dummy derived entity declaration such as struct s;

Definition at line 1082 of file statement.c.

Referenced by dummy_prettyprint_control_list_p(), and set_prettyprint_control_list_to_dummy().

◆ extern_declaration_p

bool extern_declaration_p = false
static

Force declaration statement s to be an extern declaration.

Definition at line 1040 of file statement.c.

Referenced by add_prettyprint_control_list_to_declaration_statement(), extern_prettyprint_control_list_p(), and set_prettyprint_control_list_to_extern().

◆ LabeledStatements

list LabeledStatements

BlockStack is used to handle block scope.

Definition at line 60 of file statement.c.

Referenced by FindStatementFromLabel(), MakeCurrentModule(), MakeGotoStatement(), and MakeLabeledStatement().

◆ LoopStack

◆ SwitchControllerStack

stack SwitchControllerStack = stack_undefined

◆ SwitchGotoStack

stack SwitchGotoStack = stack_undefined

list of labeled statements of the current module

Definition at line 62 of file statement.c.

Referenced by c_parser_error(), MakeCaseStatement(), MakeCurrentModule(), MakeDefaultStatement(), MakeSwitchStatement(), and ResetCurrentModule().