PIPS
c_syntax.h File Reference
#include "c_parser_private.h"
+ Include dependency graph for c_syntax.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define get_label_prefix()   "-"
 The labels in C have function scope... More...
 
#define FIRST_C_LINE_NUMBER   (1)
 Error handling. More...
 
#define UNDEFINED_C_LINE_NUMBER   (-1)
 
#define CParserError(m)   c_parser_error(CURRENT_FUNCTION, m)
 
#define c_parser_user_warning(...)    c_parser_user_warning_func(CURRENT_FUNCTION, __FILE__, __LINE__, __VA_ARGS__)
 

Functions

int c_lex ()
 
int c_parse ()
 
entity GetFunction (void)
 cproto workaround More...
 
void reset_expression_comment (void)
 we don't want an expression comment with new lines, it is disgracefull More...
 
string pop_block_scope (string)
 The scope is moved up the scope tree and a NULL is return when there are no more scope to explore. More...
 
string scope_to_block_scope (string)
 Allocate a new string containing only block scope information. More...
 
c_parser_context CreateDefaultContext (void)
 
void InitScope (void)
 
int ScopeStackSize (void)
 
string GetScope (void)
 
string GetParentScope (void)
 
void ExitScope (void)
 
void PushContext (c_parser_context)
 
void PopContext (void)
 
c_parser_context GetContext (void)
 
c_parser_context GetContextCopy (void)
 
void reset_declaration_counter (void)
 
int get_declaration_counter (void)
 
void init_c_parser_scope_stack (void)
 
void reset_c_parser_scope_stack (void)
 
void force_reset_c_parser_scope_stack (void)
 To be used by an error handler. More...
 
void push_new_c_parser_scope (void)
 
void pop_c_parser_scope_stack (void)
 
bool c_parser_scope_stack_empty_p (void)
 
string get_c_parser_current_scope (void)
 
string get_c_parser_nth_scope (int)
 
int c_parser_number_of_scopes (void)
 
int get_previous_c_lineno (void)
 
unsigned int character_occurences_in_string (string, char)
 Use a stack to survive to file inclusions if any. More...
 
int get_current_C_line_number (void)
 
int get_previous_C_line_number (void)
 Should be called just before get_current_C_line_number. More...
 
void set_current_C_line_number (void)
 
void push_current_C_line_number (void)
 The line number stack, designed for structured control structure, is not used yet. More...
 
int pop_current_C_line_number (void)
 
void reset_current_C_line_number (void)
 
void error_reset_current_C_line_number (void)
 
void reset_token_has_been_seen_p (void)
 
string get_current_C_comment (void)
 Return the current comment as a string to be freed by the caller and reset the current comment. More...
 
void push_current_C_comment (void)
 Push the current C comment so that we can get it back when building the statement later. More...
 
string pop_current_C_comment (void)
 Pop the current comment. More...
 
void update_C_comment (string)
 Add a comment to the current one. More...
 
void remove_LFs_from_C_comment (int)
 Remove "extra_LF" trailing LF from C_current_comment if they can be found at the end of the comment string. More...
 
void discard_C_comment (void)
 Discard a C comment because we don't know how to deal with it. More...
 
void reset_C_comment (bool)
 reset and reset_error should be handled differently More...
 
void error_reset_C_comment (bool)
 
void clear_C_comment (void)
 
void init_C_comment (void)
 
void c_error (char *)
 
void c_reset_lex (void)
 
int c_wrap (void)
 
string get_c_parser_current_input_file_name (void)
 
void set_c_parser_current_input_file_name (string)
 
void reset_c_parser_current_input_file_name (void)
 
void error_reset_c_parser_current_input_file_name (void)
 
string get_c_parser_current_user_input_file_name (void)
 
void set_c_parser_current_user_input_file_name (string)
 
void reset_c_parser_current_user_input_file_name (void)
 
void error_reset_c_parser_current_user_input_file_name (void)
 
void init_entity_type_storage_table (void)
 
void put_to_entity_type_stack_table (entity, stack value)
 
stack get_from_entity_type_stack_table (entity)
 
void remove_entity_type_stack (entity)
 
void remove_entity_type_stacks (list)
 
void reset_entity_type_stack_table (void)
 
void parser_init_keyword_typedef_table (void)
 
bool c_parser_error (const char *, const char *)
 Output a parser message error. More...
 
void make_predefined_C_entities (string)
 
bool c_parser (const char *)
 
bool compilation_unit_parser (const char *)
 
void MakeCurrentModule (entity)
 is used for switch statements also, because we do not distinguish a break in a loop or a switch More...
 
void ResetCurrentModule (void)
 
void InitializeBlock (void)
 
statement MakeBlock (list)
 Create a block statement. More...
 
statement FindStatementFromLabel (entity)
 
statement MakeLabeledStatement (string, statement, string)
 Construct a new statement from. More...
 
statement MakeGotoStatement (string)
 
entity MakeCLabel (string)
 
statement MakeWhileLoop (list, statement, bool)
 
statement MakeForloop (expression, expression, expression, statement)
 Create a for-loop statement with some parser-specific characteristics. More...
 
statement MakeForloopWithIndexDeclaration (list, expression, expression, statement)
 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)
 
statement MakeCaseStatement (expression)
 Transform. More...
 
statement MakeDefaultStatement (void)
 
statement MakeBreakStatement (string)
 
statement MakeContinueStatement (string)
 
statement ExpressionToStatement (expression)
 e is now owned by returned statement More...
 
list add_prettyprint_control_list_to_declaration_statement (statement, list)
 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...
 
void c_parser_user_warning_alist (const char *, const char *, const int, const char *, va_list *)
 util.c More...
 
void c_parser_user_warning_func (const char *, const char *, const int, const char *,...)
 
void reset_current_dummy_parameter_number (void)
 
entity get_top_level_entity (void)
 
void MakeTopLevelEntity (void)
 
void init_c_areas (void)
 In C we have 4 areas. More...
 
entity make_C_constant_entity (string, tag, size_t)
 
void init_c_implicit_variables (entity)
 
entity get_current_compilation_unit_entity (void)
 
void MakeCurrentCompilationUnitEntity (const char *)
 A compilation unit is also considered as a module. More...
 
void ResetCurrentCompilationUnitEntity (bool)
 
expression MakeFunctionExpression (expression, list)
 e is now owned by returned expression and must not be used any longer More...
 
expression MemberDerivedIdentifierToExpression (type, string)
 
expression MemberIdentifierToExpression (expression, string)
 
expression IdentifierToExpression (string)
 
expression MakeArrayExpression (expression, list)
 FI: this function is called for a bracketed comma expression. More...
 
entity FindEntityFromLocalName (string)
 
entity FindOrCreateEntityFromLocalNameAndPrefix (string, string, bool)
 
entity FindOrCreateEntityFromLocalNameAndPrefixAndScope (string, string, string, bool)
 
entity FindEntityFromLocalNameAndPrefixAndScope (string, string, string)
 The parameter "scope" is potentially destroyed. More...
 
entity FindEntityFromLocalNameAndPrefix (string, string)
 
entity CreateEntityFromLocalNameAndPrefix (string, string, bool)
 
bool CheckExternList (void)
 
void c_parser_put_new_typedef (const char *)
 Store named type for the lexical analyzer, which has to decide if a character string is the name of a type or the name of a variable. More...
 
void put_new_typedef (const char *)
 This function is used by libraries "step"* and "task_parallelization". More...
 
entity FindOrCreateCurrentEntity (string, stack, stack, stack, bool)
 
void UpdateParenEntity (entity, list)
 
dimension MakeDimension (list, list)
 
type UpdateFinalPointer (type, type)
 
void UpdatePointerEntity (entity, type, list)
 
void UpdateArrayEntity (entity, list, list)
 
entity RenameFunctionEntity (entity)
 Rename function oe if necessary. More...
 
void UpdateFunctionEntity (entity, list)
 The parser has found out that an entity is a function and partially sets its type. More...
 
type UpdateType (type, type)
 This function replaces the undefined field in t1 by t2. More...
 
void CCompilationUnitMemoryAllocations (entity, bool)
 This function allocates the memory to the Current Compilation Unit. More...
 
void CCompilationUnitMemoryAllocation (entity)
 
void CCompilationUnitMemoryReallocation (entity)
 
void CModuleMemoryAllocation (entity)
 This function is for MemoryAllocation for Module of C programs. More...
 
void UseDummyArguments (entity)
 If f has regular formal parameters, destroy them. More...
 
void UseFormalArguments (entity)
 If f has dummy formal parameters, replace them by standard formal parameters. More...
 
void RemoveDummyArguments (entity, list)
 To chase formals in type declarations. More...
 
void SubstituteDummyParameters (entity, list)
 
void CreateReturnEntity (entity)
 If necessary, create the return entity, which is a hidden variable used in PIPS internal representation to carry the value returned by a function. More...
 
void UpdateEntity2 (entity, stack, stack)
 
void UpdateEntity (entity, stack, stack, stack, stack, bool, bool)
 Update the entity with final type, storage and initial value; and also (sometimes?) declare it at the module level. More...
 
void UpdateEntities (list, stack, stack, stack, stack, bool, bool)
 
void CleanUpEntities (list)
 
void UpdateAbstractEntity (entity, stack)
 
void RemoveFromExterns (entity)
 
void AddToExterns (entity, entity)
 
void AddToDeclarations (entity, entity)
 FI: check the difference with AddEntityToDeclarations() More...
 
void UpdateDerivedEntity (list, entity, stack)
 
list TakeDerivedEntities (list)
 
void UpdateDerivedEntities (list, list, stack)
 
void InitializeEnumMemberValues (list)
 
entity MakeDerivedEntity (string, list, bool, int)
 
storage MakeStorageRam (entity, bool, bool)
 The storage part should not be called twice when reparsing compilation unit. More...
 
string CreateMemberScope (string, bool)
 
value MakeEnumeratorInitialValue (list, int)
 
int ComputeAreaOffset (entity, entity)
 
list MakeParameterList (list, list, stack)
 
parameter FindParameterEntity (string, int, list)
 
void AddToCalledModules (entity)
 
void NStackPop (stack, int)
 Pop n times the stack s. More...
 
void StackPop (stack)
 The OffsetStack is poped n times, where n is the number of formal arguments of the actual function. More...
 
void StackPush (stack)
 The OffsetStack is pushed incrementally. More...
 
void set_entity_initial (entity, expression)
 Be careful if the initial value has already been set. More...
 
bool check_declaration_uniqueness_p (statement)
 This is designed for standard C functions, not for compilation units. More...
 
list insert_qualifier (list, qualifier)
 if qualifier "nq" does not already belong to qualifier list "ql", add it in front of the list. More...
 
void reset_preprocessor_line_analysis (void)
 
int analyze_preprocessor_line (string, int)
 Analyze information about user line number provided by the C preprocessor and by PIPS file splitter and return the C line number in the source file. More...
 
entity Generate_C_ReturnLabel (entity)
 return.c More...
 
statement Generate_C_ReturnStatement (void)
 
void Reset_C_ReturnStatement (void)
 The return statement must be reset when it is used by the parser to add the return statement to the function body or when a parser error is encountered. More...
 
statement Get_C_ReturnStatement (void)
 This function is used to generate all goto's towards the unique return used to C replace return statement and to insert this unique return at the end of the current function's body. More...
 
statement C_MakeReturnStatement (list, int, string)
 This function creates a goto instruction to label end_label. More...
 
int GetReturnNumber (void)
 
void FixCReturnStatements (statement)
 When return statements have been encountered, each of them has been replaced by a goto to a unique return statement. More...
 
void c_restart (FILE *)
 
void c_pop_buffer_state (void)
 
int c_get_lineno (void)
 
FILE * c_get_in (void)
 
FILE * c_get_out (void)
 
int c_get_leng (void)
 
char * c_get_text (void)
 
void c_set_lineno (int)
 
void c_set_in (FILE *)
 
void c_set_out (FILE *)
 
int c_get_debug (void)
 
void c_set_debug (int)
 
int c_lex_destroy (void)
 
void * c_alloc (yy_size_t)
 
void * c_realloc (void *, yy_size_t)
 
void c_free (void *)
 

Variables

FILE * c_in
 Warning! Do not modify this file that is automatically generated! More...
 
int c_lineno
 the file read in by the c_lexer More...
 
entity DynamicArea
 These global variables are declared in ri-util/util.c. More...
 
entity StaticArea
 
entity HeapArea
 
entity StackArea
 
entity AllocatableArea
 
int C_line_increment
 from "clex.l" More...
 
string compilation_unit_name
 cproto-generated files More...
 
list CalledModules
 
statement ModuleStatement
 
stack ContextStack
 
stack FunctionStack
 
stack FormalStack
 
stack OffsetStack
 
stack StructNameStack
 
int loop_counter
 Global counter. More...
 
int derived_counter
 
bool compilation_unit_parser_is_running_p
 To pass down the information to functions used by the syntactical analyzer. More...
 
list removable_extern_entities
 
stack BlockStack
 statement.c More...
 
list LabeledStatements
 BlockStack is used to handle block scope. More...
 
stack SwitchGotoStack
 list of labeled statements of the current module More...
 
stack SwitchControllerStack
 
stack LoopStack
 
int c_debug
 
int c_char
 
int c_nerrs
 
int c_leng
 clexer.c More...
 
FILE * c_out
 
int c__flex_debug
 
char * c_text
 

Macro Definition Documentation

◆ c_parser_user_warning

#define c_parser_user_warning (   ...)     c_parser_user_warning_func(CURRENT_FUNCTION, __FILE__, __LINE__, __VA_ARGS__)

Definition at line 63 of file c_syntax.h.

◆ CParserError

#define CParserError (   m)    c_parser_error(CURRENT_FUNCTION, m)

Definition at line 62 of file c_syntax.h.

◆ FIRST_C_LINE_NUMBER

#define FIRST_C_LINE_NUMBER   (1)

Error handling.

Definition at line 59 of file c_syntax.h.

◆ get_label_prefix

#define get_label_prefix ( )    "-"

The labels in C have function scope...

but beware of inlining... and conflict with user labels To disambiguate labels, in case inlining is performed later and to suppress the potential for conflicts with user labels.

Temporary entities have to be generated to be replaced later by the final labels. The temporary entities should be eliminated from the symbol table...

Definition at line 49 of file c_syntax.h.

◆ UNDEFINED_C_LINE_NUMBER

#define UNDEFINED_C_LINE_NUMBER   (-1)

Definition at line 60 of file c_syntax.h.

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:

◆ AddToCalledModules()

void AddToCalledModules ( entity  e)

Definition at line 3413 of file util.c.

3414 {
3415  if (!intrinsic_entity_p(e))
3416  {
3417  bool already_here = false;
3418  //string n = top_level_entity_p(e)?entity_local_name(e):entity_name(e);
3419  const char* n = entity_local_name(e);
3420  MAP(STRING,s,
3421  {
3422  if (strcmp(n, s) == 0)
3423  {
3424  already_here = true;
3425  break;
3426  }
3427  }, CalledModules);
3428 
3429  if (! already_here)
3430  {
3431  pips_debug(2, "Adding %s to list of called modules\n", n);
3433  }
3434  }
3435 }
list CalledModules
Definition: c_parser.c:51
#define STRING(x)
Definition: genC.h:87
#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 pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
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
char * strdup()

References CalledModules, CONS, entity_local_name(), intrinsic_entity_p(), MAP, pips_debug, strdup(), and STRING.

Referenced by MakeFunctionExpression().

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

◆ AddToDeclarations()

void AddToDeclarations ( entity  e,
entity  mod 
)

FI: check the difference with AddEntityToDeclarations()

Here, the declared entity is added to the module declarations only.

Parameters
modod

Definition at line 2924 of file util.c.

2925 {
2927 
2928  if (!gen_in_list_p(e,dl))
2929  {
2930  pips_debug(5,"Add entity \"%s\" (\"%s\") to module %s\n",
2931  entity_user_name(e),
2932  entity_name(e),
2933  entity_user_name(mod));
2936  CONS(ENTITY,e,NIL));
2937  }
2938 }
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define code_declarations(x)
Definition: ri.h:784
#define entity_name(x)
Definition: ri.h:2790
#define value_code(x)
Definition: ri.h:3067
#define entity_initial(x)
Definition: ri.h:2796

References code_declarations, CONS, ENTITY, entity_initial, entity_name, entity_user_name(), gen_in_list_p(), gen_nconc(), NIL, pips_debug, and value_code.

Referenced by CreateReturnEntity(), MakeFunctionExpression(), MakeParameterList(), and UpdateEntity().

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

◆ AddToExterns()

void AddToExterns ( entity  e,
entity  mod 
)
Parameters
modod

Definition at line 2898 of file util.c.

2899 {
2900  // the entity e can be extern variable and extern functions
2902 
2903  pips_assert("le is an entity list", entity_list_p(le));
2904 
2905  if(!gen_in_list_p(e, le))
2906  {
2907  pips_debug(5,"Add entity %s to extern declaration %s \n",
2909  pips_assert("e is an entity", entity_domain_number(e)==entity_domain);
2910  pips_assert("mod is an entity", entity_domain_number(mod)==entity_domain);
2913  CONS(ENTITY,e,NIL));
2914 
2916  pips_assert("le is an entity list", entity_list_p(le));
2917  }
2918 }
bool entity_list_p(list el)
Checks that el only contains entity.
Definition: entity.c:1411
#define code_externs(x)
Definition: ri.h:790
#define entity_domain_number(x)
Definition: ri.h:2788
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410

References code_externs, CONS, ENTITY, entity_domain, entity_domain_number, entity_initial, entity_list_p(), entity_user_name(), gen_in_list_p(), gen_nconc(), NIL, pips_assert, pips_debug, and value_code.

Referenced by FindOrCreateCurrentEntity(), and UpdateEntity().

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

◆ analyze_preprocessor_line()

int analyze_preprocessor_line ( string  line,
int  C_line_number 
)

Analyze information about user line number provided by the C preprocessor and by PIPS file splitter and return the C line number in the source file.

We do not have specs and must evolve with C preprocessors such as cpp.

We assume that information about the lines in the included files is only provided for compilation unit.

We assume that information about user line in a module is always related to the user source file, and that the first line has been generated by PIPS file splitter with syntax "x nnn", with no information about the user source file name.

See examples line00.c, line01.c, line02.c and line03.c. And do not forget cominc02 for the compilation unit case. And missing01.c for synthesized code.

More examples needed for include lines placed within a function body, with C code or preprocessor definitions: line04 and line05.

the C preprocessors, such as cpp, and PIPS file splitter provide line information in pragmas which are not line pragmas.

Not too sure about C source code generated by PIPS by passes initializer, clone, outlining, inlinging...

strstr(line, "#line")==line &&

Not to sure about this case

The next lines have been imported from an included file. Ignore information about include files, preserve the current C_line_number.

Not to sure about this case: internal error?

Parameters
lineine
C_line_number_line_number

Definition at line 3617 of file util.c.

3618 {
3619  // In compilation units, ignore information about include files
3620  // Could be used so size "buffer", but not "init_buffer"
3621  // int s = strlen(line);
3622  char buffer[1024];
3623  static char init_buffer[1024];
3624 
3625  pips_debug(9,"Pragma-like comment %s\n",line);
3626 
3627  /* the C preprocessors, such as cpp, and PIPS file splitter provide
3628  * line information in pragmas which are not #line pragmas.
3629  *
3630  * Not too sure about C source code generated by PIPS by passes
3631  * initializer, clone, outlining, inlinging...
3632  */
3633 
3634  if(/* strstr(line, "#line")==line && */ strlen(line)>=4) {
3635  int initial_C_line_number = -1;
3636  int items = sscanf(line+1, "%d %s", &initial_C_line_number, buffer);
3637  if(items==2) {
3638  // if(C_line_number==UNDEFINED_C_LINE_NUMBER) {
3639  //if(C_line_number==FIRST_C_LINE_NUMBER) {
3640  // Local files are named either "./foo.c" or "foo.c"
3641  int skip = 0;
3642  if(buffer[1]=='.' && buffer[2]=='/') {
3643  skip = 2;
3644  buffer[2] = '"';
3645  }
3646  if(!buffer_initialized_p) {
3647  //if(strstr(buffer, ".h"))
3648  //fprintf(stderr, "Abnormal file name %s\n", buffer);
3649  buffer_initialized_p = true;
3650  C_line_number = initial_C_line_number;
3651  C_line_increment = 1;
3652  (void) strcpy(init_buffer, buffer+skip);
3653  }
3654  else if(same_string_p((string) (buffer+skip), (string) init_buffer)) {
3655  C_line_increment = 1;
3657  && C_line_number>initial_C_line_number) {
3658  int d = C_line_number-initial_C_line_number;
3660  C_line_number = initial_C_line_number;
3661  }
3662  else {
3663  /* Not to sure about this case */
3664  C_line_number = initial_C_line_number;
3665  }
3666  }
3667  else {
3668  /* The next lines have been imported from an included file.
3669  * Ignore information about include files, preserve the
3670  * current C_line_number.
3671  */
3672  C_line_increment = 0;
3673  }
3674  }
3675  else if(items==1) {
3676  /* Not to sure about this case: internal error? */
3677  C_line_number = initial_C_line_number;
3678  }
3679  else {
3680  // items==0
3681  pips_user_warning("No line number after a #: \"%s\".\n", line);
3682  CParserError("Ill. formated # pragma.\n");
3683  }
3684  }
3685  return C_line_number;
3686 }
bool compilation_unit_parser_is_running_p
To pass down the information to functions used by the syntactical analyzer.
Definition: c_parser.c:541
void remove_LFs_from_C_comment(int)
Remove "extra_LF" trailing LF from C_current_comment if they can be found at the end of the comment s...
Definition: clexer.c:1398
int C_line_increment
from "clex.l"
Definition: c_syntax.h:296
static bool buffer_initialized_p
Definition: util.c:3590
static int C_line_number
To track the user line number, that is the one in the original user file.
Definition: clexer.c:1102
void CParserError(char *msg)
#define pips_user_warning
Definition: misc-local.h:146
#define same_string_p(s1, s2)
static int line
FLEX_SCANNER.
Definition: scanner.c:852
static string buffer
Definition: string.c:113

References buffer, buffer_initialized_p, C_line_increment, C_line_number, compilation_unit_parser_is_running_p, CParserError(), line, pips_debug, pips_user_warning, remove_LFs_from_C_comment(), and same_string_p.

+ Here is the call graph for this function:

◆ c_alloc()

void* c_alloc ( yy_size_t  )

◆ c_error()

void c_error ( char *  )

◆ c_free()

void c_free ( void *  )

◆ c_get_debug()

int c_get_debug ( void  )

◆ c_get_in()

FILE* c_get_in ( void  )

◆ c_get_leng()

int c_get_leng ( void  )

◆ c_get_lineno()

int c_get_lineno ( void  )

◆ c_get_out()

FILE* c_get_out ( void  )

◆ c_get_text()

char* c_get_text ( void  )

◆ c_lex()

int c_lex ( )

◆ c_lex_destroy()

int c_lex_destroy ( void  )

◆ C_MakeReturnStatement()

statement C_MakeReturnStatement ( list  el,
int  ln,
string  c 
)

This function creates a goto instruction to label end_label.

This is done to eliminate return statements.

Note: I was afraid the mouse trap would not work to analyze multiple procedures but there is no problem. I guess that MakeGotoInst() generates the proper label entity regardless of end_label. FI. Generates the internal representation of a C return statement. If e is an undefined expression, a goto returnlabel is generated. Else, e is assigned to the return value of the current function, a goto is generated and both are returned within a block.

Assign the expression to the return value of the current function

Parameters
ell
lnn

Definition at line 155 of file return.c.

156 {
161 
162  last_returned_value = el;
163 
164  if(!ENDP(el)) {
165  /* Assign the expression to the return value of the current
166  function */
169  if(ENDP(CDR(el))) {
170  expression e = EXPRESSION(CAR(el));
172  }
173  else {
174  pips_internal_error("This case is not implemented yet.");
175  }
176  }
177 
179 
180  if(instruction_undefined_p(ainst)) {
181  inst = ginst;
183  ln,
185  c,
186  inst,
187  NIL,
190  }
191  else {
193  ln,
195  c,
196  ainst,
197  NIL,
201  list sl = CONS(STATEMENT, as, CONS(STATEMENT, gs, NIL));
203  inst = make_instruction_block(sl);
204  s = instruction_to_statement(inst);
205  }
206 
207  pips_assert("inst is consistent", instruction_consistent_p(inst));
208  pips_assert("s is consistent", statement_consistent_p(s));
209 
210 
211  return s;
212 }
bool instruction_consistent_p(instruction p)
Definition: ri.c:1124
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
synchronization make_synchronization_none(void)
Definition: ri.c:2424
instruction make_instruction_goto(statement _field_)
Definition: ri.c:1181
static statement last_return_value_assignment
Definition: return.c:75
static list last_returned_value
Definition: return.c:74
statement Get_C_ReturnStatement()
This function is used to generate all goto's towards the unique return used to C replace return state...
Definition: return.c:130
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
instruction make_assign_instruction(expression l, expression r)
Definition: instruction.c:87
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define string_undefined
Definition: newgen_types.h:40
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
entity entity_empty_label(void)
Definition: entity.c:1105
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
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
#define instruction_undefined_p(x)
Definition: ri.h:1455
#define instruction_undefined
Definition: ri.h:1454
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References CAR, CDR, CONS, empty_extensions(), ENDP, entity_empty_label(), entity_to_expression(), EXPRESSION, f(), function_to_return_value(), Get_C_ReturnStatement(), get_current_module_entity(), instruction_consistent_p(), instruction_to_statement(), instruction_undefined, instruction_undefined_p, last_return_value_assignment, last_returned_value, make_assign_instruction(), make_instruction_block(), make_instruction_goto(), make_statement(), make_synchronization_none(), NIL, pips_assert, pips_internal_error, STATEMENT, statement_consistent_p(), STATEMENT_ORDERING_UNDEFINED, statement_undefined, and string_undefined.

+ Here is the call graph for this function:

◆ c_parse()

int c_parse ( )

◆ c_parser()

bool c_parser ( const char *  module_name)

When the compilation_unit is parsed, it is parsed a second time and multiple declarations are certain to happen.

Parameters
module_nameodule_name

Definition at line 739 of file c_parser.c.

740 {
741  /* When the compilation_unit is parsed, it is parsed a second time
742  and multiple declarations are certain to happen. */
743  return actual_c_parser(module_name,DBR_C_SOURCE_FILE,false);
744 }
static bool actual_c_parser(const char *module_name, string dbr_file, bool is_compilation_unit_parser)
Definition: c_parser.c:544
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296

References actual_c_parser(), and module_name().

+ Here is the call graph for this function:

◆ c_parser_error()

bool c_parser_error ( const char *  func,
const char *  msg 
)

Output a parser message error.

At the end there is a pips_user_error that launch an exception so that this function may not really exit but may be caught at a higher level...

This function is called by macro CParserError()

Since many information are lost by the various resetting, first save them for later display:

Reset the parser global variables ?

The error may occur before the current module entity is defined

Stacks are not allocated yet when dealing with external declarations. I assume that all stacks are declared simultaneously, hence a single test before freeing.

Reset them to stack_undefined_p instead of STACK_NULL

get rid of all collected comments

ffective_line_number,

Parameters
funcunc
msgsg

Definition at line 266 of file c_parser.c.

267 {
269  const char * mod_name = entity_undefined_p(mod)? "entity_undefined":entity_user_name(mod);
270  /* Since many information are lost by the various resetting, first save
271  them for later display: */
273  //int effective_line_number = c_lineno;
274 
275  pips_debug(1, "Parser error detected in function \"%s\".\n", func);
276 
277  c_reset_lex();
278 
279  /* Reset the parser global variables ?*/
280 
281  pips_debug(4,"Reset current module entity %s\n", mod_name);
282 
283  /* The error may occur before the current module entity is defined */
287 
288  // Get rid of partly declared variables
289  if(mod!=entity_undefined) {
290  value v = entity_initial(mod);
291  code c = value_code(v);
292 
293  code_declarations(c) = NIL;
295  CleanLocalEntities(mod);
296  }
297 
298  // Free CalledModules?
299 
300  // Could not rebuild filename (A. Mensi)
301  // c_in = safe_fopen(file_name, "r");
302  // safe_fclose(c_in, file_name);
303 
304  /* Stacks are not allocated yet when dealing with external
305  declarations. I assume that all stacks are declared
306  simultaneously, hence a single test before freeing. */
307  if(!entity_undefined_p(mod)) {
315  /* Reset them to stack_undefined_p instead of STACK_NULL */
320 
331  }
332  }
333 
335  /* get rid of all collected comments */
336  reset_C_comment(true);
339 
340  //debug_off();
341 
342  pips_user_warning("\nRecovery from C parser failure not (fully) implemented yet.\n"
343  "C parser is likely to fail later if re-used.\n");
347  pips_user_error("\n%s at user line %d in file \"%s\"\n",
348  msg, user_line_number, /*effective_line_number,*/ fn);
349  // Never reached, but for compatibility with Fortran ParserError
350  return true;
351 }
void error_reset_c_parser_current_user_input_file_name(void)
Definition: c_parser.c:112
void reset_entity_type_stack_table()
Definition: c_parser.c:186
stack StructNameStack
Definition: c_parser.c:121
void error_reset_c_parser_current_input_file_name(void)
Definition: c_parser.c:81
stack OffsetStack
Definition: c_parser.c:120
stack FunctionStack
Definition: c_parser.c:118
string get_c_parser_current_user_input_file_name()
Definition: c_parser.c:89
stack FormalStack
Definition: c_parser.c:119
stack ContextStack
Definition: c_parser.c:117
void reset_expression_comment(void)
we don't want an expression comment with new lines, it is disgracefull
Definition: cyacc.tab.c:169
void reset_declaration_counter(void)
Definition: cyacc.tab.c:492
int get_current_C_line_number(void)
Definition: clexer.c:1146
void reset_C_comment(bool)
reset and reset_error should be handled differently
Definition: clexer.c:1450
void c_reset_lex(void)
void error_reset_current_C_line_number(void)
Definition: clexer.c:1224
void force_reset_c_parser_scope_stack(void)
To be used by an error handler.
Definition: cyacc.tab.c:539
stack SwitchControllerStack
Definition: statement.c:63
stack LoopStack
Definition: statement.c:64
void Reset_C_ReturnStatement(void)
The return statement must be reset when it is used by the parser to add the return statement to the f...
Definition: return.c:115
stack SwitchGotoStack
list of labeled statements of the current module
Definition: statement.c:62
stack BlockStack
statement.c
Definition: statement.c:58
void reset_current_dummy_parameter_number(void)
Definition: util.c:144
void CleanLocalEntities(entity function)
Fortran version.
Definition: clean.c:140
#define pips_user_error
Definition: misc-local.h:147
#define stack_undefined
Definition: newgen_stack.h:55
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
#define stack_undefined_p(s)
Definition: newgen_stack.h:56
int user_line_number
To be exported to the parser for error messages related to the user file.
Definition: lexer.c:1087
void error_reset_current_module_entity(void)
To be called by an error management routine only.
Definition: static.c:109
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define code_decls_text(x)
Definition: ri.h:786

References BlockStack, c_reset_lex(), CleanLocalEntities(), code_declarations, code_decls_text, ContextStack, entity_initial, entity_undefined, entity_undefined_p, entity_user_name(), error_reset_c_parser_current_input_file_name(), error_reset_c_parser_current_user_input_file_name(), error_reset_current_C_line_number(), error_reset_current_module_entity(), force_reset_c_parser_scope_stack(), FormalStack, FunctionStack, get_c_parser_current_user_input_file_name(), get_current_C_line_number(), get_current_module_entity(), LoopStack, NIL, OffsetStack, pips_debug, pips_user_error, pips_user_warning, reset_C_comment(), Reset_C_ReturnStatement(), reset_current_dummy_parameter_number(), reset_declaration_counter(), reset_entity_type_stack_table(), reset_expression_comment(), stack_free(), stack_undefined, stack_undefined_p, string_undefined, StructNameStack, SwitchControllerStack, SwitchGotoStack, user_line_number, and value_code.

Referenced by make_C_constant_entity().

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

◆ c_parser_number_of_scopes()

int c_parser_number_of_scopes ( void  )

Definition at line 587 of file cyacc.tab.c.

588  {
590  return n;
591  }
static stack c_parser_scope_stack
Definition: cyacc.tab.c:512
int stack_size(const stack)
observers

◆ c_parser_put_new_typedef()

void c_parser_put_new_typedef ( const char *  name)

Store named type for the lexical analyzer, which has to decide if a character string is the name of a type or the name of a variable.

See is_c_parser_keyword_typedef() in clex.l

Parameters
nameame

Definition at line 1060 of file util.c.

1061 {
1062  string s = get_c_parser_current_scope();
1063  string sname = string_undefined;
1064  if(same_string_p(s, ""))
1065  sname = strdup(name);
1066  else
1067  sname = strdup(concatenate(name,"%", s, NULL));
1068  hash_put(keyword_typedef_table, sname,(void *) TK_NAMED_TYPE);
1069  pips_debug(5, "Add typedef name %s to hash table\n",sname);
1070 }
string get_c_parser_current_scope(void)
Definition: cyacc.tab.c:569
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
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
hash_table keyword_typedef_table
Because of typedefs, the C lexers need help to decide if a character string such as toto is a type na...
Definition: static.c:253
#define TK_NAMED_TYPE
Definition: splitc.c:760

References concatenate(), get_c_parser_current_scope(), hash_put(), keyword_typedef_table, pips_debug, same_string_p, strdup(), string_undefined, and TK_NAMED_TYPE.

Referenced by FindOrCreateCurrentEntity().

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

◆ c_parser_scope_stack_empty_p()

bool c_parser_scope_stack_empty_p ( void  )

Definition at line 564 of file cyacc.tab.c.

565 {
567 }
bool stack_empty_p(const stack)

Referenced by get_c_parser_current_scope().

+ Here is the caller graph for this function:

◆ c_parser_user_warning_alist()

void c_parser_user_warning_alist ( const char *  pips_func,
const char *  pips_file,
const int  pips_line,
const char *  format,
va_list *  args 
)

util.c

util.c

Parser warning on C code synthesized by PIPS

Parameters
pips_funcips_func
pips_fileips_file
pips_lineips_line
formatormat
argsrgs

Definition at line 60 of file util.c.

66 {
67  if (get_bool_property("NO_USER_WARNING"))
68  return;
69 
70  // First and current line number in PIPS preprocessed file (ifn)
72  int fln = get_previous_c_lineno();
73  int uln = c_lineno;
74  string ifn_src = safe_get_line_interval(ifn, fln, uln);
75 
76  // Previous and current line numbers, in user input file (uifn)
77  // ??? string_undefined for pips generated code?
79  int pln = get_previous_C_line_number();
80  int cln = get_current_C_line_number();
81 
82  // Do not print more than 10 lines: the beginning of the user
83  // input C file may be full of includes and comments all
84  // considered related to the first declaration.
85  pips_assert("consistent line numbers", 1 <= pln && pln <= cln);
86  if (pln < cln-9)
87  pln = cln-9;
88 
89  string uifn_src = safe_get_line_interval(uifn, pln, cln);
90 
91  string more;
92 
93  asprintf(&more,
94  "Source code after preprocessing:\n%s"
95  "Input source code, before preprocessing:\n%s",
96  ifn_src, uifn_src);
97 
100  (const string) pips_func, (const string) pips_file, pips_line,
101  NULL, uifn, pln, cln,
102  NULL, more, (const string) format, args);
103 
104  free(more);
105 
106  // else???
107  /* Parser warning on C code synthesized by PIPS */
108  // pips_internal_error("Some synthesized code raises a "
109  // "C parser warning.\n");
110 }
void pips_log_alist(const pips_log_t tag, const string pips_pass, const string pips_owner, const string pips_func, const string pips_file, const int pips_line, const string user_func, const string user_file, const int user_line, const int user_line2, const string stmt, const string suggestion, const string format, va_list *args)
log entry with unprocessed format/alist arguments
Definition: message.c:1200
string get_pips_current_pass_name(void)
Export this piece of information to customize warning functions in passes.
Definition: message.c:77
string get_pips_current_module(void)
Definition: message.c:82
string get_c_parser_current_input_file_name()
Definition: c_parser.c:58
int get_previous_c_lineno(void)
Definition: clexer.c:1115
int get_previous_C_line_number(void)
Should be called just before get_current_C_line_number.
Definition: clexer.c:1161
int c_lineno
the file read in by the c_lexer
Definition: c_syntax.h:293
string safe_get_line_interval(const string fn, int f, int l)
return lines f-l from file fn as a string
Definition: file.c:539
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
#define asprintf
Definition: misc-local.h:225
@ warning_log
Definition: misc-local.h:34

References asprintf, c_lineno, free(), get_bool_property(), get_c_parser_current_input_file_name(), get_c_parser_current_user_input_file_name(), get_current_C_line_number(), get_pips_current_module(), get_pips_current_pass_name(), get_previous_C_line_number(), get_previous_c_lineno(), pips_assert, pips_log_alist(), safe_get_line_interval(), and warning_log.

Referenced by c_parser_user_warning_func().

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

◆ c_parser_user_warning_func()

void c_parser_user_warning_func ( const char *  pips_func,
const char *  pips_file,
const int  pips_line,
const char *  format,
  ... 
)
Parameters
pips_funcips_func
pips_fileips_file
pips_lineips_line
formatormat

Definition at line 112 of file util.c.

118 {
119  va_list args;
120  va_start(args, format);
121  c_parser_user_warning_alist(pips_func, pips_file, pips_line, format, &args);
122  va_end(args);
123 }
void c_parser_user_warning_alist(const char *pips_func, const char *pips_file, const int pips_line, const char *format, va_list *args)
Compared to pips_user_warning(), the name of the calling function is lost, which does not help mainte...
Definition: util.c:60

References c_parser_user_warning_alist().

+ Here is the call graph for this function:

◆ c_pop_buffer_state()

void c_pop_buffer_state ( void  )

◆ c_realloc()

void* c_realloc ( void *  ,
yy_size_t   
)

◆ c_reset_lex()

void c_reset_lex ( void  )

◆ c_restart()

void c_restart ( FILE *  )

◆ c_set_debug()

void c_set_debug ( int  )

◆ c_set_in()

void c_set_in ( FILE *  )

◆ c_set_lineno()

void c_set_lineno ( int  )

◆ c_set_out()

void c_set_out ( FILE *  )

◆ c_wrap()

int c_wrap ( void  )

◆ CCompilationUnitMemoryAllocation()

void CCompilationUnitMemoryAllocation ( entity  module)
Parameters
moduleodule

Definition at line 1967 of file util.c.

1968 {
1970 }
void CCompilationUnitMemoryAllocations(entity module, bool first_p)
This function allocates the memory to the Current Compilation Unit.
Definition: util.c:1881
static char * module
Definition: pips.c:74

References CCompilationUnitMemoryAllocations(), and module.

Referenced by ResetCurrentCompilationUnitEntity().

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

◆ CCompilationUnitMemoryAllocations()

void CCompilationUnitMemoryAllocations ( entity  module,
bool  first_p 
)

This function allocates the memory to the Current Compilation Unit.

Check that all variables used or defined are declared

Allocate variables

We are in trouble

check the type of variable here to avoid conflicting declarations

The C parser is no longer active when this warning is emitted. It is not possible to rely on its line numbers.

No way to know if a pointer is initialized or not

This may happen with variables such as "__morecore" which is a functional pointer to a malloc like function and which is declared in a header file.

It may or not be an error, depending on conflicting initializations or not. It seems better to leave this for gcc or clang to decide before running PIPS.

Do not modify the initial allocation

Do not allocate the memory for external variables: Set the offset of ram -2 which signifies UNKNOWN offset

Parameters
moduleodule
first_pirst_p

Definition at line 1881 of file util.c.

1882 {
1884  entity var = entity_undefined;
1885 
1886  pips_debug(8,"MEMORY ALLOCATION BEGINS\n");
1887 
1888  /* Check that all variables used or defined are declared */
1890 
1891  /* Allocate variables */
1892  for(; !ENDP(ld); ld = CDR(ld)) {
1893  var = ENTITY(CAR(ld));
1895  storage s = entity_storage(var);
1896  type t = entity_type(var);
1897  type ut = ultimate_type(t);
1898 
1899  // Make sure that the ultimate type is variable */
1900  if(!type_variable_p(ut) && storage_ram_p(s)) {
1901  /* We are in trouble */
1902  pips_internal_error("Variable %s has not a variable type",
1903  entity_user_name(var));
1904  }
1905 
1906  // Add some preconditions here
1907  if(storage_ram_p(s)) {
1908  ram r = storage_ram(s);
1909  entity a = ram_section(r);
1910  /* check the type of variable here to avoid conflicting declarations */
1911  // External variable list: evl
1913  if(!gen_in_list_p(var, evl)) {
1916  && ram_offset(r) != DYNAMIC_RAM_OFFSET ) {
1917  if(first_p) {
1918  /* The C parser is no longer active when this warning is emitted.
1919  * It is not possible to rely on its line numbers.
1920  */
1921  // c_parser_user_warning
1923  ("Multiple declarations of variable \"%s\" in different files\n",
1924  entity_local_name(var));
1925  if(top_level_entity_p(a)
1927  /* No way to know if a pointer is initialized or
1928  not */
1929  ||value_code_p(entity_initial(var)))) {
1930  /* This may happen with variables such as
1931  "__morecore" which is a functional pointer to a
1932  malloc like function and which is declared in a
1933  header file. */
1934  ;
1935  }
1936  else {
1937  // CParserError("Fix your source code!\n");
1938  /* It may or not be an error, depending on conflicting
1939  * initializations or not. It seems better to leave
1940  * this for gcc or clang to decide before running
1941  * PIPS.
1942  */
1943  }
1944  /* Do not modify the initial allocation */
1945  ;
1946  }
1947  }
1948  else {
1950  add_C_variable_to_area(a,var);
1951  }
1952  }
1953  else {
1954  /* Do not allocate the memory for external variables:
1955  Set the offset of ram -2 which signifies UNKNOWN offset
1956  */
1957 
1958  // Check type here to avoid conflict declarations
1959  if(ram_offset(r) == UNKNOWN_RAM_OFFSET)
1961  }
1962  }
1963  }
1964  }
1965 }
statement ModuleStatement
Definition: c_parser.c:53
static void nodecl_p(entity __attribute__((unused)) module, statement stat)
Definition: util.c:1868
#define DYNAMIC_RAM_OFFSET
FI: I would have assumed that it is used for the stack area, but I must be wrong.....
#define UNKNOWN_RAM_OFFSET
#define UNDEFINED_RAM_OFFSET
#define entity_declarations(e)
MISC: newgen shorthands.
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
type ultimate_type(type)
Definition: type.c:3466
bool place_holder_variable_p(entity)
Definition: variable.c:2069
int add_C_variable_to_area(entity, entity)
Definition: variable.c:1381
#define value_code_p(x)
Definition: ri.h:3065
#define area_size(x)
Definition: ri.h:544
#define value_unknown_p(x)
Definition: ri.h:3077
#define entity_storage(x)
Definition: ri.h:2794
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define type_area(x)
Definition: ri.h:2946
#define storage_ram(x)
Definition: ri.h:2521
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define ram_offset(x)
Definition: ri.h:2251

References add_C_variable_to_area(), area_size, CAR, CDR, code_externs, DYNAMIC_RAM_OFFSET, ENDP, ENTITY, entity_declarations, entity_initial, entity_local_name(), entity_storage, entity_type, entity_undefined, entity_user_name(), gen_in_list_p(), module, ModuleStatement, nodecl_p(), pips_debug, pips_internal_error, pips_user_warning, place_holder_variable_p(), ram_offset, ram_section, storage_ram, storage_ram_p, top_level_entity_p(), type_area, type_variable_p, ultimate_type(), UNDEFINED_RAM_OFFSET, UNKNOWN_RAM_OFFSET, value_code, value_code_p, and value_unknown_p.

Referenced by CCompilationUnitMemoryAllocation(), and CCompilationUnitMemoryReallocation().

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

◆ CCompilationUnitMemoryReallocation()

void CCompilationUnitMemoryReallocation ( entity  module)
Parameters
moduleodule

Definition at line 1972 of file util.c.

1973 {
1975 }

References CCompilationUnitMemoryAllocations(), and module.

Referenced by ResetCurrentCompilationUnitEntity().

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

◆ character_occurences_in_string()

unsigned int character_occurences_in_string ( string  s,
char  c 
)

Use a stack to survive to file inclusions if any.

I guess that it is currently not used since file inclusion is already done by the preprocessor... RK To track the absolute line number in the file that is parsed use the default flex yylineno that is renamed c_lineno here Use a stack to survive to file inclusions if any Count the number of c in s.

Definition at line 1133 of file clexer.c.

1134 {
1135  string p = string_undefined;
1136  unsigned int count = 0;
1137 
1138  for(p=s; *p!='\0'; p++) {
1139  count += (*p==c)? 1 : 0 ;
1140  }
1141  return count;
1142 }
static int count
Definition: SDG.c:519

Referenced by discard_C_comment().

+ Here is the caller graph for this function:

◆ check_declaration_uniqueness_p()

bool check_declaration_uniqueness_p ( statement  s)

This is designed for standard C functions, not for compilation units.

e must be a function: they can be declared several times

Definition at line 3540 of file util.c.

3541 {
3542  list dl = statement_declarations(s);
3543  bool failure_p = false;
3544 
3545  FOREACH(ENTITY, e, dl) {
3546  int n = gen_occurences(e, dl);
3547  if(n>1) {
3548  /* e must be a function: they can be declared several times */
3549  type t = ultimate_type(entity_type(e));
3550 
3551  if(!type_functional_p(t)) {
3552  pips_debug(0, "Entity \"%s\" declared %d times.\n", entity_name(e), n);
3553  failure_p = true;
3554  }
3555  }
3556  }
3557  if(failure_p)
3558  pips_internal_error("Module declarations are not unique");
3559 
3560  return !failure_p;
3561 }
int gen_occurences(const void *vo, const list l)
count occurences of vo in l
Definition: list.c:746
#define type_functional_p(x)
Definition: ri.h:2950

References ENTITY, entity_name, entity_type, FOREACH, gen_occurences(), pips_debug, pips_internal_error, statement_declarations, type_functional_p, and ultimate_type().

Referenced by actual_c_parser().

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

◆ CheckExternList()

bool CheckExternList ( void  )

Definition at line 1025 of file util.c.

1026 {
1028  if(entity_undefined_p(f))
1029  pips_debug(5,"Current module is undefined\n");
1030  else {
1031  value fv = entity_initial(f);
1032  pips_debug(5,"Current module is function \"%s\"\n", entity_name(f));
1033  if(!value_undefined_p(fv)) {
1034  code fc = value_code(fv);
1035  if(!code_undefined_p(fc)) {
1036  list el = code_externs(fc);
1037  list le = gen_last(el);
1038  pips_debug(8, "Number of extern variables and functions: %zd\n",
1039  gen_length(el));
1040  if(gen_length(el)>0) {
1041  pips_debug(8, "Last entity %s in cons %p with car=%p and cdr=%p\n",
1042  entity_name(ENTITY(CAR(le))),
1043  le,
1044  &(le->car),
1045  (void *) (le->cdr));
1046  }
1047  pips_assert("externs is an entity list", entity_list_p(el));
1048  }
1049  }
1050  }
1051  return true;
1052 }
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#define value_undefined_p(x)
Definition: ri.h:3017
#define code_undefined_p(x)
Definition: ri.h:758
struct cons * cdr
The pointer to the next element.
Definition: newgen_list.h:43
gen_chunk car
The data payload of a list element.
Definition: newgen_list.h:42

References cons::car, CAR, cons::cdr, code_externs, code_undefined_p, ENTITY, entity_initial, entity_list_p(), entity_name, entity_undefined_p, f(), gen_last(), gen_length(), get_current_module_entity(), pips_assert, pips_debug, value_code, and value_undefined_p.

+ Here is the call graph for this function:

◆ CleanUpEntities()

void CleanUpEntities ( list  le)

update entity in module declarations

Update storage area

Update entity in current entity list

Remove entity from potentially removable externs and add it the new entity

Apparently, formal parameters may have been declared for such an entity and PIPS code dumps when the symbol table is written.

See decl62.c and decl63.c

Parameters
lee

Definition at line 2772 of file util.c.

2773 {
2774  list ce = list_undefined;
2775  bool found = false;
2776 
2777  for(ce=le; !ENDP(ce); POP(ce)) {
2778  entity e = ENTITY(CAR(ce));
2779  entity ne = CleanUpEntity(e);
2780  if(ne!=e) {
2783  list de = list_undefined;
2784  storage s = entity_storage(e);
2785 
2786  /* update entity in module declarations */
2787  found = false;
2788  for(de=d; !ENDP(de); POP(de)) {
2789  entity ed = ENTITY(CAR(de));
2790  if(ed==e) {
2791  CAR(de).p = (gen_chunk *) ne;
2792  found = true;
2793  }
2794  }
2795  if(!found)
2796  pips_internal_error("Entity to be replaced not declared");
2797 
2798  /* Update storage area */
2799  found = false;
2800  if(storage_ram_p(s)) {
2801  ram r = storage_ram(s);
2802  entity a = ram_section(r);
2804  list lde = list_undefined;
2805 
2806  for(lde=ld; !ENDP(lde); POP(lde)) {
2807  entity ed = ENTITY(CAR(lde));
2808  if(ed==e) {
2809  found = true;
2810  CAR(lde).p = (gen_chunk *) ne;
2811  }
2812  }
2813  if(!found)
2814  pips_internal_error("Entity to be replaced not allocated in its ram area");
2815  }
2816  else {
2817  pips_internal_error("Unexpected storage kind");
2818  }
2819 
2820  /* Update entity in current entity list */
2821  CAR(ce).p = (gen_chunk *) ne;
2822 
2823  /* Remove entity from potentially removable externs and add it
2824  the new entity */
2825  gen_remove(&removable_extern_entities, (void *) e);
2827 
2828  /* Apparently, formal parameters may have been declared for such
2829  * an entity and PIPS code dumps when the symbol table is
2830  * written.
2831  *
2832  * See decl62.c and decl63.c
2833  */
2834  //free_entity(e);
2835  }
2836  }
2837 }
list removable_extern_entities
Definition: c_parser.c:542
static entity CleanUpEntity(entity e)
if returned entity != original entity, e must be freed, otherwise an invalid entity is still tabulate...
Definition: util.c:2745
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define area_layout(x)
Definition: ri.h:546
A gen_chunk is used to store every object.
Definition: genC.h:58

References area_layout, CAR, CleanUpEntity(), code_declarations, CONS, ENDP, ENTITY, entity_initial, entity_storage, entity_type, gen_remove(), get_current_module_entity(), list_undefined, pips_internal_error, POP, ram_section, removable_extern_entities, storage_ram, storage_ram_p, type_area, and value_code.

+ Here is the call graph for this function:

◆ clear_C_comment()

void clear_C_comment ( void  )

Comments in the compilation unit and outside of function bodies are lost because they are related only to declarations and because comments on declarations are lost.

Definition at line 1489 of file clexer.c.

1490 {
1494  }
1495  /* Comments in the compilation unit and outside of function bodies
1496  are lost because they are related only to
1497  declarations and because comments on declarations are lost.*/
1498  if(!comments_empty_p()) {
1499  int count = 0;
1500  pips_debug(3, "Comments stack is not empty:\n");
1501  while(!comments_empty_p()) {
1502  string c = comments_pop();
1503  count++;
1504  pips_debug(3, "Element %d: \"%s\"\n",
1505  count, string_undefined_p(c) ? "string undefined" : c);
1506  if(!string_undefined_p(c))
1507  free(c);
1508  }
1509  }
1510  pips_assert("The comment stack is empty\n", comments_empty_p());
1511 }
static string C_current_comment
Comment management:
Definition: clexer.c:1266
#define string_undefined_p(s)
Definition: newgen_types.h:41

Referenced by error_reset_C_comment(), and reset_C_comment().

+ Here is the caller graph for this function:

◆ CModuleMemoryAllocation()

void CModuleMemoryAllocation ( entity  module)

This function is for MemoryAllocation for Module of C programs.

Parameters
moduleodule

Definition at line 1979 of file util.c.

1980 {
1982  entity var = entity_undefined;
1983 
1984  pips_debug(8,"MEMORY ALLOCATION BEGINS\n");
1986  //print_entities(ld);
1987  for(; !ENDP(ld); ld = CDR(ld))
1988  {
1989  var = ENTITY(CAR(ld));
1990 
1992  {
1993  storage s = entity_storage(var);
1994  if(storage_ram_p(s))
1995  {
1996  ram r = storage_ram(s);
1997  entity a = ram_section(r);
2000  if(a == StackArea)
2002  else
2003  add_C_variable_to_area(a,var);
2004  }
2005  else{
2006  if(ram_offset(r) == UNKNOWN_RAM_OFFSET)
2008  }
2009  }
2010  if(storage_formal_p(s))
2011  {
2012  //DO NOTHING
2013  }
2014  }
2015  }
2016 }
entity StackArea
Definition: area.c:60
#define storage_formal_p(x)
Definition: ri.h:2522

References add_C_variable_to_area(), area_size, CAR, CDR, code_externs, DYNAMIC_RAM_OFFSET, ENDP, ENTITY, entity_declarations, entity_initial, entity_storage, entity_type, entity_undefined, gen_in_list_p(), module, ModuleStatement, nodecl_p(), pips_debug, place_holder_variable_p(), ram_offset, ram_section, StackArea, storage_formal_p, storage_ram, storage_ram_p, type_area, type_variable_p, UNDEFINED_RAM_OFFSET, UNKNOWN_RAM_OFFSET, and value_code.

Referenced by ResetCurrentModule().

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

◆ compilation_unit_parser()

bool compilation_unit_parser ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 746 of file c_parser.c.

747 {
748  return actual_c_parser(module_name,DBR_C_SOURCE_FILE,true);
749 }

References actual_c_parser(), module_name(), and STUB_ERROR.

Referenced by AddEntityToCompilationUnit(), and outliner_independent().

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

◆ ComputeAreaOffset()

int ComputeAreaOffset ( entity  a,
entity  v 
)

Update the size and layout of the area aa. This function is called too earlier, we may not have the size of v. To be changed !!!

FI: who wrote this? when should the offsets be computed? how do we deal with scoping?

area_size(aa) = offset + 0;

Definition at line 3324 of file util.c.

3325 {
3326  type ta = entity_type(a);
3327  area aa = type_area(ta);
3328  int offset = area_size(aa);
3329 
3330  pips_assert("Not used", false);
3331 
3332  /* Update the size and layout of the area aa.
3333  This function is called too earlier, we may not have the size of v.
3334  To be changed !!!
3335 
3336  FI: who wrote this? when should the offsets be computed? how do we deal with
3337  scoping?
3338  */
3339 
3340  pips_assert("Type is correctly defined", CSafeSizeOfArray(v)!=0);
3341 
3342  /* area_size(aa) = offset + 0; */
3343  area_size(aa) = offset + CSafeSizeOfArray(v);
3344  area_layout(aa) = gen_nconc(area_layout(aa), CONS(ENTITY, v, NIL));
3345  return offset;
3346 }
static Value offset
Definition: translation.c:283
int CSafeSizeOfArray(entity)
BEGIN_EOLE.
Definition: size.c:225

References area_layout, area_size, CONS, CSafeSizeOfArray(), ENTITY, entity_type, gen_nconc(), NIL, offset, pips_assert, and type_area.

+ Here is the call graph for this function:

◆ CreateDefaultContext()

c_parser_context CreateDefaultContext ( void  )

Definition at line 292 of file cyacc.tab.c.

293 {
297  NIL,
298  false,
299  false);
300  pips_debug(8, "New default context %p\n", c);
301  return c;
302 }
c_parser_context make_c_parser_context(string a1, type a2, storage a3, list a4, bool a5, bool a6)
string empty_scope()
Functions used to manage the block scoping in conjunction with ContextStack and yco ntext.
Definition: entity.c:498
#define type_undefined
Definition: ri.h:2883
#define storage_undefined
Definition: ri.h:2476

Referenced by EnterScope().

+ Here is the caller graph for this function:

◆ CreateEntityFromLocalNameAndPrefix()

entity CreateEntityFromLocalNameAndPrefix ( string  name,
string  prefix,
bool  is_external 
)

We have to know the context:

  • if the entity is declared outside any function, their scope is the CurrentCompilationUnit
  • if the entity is declared inside a function, we have to know the CurrentBlock, which is omitted for the moment
  • if the function is static, their scope is CurrentCompilationUnit::CurrentModule
  • if the function is global, their scope is CurrentModule

The entity is created local to the file. For instance, derived and user-named types. This makes type checking more difficult as types such as FILE * vary from C file to C file, but this is consistent with the C standard and the behavior of production compilers: the same local name can be used for two different types in two different files.

These types are created globally, which makes type checking much easier but forbid homonym types in different files.

Parameters
nameame
prefixrefix
is_externals_external

Definition at line 962 of file util.c.

963 {
964  /* We have to know the context:
965 
966  - if the entity is declared outside any function, their scope is
967  the CurrentCompilationUnit
968 
969  - if the entity is declared inside a function, we have to know
970  the CurrentBlock, which is omitted for the moment
971 
972  - if the function is static, their scope is
973  CurrentCompilationUnit#CurrentModule
974 
975  - if the function is global, their scope is CurrentModule
976  */
977  entity ent = entity_undefined;
978 
979  if (is_external) {
980  pips_debug(5,"Entity local name is %s with prefix %s\n",name,prefix);
981  char *local_name;
982  asprintf(&local_name,"%s%s",prefix,name);
983  // See TRAC Ticket #787
984 #define FILE_LOCAL_USER_DEFINED_TYPES_P (true)
986  /* The entity is created local to the file. For instance,
987  * derived and user-named types. This makes type checking more
988  * difficult as types such as FILE * vary from C file to C file,
989  * but this is consistent with the C standard and the behavior
990  * of production compilers: the same local name can be used for
991  * two different types in two different files.
992  */
994  }
995  else {
996  /* These types are created globally, which makes type checking
997  * much easier but forbid homonym types in different files.
998  */
1000  }
1001  free(local_name);
1002  }
1003  else {
1004  string scope = scope_to_block_scope(GetScope());
1005 
1006  pips_debug(5,"Entity local name is %s with prefix %s and scope \"%s\"\n",
1007  name,prefix,scope);
1008  pips_assert("scope is a block scope", string_block_scope_p(scope));
1009 
1010  char * local_name;
1011  asprintf(&local_name,"%s%s%s",scope,prefix,name);
1014  }
1015  else {
1017  }
1018  free(local_name);
1019  free(scope);
1020  }
1021  pips_debug(5,"Entity global name is %s\n",entity_name(ent));
1022  return ent;
1023 }
string compilation_unit_name
cproto-generated files
Definition: c_parser.c:49
string scope_to_block_scope(string)
Allocate a new string containing only block scope information.
Definition: cyacc.tab.c:268
string GetScope(void)
Definition: cyacc.tab.c:371
#define FILE_LOCAL_USER_DEFINED_TYPES_P
static bool is_external
to know if the variable is declared inside or outside a function, so its scope is the current functio...
Definition: cyacc.tab.c:115
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
static const char * prefix
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool string_block_scope_p(string s)
Definition: entity.c:511
bool static_module_p(entity e)
Check if the given module entity is a static module.
Definition: module.c:80

References asprintf, compilation_unit_name, entity_name, entity_undefined, FILE_LOCAL_USER_DEFINED_TYPES_P, FindOrCreateEntity(), free(), get_current_module_entity(), get_current_module_name(), GetScope(), is_external, local_name(), pips_assert, pips_debug, prefix, scope_to_block_scope(), static_module_p(), string_block_scope_p(), and TOP_LEVEL_MODULE_NAME.

Referenced by FindOrCreateCurrentEntity(), FindOrCreateEntityFromLocalNameAndPrefix(), FindOrCreateEntityFromLocalNameAndPrefixAndScope(), and MakeDerivedEntity().

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

◆ CreateMemberScope()

string CreateMemberScope ( string  derived,
bool  is_external 
)

We have to know the context :

  • if the struct/union is declared outside any function, its scope is the CurrentCompilationUnit
  • if the struct/union is declared inside a function, we have to know the CurrentBlock, which is omitted for the moment
  • if the function is static, its scope is CurrentCompilationUnit!CurrentModule
  • if the function is global, its scope is CurrentModule

The name of the struct/union is then added to the field entity name, with the MEMBER_SEP_STRING

ompilation_unit_name,

Parameters
derivederived
is_externals_external

Definition at line 3261 of file util.c.

3262 {
3263  /* We have to know the context :
3264  - if the struct/union is declared outside any function, its scope is the CurrentCompilationUnit
3265  - if the struct/union is declared inside a function, we have to know the CurrentBlock,
3266  which is omitted for the moment
3267  - if the function is static, its scope is CurrentCompilationUnit!CurrentModule
3268  - if the function is global, its scope is CurrentModule
3269 
3270  The name of the struct/union is then added to the field entity name, with
3271  the MEMBER_SEP_STRING */
3272 
3273  string s = string_undefined;
3274 
3275  pips_debug(3,"Struc/union name is %s\n",derived);
3276 
3277  if (is_external)
3279  else {
3280  string scope = scope_to_block_scope(GetScope());
3281 
3282  pips_assert("scope is a block scope", string_block_scope_p(scope));
3283 
3285  s = strdup(concatenate(/*compilation_unit_name,*/
3287  scope, derived, MEMBER_SEP_STRING, NULL));
3288  else
3290  scope, derived, MEMBER_SEP_STRING, NULL));
3291  }
3292 
3293  pips_debug(3,"The struct/union member's scope is %s\n",s);
3294 
3295  return s;
3296 }
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define MEMBER_SEP_STRING
Definition: naming-local.h:53

References compilation_unit_name, concatenate(), get_current_module_entity(), get_current_module_name(), GetScope(), is_external, MEMBER_SEP_STRING, MODULE_SEP_STRING, pips_assert, pips_debug, scope_to_block_scope(), static_module_p(), strdup(), string_block_scope_p(), and string_undefined.

+ Here is the call graph for this function:

◆ CreateReturnEntity()

void CreateReturnEntity ( entity  f)

If necessary, create the return entity, which is a hidden variable used in PIPS internal representation to carry the value returned by a function.

c_parser_user_warning() should not be called as it may be some times too late to get significant line numbers.

Create the return value

set the language

Definition at line 2382 of file util.c.

2383 {
2385  /* c_parser_user_warning() should not be called as it may be some
2386  * times too late to get significant line numbers.
2387  */
2388  c_parser_user_warning("Type of \"%s\" is undefined."
2389  " Return value cannot be created.\n",
2390  entity_user_name(f));
2391  }
2392  else {
2394 
2395  pips_debug(8, "For module \"%s\"\n", entity_name(f));
2396 
2397  if(type_functional_p(ft)) {
2399 
2400  if(type_undefined_p(rt)) {
2401  c_parser_user_warning("Return type of \"%s\" is undefined."
2402  " Return value cannot be created.\n",
2403  entity_user_name(f));
2404  }
2405  else if(!type_void_p(rt)) {
2406  /* Create the return value */
2407  const char* fn = entity_local_name(f);
2408  entity re = FindOrCreateEntity(fn,fn);
2409  if(type_undefined_p(entity_type(re))) {
2410  entity_type(re) = copy_type(rt);
2412  /* set the language */
2414  AddToDeclarations(re, f);
2415  }
2416  }
2417  }
2418  else
2419  pips_internal_error("This function should only be called with a function entity");
2420  }
2421 }
value make_value_unknown(void)
Definition: ri.c:2847
type copy_type(type p)
TYPE.
Definition: ri.c:2655
storage make_storage_return(entity _field_)
Definition: ri.c:2276
#define c_parser_user_warning(...)
void AddToDeclarations(entity e, entity mod)
FI: check the difference with AddEntityToDeclarations()
Definition: util.c:2924
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
#define type_undefined_p(x)
Definition: ri.h:2884
#define type_void_p(x)
Definition: ri.h:2959

References AddToDeclarations(), c_parser_user_warning, copy_type(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_user_name(), f(), FindOrCreateEntity(), functional_result, make_storage_return(), make_value_unknown(), pips_debug, pips_internal_error, type_functional, type_functional_p, type_undefined_p, type_void_p, and ultimate_type().

Referenced by UpdateEntity(), and UpdateEntity2().

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

◆ discard_C_comment()

void discard_C_comment ( void  )

Discard a C comment because we don't know how to deal with it.

The comments are only made of '
', just silently discarding them

Definition at line 1426 of file clexer.c.

1427 {
1430  == strlen(C_current_comment)) {
1431  /* The comments are only made of '\n', just silently discarding them */
1432  pips_debug(3,"The \\n are lost, so the code presentation may be wrong...\n");
1433  }
1434  else {
1435  /*
1436  pips_user_warning("Comment \"%s\" is lost at line %d, "
1437  "probably because comments cannot be attached to declarations.\n",
1438  C_current_comment, C_line_number);
1439  */
1440  pips_debug(8, "Comment \"%s\" is lost at line %d, "
1441  "probably because comments cannot be attached to declarations.\n",
1443  }
1446  }
1447 }
unsigned int character_occurences_in_string(string s, char c)
Use a stack to survive to file inclusions if any.
Definition: clexer.c:1133

◆ 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:

◆ error_reset_C_comment()

void error_reset_C_comment ( bool  )

◆ error_reset_c_parser_current_input_file_name()

void error_reset_c_parser_current_input_file_name ( void  )

Definition at line 81 of file c_parser.c.

82 {
84 }
static string c_parser_current_file_name
Definition: c_parser.c:56

References c_parser_current_file_name, and string_undefined.

Referenced by c_parser_error().

+ Here is the caller graph for this function:

◆ error_reset_c_parser_current_user_input_file_name()

void error_reset_c_parser_current_user_input_file_name ( void  )

Definition at line 112 of file c_parser.c.

113 {
115 }
static string c_parser_current_user_input_file_name
Definition: c_parser.c:87

References c_parser_current_user_input_file_name, and string_undefined.

Referenced by c_parser_error().

+ Here is the caller graph for this function:

◆ error_reset_current_C_line_number()

void error_reset_current_C_line_number ( void  )

Definition at line 1224 of file clexer.c.

1225 {
1230 
1231  free_line_number_stack();
1232  free_absolute_line_number_stack();
1233 }
#define UNDEFINED_C_LINE_NUMBER
#define FIRST_C_LINE_NUMBER
Error handling.
static int previous_C_line_number
Definition: clexer.c:1144
static int previous_c_lineno
To keep track of line intervals.
Definition: clexer.c:1113

◆ ExitScope()

void ExitScope ( void  )

Definition at line 400 of file cyacc.tab.c.

401 {
403 
405 
406  pips_assert("The current context is defined", !c_parser_context_undefined_p(c));
407  pips_assert("The current context scope is defined",
409  && c_parser_context_scope(c)!=NULL);
410  pips_assert("The current context only contains scope information",
411  //type_undefined_p(c_parser_context_type(c)) &&
414  //&& !c_parser_context_typedef(c)
415  //&& !c_parser_context_static(c)
416  );
417  pips_debug(8, "Exiting context scope \"\%s\" in context %p\n",
418  c_parser_context_scope(c), c);
420  (void) stack_pop(ContextStack);
423  //pips_assert("ycontext is consistant with stack_head(ContextStack)",
424  // ycontext==stack_head(ContextStack));
425  pips_debug(8, "Back to context scope \"\%s\" in context %p\n",
426  c_parser_context_scope(oc), oc);
427  }
428  else {
429  // ycontext = c_parser_context_undefined;
430  pips_debug(8, "Back to undefined context scope\n");
431  }
432 }
void free_c_parser_context(c_parser_context p)
#define c_parser_context_undefined_p(x)
#define c_parser_context_storage(x)
#define c_parser_context_qualifiers(x)
struct _newgen_struct_c_parser_context_ * c_parser_context
#define c_parser_context_scope(x)
void pop_c_parser_scope_stack()
Definition: cyacc.tab.c:558
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
#define storage_undefined_p(x)
Definition: ri.h:2477

◆ 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
#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

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:

◆ FindEntityFromLocalName()

entity FindEntityFromLocalName ( string  name)

Find an entity from its local name. We have to look for all possible prefixes, which are: blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX

How about multiple results ? The order of prefixes ?

Is it a static function? It must have been parsed in the compilation unit

Parameters
nameame

Definition at line 778 of file util.c.

779 {
780  /* Find an entity from its local name.
781  We have to look for all possible prefixes, which are:
782  blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX
783 
784  How about multiple results ? The order of prefixes ? */
785 
786  entity ent = entity_undefined;
788  int i;
789  //c_parser_context cpc = GetScope();
790  //string scope = scope_to_block_scope(c_parser_context_scope(cpc));
791 
792  for (i=0; prefixes[i]!=NULL; i++)
793  {
795  return ent;
796  }
797 
798  if(entity_undefined_p(ent)) {
799  /* Is it a static function? It must have been parsed in the compilation unit */
800  string sname = strdup(concatenate(compilation_unit_name, name, NULL));
801  ent = FindEntity(compilation_unit_name, sname);
802  free(sname);
803  return ent;
804  }
805 
806  c_parser_user_warning("Cannot find entity %s\n", name);
807 
808  return entity_undefined;
809 }
entity FindEntityFromLocalNameAndPrefix(string name, string prefix)
Definition: util.c:877
#define TYPEDEF_PREFIX
Definition: naming-local.h:62
#define UNION_PREFIX
Definition: naming-local.h:58
#define ENUM_PREFIX
Definition: naming-local.h:60
#define STRUCT_PREFIX
Definition: naming-local.h:56
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
static string prefixes[]
Definition: entity.c:1433

References c_parser_user_warning, compilation_unit_name, concatenate(), entity_undefined, entity_undefined_p, ENUM_PREFIX, FindEntity(), FindEntityFromLocalNameAndPrefix(), free(), prefixes, strdup(), STRUCT_PREFIX, TYPEDEF_PREFIX, and UNION_PREFIX.

Referenced by IdentifierToExpression().

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

◆ FindEntityFromLocalNameAndPrefix()

entity FindEntityFromLocalNameAndPrefix ( string  name,
string  prefix 
)

Find an entity from its local name and prefix. We have to look from the most enclosing scope.

Possible name combinations and the looking order:

  1. FILE!MODULE:BLOCKPREFIXname or MODULE:BLOCKPREFIXname
  2. FILE!MODULE:PREFIXname or MODULE:PREFIXname
  3. FILE!:PREFIXname (used to be FILE!PREFIXname)
  4. TOP-LEVEL:PREFIXname

with 5 possible prefixes: blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX

"!" is FILE_SEP_STRING and ":" is MODULE_SEP_STRING and "`" is BLOCK_SEP_STRING

First, look up the surrounding scopes

Is it a formal parameter not yet converted in the function frame?

Should we change the current dummy parameter number?

Is it a static variable declared in the compilation unit?

we have an issue there : a static function will be declared FILE!MODULE:FILE!name, but a static variable will be declared FILE!MODULE:name so try both ... CleanupEntity has been fixed to remove buggy situations ...

Is it a global variable declared in the compilation unit?

Is it a local type used within a function declaration?

It may be a parser error or a normal behavior when an entity is used before it is defined as, for example, a struct in a typedef: typedef struct foo foo;

CParserError("Variable appears to be undefined\n");

Parameters
nameame
prefixrefix

Definition at line 877 of file util.c.

878 {
879  /* Find an entity from its local name and prefix.
880  We have to look from the most enclosing scope.
881 
882  Possible name combinations and the looking order:
883 
884  1. FILE!MODULE:BLOCK`PREFIXname or MODULE:BLOCK`PREFIXname
885  2. FILE!MODULE:PREFIXname or MODULE:PREFIXname
886  3. FILE!:PREFIXname (used to be FILE!PREFIXname)
887  4. TOP-LEVEL:PREFIXname
888 
889  with 5 possible prefixes: blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX
890 
891  "!" is FILE_SEP_STRING and ":" is MODULE_SEP_STRING and "`" is BLOCK_SEP_STRING
892  */
893 
894  entity ent = entity_undefined;
895  string global_name = string_undefined;
896  string scope = scope_to_block_scope(GetScope());
897  string ls = strdup(scope);
898  string ls_head = ls;
899 
900  pips_debug(5,"Entity local name is \"%s\" with prefix \"%s\" and scope \"%s\"\n",
901  name,prefix,scope);
902  pips_assert("Scope is a block scope", string_block_scope_p(scope));
903  free(scope);
904 
905  /* First, look up the surrounding scopes */
907 
908  /* Is it a formal parameter not yet converted in the function frame? */
909  if(entity_undefined_p(ent)) {
910  /* Should we change the current dummy parameter number? */
912 
914  prefix,name,NULL));
915  ent = gen_find_tabulated(global_name,entity_domain);
916  free(sn);
917  }
918 
919  /* Is it a static variable declared in the compilation unit? */
920  /* we have an issue there : a static function will be declared FILE!MODULE:FILE!name,
921  * but a static variable will be declared FILE!MODULE:name
922  * so try both ... CleanupEntity has been fixed to remove buggy situations ...*/
923  if(entity_undefined_p(ent)) {
925  prefix,name,NULL));
926  ent = gen_find_tabulated(global_name,entity_domain);
927  }
928  if(entity_undefined_p(ent)) {
930  prefix,name,NULL));
931  ent = gen_find_tabulated(global_name,entity_domain);
932  }
933 
934  /* Is it a global variable declared in the compilation unit? */
935  if(entity_undefined_p(ent)) {
937  prefix,name,NULL));
938  ent = gen_find_tabulated(global_name,entity_domain);
939  }
940 
941  /* Is it a local type used within a function declaration? */
942  if(entity_undefined_p(ent) && strcmp(ls, "")==0 && ScopeStackSize()>=2) {
943  string lls = strdup(scope_to_block_scope(GetParentScope()));
945  free(lls);
946  }
947 
948  if(entity_undefined_p(ent)) {
949  pips_debug(8, "Cannot find entity with local name \"%s\" with prefix \"%s\" at line %d\n",
951  /* It may be a parser error or a normal behavior when an entity is
952  used before it is defined as, for example, a struct in a typedef:
953  typedef struct foo foo; */
954  /* CParserError("Variable appears to be undefined\n"); */
955  } else
956  pips_debug(5,"Entity global name is %s\n",entity_name(ent));
957  //free(global_name);
958  free(ls_head);
959  return ent;
960 }
int ScopeStackSize(void)
Definition: cyacc.tab.c:366
string GetParentScope(void)
Definition: cyacc.tab.c:387
entity FindEntityFromLocalNameAndPrefixAndScope(string name, string prefix, string scope)
The parameter "scope" is potentially destroyed.
Definition: util.c:850
static int get_current_dummy_parameter_number(void)
Definition: util.c:147
#define DUMMY_PARAMETER_PREFIX
For dmmmy parameters in functions declarations.
Definition: naming-local.h:93
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
char * int2a(int i)
util.c
Definition: util.c:42

References compilation_unit_name, concatenate(), DUMMY_PARAMETER_PREFIX, entity_domain, entity_name, entity_undefined, entity_undefined_p, FindEntityFromLocalNameAndPrefixAndScope(), free(), gen_find_tabulated(), get_current_C_line_number(), get_current_dummy_parameter_number(), GetParentScope(), GetScope(), int2a(), MODULE_SEP_STRING, pips_assert, pips_debug, prefix, scope_to_block_scope(), ScopeStackSize(), strdup(), string_block_scope_p(), string_undefined, and TOP_LEVEL_MODULE_NAME.

Referenced by FindEntityFromLocalName(), FindOrCreateEntityFromLocalNameAndPrefix(), and FindOrCreateEntityFromLocalNameAndPrefixAndScope().

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

◆ FindEntityFromLocalNameAndPrefixAndScope()

entity FindEntityFromLocalNameAndPrefixAndScope ( string  name,
string  prefix,
string  scope 
)

The parameter "scope" is potentially destroyed.

Add block scope case here

ompilation_unit_name,

return values are not C variables... but they are entities.

Parameters
nameame
prefixrefix
scopecope

Definition at line 850 of file util.c.

851 {
852  entity ent = entity_undefined;
853 
855  string global_name = string_undefined;
856  /* Add block scope case here */
857  do {
859  global_name = (concatenate(/*compilation_unit_name,*/
861  scope,prefix,name,NULL));
862  else
864  scope,prefix,name,NULL));
865  ent = gen_find_tabulated(global_name,entity_domain);
866  /* return values are not C variables... but they are entities. */
867  if(!entity_undefined_p(ent)
869  && storage_return_p(entity_storage(ent))) {
870  ent = entity_undefined;
871  }
872  } while(entity_undefined_p(ent) && (scope = pop_block_scope(scope))!=NULL);
873  }
874  return ent;
875 }
string pop_block_scope(string)
The scope is moved up the scope tree and a NULL is return when there are no more scope to explore.
Definition: cyacc.tab.c:235
#define storage_return_p(x)
Definition: ri.h:2516

References concatenate(), entity_domain, entity_storage, entity_undefined, entity_undefined_p, gen_find_tabulated(), get_current_module_entity(), get_current_module_name(), MODULE_SEP_STRING, pop_block_scope(), prefix, static_module_p(), storage_return_p, storage_undefined_p, and string_undefined.

Referenced by FindEntityFromLocalNameAndPrefix().

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

◆ FindOrCreateCurrentEntity()

entity FindOrCreateCurrentEntity ( string  ,
stack  ,
stack  ,
stack  ,
bool   
)

◆ FindOrCreateEntityFromLocalNameAndPrefix()

entity FindOrCreateEntityFromLocalNameAndPrefix ( string  name,
string  prefix,
bool  is_external 
)
Parameters
nameame
prefixrefix
is_externals_external

Definition at line 811 of file util.c.

812 {
813  entity e;
814 
816  return e;
818 }
entity CreateEntityFromLocalNameAndPrefix(string name, string prefix, bool is_external)
Definition: util.c:962

References CreateEntityFromLocalNameAndPrefix(), entity_undefined, FindEntityFromLocalNameAndPrefix(), is_external, and prefix.

+ Here is the call graph for this function:

◆ FindOrCreateEntityFromLocalNameAndPrefixAndScope()

entity FindOrCreateEntityFromLocalNameAndPrefixAndScope ( string  name,
string  prefix,
string  scope,
bool  is_external 
)

The current scope will be automatically added

Parameters
nameame
prefixrefix
scopecope
is_externals_external

Definition at line 820 of file util.c.

824 {
826  string ls = strdup(scope);
827  string ls_head = ls;
828 
829  pips_assert("Should not be used", false);
830 
831  pips_assert("scope is a block scope", string_block_scope_p(scope));
832 
833  do {
834  string sname = strdup(concatenate(ls, name, NULL));
836  free(sname);
837  }
838  while(e != entity_undefined && (ls = pop_block_scope(ls)));
839 
840  if(entity_undefined_p(e)) {
841  /* The current scope will be automatically added */
843  }
844  free(ls_head);
845  pips_debug(8, "Entity returned: \"%s\"\n", entity_name(e));
846  return e;
847 }

References concatenate(), CreateEntityFromLocalNameAndPrefix(), entity_name, entity_undefined, entity_undefined_p, FindEntityFromLocalNameAndPrefix(), free(), is_external, pips_assert, pips_debug, pop_block_scope(), prefix, strdup(), and string_block_scope_p().

+ Here is the call graph for this function:

◆ FindParameterEntity()

parameter FindParameterEntity ( string  s,
int  offset,
list  l 
)

to be verified in C, when by reference, when by value

Parameters
offsetffset

Definition at line 3384 of file util.c.

3385 {
3386  FOREACH(ENTITY,e,l)
3387  {
3388  const char* name = entity_user_name(e);
3389  if (strcmp(name,s)==0)
3390  {
3391  type t = entity_type(e);
3392  mode m = make_mode_value(); /* to be verified in C, when by reference, when by value*/
3393  /*
3394  What about the storage of
3395 
3396  void AMMPmonitor( vfs,ffs,nfs,op )
3397  int (*vfs[])(),(*ffs[])();
3398  int nfs;
3399  FILE *op;*/
3400 
3401  storage st = entity_storage(e);
3402  if (storage_formal_p(st))
3403  {
3404  formal f = storage_formal(st);
3405  formal_offset(f) = offset;
3406  }
3407  return make_parameter(t,m,make_dummy_identifier(e)); // FI: Could be entity_undefined
3408  }
3409  }
3410  return parameter_undefined;
3411 }
dummy make_dummy_identifier(entity _field_)
Definition: ri.c:620
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
mode make_mode_value(void)
Definition: ri.c:1353
#define formal_offset(x)
Definition: ri.h:1408
#define parameter_undefined
Definition: ri.h:1794
#define storage_formal(x)
Definition: ri.h:2524

References ENTITY, entity_storage, entity_type, entity_user_name(), f(), FOREACH, formal_offset, make_dummy_identifier(), make_mode_value(), make_parameter(), offset, parameter_undefined, storage_formal, and storage_formal_p.

Referenced by MakeParameterList().

+ 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 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:

◆ FixCReturnStatements()

void FixCReturnStatements ( statement  ms)

When return statements have been encountered, each of them has been replaced by a goto to a unique return statement.

This unique return statement may have to be added to the function body.

How many return statements have been encountered?

nothing to be done

If the return statement is the last statement of the module statement, the goto and the assignment can be replaced by a call to return. Otherwise, a return statement with the proper label must be added at the end of the module statement ms

The goto instruction and, possibly, the return value assignment can be removed: just remove the label?

Do not forget to declare the return variable...

Parameters
mss

Definition at line 223 of file return.c.

224 {
225  if(get_bool_property("C_PARSER_RETURN_SUBSTITUTION")) {
226  /* How many return statements have been encountered? */
227  int nrs = GetReturnNumber();
228  int replace_p = false;
229  if(nrs==-1 || nrs==0)
230  ; /* nothing to be done */
231  else if(nrs==1) {
232  /* If the return statement is the last statement of the module
233  statement, the goto and the assignment can be replaced by a
234  call to return. Otherwise, a return statement with the
235  proper label must be added at the end of the module statement
236  ms */
237  //statement ls = find_last_statement(ms);
238  statement ls = last_statement(ms);
239  if(!statement_undefined_p(ls)) {
241  if(instruction_goto_p(li)) {
242  statement ts = instruction_goto(li);
243  if(ts==C_return_statement) {
244  //instruction lrvai =
245  // statement_instruction(last_return_value_assignment);
246  /* The goto instruction and, possibly, the return value
247  assignment can be removed: just remove the label? */
254  free_instruction(li);
255  //free_instruction(lrvai); contains the expression resued above!
256  replace_p = false;
257  }
258  else
259  replace_p = true;
260  }
261  else
262  replace_p = true;
263  }
264  else
265  replace_p = true;
266  }
267  else if(nrs>1)
268  replace_p = true;
269  else
270  pips_internal_error("The number of return statements has"
271  " not been initialized");
272 
273  if(replace_p) {
274  /* Do not forget to declare the return variable... */
276  pips_assert("ms is a block", statement_block_p(ms));
280  ms);
282  }
284  }
285  }
287 }
call make_call(entity a1, list a2)
Definition: ri.c:269
void free_instruction(instruction p)
Definition: ri.c:1118
static entity return_current_module
get_current_module_entity() is reset too early by the parser
Definition: return.c:82
static entity return_value_entity
It is saved because it is hard to retrieve from within actual_c_parser() once the aprsing is over.
Definition: return.c:80
static statement C_return_statement
Generate a unique call statement to RETURN per module.
Definition: return.c:68
void Reset_C_ReturnStatement()
The return statement must be reset when it is used by the parser to add the return statement to the f...
Definition: return.c:115
int GetReturnNumber()
Definition: return.c:214
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
statement last_statement(statement)
A simplified version of find_last_statement() located in prettyprint.c and designed to be used within...
Definition: statement.c:168
#define statement_block_p(stat)
#define C_RETURN_FUNCTION_NAME
#define call_to_instruction
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 AddLocalEntityToDeclarations(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:233
#define instruction_goto(x)
Definition: ri.h:1526
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_undefined_p(x)
Definition: ri.h:2420
#define instruction_goto_p(x)
Definition: ri.h:1524

References AddLocalEntityToDeclarations(), C_RETURN_FUNCTION_NAME, C_return_statement, call_to_instruction, CreateIntrinsic(), entity_undefined_p, free_instruction(), get_bool_property(), GetReturnNumber(), insert_statement(), instruction_goto, instruction_goto_p, last_return_value_assignment, last_returned_value, last_statement(), make_call(), make_continue_instruction(), pips_assert, pips_internal_error, Reset_C_ReturnStatement(), reset_current_module_entity(), return_current_module, return_value_entity, set_current_module_entity(), statement_block_p, statement_instruction, and statement_undefined_p.

Referenced by actual_c_parser().

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

◆ force_reset_c_parser_scope_stack()

void force_reset_c_parser_scope_stack ( void  )

To be used by an error handler.

Definition at line 539 of file cyacc.tab.c.

540  {
544  }
546  return;
547  }
#define SCOPE_UNDEFINED
Each scope in the current unit has its own number.
Definition: cyacc.tab.c:510
static int c_parser_scope_number
Definition: cyacc.tab.c:511

◆ Generate_C_ReturnLabel()

entity Generate_C_ReturnLabel ( entity  m)

return.c

return.c

Unlike Fortran return statements, C return statements carry the value returned by functions. In some sense, they have a continuation since they return to the caller, but there is no local continuation. So C return cannot be simply replaced by goto statements. This only preserves the control semantics. An additional variable, the return value, must be declared and used to collect information about the different values that are returned. This translation can be removed when there is only one return at the end of the function body. Note that pass restructure_control may be useful for procedure with several returns because unspaghettify, called by the controlizer, is not strong enough.

Francois Irigoin

Definition at line 58 of file return.c.

59 {
61  return l;
62 }
#define LABEL_PREFIX
Definition: naming-local.h:31
#define RETURN_LABEL_NAME
Definition: naming-local.h:106
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
entity make_label(const char *module_name, const char *local_name)
Definition: entity.c:308

References entity_module_name(), LABEL_PREFIX, make_label(), and RETURN_LABEL_NAME.

Referenced by Generate_C_ReturnStatement().

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

◆ Generate_C_ReturnStatement()

statement Generate_C_ReturnStatement ( void  )

Definition at line 84 of file return.c.

85 {
90  type mt = entity_type(m);
93 
94  if(type_void_p(r))
96  else {
102  CONS(EXPRESSION, arg, NIL));
103  }
104 
105  // FI: I'd like to add a return label to this special statement...
107  statement_label(s) = l;
108  return s;
109 }
entity Generate_C_ReturnLabel(entity m)
Handling of C return statements.
Definition: return.c:58
instruction make_call_instruction(entity e, list l)
Build an instruction that call a function entity with an argument list.
Definition: instruction.c:51
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292

References C_RETURN_FUNCTION_NAME, CONS, entity_intrinsic(), entity_to_expression(), entity_type, EXPRESSION, f(), function_to_return_value(), functional_result, Generate_C_ReturnLabel(), get_current_module_entity(), instruction_to_statement(), instruction_undefined, make_call_instruction(), NIL, return_current_module, return_value_entity, statement_label, statement_undefined, type_functional, and type_void_p.

Referenced by Get_C_ReturnStatement().

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

◆ get_c_parser_current_input_file_name()

string get_c_parser_current_input_file_name ( void  )

Definition at line 58 of file c_parser.c.

59 {
61  pips_internal_error("c_parser_current_file_name not initialized.\n");
63 }

References c_parser_current_file_name, pips_internal_error, and string_undefined_p.

Referenced by c_parser_user_warning_alist(), and UpdateEntity().

+ Here is the caller graph for this function:

◆ get_c_parser_current_scope()

string get_c_parser_current_scope ( void  )

Definition at line 569 of file cyacc.tab.c.

570  {
571  string sn = string_undefined;
573  // We are at the global level: no scope has been entered yet
574  sn = "";
575  }
576  else
578  return sn;
579  }
bool c_parser_scope_stack_empty_p()
Definition: cyacc.tab.c:564
char * string
STRING.
Definition: newgen_types.h:39

◆ get_c_parser_current_user_input_file_name()

string get_c_parser_current_user_input_file_name ( void  )

Definition at line 89 of file c_parser.c.

90 {
92  pips_internal_error("c_parser_current_user_input_file_name not initialized.\n");
94 }

References c_parser_current_user_input_file_name, pips_internal_error, and string_undefined_p.

Referenced by c_parser_error(), and c_parser_user_warning_alist().

+ Here is the caller graph for this function:

◆ get_c_parser_nth_scope()

string get_c_parser_nth_scope ( int  n)

Definition at line 581 of file cyacc.tab.c.

582  {
583  string sn = (string) stack_nth(c_parser_scope_stack, n);
584  return sn;
585  }
void * stack_nth(const stack, int)
returns the nth item starting from the head and counting from 1, when possible, or NULL,...
Definition: stack.c:436

◆ Get_C_ReturnStatement()

statement Get_C_ReturnStatement ( void  )

This function is used to generate all goto's towards the unique return used to C replace return statement and to insert this unique return at the end of the current function's body.

Definition at line 130 of file return.c.

131 {
133  pips_assert("No return statement yet\n", number_of_return_statements==-1);
136  }
138  return C_return_statement;
139 }
static int number_of_return_statements
Saved to optimize the internal representation instead of relying on the parser and/or on control_rest...
Definition: return.c:73
statement Generate_C_ReturnStatement()
Definition: return.c:84

References C_return_statement, Generate_C_ReturnStatement(), number_of_return_statements, pips_assert, and statement_undefined_p.

Referenced by C_MakeReturnStatement().

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

◆ get_current_C_comment()

string get_current_C_comment ( void  )

Return the current comment as a string to be freed by the caller and reset the current comment.

If the current comment is undefined, returns a copy of the empty string, "".

Reset also the current comment.

If the comment begins with a new-line, it is indeed the new-line that ends the previous statement, so skip it. Quicker than strlen()

  • memmove():

Note there won't be a memory leak since the orginal '\0' is in the malloc() bloc to be free()ed anyway...

If the comment is only an empty one, do not retain it:

Do retain it to keep the statement data structure easy to use, allowing strdup() on its text fields

Remove the trailing new-line if any since the RI is already line-oriented at the comment level: This is already done above.

It is a trailing new-line: just get rid of it:

pips_debug(3, "get_current_C_comment comment \"s"
", cc);

Definition at line 1282 of file clexer.c.

1283 {
1284  string cc = C_current_comment;
1286  if (cc != string_undefined) {
1287  if (cc[0] == '\n') {
1288  /* If the comment begins with a new-line, it is indeed the new-line
1289  that ends the previous statement, so skip it. Quicker than strlen()
1290  + memmove(): */
1291  char * p = &cc[0];
1292  do {
1293  p[0] = p[1];
1294  }
1295  while (*p++ != '\0');
1296  /* Note there won't be a memory leak since the orginal '\0' is in the
1297  malloc() bloc to be free()ed anyway... */
1298  }
1299  /* If the comment is only an empty one, do not retain it: */
1300  if (cc[0] == '\0') {
1301  /* Do retain it to keep the statement data structure easy to use, allowing strdup() on its text fields */
1302  //free(cc);
1303  //cc = string_undefined;
1304  ;
1305  }
1306  else {
1307  /* Remove the trailing new-line if any since the RI is already
1308  line-oriented at the comment level: This is already done above. */
1309  char * last_newline = strrchr(cc, '\n');
1310  if (last_newline != NULL && last_newline[1] == '\0') {
1311  /* It is a trailing new-line: just get rid of it: */
1312  //last_newline[0] = '\0';
1313  ;
1314  }
1315  }
1316  }
1317  else
1318  cc = strdup("");
1319  /* pips_debug(3, "get_current_C_comment comment \"%s\"\n",
1320  cc); */
1321  // Too early
1322  // token_has_been_seen_p = false;
1323  return cc;
1324 }

Referenced by push_current_C_comment().

+ Here is the caller graph for this function:

◆ get_current_C_line_number()

int get_current_C_line_number ( void  )

FI: I assume that get_current_C_line_number is called only by some kind of make_statement()

The PIPS preprocessed C function files contain a specific first line to convert the line number in the workspace unto a line number in the user source file.

Definition at line 1146 of file clexer.c.

1147 {
1148  /* FI: I assume that get_current_C_line_number is called only
1149  * by some kind of make_statement()
1150  *
1151  * The PIPS preprocessed C function files contain a specific first line
1152  * to convert the line number in the workspace unto a line number in the
1153  * user source file.
1154  */
1157  return C_line_number;
1158 }

Referenced by pop_current_C_comment(), push_current_C_comment(), and push_current_C_line_number().

+ Here is the caller graph for this function:

◆ get_current_compilation_unit_entity()

entity get_current_compilation_unit_entity ( void  )

Definition at line 320 of file util.c.

References compilation_unit_name, FindOrCreateEntity(), and TOP_LEVEL_MODULE_NAME.

Referenced by callnodeclfilter(), FindOrCreateCurrentEntity(), MakeFunctionExpression(), MakeStorageRam(), and referencenodeclfilter().

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

◆ get_declaration_counter()

int get_declaration_counter ( void  )

Definition at line 497 of file cyacc.tab.c.

498  {
499  return declaration_counter;
500  }
static int declaration_counter
Declaration counter.
Definition: cyacc.tab.c:490

◆ get_from_entity_type_stack_table()

stack get_from_entity_type_stack_table ( entity  key)
Parameters
keyey

Definition at line 146 of file c_parser.c.

147 {
149 
150  if(p==HASH_UNDEFINED_VALUE)
151  return stack_undefined;
152  else
153  return ((stack) p);
154 }
static hash_table entity_to_type_stack_table
Definition: c_parser.c:128
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
#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
the stack head
Definition: stack.c:62

References entity_name, entity_to_type_stack_table, hash_get(), HASH_UNDEFINED_VALUE, and stack_undefined.

Referenced by FindOrCreateCurrentEntity(), RenameFunctionEntity(), SubstituteDummyParameters(), UpdateAbstractEntity(), UpdateDerivedEntity(), UpdateEntity(), and UseFormalArguments().

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

◆ get_previous_C_line_number()

int get_previous_C_line_number ( void  )

Should be called just before get_current_C_line_number.

Definition at line 1161 of file clexer.c.

1162 {
1163  return previous_C_line_number;
1164 }

◆ get_previous_c_lineno()

int get_previous_c_lineno ( void  )

Definition at line 1115 of file clexer.c.

1116 {
1117  return previous_c_lineno;
1118 }

◆ get_top_level_entity()

entity get_top_level_entity ( void  )

Definition at line 152 of file util.c.

References FindOrCreateEntity(), and TOP_LEVEL_MODULE_NAME.

Referenced by MakeStorageRam(), and step_parameter().

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

◆ GetContext()

c_parser_context GetContext ( void  )

Definition at line 458 of file cyacc.tab.c.

459 {
460 
462 
465  else
466  // Should we return a default context?
467  // Not really compatible with a clean memory allocation policy
468  pips_internal_error("No current context");
469 
470  pips_debug(8, "Context %p is obtained from stack position %d\n",
472 
473  return c;
474 }
#define c_parser_context_undefined

◆ GetContextCopy()

c_parser_context GetContextCopy ( void  )

Definition at line 476 of file cyacc.tab.c.

477 {
480  pips_debug(8, "Context copy %p with scope \"%s\" is obtained from context %p with scope \"%s\" at stack position %d\n",
481  cc, c_parser_context_scope(cc),
484  return cc;
485 }
c_parser_context copy_c_parser_context(c_parser_context p)
C_PARSER_CONTEXT.

◆ GetFunction()

entity GetFunction ( void  )

cproto workaround

cyacc.tab.c

from "cyacc.y"

cyacc.tab.c

from "cyacc.y"

Definition at line 146 of file cyacc.tab.c.

147 {
149  return f;
150 }

◆ GetParentScope()

string GetParentScope ( void  )

Definition at line 387 of file cyacc.tab.c.

388 {
389  string s = "";
390 
393 
394  s = c_parser_context_scope(c);
395  }
396 
397  return s;
398 }

◆ GetReturnNumber()

int GetReturnNumber ( void  )

Definition at line 214 of file return.c.

215 {
217 }

References number_of_return_statements.

Referenced by FixCReturnStatements().

+ Here is the caller graph for this function:

◆ GetScope()

string GetScope ( void  )

FI: I do not know if it wouldn't be better to initialize the ContextStack with a default context before calling the C parser

Definition at line 371 of file cyacc.tab.c.

372 {
373  string s = "";
374 
375  /* FI: I do not know if it wouldn't be better to initialize the
376  ContextStack with a default context before calling the C
377  parser */
380 
381  s = c_parser_context_scope(c);
382  }
383 
384  return s;
385 }

◆ IdentifierToExpression()

expression IdentifierToExpression ( string  s)

Could this be non declared variables ?

This identifier has not been passed by the parser. It is probably a function call => try this case now and complete others later. The scope of this function is global

This may be a call or a reference in case a functional pointer is initialized

eturn MakeNullaryCall(ent);

FI: This may happen when a variable is used to initialize another variable within the same declaration statement: see decl29.c. This might not be a general fix as the type could be functional: to be checked. But setting up type earlier would require a huge change in the parser rules. Unless FindOrCreateCurrentEntity() could do a better job? But the information added is later destroyed by the parser.

Generate a call to an enum member

Definition at line 650 of file util.c.

651 {
654 
655  pips_debug(5,"Identifier is \"%s\" and entity_name is \"\%s\"\n",
656  s, safe_entity_name(ent));
657 
658  if (entity_undefined_p(ent)) {
659  /* Could this be non declared variables ?*/
660  /* This identifier has not been passed by the parser.
661  It is probably a function call => try this case now and complete others later.
662  The scope of this function is global */
663  pips_debug(5,"Create unparsed global function: %s\n",s);
665  //entity_storage(ent) = make_storage_return(ent);
669  /* This may be a call or a reference in case a functional pointer is initialized */
671  /*return MakeNullaryCall(ent);*/
672  }
673  else if(type_undefined_p(entity_type(ent))) {
674  /* FI: This may happen when a variable is used to initialize another
675  variable within the same declaration statement: see
676  decl29.c. This might not be a general fix as the type could be
677  functional: to be checked. But setting up type earlier would require a huge
678  change in the parser rules. Unless FindOrCreateCurrentEntity()
679  could do a better job? But the information added is later
680  destroyed by the parser. */
683  }
684  else {
685  switch (type_tag(entity_type(ent))) {
686  case is_type_variable:
687  case is_type_functional:
688  {
689  value iv = entity_initial(ent);
690 
691  if(!value_undefined_p(iv) && value_symbolic_p(iv))
692  /* Generate a call to an enum member */
694  else
697 
698  break;
699  }
700  default:
701  {
702  CParserError("Which kind of expression?\n");
703  }
704  }
705  }
706  return exp;
707 }
functional make_functional(list a1, type a2)
Definition: ri.c:1109
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
storage make_storage_rom(void)
Definition: ri.c:2285
type make_type_functional(functional _field_)
Definition: ri.c:2718
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
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
type make_type_unknown(void)
Definition: ri.c:2724
sequence make_sequence(list a)
Definition: ri.c:2125
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
entity FindEntityFromLocalName(string name)
Definition: util.c:778
string safe_entity_name(entity e)
predicates and functions for entities
Definition: entity.c:433
#define normalized_undefined
Definition: ri.h:1745
#define type_tag(x)
Definition: ri.h:2940
@ is_value_code
Definition: ri.h:3031
#define expression_undefined
Definition: ri.h:1223
#define value_symbolic_p(x)
Definition: ri.h:3068
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References CParserError(), entity_initial, entity_storage, entity_type, entity_undefined_p, exp, expression_undefined, FindEntityFromLocalName(), FindOrCreateEntity(), is_type_functional, is_type_variable, is_value_code, make_call(), make_code(), make_expression(), make_functional(), make_language_c(), make_reference(), make_sequence(), make_storage_rom(), make_syntax_call(), make_syntax_reference(), make_type_functional(), make_type_unknown(), make_value(), NIL, normalized_undefined, pips_debug, safe_entity_name(), strdup(), TOP_LEVEL_MODULE_NAME, type_tag, type_undefined_p, value_symbolic_p, and value_undefined_p.

Referenced by MemberDerivedIdentifierToExpression().

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

◆ init_c_areas()

void init_c_areas ( void  )

In C we have 4 areas.

  1. globalStaticArea: For the Global Variables, these variables are added into StaticArea.
  2. moduleStaticArea: For the Static module variables
  3. localStaticArea(SticArea): General Static variables
  4. DynamicArea The GlobalStaticArea and ModuleStaticArea are basically static areas but they are not defined globally. It is to be added to the Declarations for C

Create a hidden pointer in the heap area to modelize malloc and free effects and to keep track of the corresponding abstract state.

FI: I use a complex type to avoid seeing this variable in the transformers and preconditions... OK, it's not a clean way to do it. Should we create another area to allocate this abstract heap state?

FI: I keep the code below, because it may turn useful again if context-insensitive address values must be generated.

This is because of the reparsing of the compilation unit The area is set to zero and all the declarations are overrided and the memory is reallocated The area is reset to only when it is called by same compilation unit twice. The code is dangerous hence it is commented. Please have a look

if( get_current_compilation_unit_entity() == get_current_module_entity() && (get_current_compilation_unit_entity() == previouscompilationunit)) area_size(type_area(entity_type(msae))) = 0;

if( get_current_compilation_unit_entity() == get_current_module_entity() && (get_current_compilation_unit_entity() == previouscompilationunit)) area_size(type_area(entity_type(gsae))) = previoussizeofGlobalArea ;

Definition at line 186 of file util.c.

187 {
194 
201 
202  //HeapArea = FindOrCreateEntity(compilation_unit_name, HEAP_AREA_LOCAL_NAME);
209 
210  /* Create a hidden pointer in the heap area to modelize malloc and
211  free effects and to keep track of the corresponding abstract
212  state. */
213  /* FI: I use a complex type to avoid seeing this variable in the
214  transformers and preconditions... OK, it's not a clean way to
215  do it. Should we create another area to allocate this abstract
216  heap state? */
217  /* FI: I keep the code below, because it may turn useful again if
218  context-insensitive address values must be generated. */
219  /*
220  if(!compilation_unit_entity_p(get_current_module_entity())) {
221  make_entity(AddPackageToName(get_current_module_name(),
222  MALLOC_EFFECTS_NAME),
223  make_scalar_complex_type(DEFAULT_COMPLEX_TYPE_SIZE),
224 
225  Chose a storage... Maybe in MALLOC_EFFECTS_PACKAGE_NAME?
226 
227  make_storage(is_storage_ram,
228  make_ram(entity_undefined, DynamicArea, 0, NIL))
229 
230  make_storage(is_storage_ram,
231  make_ram(get_current_module_entity(),
232  HeapArea,
233  0, NIL)),
234  make_value(is_value_unknown, UU));
235  }
236  */
237 
238  // Dynamic variables whose size are not known are stored in Stack area
245 
249 
253 
254  /* This is because of the reparsing of the compilation unit
255  The area is set to zero and all the declarations are overrided and the memory is reallocated
256  The area is reset to only when it is called by same compilation unit twice.
257  The code is dangerous hence it is commented. Please have a look
258 
259  if( get_current_compilation_unit_entity() == get_current_module_entity() &&
260  (get_current_compilation_unit_entity() == previouscompilationunit))
261  area_size(type_area(entity_type(msae))) = 0;
262 
263  if( get_current_compilation_unit_entity() == get_current_module_entity() &&
264  (get_current_compilation_unit_entity() == previouscompilationunit))
265  area_size(type_area(entity_type(gsae))) = previoussizeofGlobalArea ;
266  */
267 }
area make_area(intptr_t a1, list a2)
Definition: ri.c:98
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
entity DynamicArea
These global variables are declared in ri-util/util.c.
Definition: area.c:57
entity HeapArea
Definition: area.c:59
entity StaticArea
Definition: area.c:58
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
#define STACK_AREA_LOCAL_NAME
Definition: naming-local.h:72
#define STATIC_AREA_LOCAL_NAME
Definition: naming-local.h:70
#define HEAP_AREA_LOCAL_NAME
Definition: naming-local.h:71
@ ENTITY_STATIC_AREA
@ ABSTRACT_LOCATION
@ ENTITY_DYNAMIC_AREA
@ ENTITY_STACK_AREA
@ ENTITY_HEAP_AREA
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
#define entity_kind(x)
Definition: ri.h:2798
@ is_type_area
Definition: ri.h:2899

References ABSTRACT_LOCATION, AddEntityToDeclarations(), compilation_unit_name, DYNAMIC_AREA_LOCAL_NAME, DynamicArea, ENTITY_DYNAMIC_AREA, ENTITY_HEAP_AREA, entity_initial, entity_kind, ENTITY_STACK_AREA, ENTITY_STATIC_AREA, entity_storage, entity_type, FindOrCreateEntity(), get_current_module_entity(), get_current_module_name(), HEAP_AREA_LOCAL_NAME, HeapArea, is_type_area, make_area(), make_storage_rom(), make_type(), make_value_unknown(), NIL, STACK_AREA_LOCAL_NAME, StackArea, STATIC_AREA_LOCAL_NAME, StaticArea, and TOP_LEVEL_MODULE_NAME.

Referenced by MakeCurrentCompilationUnitEntity(), and MakeCurrentModule().

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

◆ init_C_comment()

void init_C_comment ( void  )

Definition at line 1513 of file clexer.c.

1514 {
1515  bracket_depth = 0;
1517  pips_internal_error("Missing reset for C_current_comment");
1518  }
1519  if(!stack_undefined_p(comments_stack) && !STACK_NULL_P(comments_stack) && !comments_empty_p()) {
1520  pips_internal_error("Comment stack is not empty");
1521  }
1522  make_comments_stack();
1523  token_has_been_seen_p = false;
1524 }
static int bracket_depth
Definition: clexer.c:1274
static bool token_has_been_seen_p
To see if comments are collected within a statement or outside it is pretty easy to turn it on.
Definition: clexer.c:1268
#define STACK_NULL_P(s)
Definition: newgen_stack.h:53

◆ init_c_implicit_variables()

void init_c_implicit_variables ( entity  m)

Function name variable function and FUNCTION

Should be static, but not compatible with FREIA inlining.

It is not clear if the encoding is correct or not. It may also be correct but not supported. This could be checked by computing the preconditions for strings and/or by adding initial values to the symbol table display.

Since the declarations are not added to a statement_declarations field, they are not going to be prettyprinted.

Definition at line 277 of file util.c.

278 {
279  /* Function name variable __function__ and __FUNCTION__ */
280  const char * mn = entity_local_name(m);
281  string bs = "0`"; // first local scope in a module: should be
282  // returned by a function to stay consistent in
283  // case of change
284  string fn1 = strdup(concatenate(bs, IMPLICIT_VARIABLE_NAME_1, NULL));
285  string fn2 = strdup(concatenate(bs, IMPLICIT_VARIABLE_NAME_2, NULL));
286  entity func_name1 = FindOrCreateEntity(mn, fn1);
287  entity func_name2 = FindOrCreateEntity(mn, fn2);
288  const char * name = entity_user_name(m);
289  string cn = strdup(concatenate("\"", mn, "\"", NULL));
292  strlen(name)+1);
293  free(cn);
294  entity a = DynamicArea; /* Should be static, but not compatible with
295  FREIA inlining. */
296 
297  entity_type(func_name1) = make_char_array_type(strlen(name)+1);
298  entity_storage(func_name1) =
300  /* It is not clear if the encoding is correct or not. It may also
301  be correct but not supported. This could be checked by computing
302  the preconditions for strings and/or by adding initial values to
303  the symbol table display. */
305  AddEntityToDeclarations(func_name1, m);
306 
307  entity_type(func_name2) = make_char_array_type(strlen(name)+1);
308  entity_storage(func_name2) =
311  AddEntityToDeclarations(func_name2, m);
312  /* Since the declarations are not added to a statement_declarations
313  field, they are not going to be prettyprinted. */
314 
315  free(fn1);
316  free(fn2);
317 }
value make_value_expression(expression _field_)
Definition: ri.c:2850
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
storage make_storage_ram(ram _field_)
Definition: ri.c:2279
entity make_C_constant_entity(string name, tag bt, size_t size)
Definition: util.c:269
#define IMPLICIT_VARIABLE_NAME_1
Implicit variable names for C.
#define IMPLICIT_VARIABLE_NAME_2
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
type make_char_array_type(int)
Definition: type.c:5213
@ is_basic_string
Definition: ri.h:576

References AddEntityToDeclarations(), concatenate(), DynamicArea, entity_initial, entity_local_name(), entity_storage, entity_type, entity_user_name(), FindOrCreateEntity(), free(), IMPLICIT_VARIABLE_NAME_1, IMPLICIT_VARIABLE_NAME_2, is_basic_string, make_C_constant_entity(), make_call_expression(), make_char_array_type(), make_ram(), make_storage_ram(), make_value_expression(), NIL, strdup(), and UNKNOWN_RAM_OFFSET.

Referenced by MakeCurrentModule().

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

◆ init_c_parser_scope_stack()

void init_c_parser_scope_stack ( void  )

Definition at line 514 of file cyacc.tab.c.

515  {
517  pips_assert("The stack is undefined",
520  }
@ string_domain
Definition: genC.h:170
stack stack_make(int, int, int)
allocation
Definition: stack.c:246

◆ init_entity_type_storage_table()

void init_entity_type_storage_table ( void  )

Definition at line 131 of file c_parser.c.

132 {
136  //put_stack_storage_table("test","T");
137 }
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
@ hash_string
Definition: newgen_hash.h:32
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50

References entity_to_type_stack_table, hash_string, hash_table_make(), hash_table_undefined_p, and reset_entity_type_stack_table().

Referenced by actual_c_parser().

+ Here is the call graph for this function:
+ 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
#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:

◆ InitializeEnumMemberValues()

void InitializeEnumMemberValues ( list  lem)

The expression evaluation may have been delayed

Parameters
lemem

Definition at line 3104 of file util.c.

3105 {
3106  // enum member with implicit values are not yet fully instantiated
3107  list cem = list_undefined;
3108  _int cv = 0;
3109 
3110  for(cem = lem; !ENDP(cem); POP(cem)) {
3111  entity em = ENTITY(CAR(cem));
3112  value emv = entity_initial(em);
3113 
3114  if(value_undefined_p(emv)) {
3115  entity_initial(em) =
3117  make_constant(is_constant_int, (void *) cv)));
3118  }
3119  else {
3120  symbolic s = value_symbolic(emv);
3121  constant c = symbolic_constant(s);
3122 
3125  symbolic_constant(s) = make_constant(is_constant_int, (void *) cv);
3126  }
3127  else if(constant_unknown_p(c)) {
3128  /* The expression evaluation may have been delayed */
3132  }
3134  pips_assert("The symbolic field is consisten", symbolic_consistent_p(s));
3135  }
3136  cv++;
3137  }
3138 }
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
bool symbolic_consistent_p(symbolic p)
Definition: ri.c:2342
symbolic make_symbolic(expression a1, constant a2)
Definition: ri.c:2369
value make_value_symbolic(symbolic _field_)
Definition: ri.c:2838
intptr_t _int
_INT
Definition: newgen_types.h:53
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
#define value_constant(x)
Definition: ri.h:3073
#define symbolic_constant(x)
Definition: ri.h:2599
#define constant_int(x)
Definition: ri.h:850
#define constant_unknown_p(x)
Definition: ri.h:863
@ is_constant_int
Definition: ri.h:817
#define value_constant_p(x)
Definition: ri.h:3071
#define value_symbolic(x)
Definition: ri.h:3070
#define constant_int_p(x)
Definition: ri.h:848
#define expression_undefined_p(x)
Definition: ri.h:1224
#define symbolic_expression(x)
Definition: ri.h:2597

References CAR, constant_int, constant_int_p, constant_unknown_p, ENDP, ENTITY, entity_initial, EvalExpression(), expression_undefined_p, int_to_expression(), is_constant_int, list_undefined, make_constant(), make_symbolic(), make_value_symbolic(), pips_assert, POP, symbolic_consistent_p(), symbolic_constant, symbolic_expression, value_constant, value_constant_p, value_symbolic, and value_undefined_p.

+ Here is the call graph for this function:

◆ InitScope()

void InitScope ( void  )

Definition at line 306 of file cyacc.tab.c.

307 {
308  C_scope_identifier = -1;
309 }
static int C_scope_identifier
Definition: cyacc.tab.c:304

◆ insert_qualifier()

list insert_qualifier ( list  ql,
qualifier  nq 
)

if qualifier "nq" does not already belong to qualifier list "ql", add it in front of the list.

The list is probably reversed somewhere else... for instance by the parsing grammar rules

FI: either the context was not stacked or it was not used and emptied...

Parameters
qll
nqq

Definition at line 3567 of file util.c.

3568 {
3569  bool found = false; // FI: Should never be useful...
3570  list nql = ql;
3571 
3572  FOREACH(QUALIFIER, q, ql) {
3573  if(qualifier_equal_p(q, nq)) {
3574  /* FI: either the context was not
3575  stacked or it was not used and
3576  emptied... */
3577  c_parser_user_warning("Dupliquate qualifier \"%s\"\n",
3578  qualifier_to_string(q));
3579  found = true;
3580  }
3581  }
3582 
3583  if(!found)
3584  //c_parser_context_qualifiers(ycontext) =
3585  nql = CONS(QUALIFIER, nq, ql);
3586 
3587  return nql;
3588 }
string qualifier_to_string(qualifier)
Definition: type.c:5427
bool qualifier_equal_p(qualifier, qualifier)
Definition: type.c:5420
#define QUALIFIER(x)
QUALIFIER.
Definition: ri.h:2106

References c_parser_user_warning, CONS, FOREACH, QUALIFIER, qualifier_equal_p(), and qualifier_to_string().

+ Here is the call graph for this function:

◆ make_C_constant_entity()

entity make_C_constant_entity ( string  name,
tag  bt,
size_t  size 
)
Parameters
nameame
btt
sizeize

Definition at line 269 of file util.c.

272 {
273  return make_C_or_Fortran_constant_entity(name, bt, size, false, c_parser_error);
274 }
bool c_parser_error(const char *func, const char *msg)
Output a parser message error.
Definition: c_parser.c:266
entity make_C_or_Fortran_constant_entity(const char *name, tag bt, size_t size, bool is_fortran, bool(*error_manager)(const char *, const char *))
This function creates a constant.
Definition: constant.c:148

References c_parser_error(), and make_C_or_Fortran_constant_entity().

Referenced by init_c_implicit_variables().

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

◆ make_predefined_C_entities()

void make_predefined_C_entities ( string  compilation_unit_name)

Predefined type(s): __builtin_va_list

Let's lie about the real type

Predefined functions(s): __builtin_va_end (va_arg() is parsed directly)

Let's lie about the real type...

Let's lie about the real type

Let's lie about the real type

Parameters
compilation_unit_nameompilation_unit_name

Definition at line 425 of file c_parser.c.

426 {
427  entity built_in_va_list = entity_undefined;
428  entity built_in_bool = entity_undefined;
429  entity built_in_complex = entity_undefined;
430  entity built_in_va_start = entity_undefined;
431  entity built_in_va_end = entity_undefined;
432  entity built_in_va_copy = entity_undefined;
433 
434  /* Predefined type(s): __builtin_va_list */
435  built_in_va_list =
437  if(storage_undefined_p(entity_storage(built_in_va_list))) {
438  entity_storage(built_in_va_list) = make_storage_rom();
439  /* Let's lie about the real type */
440  entity_type(built_in_va_list) =
443  NIL,
444  NIL));
445  entity_initial(built_in_va_list) = make_value_unknown();
446  }
447  built_in_bool =
449  if(storage_undefined_p(entity_storage(built_in_bool))) {
450  entity_storage(built_in_bool) = make_storage_rom();
451  entity_type(built_in_bool) =
454  NIL, NIL));
455  entity_initial(built_in_bool) = make_value_unknown();
456  }
457  built_in_complex =
459  if(storage_undefined_p(entity_storage(built_in_complex))) {
460  entity_storage(built_in_complex) = make_storage_rom();
461  entity_type(built_in_complex) =
464  NIL, NIL));
465  entity_initial(built_in_complex) = make_value_unknown();
466  }
467 
468  /* Predefined functions(s): __builtin_va_end (va_arg() is parsed directly) */
469  built_in_va_start =
471  if(storage_undefined_p(entity_storage(built_in_va_start))) {
472  basic va_list_b = make_basic(is_basic_typedef, built_in_va_list);
473  type va_list_t =
476  type void_start_t =
478  entity_storage(built_in_va_start) = make_storage_rom();
479  /* Let's lie about the real type... */
480  entity_type(built_in_va_start) =
483  make_parameter(va_list_t,
485  UU),
487  CONS(PARAMETER,
488  make_parameter(void_start_t,
491  NIL)),
493  entity_initial(built_in_va_start) = make_value_intrinsic();
494  }
495 
496  built_in_va_end =
498  if(storage_undefined_p(entity_storage(built_in_va_end))) {
499  basic va_list_b = make_basic(is_basic_typedef, built_in_va_list);
500  type va_list_t =
502  entity_storage(built_in_va_end) = make_storage_rom();
503  /* Let's lie about the real type */
504  entity_type(built_in_va_end) =
507  make_parameter(va_list_t,
510  NIL),
512  entity_initial(built_in_va_end) = make_value_intrinsic();
513  }
514 
515  built_in_va_copy =
517  if(storage_undefined_p(entity_storage(built_in_va_copy))) {
518  basic va_list_b = make_basic(is_basic_typedef, built_in_va_list);
519  type va_list_t =
521  parameter va_list_p = make_parameter(va_list_t,
522  make_mode_value(),
524  entity_storage(built_in_va_copy) = make_storage_rom();
525  /* Let's lie about the real type */
526  entity_type(built_in_va_copy) =
529  va_list_p,
530  CONS(PARAMETER,
531  copy_parameter(va_list_p),
532  NIL)),
534  entity_initial(built_in_va_copy) = make_value_intrinsic();
535  }
536 }
parameter copy_parameter(parameter p)
PARAMETER.
Definition: ri.c:1459
basic make_basic_complex(intptr_t _field_)
Definition: ri.c:170
mode make_mode(enum mode_utype tag, void *val)
Definition: ri.c:1350
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
type make_type_void(list _field_)
Definition: ri.c:2727
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
basic make_basic_logical(intptr_t _field_)
Definition: ri.c:164
value make_value_intrinsic(void)
Definition: ri.c:2844
dummy make_dummy_unknown(void)
Definition: ri.c:617
#define UU
Definition: newgen_types.h:98
#define BUILTIN_VA_END
vararg stuff.
#define DEFAULT_LOGICAL_TYPE_SIZE
#define BUILTIN_VA_COPY
#define DEFAULT_INTEGER_TYPE_SIZE
#define DEFAULT_COMPLEX_TYPE_SIZE
#define BUILTIN_VA_START
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_typedef
Definition: ri.h:580
@ is_mode_value
Definition: ri.h:1675
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
@ is_type_void
Definition: ri.h:2904

References BUILTIN_VA_COPY, BUILTIN_VA_END, BUILTIN_VA_START, compilation_unit_name, CONS, copy_parameter(), DEFAULT_COMPLEX_TYPE_SIZE, DEFAULT_INTEGER_TYPE_SIZE, DEFAULT_LOGICAL_TYPE_SIZE, entity_initial, entity_storage, entity_type, entity_undefined, FindOrCreateEntity(), is_basic_pointer, is_basic_typedef, is_mode_value, is_type_functional, is_type_variable, is_type_void, make_basic(), make_basic_complex(), make_basic_int(), make_basic_logical(), make_dummy_unknown(), make_functional(), make_mode(), make_mode_value(), make_parameter(), make_storage_rom(), make_type(), make_type_void(), make_value_intrinsic(), make_value_unknown(), make_variable(), NIL, PARAMETER, storage_undefined_p, TYPEDEF_PREFIX, and UU.

Referenced by actual_c_parser().

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

◆ MakeArrayExpression()

expression MakeArrayExpression ( expression  exp,
list  lexp 
)

FI: this function is called for a bracketed comma expression.

The two arguments are (should be) reused within the returned expression

There are two cases:

  1. Simple array reference, where the first argument is a simple array or pointer name. We create a reference expression (syntax = reference).
  2. Complicated subscripting array, where the first argument can be a function call (foo()[]), a structure or union member (str[5].field[7], ... We create a subscripting expression (syntax = subscript).

FI: Memory leak with exp?

FI: we might have preexisting subscript? No, in this context, only one index due to lack of type information?

Parameters
expxp
lexpexp

Definition at line 713 of file util.c.

714 {
715  /* There are two cases:
716 
717  1. Simple array reference, where the first argument is a simple
718  array or pointer name. We create a reference expression (syntax =
719  reference).
720 
721  2. Complicated subscripting array, where the first argument can be
722  a function call (foo()[]), a structure or union member
723  (str[5].field[7], ... We create a subscripting expression (syntax =
724  subscript).
725  */
726 
729  list sl = lexp;
730 
731  if(!ENDP(CDR(lexp))) {
733  sl = CONS(EXPRESSION, se, NIL);
734  }
735 
736  switch(syntax_tag(s)) {
737  case is_syntax_reference:
738  {
739  /* FI: Memory leak with exp? */
741  entity ent = reference_variable(r);
742  list l = reference_indices(r);
743  pips_debug(6,"Normal reference expression\n");
745  break;
746  }
747  case is_syntax_call:
748  case is_syntax_range:
749  case is_syntax_cast:
751  case is_syntax_subscript:
753  {
754  /* FI: we might have preexisting subscript? No, in this
755  context, only one index due to lack of type information? */
756  subscript a = make_subscript(exp,sl);
758  pips_debug(6,"Subscripting array expression\n");
760  break;
761  }
762  default:
763  {
764  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
765  }
766  }
767  return e;
768 }
subscript make_subscript(expression a1, list a2)
Definition: ri.c:2327
syntax make_syntax_subscript(subscript _field_)
Definition: ri.c:2509
static list lexp
expression reference_to_expression(reference r)
Definition: expression.c:196
expression MakeCommaExpression(list l)
Definition: expression.c:3918
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_variable(x)
Definition: ri.h:2326
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define reference_indices(x)
Definition: ri.h:2328

References CDR, CONS, ENDP, exp, EXPRESSION, expression_syntax, expression_undefined, gen_nconc(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, lexp, make_expression(), make_reference(), make_subscript(), make_syntax_subscript(), MakeCommaExpression(), NIL, normalized_undefined, pips_debug, pips_internal_error, reference_indices, reference_to_expression(), reference_variable, syntax_reference, and syntax_tag.

+ 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 }
instruction make_instruction_sequence(sequence _field_)
Definition: ri.c:1169
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_NUMBER_UNDEFINED
default values
#define empty_comments
Empty comments (i.e.

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
#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 }
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
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
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)
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 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 }
constant make_constant_litteral(void)
Definition: ri.c:418
type MakeTypeStatement(void)
Definition: type.c:92
@ is_value_constant
Definition: ri.h:3033

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:

◆ MakeCurrentCompilationUnitEntity()

void MakeCurrentCompilationUnitEntity ( const char *  name)

A compilation unit is also considered as a module.

value v = entity_initial(e);

if(value_code_p(v)) {

code c = value_code(v);

language l = code_language(c);

if(language_unknown_p(l))

code_language(c) = make_language_c();

else if(language_fortran_p(l) || language_fortran95_p(l))

pips_internal_error("A compilation unit should have language \"C".
");

}

else

pips_internal_error("A compilation unit should have value \"code".
");

Parameters
nameame

Definition at line 328 of file util.c.

329 {
331  /* value v = entity_initial(e); */
332  /* if(value_code_p(v)) { */
333  /* code c = value_code(v); */
334  /* language l = code_language(c); */
335  /* if(language_unknown_p(l)) */
336  /* code_language(c) = make_language_c(); */
337  /* else if(language_fortran_p(l) || language_fortran95_p(l)) */
338  /* pips_internal_error("A compilation unit should have language \"C\".\n"); */
339  /* } */
340  /* else */
341  /* pips_internal_error("A compilation unit should have value \"code\".\n"); */
342 
343  pips_debug(4,"Set current module entity for compilation unit %s\n",name);
345  //init_stack_storage_table();
346  init_c_areas();
347 }
void init_c_areas()
In C we have 4 areas.
Definition: util.c:186
entity MakeCompilationUnitEntity(const char *name)
This is useful for the C language only.
Definition: entity.c:1954

References init_c_areas(), MakeCompilationUnitEntity(), pips_debug, and set_current_module_entity().

Referenced by actual_c_parser().

+ Here is the call graph for this function:
+ Here is the caller 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 }
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
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define basic_domain
newgen_area_domain_defined
Definition: ri.h:42
#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:

◆ MakeDerivedEntity()

entity MakeDerivedEntity ( string  name,
list  members,
bool  is_external,
int  i 
)

FI: What should the initial value be?

Parameters
nameame
membersembers
is_externals_external

Definition at line 3140 of file util.c.

3141 {
3142  entity ent = entity_undefined;
3143  switch (i) {
3144  case is_type_struct:
3145  {
3147  entity_type(ent) = make_type_struct(members);
3148  break;
3149  }
3150  case is_type_union:
3151  {
3153  entity_type(ent) = make_type_union(members);
3154  break;
3155  }
3156  case is_type_enum:
3157  {
3159  entity_type(ent) = make_type_enum(members);
3160  break;
3161  }
3162  }
3164  /* FI: What should the initial value be? */
3168 
3169  return ent;
3170 }
type make_type_union(list _field_)
Definition: ri.c:2733
type make_type_struct(list _field_)
Definition: ri.c:2730
type make_type_enum(list _field_)
Definition: ri.c:2736
@ is_type_enum
Definition: ri.h:2907
@ is_type_union
Definition: ri.h:2906
@ is_type_struct
Definition: ri.h:2905

References AddEntityToDeclarations(), CreateEntityFromLocalNameAndPrefix(), entity_initial, entity_storage, entity_type, entity_undefined, ENUM_PREFIX, get_current_module_entity(), is_external, is_type_enum, is_type_struct, is_type_union, make_storage_rom(), make_type_enum(), make_type_struct(), make_type_union(), make_value_unknown(), STRUCT_PREFIX, UNION_PREFIX, and value_undefined_p.

+ Here is the call graph for this function:

◆ MakeDimension()

dimension MakeDimension ( list  le,
list  ql 
)

Take only the first expression of le, do not know why it can be a list ?

use the integer value

If we do this, we cannot restitute the source code

Build a new expression e' == e-1

Parameters
lee
qll

Definition at line 1389 of file util.c.

1390 {
1391  dimension d;
1392  if (le == NIL)
1393  {
1395  pips_debug(5,"Unbounded dimension\n");
1396  }
1397  else
1398  {
1399  /* Take only the first expression of le, do not know why it can be a list ?*/
1400  expression e = EXPRESSION(CAR(le));
1401  intptr_t up;
1402 
1403  if (false && expression_integer_value(e,&up))
1404  /* use the integer value */ /* If we do this, we cannot restitute the source code */
1406  else
1407  /* Build a new expression e' == e-1 */
1410  e,
1411  int_to_expression(1)),
1412  ql);
1413 
1414  ifdebug(9)
1415  {
1416  pips_debug(5,"Array dimension:");
1417  print_expression(e);
1418  pips_debug(8,"Array lower bound:");
1420  pips_debug(5,"Array dimension:");
1422  }
1423  }
1424  return d;
1425 }
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define MINUS_C_OPERATOR_NAME
expression make_unbounded_expression()
Definition: expression.c:4339
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
#define dimension_lower(x)
Definition: ri.h:980
#define dimension_upper(x)
Definition: ri.h:982

References CAR, CreateIntrinsic(), dimension_lower, dimension_upper, EXPRESSION, expression_integer_value(), ifdebug, int_to_expression(), intptr_t, make_dimension(), make_unbounded_expression(), MakeBinaryCall(), MINUS_C_OPERATOR_NAME, NIL, pips_debug, and print_expression().

Referenced by UpdateArrayEntity().

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

◆ MakeEnumeratorInitialValue()

value MakeEnumeratorInitialValue ( list  enum_list,
int  counter 
)

The initial value = 0 if this is the first member in the enumerator list else, it is equal to : intial_value(predecessor) + 1

Find the predecessor of the counter-th member

Parameters
enum_listnum_list
counterounter

Definition at line 3299 of file util.c.

3300 {
3301  /* The initial value = 0 if this is the first member in the enumerator list
3302  else, it is equal to : intial_value(predecessor) + 1 */
3303  value v = value_undefined;
3304  if (counter == 1)
3306  else
3307  {
3308  /* Find the predecessor of the counter-th member */
3309  entity pre = ENTITY(gen_nth(counter-1, enum_list));
3310  value vp = entity_initial(pre);
3311  if (value_constant_p(vp))
3312  {
3313  constant c = value_constant(vp);
3314  if (constant_int_p(c))
3315  {
3316  int i = constant_int(c);
3318  }
3319  }
3320  }
3321  return v;
3322 }
value make_value_constant(constant _field_)
Definition: ri.c:2841
constant make_constant_int(intptr_t _field_)
Definition: ri.c:409
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define value_undefined
Definition: ri.h:3016

References constant_int, constant_int_p, ENTITY, entity_initial, gen_nth(), make_constant_int(), make_value_constant(), value_constant, value_constant_p, and value_undefined.

+ 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
#define CONTINUE_FUNCTION_NAME
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
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
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
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
list statement_block(statement s)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
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 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:

◆ MakeFunctionExpression()

expression MakeFunctionExpression ( expression  e,
list  le 
)

e is now owned by returned expression and must not be used any longer

There are 2 cases:

  1. The first argument corresponds to a function name (an entity).

    In this case, we create a normal call expression and the corresponding entity is added to the list of callees.

  2. The first argument can be any expression denoting a called function (a pointer to a function,... such as (*ctx->Driver.RenderString)() in the benchmark mesa in SPEC2000). In this case, we create a function application expression.

Must be a pointer to a function

Undeclared functions return int by default

This cannot be checked unless bootstrap typing is improved for varargs intrinsics, mostly IOs.

Parameters
lee

Definition at line 368 of file util.c.

369 {
370  /* There are 2 cases:
371 
372  1. The first argument corresponds to a function name (an entity).
373 
374  In this case, we create a normal call expression and the
375  corresponding entity is added to the list of callees.
376 
377  2. The first argument can be any expression denoting a called
378  function (a pointer to a function,... such as
379  (*ctx->Driver.RenderString)() in the benchmark mesa in
380  SPEC2000). In this case, we create a function application
381  expression.
382  */
384  syntax s = expression_syntax(e);
385  switch (syntax_tag(s))
386  {
387  case is_syntax_reference:
388  {
390  free_expression(e);
392 
393  ifdebug(8) {
394  pips_debug(8, "Call to \"\%s\" with %zd argument(s)\n",
395  entity_name(ent), gen_length(le));
396  print_expressions(le);
397  }
398 
399  if(!intrinsic_entity_p(ent)) {
402  type ut = ultimate_type(entity_type(ent));
403 
404  if(type_functional_p(ut))
405  AddToCalledModules(ent);
406  else {
407  /* Must be a pointer to a function */
408  const char * eun = entity_user_name(ent);
409  c_parser_user_warning("Call to an unknown function via function pointer \"\%s\"\n",
410  eun);
411  }
412 
413  if(!gen_in_list_p(ent, cudl)) {
414  /* Undeclared functions return int by default */
415  type ft = entity_type(ent);
417 
418  pips_assert("function's type is ultimately functional or pointer to functional",
420  f = type_functional(ft);
423  AddToDeclarations(ent, cf);
424  }
425  }
426  pips_debug(6,"Normal function or intrinsics call\n");
427  (void)check_C_function_type(ent,le);
428  exp = make_call_expression(ent,le);
429  /* This cannot be checked unless bootstrap typing is improved
430  for varargs intrinsics, mostly IOs. */
431  /*
432  if(!ok) {
433  c_parser_user_warning("Actual arguments do not fit the declared formal "
434  "arguments of function \"%s\"\n",
435  entity_user_name(ent));
436  CParserError("Type mismatch\n");
437  }
438  */
439  break;
440  }
441  case is_syntax_call:
442  {
443  application a = make_application(e,le);
444  pips_debug(6,"Application function call\n");
446  break;
447  }
448  case is_syntax_range:
449  case is_syntax_cast:
451  case is_syntax_subscript:
453  CParserError("This is not a functional expression\n");
454  break;
455  default:
456  {
457  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
458  }
459  }
460  return exp;
461 }
syntax make_syntax_application(application _field_)
Definition: ri.c:2512
application make_application(expression a1, list a2)
Definition: ri.c:56
entity get_current_compilation_unit_entity()
Definition: util.c:320
void AddToCalledModules(entity e)
Definition: util.c:3413
bool call_compatible_type_p(type)
end of basic_concrete_types
Definition: type.c:3764
bool check_C_function_type(entity, list)
Check that an effective parameter list is compatible with a function type.
Definition: type.c:4716
type MakeIntegerResult(void)
Definition: type.c:276
#define type_unknown_p(x)
Definition: ri.h:2956

References AddToCalledModules(), AddToDeclarations(), c_parser_user_warning, call_compatible_type_p(), check_C_function_type(), code_declarations, CParserError(), entity_initial, entity_name, entity_type, entity_user_name(), exp, expression_syntax, expression_undefined, f(), free_expression(), functional_result, gen_in_list_p(), gen_length(), get_current_compilation_unit_entity(), get_current_module_entity(), ifdebug, intrinsic_entity_p(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, make_application(), make_call_expression(), make_expression(), make_syntax_application(), MakeIntegerResult(), normalized_undefined, pips_assert, pips_debug, pips_internal_error, print_expressions(), reference_variable, syntax_reference, syntax_tag, type_functional, type_functional_p, type_unknown_p, ultimate_type(), and value_code.

+ 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

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:

◆ MakeParameterList()

list MakeParameterList ( list  l1,
list  l2,
stack  FunctionStack 
)

l1 is a list of parameter names and it represents the exact order in the parameter list l2 is a list of entities with their type, storage,... and the order can be different from l1 In addition, l2 can be incomplete wrt l1, so other entities must be created from l1, with default type : scalar integer variable.

We create the list of parameters with the order of l1, and the parameter type and mode are retrieved from l2.

Since the offset of formal argument in l2 can be false, we have to update it here by using l1

s is not declared in l2, create the corresponding entity/ formal variable and add it to the declaration list, because it cannot be added with par_def in l2

Parameters
l11
l22
FunctionStackunctionStack

Definition at line 3348 of file util.c.

3349 {
3350  /* l1 is a list of parameter names and it represents the exact order in the parameter list
3351  l2 is a list of entities with their type, storage,... and the order can be different from l1
3352  In addition, l2 can be incomplete wrt l1, so other entities must be created from l1, with
3353  default type : scalar integer variable.
3354 
3355  We create the list of parameters with the order of l1, and the parameter type and mode
3356  are retrieved from l2.
3357 
3358  Since the offset of formal argument in l2 can be false, we have to update it here by using l1 */
3359  list l = NIL;
3360  int offset = 1;
3361  entity function = stack_head(FunctionStack);
3362  FOREACH(STRING, s,l1)
3363  {
3365  if (parameter_undefined_p(p))
3366  {
3367  /* s is not declared in l2, create the corresponding entity/ formal variable
3368  and add it to the declaration list, because it cannot be added with par_def in l2*/
3369  entity ent = FindOrCreateEntity(entity_user_name(function),s);
3371  entity_type(ent) = make_type_variable(v);
3373  AddToDeclarations(ent,function);
3374  p = make_parameter(entity_type(ent),
3375  make_mode_value(),
3376  make_dummy_identifier(ent)); // FI: could be unknown?
3377  }
3378  l = gen_nconc(l,CONS(PARAMETER,p,NIL));
3379  offset++;
3380  }
3381  return l;
3382 }
type make_type_variable(variable _field_)
Definition: ri.c:2715
storage make_storage_formal(formal _field_)
Definition: ri.c:2282
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
parameter FindParameterEntity(string s, int offset, list l)
Definition: util.c:3384
#define parameter_undefined_p(x)
Definition: ri.h:1795

References AddToDeclarations(), CONS, DEFAULT_INTEGER_TYPE_SIZE, entity_storage, entity_type, entity_user_name(), FindOrCreateEntity(), FindParameterEntity(), FOREACH, FunctionStack, gen_nconc(), make_basic_int(), make_dummy_identifier(), make_formal(), make_mode_value(), make_parameter(), make_storage_formal(), make_type_variable(), make_variable(), NIL, offset, PARAMETER, parameter_undefined_p, stack_head(), and STRING.

+ Here is the call graph for this function:

◆ MakeStorageRam()

storage MakeStorageRam ( entity  v,
bool  is_external,
bool  is_static 
)

The storage part should not be called twice when reparsing compilation unit.

We assume that double declarations are dealt with someone else

ComputeAreaOffset(StaticArea,e)

he offset must be recomputed lately, when we know for sure the size of the variables

This must be a variable, not a function/typedef/struct/union/enum. The variable is declared outside any function, and hence is global

ComputeAreaOffset(get_top_level_entity(),e)

the offset must be recomputed lately, when we know for sure the size of the variable

Global variable can be declared in many different file

ADD BLOCK SCOPE

ComputeAreaOffset(StaticArea,e)

he offset must be recomputed lately, when we know for sure the size of the variable

ComputeAreaOffset(DynamicArea,e)

the offset must be recomputed lately, when we know for sure the size of the variable

Parameters
is_externals_external
is_statics_static

Definition at line 3177 of file util.c.

3178 {
3179  ram r = ram_undefined;
3183  area msa = type_area(entity_type(moduleStaticArea));
3185  area gsa = type_area(entity_type(globalStaticArea));
3187  //area heap = type_area (entity_type(HeapArea));
3188  //entity m = get_current_module_entity();
3189 
3190  pips_assert("RAM Storage is used only for variables", type_variable_p(entity_type(v)));
3191 
3192  if (is_external)
3193  {
3194  if (is_static)
3195  {
3197  moduleStaticArea,
3198  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(StaticArea,e) */,
3199  NIL);
3200 
3201  /*the offset must be recomputed lately, when we know for
3202  sure the size of the variables */
3204  || !gen_in_list_p(v,area_layout(msa)))
3205  area_layout(msa) = gen_nconc(area_layout(msa), CONS(ENTITY, v, NIL));
3206  }
3207  else
3208  {
3209  /* This must be a variable, not a function/typedef/struct/union/enum.
3210  The variable is declared outside any function, and hence is global*/
3211 
3213  globalStaticArea,
3214  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(get_top_level_entity(),e) */,
3215  NIL);
3216  /* the offset must be recomputed lately, when we know for
3217  sure the size of the variable */
3218  /* Global variable can be declared in many different file */
3219  if(!gen_in_list_p(v,area_layout(gsa)))
3220  area_layout(gsa) = gen_nconc(area_layout(gsa), CONS(ENTITY, v, NIL));
3221  }
3222  }
3223  else
3224  {
3225  /* ADD BLOCK SCOPE */
3226  if (is_static)
3227  {
3229  StaticArea,
3230  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(StaticArea,e) */,
3231  NIL);
3232  /*the offset must be recomputed lately, when we know for
3233  sure the size of the variable */
3234  area_layout(lsa) = gen_nconc(area_layout(lsa), CONS(ENTITY, v, NIL));
3235  }
3236  else
3237  {
3238  int s = 0;
3239  if(!SizeOfArray(v, &s))
3240  {
3242  StackArea,
3244  NIL);
3246  }
3247  else {
3249  DynamicArea,
3250  UNKNOWN_RAM_OFFSET /* ComputeAreaOffset(DynamicArea,e) */,
3251  NIL);
3252  /* the offset must be recomputed lately, when we know for
3253  sure the size of the variable */
3254  area_layout(dsa) = gen_nconc(area_layout(dsa), CONS(ENTITY, v, NIL));
3255  }
3256  }
3257  }
3258  return make_storage_ram(r);
3259 }
entity get_top_level_entity()
Definition: util.c:152
bool SizeOfArray(entity, int *)
This function computes the total size of a variable in bytes, ie.
Definition: size.c:87
#define ram_undefined
Definition: ri.h:2221

References area_layout, compilation_unit_name, CONS, DYNAMIC_RAM_OFFSET, DynamicArea, ENTITY, entity_type, FindOrCreateEntity(), gen_in_list_p(), gen_nconc(), get_current_compilation_unit_entity(), get_current_module_entity(), get_top_level_entity(), is_external, make_ram(), make_storage_ram(), NIL, pips_assert, ram_undefined, SizeOfArray(), StackArea, STATIC_AREA_LOCAL_NAME, StaticArea, TOP_LEVEL_MODULE_NAME, type_area, type_variable_p, and UNKNOWN_RAM_OFFSET.

Referenced by UpdateEntity().

+ 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
struct _newgen_struct_sequence_ * sequence
Definition: ri.h:351

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:

◆ MakeTopLevelEntity()

void MakeTopLevelEntity ( void  )

To be economic, group this top-level entity to it areas

FI: this is not convenient if top-level:top-level is a module. All global variables should be declared there. I need also to generate stubs for global variables... Do I? Yes, because the points-to information is computed bottom-up.

Definition at line 157 of file util.c.

158 {
159  /* To be economic, group this top-level entity to it areas*/
160  /* FI: this is not convenient if top-level:top-level is a
161  module. All global variables should be declared there. I need
162  also to generate stubs for global variables... Do I? Yes, because
163  the points-to information is computed bottom-up. */
166  //entity_type(e) = make_type(is_type_area, make_area(0, NIL));
167  entity_type(e) =
169  //entity_initial(e) = make_value_unknown();
171  NIL, make_language_c());
173 }
value make_value_code(code _field_)
Definition: ri.c:2835

References entity_initial, entity_storage, entity_type, FindOrCreateEntity(), make_code(), make_functional(), make_language_c(), make_sequence(), make_storage_rom(), make_type_functional(), make_type_void(), make_value_code(), NIL, strdup(), and TOP_LEVEL_MODULE_NAME.

Referenced by actual_c_parser().

+ Here is the call graph for this function:
+ Here is the caller 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 }
statement make_whileloop_statement(expression condition, statement body, int line_number, bool before)
Build a while loop statement.
Definition: statement.c:1150

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:

◆ MemberDerivedIdentifierToExpression()

expression MemberDerivedIdentifierToExpression ( type  t,
string  m 
)

Definition at line 463 of file util.c.

464 {
465  if (type_variable_p(t))
466  {
468  pips_debug(6,"Basic tag is %d\n",basic_tag(b));
469  switch (basic_tag(b)) {
470  case is_basic_pointer:
471  {
472  type tp = basic_pointer(b);
474  }
475  case is_basic_typedef:
476  {
477  entity te = basic_typedef(b);
478  type tp = entity_type(te);
480  }
481  case is_basic_derived:
482  {
483  entity de = basic_derived(b);
484  const char * name = entity_user_name(de);
485  string id = strdup(concatenate(name,MEMBER_SEP_STRING,m,NULL));
487  free(id);
488  return exp;
489  }
490  default:
491  break;
492  }
493  }
494  CParserError("Cannot find the field identifier from current type\n");
495  return expression_undefined;
496 }
expression MemberDerivedIdentifierToExpression(type t, string m)
Definition: util.c:463
expression IdentifierToExpression(string s)
Definition: util.c:650
@ is_basic_derived
Definition: ri.h:579
#define basic_pointer(x)
Definition: ri.h:637
#define basic_derived(x)
Definition: ri.h:640
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define basic_typedef(x)
Definition: ri.h:643
#define variable_basic(x)
Definition: ri.h:3120

References basic_derived, basic_pointer, basic_tag, basic_typedef, concatenate(), CParserError(), entity_type, entity_user_name(), exp, expression_undefined, free(), IdentifierToExpression(), is_basic_derived, is_basic_pointer, is_basic_typedef, MEMBER_SEP_STRING, MemberDerivedIdentifierToExpression(), pips_debug, strdup(), type_variable, type_variable_p, and variable_basic.

Referenced by MemberDerivedIdentifierToExpression(), and MemberIdentifierToExpression().

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

◆ MemberIdentifierToExpression()

expression MemberIdentifierToExpression ( expression  e,
string  m 
)

Find the name of struct/union of m from the type of expression e

The first expression must be a pointer

standard integer arithmetic: why bother? why take the CDR?

FI: seems too simple. No need to remember if you sarted with "." or "->"?

Let use the second argument

More types of call must be taken into account: typedef and pointer to functions

User defined call and intrinsics not processed above

A call must have occured somewhere...

An apply must have occured somewhere...

expression exp = subscript_array(syntax_subscript(s));

pips_debug(6,"Subscripting array expression\n");

return MemberIdentifierToExpression(exp, m);

Definition at line 498 of file util.c.

499 {
500  /* Find the name of struct/union of m from the type of expression e*/
501 
502  syntax s = expression_syntax(e);
503  ifdebug(6)
504  {
505  pips_debug(6,"Find the struct/union of \"%s\" from expression:\n",m);
506  print_expression(e);
507  }
508  switch (syntax_tag(s))
509  {
510  case is_syntax_call:
511  {
512  call c = syntax_call(s);
513  entity f = call_function(c);
514  pips_debug(6,"Called operator is \"%s\"\n",entity_name(f));
515  if(ENTITY_PLUS_C_P(f))
516  {
522 
524  exp = e1;
525  else if(basic_pointer_p(b2) && (basic_int_p(b1)||basic_bit_p(b1)))
526  exp = e2;
527  else
528  CParserError("Pointer arithmetic error, incompatible types");
529  free_basic(b1);
530  free_basic(b2);
531 
533  }
536  {
539  }
540  else if(ENTITY_MINUS_C_P(f))
541  {
542  /* The first expression must be a pointer */
545  }
546  else if(ENTITY_PLUS_P(f))
547  {
548  /* standard integer arithmetic: why bother? why take the CDR? */
551  }
552  else if (ENTITY_FIELD_P(f) || ENTITY_POINT_TO_P(f))
553  {
556  }
557  else if (ENTITY_DEREFERENCING_P(f))
558  {
561  }
562  /* FI: seems too simple. No need to remember if you sarted with "." or "->"? */
563  else if (ENTITY_ADDRESS_OF_P(f))
564  {
567  }
568  else if (ENTITY_ASSIGN_P(f))
569  {
572  }
573  else if (ENTITY_CONDITIONAL_P(f))
574  {
575  /* Let use the second argument */
578  }
579  /* More types of call must be taken into account: typedef and
580  pointer to functions */
581  else if (true || type_functional_p(entity_type(f)))
582  {
583  /* User defined call and intrinsics not processed above */
584  type ft = call_to_functional_type(c, true);
586  if(overloaded_type_p(t))
587  pips_internal_error("Unresolved expression type\n");
589  }
590  break;
591  }
592  case is_syntax_reference:
593  {
595  type t = ultimate_type(entity_type(ent));
596  pips_debug(6,"Reference expression\n");
597 
598  if(type_functional_p(t)) {
599  /* A call must have occured somewhere... */
602  }
605 
606  if(type_functional_p(pt)) {
607  /* An apply must have occured somewhere... */
610  }
611  else
613  }
614  else
616  }
617  case is_syntax_cast:
618  {
619  type t = cast_type(syntax_cast(s));
620  pips_debug(6,"Cast expression\n");
622  }
623  case is_syntax_range:
624  break;
626  break;
627  case is_syntax_subscript:
628  {
629  /* expression exp = subscript_array(syntax_subscript(s)); */
630  /* pips_debug(6,"Subscripting array expression\n"); */
631  /* return MemberIdentifierToExpression(exp, m); */
632  type t = expression_to_type(e);
634  }
636  {
638  return MemberIdentifierToExpression(fe, m);
639  break;
640  }
641  default:
642  {
643  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
644  }
645  }
646  CParserError("Cannot find the field identifier from current expression\n");
647  return expression_undefined;
648 }
void free_basic(basic p)
Definition: ri.c:107
expression MemberIdentifierToExpression(expression e, string m)
Definition: util.c:498
#define ENTITY_ASSIGN_P(e)
#define ENTITY_DEREFERENCING_P(e)
#define ENTITY_PLUS_P(e)
#define ENTITY_POINT_TO_P(e)
#define ENTITY_PRE_DECREMENT_P(e)
#define ENTITY_POST_DECREMENT_P(e)
#define ENTITY_POST_INCREMENT_P(e)
#define ENTITY_CONDITIONAL_P(e)
#define ENTITY_PRE_INCREMENT_P(e)
#define ENTITY_PLUS_C_P(e)
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
#define ENTITY_MINUS_C_P(e)
#define ENTITY_ADDRESS_OF_P(e)
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 expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
type call_to_functional_type(call, bool)
The function called can have a functional type, or a typedef type or a pointer type to a functional t...
Definition: type.c:3824
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
#define basic_int_p(x)
Definition: ri.h:614
#define call_function(x)
Definition: ri.h:709
#define syntax_cast(x)
Definition: ri.h:2739
#define syntax_application(x)
Definition: ri.h:2748
#define basic_pointer_p(x)
Definition: ri.h:635
#define cast_type(x)
Definition: ri.h:745
#define application_function(x)
Definition: ri.h:508
#define call_arguments(x)
Definition: ri.h:711
#define basic_bit_p(x)
Definition: ri.h:632
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105

References application_function, b1, b2, basic_bit_p, basic_int_p, basic_of_expression(), basic_pointer, basic_pointer_p, call_arguments, call_function, call_to_functional_type(), CAR, cast_type, CDR, CParserError(), ENTITY_ADDRESS_OF_P, ENTITY_ASSIGN_P, ENTITY_CONDITIONAL_P, ENTITY_DEREFERENCING_P, ENTITY_FIELD_P, ENTITY_MINUS_C_P, entity_name, ENTITY_PLUS_C_P, ENTITY_PLUS_P, ENTITY_POINT_TO_P, ENTITY_POST_DECREMENT_P, ENTITY_POST_INCREMENT_P, ENTITY_PRE_DECREMENT_P, ENTITY_PRE_INCREMENT_P, entity_type, exp, EXPRESSION, expression_syntax, expression_to_type(), expression_undefined, f(), free_basic(), functional_result, ifdebug, is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, MemberDerivedIdentifierToExpression(), MemberIdentifierToExpression(), overloaded_type_p(), pips_debug, pips_internal_error, print_expression(), reference_variable, syntax_application, syntax_call, syntax_cast, syntax_reference, syntax_tag, type_functional, type_functional_p, type_variable, type_variable_p, ultimate_type(), and variable_basic.

Referenced by MemberIdentifierToExpression().

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

◆ NStackPop()

void NStackPop ( stack  s,
int  n 
)

Pop n times the stack s.

Definition at line 3442 of file util.c.

3443 {
3444  while (n-->0)
3445  gen_free(stack_pop(s));
3446 }
void gen_free(gen_chunk *obj)
version without shared_pointers.
Definition: genClib.c:992

References gen_free(), and stack_pop().

Referenced by StackPop().

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

◆ parser_init_keyword_typedef_table()

void parser_init_keyword_typedef_table ( void  )

FI: keyword_typedef_table is also a global variable. I am trying to move towards some kind of functional wrapping around the global variable, which I would like to declare static in ri-util/static.c.

GNU predefined type(s), expecting no conflict with user named type

AM: en attendant mieux...

typedef names are added later when encoutered.

Definition at line 193 of file c_parser.c.

194 {
195  /* FI: keyword_typedef_table is also a global variable. I am trying
196  * to move towards some kind of functional wrapping around the
197  * global variable, which I would like to declare static in
198  * ri-util/static.c.
199  */
201  hash_put(keyword_typedef_table,"auto", (char *) TK_AUTO);
202  hash_put(keyword_typedef_table,"break", (char *) TK_BREAK);
203  hash_put(keyword_typedef_table,"case", (char *) TK_CASE);
204  hash_put(keyword_typedef_table,"char", (char *) TK_CHAR);
205  hash_put(keyword_typedef_table,"const", (char *) TK_CONST);
206  hash_put(keyword_typedef_table,"__const", (char *) TK_CONST);
207  hash_put(keyword_typedef_table,"continue", (char *) TK_CONTINUE);
208  hash_put(keyword_typedef_table,"default", (char *) TK_DEFAULT);
209  hash_put(keyword_typedef_table,"do", (char *) TK_DO);
210  hash_put(keyword_typedef_table,"double", (char *) TK_DOUBLE);
211  hash_put(keyword_typedef_table,"else", (char *) TK_ELSE);
212  hash_put(keyword_typedef_table,"enum", (char *) TK_ENUM);
213  hash_put(keyword_typedef_table,"extern", (char *) TK_EXTERN);
214  hash_put(keyword_typedef_table,"float", (char *) TK_FLOAT);
215  hash_put(keyword_typedef_table,"for", (char *) TK_FOR);
216  hash_put(keyword_typedef_table,"goto", (char *) TK_GOTO);
217  hash_put(keyword_typedef_table,"if", (char *) TK_IF);
218  hash_put(keyword_typedef_table,"inline", (char *) TK_INLINE);
219  hash_put(keyword_typedef_table,"int", (char *) TK_INT);
220  hash_put(keyword_typedef_table,"__int128_t", (char *) TK_INT128);
221  hash_put(keyword_typedef_table,"__uint128_t", (char *) TK_UINT128);
222  hash_put(keyword_typedef_table,"_Complex", (char *) TK_COMPLEX);
223  hash_put(keyword_typedef_table,"long", (char *) TK_LONG);
224  hash_put(keyword_typedef_table,"register", (char *) TK_REGISTER);
225  hash_put(keyword_typedef_table,"restrict", (char *) TK_RESTRICT);
226  hash_put(keyword_typedef_table,"__restrict", (char *) TK_RESTRICT);
227  hash_put(keyword_typedef_table,"__restrict__", (char *) TK_RESTRICT);
228  hash_put(keyword_typedef_table,"return", (char *) TK_RETURN);
229  hash_put(keyword_typedef_table,"short", (char *) TK_SHORT);
230  hash_put(keyword_typedef_table,"signed", (char *) TK_SIGNED);
231  hash_put(keyword_typedef_table,"sizeof", (char *) TK_SIZEOF);
232  hash_put(keyword_typedef_table,"static", (char *) TK_STATIC);
233  hash_put(keyword_typedef_table,"struct", (char *) TK_STRUCT);
234  hash_put(keyword_typedef_table,"switch", (char *) TK_SWITCH);
235  hash_put(keyword_typedef_table,"__thread", (char *) TK_THREAD);
236  hash_put(keyword_typedef_table,"typedef", (char *) TK_TYPEDEF);
237  hash_put(keyword_typedef_table,"union", (char *) TK_UNION);
238  hash_put(keyword_typedef_table,"unsigned", (char *) TK_UNSIGNED);
239  hash_put(keyword_typedef_table,"void", (char *) TK_VOID);
240  hash_put(keyword_typedef_table,"volatile", (char *) TK_VOLATILE);
241  hash_put(keyword_typedef_table,"while", (char *) TK_WHILE);
242  hash_put(keyword_typedef_table,"__builtin_va_arg", (char *) TK_BUILTIN_VA_ARG);
243  hash_put(keyword_typedef_table,"asm", (char *) TK_ASM);
244  hash_put(keyword_typedef_table,"__asm__", (char *) TK_ASM);
245  hash_put(keyword_typedef_table,"__volatile__", (char *) TK_VOLATILE);
246 
247  /* GNU predefined type(s), expecting no conflict with user named type */
248 
249  hash_put(keyword_typedef_table,"__builtin_va_list", (char *) TK_NAMED_TYPE);
250  hash_put(keyword_typedef_table,"_Bool", (char *) TK_NAMED_TYPE);
251 
252  /* AM: en attendant mieux... */
253  hash_put(keyword_typedef_table,"STEP_ARG", (char *) TK_NAMED_TYPE);
254 
255  /* typedef names are added later when encoutered. */
256 }
hash_table make_keyword_typedef_table(int)
Definition: static.c:256
#define TK_STATIC
Definition: splitc.c:782
#define TK_BREAK
Definition: splitc.c:837
#define TK_SHORT
Definition: splitc.c:779
#define TK_WHILE
Definition: splitc.c:844
#define TK_RESTRICT
Definition: splitc.c:784
#define TK_INT128
Definition: splitc.c:766
#define TK_RETURN
Definition: splitc.c:840
#define TK_INLINE
Definition: splitc.c:850
#define TK_THREAD
Definition: splitc.c:787
#define TK_CASE
Definition: splitc.c:842
#define TK_REGISTER
Definition: splitc.c:786
#define TK_COMPLEX
Definition: splitc.c:771
#define TK_GOTO
Definition: splitc.c:839
#define TK_STRUCT
Definition: splitc.c:773
#define TK_SIZEOF
Definition: splitc.c:789
#define TK_CONST
Definition: splitc.c:783
#define TK_VOID
Definition: splitc.c:770
#define TK_UINT128
Definition: splitc.c:767
#define TK_INT
Definition: splitc.c:765
#define TK_LONG
Definition: splitc.c:778
#define TK_FOR
Definition: splitc.c:846
#define TK_FLOAT
Definition: splitc.c:769
#define TK_SIGNED
Definition: splitc.c:776
#define TK_BUILTIN_VA_ARG
Definition: splitc.c:856
#define TK_SWITCH
Definition: splitc.c:841
#define TK_VOLATILE
Definition: splitc.c:780
#define TK_CONTINUE
Definition: splitc.c:838
#define TK_ELSE
Definition: splitc.c:848
#define TK_EXTERN
Definition: splitc.c:781
#define TK_ENUM
Definition: splitc.c:772
#define TK_IF
Definition: splitc.c:847
#define TK_CHAR
Definition: splitc.c:764
#define TK_AUTO
Definition: splitc.c:785
#define TK_TYPEDEF
Definition: splitc.c:774
#define TK_DO
Definition: splitc.c:845
#define TK_DEFAULT
Definition: splitc.c:843
#define TK_DOUBLE
Definition: splitc.c:768
#define TK_UNSIGNED
Definition: splitc.c:777
#define TK_UNION
Definition: splitc.c:775
#define TK_ASM
Definition: splitc.c:851

References hash_put(), keyword_typedef_table, make_keyword_typedef_table(), TK_ASM, TK_AUTO, TK_BREAK, TK_BUILTIN_VA_ARG, TK_CASE, TK_CHAR, TK_COMPLEX, TK_CONST, TK_CONTINUE, TK_DEFAULT, TK_DO, TK_DOUBLE, TK_ELSE, TK_ENUM, TK_EXTERN, TK_FLOAT, TK_FOR, TK_GOTO, TK_IF, TK_INLINE, TK_INT, TK_INT128, TK_LONG, TK_NAMED_TYPE, TK_REGISTER, TK_RESTRICT, TK_RETURN, TK_SHORT, TK_SIGNED, TK_SIZEOF, TK_STATIC, TK_STRUCT, TK_SWITCH, TK_THREAD, TK_TYPEDEF, TK_UINT128, TK_UNION, TK_UNSIGNED, TK_VOID, TK_VOLATILE, and TK_WHILE.

Referenced by actual_c_parser().

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

◆ pop_block_scope()

string pop_block_scope ( string  old_scope)

The scope is moved up the scope tree and a NULL is return when there are no more scope to explore.

get rid of last block separator

Parameters
old_scopeld_scope

Definition at line 235 of file cyacc.tab.c.

236 {
237  string new_scope = old_scope;
238  string last_scope = string_undefined;
239 
240  pips_debug(8, "old_scope = \"%s\"\n", old_scope);
241  pips_assert("old_scope is a scope", string_block_scope_p(old_scope));
242 
243  if(strlen(old_scope)>0) {
244  /* get rid of last block separator */
245  new_scope[strlen(new_scope)-1] = '\0';
246  last_scope = strrchr(new_scope, BLOCK_SEP_CHAR);
247 
248  if(last_scope==NULL)
249  *new_scope = '\0';
250  else
251  *(last_scope+1) = '\0';
252  }
253  else
254  new_scope = NULL;
255 
256  if(new_scope!=NULL) {
257  pips_debug(8, "new_scope = \"%s\"\n", new_scope);
258  pips_assert("new_scope is a scope", string_block_scope_p(new_scope));
259  }
260  else {
261  pips_debug(8, "new_scope = NULL\n");
262  }
263 
264  return new_scope;
265 }
#define BLOCK_SEP_CHAR
Definition: naming-local.h:51

◆ pop_c_parser_scope_stack()

void pop_c_parser_scope_stack ( void  )

Definition at line 558 of file cyacc.tab.c.

559  {
561  return;
562  }

Referenced by ExitScope().

+ Here is the caller graph for this function:

◆ pop_current_C_comment()

string pop_current_C_comment ( void  )

Pop the current comment.

Returns
the previous current comment.

This is typically used at the end of a statement to be built.

Note this do not set the current comment. Strange API...

Definition at line 1352 of file clexer.c.

1353 {
1354  string cc = comments_pop();
1355  if (string_undefined_p(cc))
1356  pips_debug(3, "empty comment popped at line %d\n",
1358  else
1359  pips_debug(3, "comment \"%s\" popped at line %d\n", cc,
1361  return cc;
1362 }
int get_current_C_line_number(void)
Definition: clexer.c:1146

◆ pop_current_C_line_number()

int pop_current_C_line_number ( void  )

Definition at line 1202 of file clexer.c.

1203 {
1204  int ln = line_number_pop();
1205  c_lineno = absolute_line_number_pop();
1206 
1207  return ln;
1208 }

◆ PopContext()

void PopContext ( void  )

Definition at line 441 of file cyacc.tab.c.

442 {
444 
445  pips_debug(8, "Context %p with scope \"%s\" is popped from stack position %d\n",
447  (void)stack_pop(ContextStack);
449  pips_debug(8, "context stack is now empty\n");
450  }
451  else {
453  pips_debug(8, "Context %p with scope \"%s\" is top of stack at position %d\n",
455  }
456 }

◆ push_current_C_comment()

void push_current_C_comment ( void  )

Push the current C comment so that we can get it back when building the statement later.

This reset the current comment through get_current_C_comment()

Definition at line 1331 of file clexer.c.

1332 {
1333  string cc = get_current_C_comment();
1334 
1335  if (string_undefined_p(cc))
1336  pips_debug(3, "empty comment pushed at line %d\n",
1338  else
1339  pips_debug(3, "comment \"%s\" pushed at line %d\n", cc,
1341  comments_push(cc);
1342 }
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

◆ push_current_C_line_number()

void push_current_C_line_number ( void  )

The line number stack, designed for structured control structure, is not used yet.

Definition at line 1194 of file clexer.c.

1195 {
1196  int ln = get_current_C_line_number();
1197 
1198  line_number_push(ln);
1199  absolute_line_number_push(c_lineno);
1200 }

◆ push_new_c_parser_scope()

void push_new_c_parser_scope ( void  )

Definition at line 549 of file cyacc.tab.c.

550  {
552  string sn = string_undefined;
553  (void) asprintf(&sn, "%d", c_parser_scope_number);
554  stack_push((void *) sn, c_parser_scope_stack);
555  return;
556  }
void stack_push(void *, stack)
stack use
Definition: stack.c:373

Referenced by EnterScope().

+ Here is the caller graph for this function:

◆ PushContext()

void PushContext ( c_parser_context  c)

Definition at line 434 of file cyacc.tab.c.

435 {
436  stack_push((char *) c, ContextStack);
437  pips_debug(8, "Context %p with scope \"%s\" is put in stack position %d\n",
439 }

◆ put_new_typedef()

void put_new_typedef ( const char *  name)

This function is used by libraries "step"* and "task_parallelization".

FI: I have no idea why it works although the keyword_typedef_table should not be initialized... It could not be made static, because it might be used by any file in the c_syntax library.

Parameters
nameame

Definition at line 1078 of file util.c.

1079 {
1081  pips_debug(5,"Add typedef name %s to hash table\n",name);
1082 }

References hash_put(), keyword_typedef_table, pips_debug, strdup(), and TK_NAMED_TYPE.

Referenced by cast_STEP_ARG(), mpi_initialize(), mpi_type_mpi_comm(), mpi_type_mpi_request(), and mpi_type_mpi_status().

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

◆ put_to_entity_type_stack_table()

void put_to_entity_type_stack_table ( entity  key,
stack  value 
)
Parameters
keyey

Definition at line 139 of file c_parser.c.

140 {
142  pips_internal_error("The stack must be defined");
144 }

References entity_name, entity_to_type_stack_table, hash_put(), pips_internal_error, and stack_undefined_p.

Referenced by RenameFunctionEntity(), and SubstituteDummyParameters().

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

◆ remove_entity_type_stack()

void remove_entity_type_stack ( entity  e)

Definition at line 156 of file c_parser.c.

157 {
158  //entity te = entity_undefined;
159  void * p = hash_get(entity_to_type_stack_table, (void *) entity_name(e));
160  //void * p = hash_delget(entity_to_type_stack_table, (void *) e, (void **) &te);
161 
162  pips_debug(8, "Remove type stack for \"%s\":", entity_name(e));
163  //fprintf(stderr, "Remove type stack for \"%s\"\n", entity_name(e));
164  //pips_debug(8, "get=%p, delget=%p\n", p1, p);
165  if(p==HASH_UNDEFINED_VALUE) {
166  ifdebug(8) {fprintf(stderr, "no associated stack\n");
167  }
168  }
169  else {
170  stack es = (stack) p;
171 
172  (void) hash_del(entity_to_type_stack_table, (void *) entity_name(e));
173  if(!stack_undefined_p(es))
174  stack_free(&es);
175  ifdebug(8) fprintf(stderr, "done\n");
176  }
177 }
void * hash_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:439
struct __stack_head * stack
STACK MANAGEMENT – headers.
Definition: newgen_stack.h:47

References entity_name, entity_to_type_stack_table, fprintf(), hash_del(), hash_get(), HASH_UNDEFINED_VALUE, ifdebug, pips_debug, stack_free(), and stack_undefined_p.

Referenced by remove_entity_type_stacks(), and SubstituteDummyParameters().

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

◆ remove_entity_type_stacks()

void remove_entity_type_stacks ( list  el)
Parameters
ell

Definition at line 179 of file c_parser.c.

180 {
181  FOREACH(ENTITY, e, el) {
183  }
184 }
void remove_entity_type_stack(entity e)
Definition: c_parser.c:156

References ENTITY, FOREACH, and remove_entity_type_stack().

Referenced by RemoveDummyArguments(), and UseFormalArguments().

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

◆ remove_LFs_from_C_comment()

void remove_LFs_from_C_comment ( int  extra_LF)

Remove "extra_LF" trailing LF from C_current_comment if they can be found at the end of the comment string.


Parameters
extra_LFxtra_LF

Definition at line 1398 of file clexer.c.

1399 {
1401  int l = strlen(C_current_comment);
1402  int c = 0;
1403  char * p = C_current_comment+l-1;
1404  pips_debug(3,"begin: %s\n", C_current_comment);
1405  // pips_assert("The comment string is longer than the number of LF to remove\n",
1406  // extra_LF<=l);
1407  if(extra_LF<=l) {
1408  while(c<extra_LF && *p=='\n') {
1409  c++;
1410  *p = '\000';
1411  p--;
1412  }
1413  if(c==extra_LF) { // We are fine
1414  ;
1415  }
1416  else {
1417  // Should be a pips_internal_warning()
1418  pips_user_warning("%d extraneous LF left in comment\n", extra_LF-c);
1419  }
1420  }
1421  pips_debug(3,"end: %s\n", C_current_comment);
1422  }
1423 }

◆ RemoveDummyArguments()

void RemoveDummyArguments ( entity  f,
list  refs 
)

To chase formals in type declarations.

If f has dummy formal parameters, replace them by standard formal parameters

make a list of formal dummy parameters

Since the compilation order is not known, the standard formal parameters may already exist and they should not be removed.

Update the "dummy" field of the "parameter" data structure

This special case could be ignored and handled like the next one to avoid cut-and-past and/or the definition of a new function.

no dummy naming information available as in foo(int);

FI: just in case?

Remore the dummy formals from f's declaration list (and from the symbol table?) but keep all pointers towards them in the declarations as in "void foo(n,a[n])"

FI: The storage might point to another dummy argument (although it should not)

Let's hope there are no other pointers towards dummy formal parameters

No, there may be occurences due to dependent types.

Parameters
refsefs

Definition at line 2224 of file util.c.

2225 {
2226  value fv = entity_initial(f);
2227 
2228  pips_assert("The function value is defined", !value_undefined_p(fv));
2229  pips_assert("The entity has a functional type", type_functional_p(entity_type(f)));
2230  pips_assert("The entity is not a typedef", !typedef_entity_p(f));
2231 
2232  if(!value_undefined_p(fv) && !value_intrinsic_p(fv)) {
2233  code fc = value_code(fv);
2234  list dl = code_declarations(fc);
2235  list cd = list_undefined;
2236  list formals = NIL;
2237  type ft = entity_type(f);
2239  list cformals = list_undefined;
2240  list cfp = list_undefined;
2241  int nformals=-1;
2242  int nfp = gen_length(fp);
2243 
2244  pips_assert("the value is code", value_code_p(fv));
2245 
2246  /* make a list of formal dummy parameters */
2247  for(cd = dl; !ENDP(cd); POP(cd)) {
2248  entity v = ENTITY(CAR(cd));
2249  if(entity_formal_p(v)) {
2250  pips_debug(8, "Formal dummy parameter: \"%s\"\n", entity_name(v));
2251  /* Since the compilation order is not known, the standard
2252  formal parameters may already exist and they should not be
2253  removed. */
2255  formals = gen_nconc(formals, CONS(ENTITY, v, NIL));
2256  }
2257  }
2258  nformals = gen_length(formals);
2259 
2260  /* Update the "dummy" field of the "parameter" data structure */
2261 
2262  if(nformals==nfp) {
2263  /* This special case could be ignored and handled like the next
2264  one to avoid cut-and-past and/or the definition of a new
2265  function. */
2266  for(cformals=formals, cfp = fp; !ENDP(cfp); POP(cformals), POP(cfp)) {
2267  parameter p = PARAMETER(CAR(cfp));
2268  entity ep = ENTITY(CAR(cformals));
2269  dummy d = parameter_dummy(p);
2270 
2271  if(dummy_identifier_p(d)) {
2272  entity oep = dummy_identifier(d);
2273 
2274  MAP(REFERENCE, r, {
2275  entity v = reference_variable(r);
2276 
2277  if(v==oep) {
2278  pips_debug(8, "Reference to \"\%s\" now refers \"\%s\"\n",
2279  entity_name(oep), entity_name(ep));
2280  reference_variable(r) = ep;
2281  }
2282  }, refs);
2283  }
2284 
2285  update_dummy_parameter(p, ep);
2286  }
2287  }
2288  else if(nformals>0) {
2289  int i = -1;
2290  for(cfp=fp, i= 1;!ENDP(cfp); POP(cfp), i++) {
2291  entity ep = find_ith_parameter(f,i);
2292  if(!entity_undefined_p(ep)) {
2293  parameter p = PARAMETER(CAR(cfp));
2294  dummy d = parameter_dummy(p);
2295 
2296  if(dummy_identifier_p(d)) {
2297  entity oep = dummy_identifier(d);
2298 
2299  MAP(REFERENCE, r, {
2300  entity v = reference_variable(r);
2301 
2302  if(v==oep) {
2303  pips_debug(8, "Reference to \"\%s\" now refers \"\%s\"\n",
2304  entity_name(oep), entity_name(ep));
2305  reference_variable(r) = ep;
2306  }
2307  }, refs);
2308  }
2309 
2310  update_dummy_parameter(p, ep);
2311  }
2312  }
2313  }
2314  else {
2315  /* no dummy naming information available as in foo(int); */
2316  ;
2317  }
2318 
2319  if(true) {
2320 
2321  /* FI: just in case? */
2322  remove_entity_type_stacks(formals);
2323 
2324  /* Remore the dummy formals from f's declaration list (and from
2325  the symbol table?) but keep all pointers towards them in the
2326  declarations as in "void foo(n,a[n])" */
2327  for(cd = formals; !ENDP(cd); POP(cd)) {
2328  entity p = ENTITY(CAR(cd));
2329  //type pt = entity_type(p);
2330  //storage ps = entity_storage(p);
2331  //formal pfs = storage_formal(ps);
2332 
2333  pips_debug(8, "Formal dummy parameter \"%s\" is removed from declarations\n",
2334  entity_name(p));
2335 
2336  //clean_up_dummy_parameter_type(pt, formals);
2337  gen_remove(&code_declarations(fc), (void *) p);
2338 
2339  /* FI: The storage might point to another dummy argument
2340  (although it should not) */
2341  //formal_function(pfs) = entity_undefined;
2342  /* Let's hope there are no other pointers towards dummy formal parameters */
2343  /* No, there may be occurences due to dependent types. */
2344  //free_entity(p);
2345  }
2346  }
2347  gen_free_list(formals);
2348  }
2349 }
void remove_entity_type_stacks(list el)
Definition: c_parser.c:179
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
bool dummy_parameter_entity_p(entity p)
is p a dummy parameter?
Definition: entity.c:1941
bool entity_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
void update_dummy_parameter(parameter p, entity ep)
Definition: entity.c:2072
entity find_ith_parameter(entity e, int i)
Definition: util.c:93
#define dummy_identifier(x)
Definition: ri.h:1033
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define parameter_dummy(x)
Definition: ri.h:1823
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define functional_parameters(x)
Definition: ri.h:1442
#define dummy_identifier_p(x)
Definition: ri.h:1031

References CAR, code_declarations, CONS, dummy_identifier, dummy_identifier_p, dummy_parameter_entity_p(), ENDP, ENTITY, entity_formal_p(), entity_initial, entity_name, entity_type, entity_undefined_p, f(), find_ith_parameter(), functional_parameters, gen_free_list(), gen_length(), gen_nconc(), gen_remove(), list_undefined, MAP, NIL, PARAMETER, parameter_dummy, pips_assert, pips_debug, POP, REFERENCE, reference_variable, remove_entity_type_stacks(), type_functional, type_functional_p, typedef_entity_p(), update_dummy_parameter(), value_code, value_code_p, value_intrinsic_p, and value_undefined_p.

Referenced by UpdateEntity().

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

◆ RemoveFromExterns()

void RemoveFromExterns ( entity  e)

This may happen when functional arguments are dealt with

Definition at line 2884 of file util.c.

2885 {
2887  if(!entity_undefined_p(f)) {
2889 
2890  gen_remove(&code_externs(fc), (void *) e);
2891  }
2892  else {
2893  /* This may happen when functional arguments are dealt with */
2894  c_parser_user_warning("The C parser should not execute this call.\n");
2895  }
2896 }

References c_parser_user_warning, code_externs, entity_initial, entity_undefined_p, f(), gen_remove(), get_current_module_entity(), and value_code.

Referenced by actual_c_parser(), and FindOrCreateCurrentEntity().

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

◆ RenameFunctionEntity()

entity RenameFunctionEntity ( entity  oe)

Rename function oe if necessary.

The function name may be wrong because not enough information was available when it was created by FindOrCreateCurrentEntity().

oe must be a function and not a pointer to a function

oe should be added to the declarations of the current block

A C function or intrinsics name should include no scope information. But a functional typedef should.

In fact, we'd like to know if it is found before we create it...

FI I do not understand how formal parameters could be declared before

We assume oe is not already part of a declaration list since its formal parameters have been taken care of

Parameters
oee

Definition at line 1556 of file util.c.

1557 {
1558  entity ne = oe;
1559  string oen = entity_name(oe);
1560  const char* oeln = entity_local_name(oe);
1561  string sn = local_name_to_scope(oeln);
1562  //type oet = entity_type(oe);
1563 
1564  /* A C function or intrinsics name should include no scope
1565  information. But a functional typedef should. */
1566  if(!typedef_entity_p(oe) && !empty_string_p(sn)) {
1567  if(strchr(oen, MODULE_SEP)!=NULL) {
1568  //string mn = entity_module_name(ne);
1569  const char * ln = entity_user_name(ne);
1570  value voe = entity_initial(oe);
1572  stack ns = stack_copy(s);
1573 
1574  /* In fact, we'd like to know if it is found before we create it... */
1576  if(entity_undefined_p(ne)) {
1578  entity_type(ne) = copy_type(entity_type(oe));
1580  /* FI I do not understand how formal parameters could be declared before */
1581  if(value_undefined_p(voe) || value_unknown_p(voe))
1584  else {
1585  list dl = list_undefined;
1587 
1589  FOREACH(ENTITY, v, dl) {
1590  storage s = entity_storage(v);
1591  if(storage_formal_p(s)) {
1592  formal fs = storage_formal(s);
1593  formal_function(fs) = ne;
1594  }
1595  }
1596  }
1598  }
1599 
1600  pips_debug(1, "entity %s renamed %s\n", entity_name(oe), entity_name(ne));
1601 
1602  /* We assume oe is not already part of a declaration list since
1603  its formal parameters have been taken care of */
1605  }
1606  }
1607  free(sn);
1608  return ne;
1609 }
value copy_value(value p)
VALUE.
Definition: ri.c:2784
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
stack get_from_entity_type_stack_table(entity key)
Definition: c_parser.c:146
void put_to_entity_type_stack_table(entity key, stack value)
Definition: c_parser.c:139
bool empty_string_p(const char *s)
Definition: entity_names.c:239
#define MODULE_SEP
special characters to build entity names of various kinds
Definition: naming-local.h:27
stack stack_copy(const stack)
duplicate a stack with its contents.
Definition: stack.c:267
string local_name_to_scope(const char *ln)
allocates a new string
Definition: entity.c:563
#define formal_function(x)
Definition: ri.h:1406
void gen_clear_tabulated_element(gen_chunk *obj)
GEN_CLEAR_TABULATED_ELEMENT only clears the entry for object OBJ in the gen_tabulated_ and gen_tabula...
Definition: tabulated.c:251

References code_declarations, copy_storage(), copy_type(), copy_value(), empty_string_p(), ENTITY, entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined_p, entity_user_name(), FindEntity(), FindOrCreateEntity(), FOREACH, formal_function, free(), gen_clear_tabulated_element(), get_from_entity_type_stack_table(), is_value_code, list_undefined, local_name_to_scope(), make_code(), make_language_c(), make_sequence(), make_value(), MODULE_SEP, NIL, pips_debug, put_to_entity_type_stack_table(), stack_copy(), storage_formal, storage_formal_p, strdup(), TOP_LEVEL_MODULE_NAME, typedef_entity_p(), value_code, value_undefined_p, and value_unknown_p.

+ Here is the call graph for this function:

◆ reset_C_comment()

void reset_C_comment ( bool  is_compilation_unit_p)

reset and reset_error should be handled differently

Comments in the compilation unit are lost because they are related only to declarations and because comments on declarations are lost. Also, comments located at the end of a block are lost, as we do not generate an extra NOP to carry them.

pips_internal_error("Comments stack is not empty\n");

Parameters
is_compilation_unit_ps_compilation_unit_p

Definition at line 1450 of file clexer.c.

1451 {
1455  }
1456  /* Comments in the compilation unit are lost because they are related only to
1457  declarations and because comments on declarations are lost. Also, comments
1458  located at the end of a block are lost, as we do not generate an extra NOP to carry them. */
1459  if(!is_compilation_unit_p && !comments_empty_p()) {
1460  int count = 0;
1461  pips_user_warning("Comments stack is not empty (only meaningful comments are shown):\n");
1462  while(!comments_empty_p()) {
1463  string c = comments_pop();
1464  count++;
1465  if(strcmp(c, "\n")!=0)
1466  fprintf(stderr, "Element %d: \"%s\"\n", count, c);
1467  free(c);
1468  }
1469  /* pips_internal_error("Comments stack is not empty\n"); */
1470  }
1471  clear_C_comment();
1472  free_comments_stack();
1473  bracket_depth = -1;
1474  token_has_been_seen_p = false;
1475 }
void clear_C_comment()
Definition: clexer.c:1489

◆ reset_c_parser_current_input_file_name()

void reset_c_parser_current_input_file_name ( void  )

Definition at line 73 of file c_parser.c.

74 {
75  // Could check that it is defined on entry
77  pips_internal_error("c_parser_current_file_name no initialized.\n");
79 }

References c_parser_current_file_name, pips_internal_error, string_undefined, and string_undefined_p.

Referenced by actual_c_parser().

+ Here is the caller graph for this function:

◆ reset_c_parser_current_user_input_file_name()

void reset_c_parser_current_user_input_file_name ( void  )

Definition at line 104 of file c_parser.c.

105 {
106  // Could check that it is defined on entry
108  pips_internal_error("c_parser_current_user_input_file_name no initialized.\n");
110 }

References c_parser_current_user_input_file_name, pips_internal_error, string_undefined, and string_undefined_p.

Referenced by actual_c_parser().

+ Here is the caller graph for this function:

◆ reset_c_parser_scope_stack()

void reset_c_parser_scope_stack ( void  )

Definition at line 522 of file cyacc.tab.c.

523  {
528  }
529  else {
530  // pips_internal_error? Could be a bad input C file...
531  pips_user_warning("Parser scope stack is not empty.\n");
532  }
533  }
535  return;
536  }

◆ Reset_C_ReturnStatement()

void Reset_C_ReturnStatement ( void  )

The return statement must be reset when it is used by the parser to add the return statement to the function body or when a parser error is encountered.

Definition at line 115 of file return.c.

References C_return_statement, entity_undefined, last_return_value_assignment, last_returned_value, list_undefined, number_of_return_statements, return_current_module, return_value_entity, and statement_undefined.

Referenced by c_parser_error(), and FixCReturnStatements().

+ Here is the caller graph for this function:

◆ reset_current_C_line_number()

void reset_current_C_line_number ( void  )

Definition at line 1210 of file clexer.c.

1211 {
1216 
1217  if(!line_number_empty_p()) {
1218  pips_internal_error("Line number stack is not empty\n");
1219  }
1220  free_line_number_stack();
1221  free_absolute_line_number_stack();
1222 }

◆ reset_current_dummy_parameter_number()

void reset_current_dummy_parameter_number ( void  )

Definition at line 144 of file util.c.

static int current_dummy_parameter_number
The data structure to tackle the memory allocation problem due to reparsing of compilation unit.
Definition: util.c:137

References current_dummy_parameter_number.

Referenced by actual_c_parser(), and c_parser_error().

+ Here is the caller graph for this function:

◆ reset_declaration_counter()

void reset_declaration_counter ( void  )

Definition at line 492 of file cyacc.tab.c.

493  {
495  }

◆ reset_entity_type_stack_table()

void reset_entity_type_stack_table ( void  )

Definition at line 186 of file c_parser.c.

187 {
191 }
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49

References entity_to_type_stack_table, HASH_MAP, hash_table_free(), hash_table_undefined, and stack_free().

Referenced by actual_c_parser(), c_parser_error(), and init_entity_type_storage_table().

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

◆ reset_expression_comment()

void reset_expression_comment ( void  )

we don't want an expression comment with new lines, it is disgracefull

Too bad. This should not happen, but it happens with comma expressions in header files

Definition at line 169 of file cyacc.tab.c.

170 {
172  /* Too bad. This should not happen, but it happens with comma
173  expressions in header files */
176  }
177 
179 }
static int expression_line_number
Definition: cyacc.tab.c:166
static string expression_comment
FI: these two variables are used in conjunction with comma expressions.
Definition: cyacc.tab.c:165
void free(void *)

◆ reset_preprocessor_line_analysis()

void reset_preprocessor_line_analysis ( void  )

Definition at line 3592 of file util.c.

3593 {
3594  buffer_initialized_p = false;
3595 }

References buffer_initialized_p.

Referenced by actual_c_parser().

+ Here is the caller graph for this function:

◆ reset_token_has_been_seen_p()

void reset_token_has_been_seen_p ( void  )

Definition at line 1270 of file clexer.c.

1270 {token_has_been_seen_p = false;}

◆ ResetCurrentCompilationUnitEntity()

void ResetCurrentCompilationUnitEntity ( bool  is_compilation_unit_parser)

Let's redo the memory allocation for variables whose name has changed:-(

reset_entity_type_stack_table();

Parameters
is_compilation_unit_parsers_compilation_unit_parser

Definition at line 349 of file util.c.

350 {
351  /* Let's redo the memory allocation for variables whose name has changed:-(*/
352  if(is_compilation_unit_parser)
354  else
356 
357  /* reset_entity_type_stack_table(); */
358  if (get_bool_property("PARSER_DUMP_SYMBOL_TABLE"))
360  pips_debug(4,"Reset current module entity for compilation unit \"%s\"\n",
363 }
void CCompilationUnitMemoryReallocation(entity module)
Definition: util.c:1972
void CCompilationUnitMemoryAllocation(entity module)
Definition: util.c:1967
void fprint_C_environment(FILE *fd, entity m)
Definition: declarations.c:292

References CCompilationUnitMemoryAllocation(), CCompilationUnitMemoryReallocation(), fprint_C_environment(), get_bool_property(), get_current_module_entity(), get_current_module_name(), pips_debug, and reset_current_module_entity().

Referenced by actual_c_parser().

+ Here is the call graph for this function:
+ Here is the caller 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

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:

◆ scope_to_block_scope()

string scope_to_block_scope ( string  full_scope)

Allocate a new string containing only block scope information.

Parameters
full_scopeull_scope

Definition at line 268 of file cyacc.tab.c.

269 {
270  string l_scope = strrchr(full_scope, BLOCK_SEP_CHAR);
271  string f_scope = strchr(full_scope, MODULE_SEP);
272  string block_scope = string_undefined;
273 
274  pips_debug(8, "full_scope = \"%s\"\n", full_scope);
275 
276  if(f_scope==NULL)
277  f_scope = full_scope;
278  else
279  f_scope++;
280 
281  if(l_scope==NULL)
282  block_scope = strdup("");
283  else
284  block_scope = gen_strndup0(f_scope, (unsigned) (l_scope-f_scope+1));
285 
286  pips_debug(8, "f_scope = \"%s\", l_scope = \"%s\"\n", f_scope, l_scope);
287  pips_assert("block_scope is a scope", string_block_scope_p(block_scope));
288 
289  return block_scope;
290 }
string gen_strndup0(string, size_t)
Like strdup() but copy at most n characters.
Definition: string.c:83

◆ ScopeStackSize()

int ScopeStackSize ( void  )

Definition at line 366 of file cyacc.tab.c.

367 {
368  return stack_size(ContextStack);
369 }

◆ set_c_parser_current_input_file_name()

void set_c_parser_current_input_file_name ( string  file_name)
Parameters
file_nameile_name

Definition at line 65 of file c_parser.c.

66 {
67  // Could check that it is undefined on entry
69  pips_internal_error("c_parser_current_file_name no initialized.\n");
71 }
static string file_name

References c_parser_current_file_name, file_name, pips_internal_error, and string_undefined_p.

Referenced by actual_c_parser().

+ Here is the caller graph for this function:

◆ set_c_parser_current_user_input_file_name()

void set_c_parser_current_user_input_file_name ( string  file_name)
Parameters
file_nameile_name

Definition at line 96 of file c_parser.c.

97 {
98  // Could check that it is undefined on entry
100  pips_internal_error("c_parser_current_user_input_file_name no initialized.\n");
102 }

References c_parser_current_user_input_file_name, file_name, pips_internal_error, and string_undefined_p.

Referenced by actual_c_parser().

+ Here is the caller graph for this function:

◆ set_current_C_line_number()

void set_current_C_line_number ( void  )

Initialize the user line number...

... and the absolute line number in the current file

The first line is used to indicate the line number in the user source file

Some check on it first? It should have been disallocated by reset_current_C_line_number()

Definition at line 1166 of file clexer.c.

1167 {
1169  /* Initialize the user line number... */
1171  // Rely on preprocessor pragma lines, which are not always present
1172  // especially for code synthesized by PIPS...
1173  // C_line_number = UNDEFINED_C_LINE_NUMBER;
1175  /* ... and the absolute line number in the current file */
1177  /* The first line is used to indicate the line number in the user
1178  * source file
1179  */
1181  }
1182  else
1183  pips_internal_error("C_line_number not resetted\n");
1184 
1185  C_line_increment = 1;
1186 
1187  /* Some check on it first? It should have been disallocated by reset_current_C_line_number() */
1188  make_line_number_stack();
1189  make_absolute_line_number_stack();
1190 }
int C_line_increment
The line increment is set to zero when header files are parsed.
Definition: clexer.c:1110

◆ set_entity_initial()

void set_entity_initial ( entity  v,
expression  nie 
)

Be careful if the initial value has already been set.

Detect double definitions when possible

Take care of the special case of pointers to functions.

The compilation unit has already been scanned once for declarations. Double definitions are no surprise...

Generate initializations for pointers to functions and arrays of pointers to functions

A pointer to a function already has value code as initial value. We may not even know yet it's a pointer...

Parameters
nieie

Definition at line 3469 of file util.c.

3470 {
3471  value oiv = entity_initial(v);
3472 
3473  if(!value_undefined_p(oiv) && value_unknown_p(oiv)) {
3474  free_value(oiv);
3476  oiv = value_undefined;
3477  }
3478 
3479  if(!value_undefined_p(oiv)) {
3481  /* The compilation unit has already
3482  been scanned once for
3483  declarations. Double definitions
3484  are no surprise...*/
3485  if(value_code_p(oiv)) {
3486  /* Generate initializations for pointers to functions and arrays
3487  of pointers to functions */
3488  code c = value_code(oiv);
3490 
3492  }
3493  }
3494  else {
3495  type vt = entity_type(v);
3497  : ultimate_type(entity_type(v));
3498  if(!type_undefined_p(uvt) &&
3499  ((pointer_type_p(uvt) &&
3501  || type_functional_p(uvt)) ) {
3502  /* A pointer to a function already has value code as initial
3503  value. We may not even know yet it's a pointer... */
3504  code c = value_code(oiv);
3506 
3508  //c_parser_user_warning("The initialization of a function pointer is lost\n");
3509  }
3510  else {
3512  "double definition of initial"
3513  " value for variable \"%s\"", entity_name(v));
3514 
3515  // FI: I am not sure it so good to put any junk in any format in the
3516  // Warning file. FC: Indeed:-)
3517 
3518  string initv = expression_to_string(nie);
3519  string currv;
3520  if(value_expression_p(oiv))
3521  currv = expression_to_string(value_expression(oiv));
3522  else
3523  asprintf(&currv, "value tag: %d", value_tag(entity_initial(v)));
3524 
3525  pips_user_warning("New initial value expression:\n%s"
3526  "Current initial value:\n%s",
3527  initv, currv);
3528  free(initv);
3529  free(currv);
3530  pips_internal_error("Scoping might be the reason.");
3531  }
3532  }
3533  }
3534 
3537 }
void free_value(value p)
Definition: ri.c:2787
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
statement make_expression_statement(expression)
Build a statement from a given expression.
Definition: statement.c:1308
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
#define value_tag(x)
Definition: ri.h:3064
#define code_initializations(x)
Definition: ri.h:788
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082

References asprintf, basic_pointer, c_parser_user_warning, code_initializations, compilation_unit_p(), CONS, entity_initial, entity_name, entity_type, expression_to_string(), free(), free_value(), get_current_module_name(), make_expression_statement(), make_sequence(), make_value_expression(), NIL, pips_internal_error, pips_user_warning, pointer_type_p(), STATEMENT, type_functional_p, type_undefined, type_undefined_p, type_variable, ultimate_type(), value_code, value_code_p, value_expression, value_expression_p, value_tag, value_undefined, value_undefined_p, value_unknown_p, and variable_basic.

Referenced by freia_is_transpose_call().

+ Here is the call graph for this function:
+ Here is the caller 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.

◆ StackPop()

void StackPop ( stack  OffsetStack)

The OffsetStack is poped n times, where n is the number of formal arguments of the actual function.

Parameters
OffsetStackffsetStack

Definition at line 3450 of file util.c.

3451 {
3452  int n = basic_int((basic) stack_head(OffsetStack));
3454 }
void NStackPop(stack s, int n)
Pop n times the stack s.
Definition: util.c:3442

References basic_int, NStackPop(), OffsetStack, and stack_head().

+ Here is the call graph for this function:

◆ StackPush()

void StackPush ( stack  OffsetStack)

The OffsetStack is pushed incrementally.

Parameters
OffsetStackffsetStack

Definition at line 3457 of file util.c.

3458 {
3459  int i = basic_int((basic) stack_head(OffsetStack));
3460  stack_push((char *) make_basic_int(i+1),OffsetStack);
3461 }

References basic_int, make_basic_int(), OffsetStack, stack_head(), and stack_push().

+ Here is the call graph for this function:

◆ SubstituteDummyParameters()

void SubstituteDummyParameters ( entity  f,
list  el 
)

The copy could be avoided by substituting v->s with nv->s

Store type information. Might be useless.

Inherit any attribute you can

Parameters
ell

Definition at line 2351 of file util.c.

2352 {
2353  for(list cel=el; !ENDP(cel); POP(cel)) {
2354  entity v = ENTITY(CAR(cel));
2355  if(dummy_parameter_entity_p(v)) {
2356  const char* mn = entity_local_name(f);
2357  const char * ln = entity_user_name(v);
2358  entity nv = FindOrCreateEntity(mn, ln);
2360  /* The copy could be avoided by substituting v->s with nv->s */
2361  stack ns = stack_copy(s);
2362  ENTITY_(CAR(cel)) = nv;
2363 
2364  /* Store type information. Might be useless. */
2367 
2368  /* Inherit any attribute you can */
2369  if(!type_undefined_p(entity_type(v)))
2370  entity_type(nv) = copy_type(entity_type(v));
2375  }
2376  }
2377 }
#define ENTITY_(x)
Definition: ri.h:2758

References CAR, copy_storage(), copy_type(), copy_value(), dummy_parameter_entity_p(), ENDP, ENTITY, ENTITY_, entity_initial, entity_local_name(), entity_storage, entity_type, entity_user_name(), f(), FindOrCreateEntity(), get_from_entity_type_stack_table(), POP, put_to_entity_type_stack_table(), remove_entity_type_stack(), stack_copy(), storage_undefined_p, type_undefined_p, and value_undefined_p.

+ Here is the call graph for this function:

◆ TakeDerivedEntities()

list TakeDerivedEntities ( list  le)

To simplify debugging

The list is stored there at line 2087 of cyacc.y (5 August 2009)

e->type==entity_domain

lres = gen_nconc(lres,ltmp);

The ltmp lists seem to be somehow shared as shown in ngspice/main.tpips. The previous implementation of the current function generated cyclic lists. The new implementation is incompatible with a proper memory management.

I do not understand what's done in c_syntax/cyacc.y. The trace obtained from C_syntax/ngspice01.c shows that the same derived entities appear several times when dummy structs and unions are embedded as in ngspice01.c

Parameters
lee

Definition at line 3020 of file util.c.

3021 {
3022  list lres = NIL;
3023 
3024  if(!ENDP(le)) { /* To simplify debugging */
3025 
3026  pips_debug(8, "Begin\n");
3027 
3028  ifdebug(8) {
3029  pips_debug(8, "Input entity list: ");
3030  print_entities(le);
3031  fprintf(stderr, "\n");
3032  }
3033 
3034  FOREACH (ENTITY, e, le) {
3035  /* The list is stored there at line 2087 of cyacc.y (5 August
3036  2009) */
3037  //list ltmp = (list) entity_initial(e);
3038  list sltmp = (list) entity_initial(e);
3039  if(!ENDP(sltmp)) {
3040  // pips_assert("sltmp has only one element", gen_length(sltmp)==1);
3041  // statement stmp = STATEMENT(CAR(sltmp));
3042  // list ltmp = statement_declarations(stmp);
3043  list ltmp = sltmp;
3044 
3045  //pips_assert("sltmp is a continue statement list",
3046  // continue_statements_p(sltmp));
3047  pips_assert("e is an entity",
3048  check_entity(e) /* e->_type_==entity_domain*/ );
3049  pips_debug(8, "entity e: %s (%p)\n", entity_name(e), e);
3050 
3051  if (ltmp != NIL) {
3052  /* lres = gen_nconc(lres,ltmp);*/
3053  FOREACH(ENTITY, de, ltmp) {
3054 
3055  pips_assert("de is an entity", de->_type_==entity_domain);
3056  pips_debug(8, "entity de: %s (%p)\n", entity_name(de), de);
3057 
3058  if(!gen_in_list_p(de, lres)) {
3059  lres = gen_nconc(lres, CONS(ENTITY, de, NIL));
3060  }
3061  }
3062  }
3063  }
3064  /* The ltmp lists seem to be somehow shared as shown in
3065  * ngspice/main.tpips. The previous implementation of the
3066  * current function generated cyclic lists. The new
3067  * implementation is incompatible with a proper memory
3068  * management.
3069  *
3070  * I do not understand what's done in c_syntax/cyacc.y. The
3071  * trace obtained from C_syntax/ngspice01.c shows that the same
3072  * derived entities appear several times when dummy structs and
3073  * unions are embedded as in ngspice01.c
3074  */
3075  //gen_free_list(ltmp);
3077  }
3078  pips_assert ("an acyclic list is generated", !gen_list_cyclic_p (lres));
3079 
3080  ifdebug(8) {
3081  pips_debug(8, "Output entity list: ");
3082  if(ENDP(lres)) {
3083  fprintf(stderr, "NIL\n");
3084  }
3085  else {
3086  print_entities(lres);
3087  fprintf(stderr, "\n");
3088  }
3089  }
3090 
3091  pips_debug(8, "End\n");
3092  }
3093 
3094  return lres;
3095 }
entity check_entity(entity p)
Definition: ri.c:2527
bool gen_list_cyclic_p(const list ml)
Definition: list.c:120
struct cons * list
Definition: newgen_types.h:106

References check_entity(), CONS, ENDP, ENTITY, entity_domain, entity_initial, entity_name, FOREACH, fprintf(), gen_in_list_p(), gen_list_cyclic_p(), gen_nconc(), ifdebug, NIL, pips_assert, pips_debug, print_entities(), and value_undefined.

+ Here is the call graph for this function:

◆ update_C_comment()

void update_C_comment ( string  a_comment)

Add a comment to the current one.

Do not add LFs that appear within a statement

Do not concatenate two comments without a LF

Parameters
a_comment_comment

Definition at line 1365 of file clexer.c.

1366 {
1367  /* Do not add LFs that appear within a statement */
1368  bool is_LF_p = *a_comment=='\n' && *(a_comment+1)=='\000';
1369  if(!(token_has_been_seen_p && a_comment!=NULL
1370  && is_LF_p)) {
1371  string new_comment = string_undefined;
1372  // FI: seems to imply that concatenate accepts string_undefined as an argument...
1374  /* Do not concatenate two comments without a LF */
1375  if(l>0 && *(C_current_comment+l-1)!='\n' && !is_LF_p)
1376  new_comment = strdup(concatenate(C_current_comment, "\n", a_comment, NULL));
1377  else
1378  new_comment = strdup(concatenate(C_current_comment, a_comment, NULL));
1379 
1382  C_current_comment = new_comment;
1383  }
1384  else {
1385  static int c = 0;
1386  c++;
1387  pips_debug(8, "LF ignored: %d\n", c++);
1388  }
1389 
1390  pips_debug(3,"update_C_comment %s\n",
1392  "still undefined" : C_current_comment);
1393 }

◆ UpdateAbstractEntity()

void UpdateAbstractEntity ( entity  e,
stack  ContextStack 
)

Update the entity with final type, storage

tc must have variable type, add lq to its qualifiers

lse const void, void is not of type variable, store const where ????????? CParserError("Entity has qualifier but no type or is not variable type in the context?\n");

Use the type stack in entity_storage to create the final type for the entity

Parameters
ContextStackontextStack

Definition at line 2842 of file util.c.

2843 {
2844  /* Update the entity with final type, storage */
2845 
2846  //stack s = (stack) entity_storage(e);
2848  type t = entity_type(e);
2851  type t1,t2;
2853 
2854  pips_debug(3,"Update abstract entity %s\n",entity_name(e));
2855 
2856  if (lq != NIL)
2857  {
2858  /* tc must have variable type, add lq to its qualifiers */
2861  /*else
2862  const void, void is not of type variable, store const where ?????????
2863  CParserError("Entity has qualifier but no type or is not variable type in the context?\n");*/
2864  }
2865 
2866  /************************* TYPE PART *******************************************/
2867 
2868  /* Use the type stack in entity_storage to create the final type for the entity*/
2869  t2 = UpdateType(t,tc);
2870 
2871  while (stack_size(s) > 1)
2872  {
2873  t1 = stack_pop(s);
2874  t2 = UpdateType(t1,t2);
2875  }
2876  entity_type(e) = t2;
2877 
2878  /************************* STORAGE PART *******************************************/
2879 
2881 }
#define c_parser_context_type(x)
type UpdateType(type t1, type t2)
This function replaces the undefined field in t1 by t2.
Definition: util.c:1693
static int tc
Internal variables
Definition: reindexing.c:107
#define variable_qualifiers(x)
Definition: ri.h:3124
Definition: delay.c:253

References c_parser_context_qualifiers, c_parser_context_type, ContextStack, entity_name, entity_storage, entity_type, get_from_entity_type_stack_table(), NIL, pips_debug, stack_head(), stack_pop(), stack_size(), storage_undefined, tc, type_undefined_p, type_variable, type_variable_p, UpdateType(), and variable_qualifiers.

+ Here is the call graph for this function:

◆ UpdateArrayEntity()

void UpdateArrayEntity ( entity  e,
list  lq,
list  le 
)

lq is for what ? e or le ????: lq should be for le

Parameters
lqq
lee

Definition at line 1514 of file util.c.

1515 {
1516  type t = entity_type(e);
1517  pips_debug(3,"Update array entity %s\n",entity_name(e));
1518 
1519  /* lq is for what ? e or le ????: lq should be for le*/
1520  if (type_undefined_p(t))
1521  {
1522  pips_debug(3,"First array dimension\n");
1523  entity_type(e) =
1525  CONS(DIMENSION,MakeDimension(le, lq),NIL),
1526  NIL));
1527  }
1528  else
1529  {
1530  pips_debug(3,"Next array dimension\n");
1531  if (type_variable_p(t))
1532  {
1533  variable v = type_variable(t);
1535  variable_dimensions(v) =
1537  CONS(DIMENSION, MakeDimension(le, lq), NIL));
1538  }
1539  else
1540  {
1541  CParserError("Dimension for not variable type\n");
1542  }
1543  }
1544 }
dimension MakeDimension(list le, list ql)
Definition: util.c:1389
#define basic_undefined
Definition: ri.h:556
#define variable_dimensions(x)
Definition: ri.h:3122

References basic_undefined, CONS, CParserError(), DIMENSION, entity_name, entity_type, gen_nconc(), make_type_variable(), make_variable(), MakeDimension(), NIL, pips_debug, type_undefined_p, type_variable, type_variable_p, variable_dimensions, and variable_qualifiers.

+ Here is the call graph for this function:

◆ UpdateDerivedEntities()

void UpdateDerivedEntities ( list  ld,
list  le,
stack  ContextStack 
)
Parameters
ldd
lee
ContextStackontextStack

Definition at line 3097 of file util.c.

3098 {
3099  FOREACH (ENTITY, e, le) {
3101  }
3102 }
void UpdateDerivedEntity(list ld, entity e, stack ContextStack)
Definition: util.c:2942

References ContextStack, ENTITY, FOREACH, and UpdateDerivedEntity().

+ Here is the call graph for this function:

◆ UpdateDerivedEntity()

void UpdateDerivedEntity ( list  ld,
entity  e,
stack  ContextStack 
)

Update the derived entity with final type and rom storage. If the entity has bit type, do not need to update its type

what about context qualifiers ?

What do we do for functional types for instance?

FI: I assume the qualifiers are carried by the result

What do we do for functional types for instance?

Although it should be popped from the stack, the current context seems to be used later in case of typedef, such as seen in decl24.c

Temporally put the list of struct/union entities defined in decl_psec_list to initial value of ent

Parameters
ldd
ContextStackontextStack

Definition at line 2942 of file util.c.

2943 {
2944  /* Update the derived entity with final type and rom storage.
2945  If the entity has bit type, do not need to update its type*/
2946  type t = entity_type(e);
2947  pips_debug(3,"Update derived entity %s\n",entity_name(e));
2948  if (!bit_type_p(t))
2949  {
2950  //stack s = (stack) entity_storage(e);
2954  type t1,t2;
2956 
2957  /* what about context qualifiers ? */
2958  t2 = UpdateType(t,tc);
2959 
2960  while (stack_size(s) > 1)
2961  {
2962  t1 = stack_pop(s);
2963  t2 = UpdateType(t1,t2);
2964  }
2965  entity_type(e) = t2;
2966 
2967  if(!ENDP(ql)) {
2968  if(type_void_p(t2)) {
2969  type_void(t2) = ql;
2970  }
2971  else if(type_variable_p(t2)) {
2972  if(pointer_type_p(t2)) {
2973  // The qualifiers must be stored on the effective pointed type
2974  // type pt = type_to_final_pointed_type(t2);
2975  // type pt = type_to_pointed_type(t2);
2977  if(type_void_p(pt))
2978  type_void(pt) = ql;
2979  else if(type_variable_p(pt)) {
2980  // If pt is a typedef, the typedef is altered...
2982  //variable_qualifiers(type_variable(t2)) = ql;
2983  }
2984  else if(type_functional_p(pt)) {
2985  /* What do we do for functional types for instance? */
2986  /* FI: I assume the qualifiers are carried by the
2987  result */
2989  type rt = functional_result(f);
2990  if(type_variable_p(rt))
2992  else
2993  pips_internal_error("???");
2994  }
2995  else {/* What do we do for functional types for instance? */
2996  // FI: I assume the qualifiers are carried by the result
2997  pips_internal_error("???");
2998  }
2999  }
3000  else {
3002  }
3003  }
3004  else
3005  pips_internal_error("unexpected type");
3006  /* Although it should be popped from the stack, the current
3007  context seems to be used later in case of typedef, such as
3008  seen in decl24.c */
3010  }
3011  }
3013 
3014  /* Temporally put the list of struct/union entities defined in
3015  decl_psec_list to initial value of ent */
3016  entity_initial(e) = (value) ld;
3017 
3018 }
bool bit_type_p(type)
Definition: type.c:2843
struct _newgen_struct_value_ * value
Definition: ri.h:455
#define type_void(x)
Definition: ri.h:2961

References basic_pointer, bit_type_p(), c_parser_context_qualifiers, c_parser_context_type, ContextStack, ENDP, entity_initial, entity_name, entity_storage, entity_type, f(), functional_result, get_from_entity_type_stack_table(), make_storage_rom(), NIL, pips_debug, pips_internal_error, pointer_type_p(), stack_head(), stack_pop(), stack_size(), tc, type_functional, type_functional_p, type_variable, type_variable_p, type_void, type_void_p, UpdateType(), variable_basic, and variable_qualifiers.

Referenced by UpdateDerivedEntities().

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

◆ UpdateEntities()

void UpdateEntities ( list  le,
stack  ContextStack,
stack  FormalStack,
stack  FunctionStack,
stack  OffsetStack,
bool  is_external,
bool  is_declaration 
)
Parameters
lee
ContextStackontextStack
FormalStackormalStack
FunctionStackunctionStack
OffsetStackffsetStack
is_externals_external
is_declarations_declaration

Definition at line 2733 of file util.c.

2735 {
2736  FOREACH(ENTITY, e, le) {
2737  if(!derived_entity_p(e))
2739  is_external,is_declaration);
2740  }
2741 }
void UpdateEntity(entity e, stack ContextStack, stack FormalStack, stack FunctionStack, stack OffsetStack, bool is_external, bool is_declaration)
Update the entity with final type, storage and initial value; and also (sometimes?...
Definition: util.c:2473

References ContextStack, derived_entity_p(), ENTITY, FOREACH, FormalStack, FunctionStack, is_external, OffsetStack, and UpdateEntity().

+ Here is the call graph for this function:

◆ UpdateEntity()

void UpdateEntity ( entity  e,
stack  ContextStack,
stack  FormalStack,
stack  FunctionStack,
stack  OffsetStack,
bool  is_external,
bool  is_declaration 
)

Update the entity with final type, storage and initial value; and also (sometimes?) declare it at the module level.

Replace dummy arguments by formal arguments for functions

Generate the return variables for functions returning a result

And probably much more...

If e is an intrinsics, nothing should be done, unless you are in the compilation unit: but the intrinsic type has already been put aside in the type stack linked to the entity and destroyed

tc must have variable type, add lq to its qualifiers

lse const void, void is not of type variable, store const where ????????? CParserError("Entity has qualifier but no type or is not variable type in the context?\n");

Use the type stack in entity_storage to create the final type for the entity

The default type is int, or a function returning an int

FI: it might be a good idea to use the type "unknown" or a future type "default" to improve the prettyprinting by not adding implicit "int" declarations.

The default type is int

FI: This elseif branch is apparently useless because the probleme must be dealt with later in the parser

The default return type is int

FI: no longer true, I believe "this field is always pre-defined. It is temporarilly used to store a type. See cyacc.y rule direct-decl:"

FI: Intrinsic do not have formal named parameters in PIPS RI, however such parameters can be named in intrinsic declarations. Problem with Validation/C_syntax/memcof.c

|| type_variable_p(entity_type(function))

Storage does also matter for typedef (and function pointer)

How to access the information about the function type?

FI: This branch should never be executed

The entities for the type_variable is added to the current module and the declarations

It is too early to use extern_entity_p()

Keyword EXTERN has just been encountered

Yes, but this may have been already recognized in FindOrCreateCurrentEntity() and this may not imply the declaration as extern is another declaration of e has already been encountered.

To avoid multiple declarations

Too late to check that the first declaration did not include an initialization

The function should also added to the declarations

We are defining the current module entity

Test case C_syntax/function_name_conflict01.c

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.

Be careful if standard arguments are needed: replace the dummy parameters

FI: intrinsic may need to be processed here if they use dynamic typing, a.k.a. dependent types but they do not have a code value!

They cannot be removed in general because they may appear in declarations as in foo(int n, double a[n])

FI: I do not know if refs contains copies of references or just pointer to them

If e is a function pointer, check the storage of its formal parameters

Parameters
ContextStackontextStack
FormalStackormalStack
FunctionStackunctionStack
OffsetStackffsetStack
is_externals_external
is_declarations_declaration

Definition at line 2473 of file util.c.

2475 {
2476  //stack s = (stack) entity_storage(e);
2478  type t = entity_type(e);
2481  type t1,t2;
2483 
2484  pips_debug(3,"Update entity begins for \"%s\" with context %p\n", entity_name(e), context);
2485 
2486  /* If e is an intrinsics, nothing should be done, unless you are in
2487  the compilation unit: but the intrinsic type has already been
2488  put aside in the type stack linked to the entity and destroyed */
2490  return;
2491 
2492  if (lq != NIL)
2493  {
2494  /* tc must have variable type, add lq to its qualifiers */
2497  else if(type_void_p(tc))
2498  type_void(tc) = lq;
2499  /*else
2500  const void, void is not of type variable, store const where ?????????
2501  CParserError("Entity has qualifier but no type or is not variable type in the context?\n");*/
2503  }
2504 
2505  /************************* TYPE PART *******************************************/
2506 
2507  /* Use the type stack in entity_storage to create the final type for the entity*/
2508  //pips_assert("context type tc is defined", !type_undefined_p(tc));
2509  t2 = UpdateType(t,tc);
2510 
2511  if(t2!=t) {
2512  if(!stack_undefined_p(s)) {
2513  while (stack_size(s) > 1)
2514  {
2515  t1 = stack_pop(s);
2516  t2 = UpdateType(t1,t2);
2517  }
2518  if(type_undefined_p(t2)) {
2519  /* The default type is int, or a function returning an int */
2521  }
2522  }
2523  entity_type(e) = t2;
2524  }
2525 
2526  /* FI: it might be a good idea to use the type "unknown" or a
2527  future type "default" to improve the prettyprinting by not
2528  adding implicit "int" declarations. */
2529  if(type_undefined_p(entity_type(e))) {
2530  /* The default type is int */
2531  entity_type(e) =
2533  }
2534  /* FI: This elseif branch is apparently useless because the
2535  probleme must be dealt with later in the parser */
2536  else if(type_functional_p(entity_type(e))) {
2538  type rt = functional_result(f);
2539  if(type_undefined_p(rt)) {
2540  /* The default return type is int */
2541  functional_result(f) =
2543  }
2544  }
2545  pips_assert("the entity type is defined", !type_undefined_p(entity_type(e)));
2546 
2547  /************************* STORAGE PART *******************************************/
2548 
2549  /* FI: no longer true, I believe "this field is always
2550  pre-defined. It is temporarilly used to store a type. See cyacc.y
2551  rule direct-decl:" */
2552 
2553 
2555  pips_debug(3,"Current storage context is %d\n",
2558  if(typedef_entity_p(e)) {
2560  }
2561  }
2562  else if (!stack_undefined_p(FormalStack) && (FormalStack != NULL)
2563  && !stack_empty_p(FormalStack)) {
2564  entity function = stack_head(FunctionStack);
2566  pips_debug(3,"Create formal variable %s for function %s with offset %d\n",
2567  entity_name(e),entity_name(function),offset);
2568  if(!value_intrinsic_p(entity_initial(function))) {
2569  /* FI: Intrinsic do not have formal named parameters in PIPS
2570  RI, however such parameters can be named in intrinsic
2571  declarations. Problem with Validation/C_syntax/memcof.c */
2572  AddToDeclarations(e,function);
2573  }
2574  if(dummy_parameter_entity_p(e)) {
2575  if(typedef_entity_p(function) /* || type_variable_p(entity_type(function)) */)
2576  /* Storage does also matter for typedef (and function pointer) */
2577  /* How to access the information about the function type? */
2579  else
2581  }
2582  else
2583  /* FI: This branch should never be executed */
2585  }
2586  else if(type_variable_p(ultimate_type(entity_type(e)))) {
2587  /* The entities for the type_variable is added to the
2588  current module and the declarations*/
2589  entity function = get_current_module_entity();
2590 
2591  /* It is too early to use extern_entity_p() */
2592  //if(extern_entity_p(function, e))
2593  if(strstr(entity_name(e),TOP_LEVEL_MODULE_NAME) != NULL)
2595  /* Keyword EXTERN has just been encountered */
2596  /* Yes, but this may have been already recognized in
2597  FindOrCreateCurrentEntity() and this may not imply the
2598  declaration as extern is another declaration of e has
2599  already been encountered. */
2600  type et = ultimate_type(entity_type(e));
2601  if(type_functional_p(et))
2602  AddToExterns(e,function);
2603  }
2604 
2605  /* To avoid multiple declarations */
2606  list el = code_externs(value_code(entity_initial(function)));
2608  if(!gen_in_list_p(e, el) && gen_in_list_p(e, dl)) {
2609  if(compilation_unit_entity_p(function)) {
2610  /* Too late to check that the first declaration did not
2611  include an initialization */
2612  c_parser_user_warning("Multiple declarations of variable \"%s\".\n",
2613  entity_local_name(e));
2614  }
2615  else {
2616  user_log("Multiple declarations of variable \"%s\" in file\"%s\".\n",
2618  CParserError("Illegal Input");
2619  }
2620  }
2621 
2622  AddToDeclarations(e,function);
2623 
2624  // Check here if already stored the value
2626  entity_storage(e) =
2628  }
2630  /* The function should also added to the declarations */
2633  else if(!intrinsic_entity_p(e)) {
2634  /* We are defining the current module entity */
2635  CreateReturnEntity(e);
2636  }
2637  else {
2638  /* Test case C_syntax/function_name_conflict01.c */
2639  c_parser_user_warning("Intrinsic %s redefined.\n"
2640  "This is not supported by PIPS. Please rename \"%s\"\n",
2642  /* Unfortunately, an intrinsics cannot be redefined, just like a user function
2643  * or subroutine after editing because intrinsics are not handled like
2644  * user functions or subroutines. They are not added to the called_modules
2645  * list of other modules, unless the redefining module is parsed FIRST.
2646  * There is not mechanism in PIPS to control the parsing order.
2647  */
2648  CParserError("Name conflict between a "
2649  "function and an intrinsic\n");
2650  }
2652  }
2653  else
2654  pips_assert("not implemented yet", false);
2655 
2656 
2657  /************************* INITIAL VALUE PART ****************************************/
2660  //type t = entity_type(e);
2661  //type ut = ultimate_type(t);
2662  //if(type_functional(ut) && !typedef_entity_p(e))
2663  // entity_initial(e) = make_value_code(make_code(NIL, strdup(""),make_sequence(NIL),NIL, make_language_c()));
2664  //else
2665  // entity_initial(e) = make_value_unknown();
2666  }
2667 
2668  /* Be careful if standard arguments are needed: replace the dummy parameters */
2669  if(true || !is_declaration) {
2670  type t = entity_type(e);
2671  /* FI: intrinsic may need to be processed here if they use dynamic
2672  typing, a.k.a. dependent types but they do not have a code
2673  value!*/
2675  if(is_declaration) {
2676  /* They cannot be removed in general because they may appear
2677  in declarations as in foo(int n, double a[n]) */
2678  value ev = entity_initial(e);
2679  code ec = value_code(ev);
2680  list cmdl = code_declarations(ec);
2682 
2683  RemoveDummyArguments(e, refs);
2684 
2685  /* FI: I do not know if refs contains copies of references or just pointer to them */
2686  gen_free_list(refs);
2687  }
2688  else
2689  UseFormalArguments(e);
2690  }
2691  }
2692 
2693  /* If e is a function pointer, check the storage of its formal parameters */
2694  if(pointer_type_p(entity_type(e))) {
2696  if(type_functional_p(pt)) {
2697  code c = value_code(entity_initial(e));
2698 
2699  pips_assert("Although it's a pointer to a function, it has code...",
2701 
2702  if(code_undefined_p(c))
2703  pips_internal_error("Well, the code field is not defined yet...");
2704  else {
2705  list dl = code_declarations(c);
2706  list cl = list_undefined;
2707 
2708  for(cl=dl; !ENDP(cl); POP(cl)) {
2709  entity pe = ENTITY(CAR(cl));
2710 
2711  if(formal_parameter_p(pe)) {
2712  storage ps = entity_storage(pe);
2713 
2714  pips_debug(8, "Change storage from \"formal\" to \"rom\" for entity \"%s\"\n",
2715  entity_name(pe));
2716  free_storage(ps);
2718  }
2719  }
2720  }
2721  }
2722  }
2723 
2724  pips_debug(3,"Update entity ends for \"%s\" with type \"%s\" and storage \"%s\"\n",
2725  entity_name(e),
2728 
2729  pips_assert("Current entity is consistent",entity_consistent_p(e));
2730 }
void user_log(const char *format,...)
Definition: message.c:234
void free_storage(storage p)
Definition: ri.c:2231
bool entity_consistent_p(entity p)
Definition: ri.c:2530
string list_to_string(list l)
Return the malloc()ed version of the concatenation of all the strings in the list.
Definition: args.c:74
#define c_parser_context_static(x)
storage MakeStorageRam(entity v, bool is_external, bool is_static)
The storage part should not be called twice when reparsing compilation unit.
Definition: util.c:3177
void UseFormalArguments(entity f)
If f has dummy formal parameters, replace them by standard formal parameters.
Definition: util.c:2063
void AddToExterns(entity e, entity mod)
Definition: util.c:2898
void RemoveDummyArguments(entity f, list refs)
To chase formals in type declarations.
Definition: util.c:2224
void CreateReturnEntity(entity f)
If necessary, create the return entity, which is a hidden variable used in PIPS internal representati...
Definition: util.c:2382
list safe_c_words_entity(type t, list name)
string storage_to_string(storage s)
Definition: entity.c:2030
bool empty_scope_p(string s)
Definition: entity.c:500
list extract_references_from_declarations(list decls)
FI: this function has not yet been extended for C types!!!
Definition: entity.c:2834
bool compilation_unit_entity_p(entity e)
Check if the given module entity is a compilation unit.
Definition: module.c:87
type make_scalar_integer_type(_int)
Definition: type.c:712
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define storage_tag(x)
Definition: ri.h:2515

References AddToDeclarations(), AddToExterns(), basic_int, basic_pointer, c_parser_context_qualifiers, c_parser_context_scope, c_parser_context_static, c_parser_context_storage, c_parser_context_type, c_parser_user_warning, CAR, code_declarations, code_externs, code_undefined_p, compilation_unit_entity_p(), compilation_unit_p(), ContextStack, CParserError(), CreateReturnEntity(), DEFAULT_INTEGER_TYPE_SIZE, dummy_parameter_entity_p(), empty_scope_p(), ENDP, ENTITY, entity_consistent_p(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined_p, extract_references_from_declarations(), f(), formal_parameter_p(), FormalStack, free_storage(), functional_result, FunctionStack, gen_free_list(), gen_in_list_p(), get_c_parser_current_input_file_name(), get_current_module_entity(), get_current_module_name(), get_from_entity_type_stack_table(), intrinsic_entity_p(), is_external, list_to_string(), list_undefined, make_basic_int(), make_formal(), make_scalar_integer_type(), make_storage_formal(), make_storage_rom(), make_type_variable(), make_value_unknown(), make_variable(), MakeStorageRam(), NIL, offset, OffsetStack, pips_assert, pips_debug, pips_internal_error, pointer_type_p(), POP, RemoveDummyArguments(), safe_c_words_entity(), stack_empty_p(), stack_head(), stack_pop(), stack_size(), stack_undefined_p, storage_tag, storage_to_string(), storage_undefined_p, tc, TOP_LEVEL_MODULE_NAME, type_functional, type_functional_p, type_undefined_p, type_variable, type_variable_p, type_void, type_void_p, typedef_entity_p(), ultimate_type(), UpdateType(), UseFormalArguments(), user_log(), value_code, value_code_p, value_intrinsic_p, value_undefined_p, variable_basic, and variable_qualifiers.

Referenced by UpdateEntities().

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

◆ UpdateEntity2()

void UpdateEntity2 ( entity  ,
stack  ,
stack   
)

◆ UpdateFinalPointer()

type UpdateFinalPointer ( type  pt,
type  t 
)

This function replaces the type pointed by the pointer pt (this can be a pointer of pointer,... so we have to go until the last one) by the type t

Parameters
ptt

Definition at line 1427 of file util.c.

1428 {
1429  /* This function replaces the type pointed by the pointer pt
1430  (this can be a pointer of pointer,... so we have to go until the last one)
1431  by the type t*/
1432  pips_debug(3,"Update final pointer type %d and %d\n", type_tag(pt), type_tag(t));
1434  {
1436  if (type_undefined_p(ppt))
1438  return UpdateFinalPointer(ppt,t);
1439  }
1440  CParserError("pt is not a pointer\n");
1441  return type_undefined;
1442 }
basic make_basic_pointer(type _field_)
Definition: ri.c:179
type UpdateFinalPointer(type pt, type t)
Definition: util.c:1427

References basic_pointer, basic_pointer_p, CParserError(), make_basic_pointer(), make_type_variable(), make_variable(), NIL, pips_debug, type_tag, type_undefined, type_undefined_p, type_variable, type_variable_p, UpdateFinalPointer(), variable_basic, and variable_qualifiers.

Referenced by UpdateFinalPointer().

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

◆ UpdateFunctionEntity()

void UpdateFunctionEntity ( entity  oe,
list  la 
)

The parser has found out that an entity is a function and partially sets its type.

The function may also be an intrinsics and be already fully defined.

If oe is an intrinsics, nothing should be done if we are compiling a function that redeclares intrinsics, because they are usually badly or at least only partly redeclared.

However, il should be updated if it's declared in a compilation unit as the header files may contain more up-to-date information than bootstrap. Or if its type has already been placed in the type stack and been undefined in the entity.

Note that a user function might have the same name as a C intrinsic. Then we are in trouble.

Is oe's name compatible with a function name? Well oe might be a pointer...

FI: We used never to bump into this case...

Parameters
oee
laa

Definition at line 1614 of file util.c.

1615 {
1616  type t = entity_type(oe);
1617  //string oeln = entity_local_name(oe);
1618  //string sn = local_name_to_scope(oeln);
1619  //entity ne = oe;
1620 
1621  pips_debug(3,"Update function entity \"%s\"\n",entity_name(oe));
1622 
1623  ifdebug(8) {
1624  pips_debug(8, "with type list la: ");
1625  if(ENDP(la)) {
1626  (void) fprintf(stderr, "empty list");
1627  }
1628  MAP(PARAMETER, at, {
1629  (void) fprintf(stderr, "%s, ", list_to_string(safe_c_words_entity(parameter_type(at), NIL)));
1630  }, la);
1631  (void) fprintf(stderr, "\n");
1632  }
1633 
1634  /* If oe is an intrinsics, nothing should be done if we are
1635  compiling a function that redeclares intrinsics, because they are
1636  usually badly or at least only partly redeclared.
1637 
1638  However, il should be updated if it's declared in a compilation unit
1639  as the header files may contain more up-to-date information than
1640  bootstrap. Or if its type has already been placed in the type
1641  stack and been undefined in the entity.
1642 
1643  Note that a user function might have the same name as a C
1644  intrinsic. Then we are in trouble.
1645  */
1646  if(intrinsic_entity_p(oe)
1649  && !type_undefined_p(entity_type(oe)))
1650  return;
1651 
1652  /* Is oe's name compatible with a function name? Well oe might be a
1653  pointer... */
1654  // pips_assert("A function name does not include a scope", empty_string_p(sn));
1655 
1656  if (type_undefined_p(t))
1658  else if(type_functional_p(t)) {
1659  /* FI: We used never to bump into this case... */
1661  functional_parameters(f) = la;
1662  }
1663  else {
1664  pips_internal_error("What should be done here?");
1665  CParserError("This entity must have undefined type\n");
1666  }
1667 
1668  pips_debug(3,"Update function entity \"%s\" with type \"\%s\"\n",
1669  entity_name(oe),
1671 }
#define parameter_type(x)
Definition: ri.h:1819

References compilation_unit_p(), CParserError(), ENDP, entity_name, entity_type, entity_undefined_p, f(), fprintf(), functional_parameters, get_current_module_entity(), get_current_module_name(), ifdebug, intrinsic_entity_p(), list_to_string(), make_functional(), make_type_functional(), MAP, NIL, PARAMETER, parameter_type, pips_debug, pips_internal_error, safe_c_words_entity(), type_functional, type_functional_p, type_undefined, and type_undefined_p.

+ Here is the call graph for this function:

◆ UpdateParenEntity()

void UpdateParenEntity ( entity  e,
list  lq 
)
Parameters
lqq

Definition at line 1368 of file util.c.

1369 {
1370  type t = entity_type(e);
1371  pips_debug(3,"Update entity in parentheses \"%s\" with type \"%s\"\n",
1373  if (lq != NIL) {
1374  if (type_undefined_p(t))
1376  else {
1377  if (type_variable_p(t)) {
1378  variable v = type_variable(t);
1380  }
1381  else {
1382  CParserError("Attributes for not variable type\n");
1383  }
1384  }
1385  }
1386 }
string safe_type_to_string(const type)
Definition: type.c:59

References basic_undefined, CParserError(), entity_name, entity_type, gen_nconc(), list_undefined, make_type_variable(), make_variable(), NIL, pips_debug, safe_type_to_string(), type_undefined_p, type_variable, type_variable_p, and variable_qualifiers.

+ Here is the call graph for this function:

◆ UpdatePointerEntity()

void UpdatePointerEntity ( entity  e,
type  pt,
list  lq 
)

Make e an array of pointers whose type is this of pt

Make e a function returns a pointer

Parameters
ptt
lqq

Definition at line 1444 of file util.c.

1445 {
1446  type t = entity_type(e);
1447  ifdebug(3) {
1448  list pdl = NIL;
1449  pips_debug(3,"Update pointer entity %s with type pt=\"%s\"\n",
1450  entity_name(e), list_to_string(c_words_entity(pt, NIL, &pdl)));
1451  gen_free_list(pdl);
1452  }
1453  if (type_undefined_p(t))
1454  {
1455  pips_debug(3,"Undefined entity type\n");
1456  entity_type(e) = pt;
1457  /*
1458  if(type_undefined_p(pt)) {
1459  type npt = make_type(is_type_variable,
1460  make_variable(make_basic(is_basic_pointer, type_undefined),
1461  NIL, NIL));
1462  entity_type(e) = npt;
1463  }
1464  else if(type_variable_p(pt) && basic_pointer_p(variable_basic(type_variable(pt))))
1465  entity_type(e) = pt;
1466  else {
1467  type npt = make_type(is_type_variable,
1468  make_variable(make_basic(is_basic_pointer, pt),
1469  NIL, NIL));
1470  entity_type(e) = npt;
1471  }
1472  */
1473 
1475  }
1476  else
1477  {
1478  switch (type_tag(t)) {
1479  case is_type_variable:
1480  {
1481  /* Make e an array of pointers whose type is this of pt */
1482  variable v = type_variable(t);
1483  pips_debug(3,"Array of pointers\n");
1486  gen_nconc(variable_qualifiers(v),lq)));
1487  break;
1488  }
1489  case is_type_functional:
1490  {
1491  /* Make e a function returns a pointer */
1493  pips_debug(3,"Function returns a pointer \n");
1494  entity_type(e) =
1496  break;
1497  }
1498  default:
1499  {
1500  CParserError("Entity is neither an array of pointers nor a pointer to a function?\n");
1501  }
1502  }
1503  }
1504  ifdebug(3) {
1505  list pdl = NIL;
1506  pips_debug(3,"Ends with type \"%s\" for entity %s\n",
1508  entity_name(e));
1509  gen_free_list(pdl);
1510  }
1511 
1512 }
list c_words_entity(type t, list name, list *ppdl)

References c_words_entity(), CParserError(), entity_name, entity_type, f(), functional_parameters, gen_free_list(), gen_nconc(), ifdebug, is_type_functional, is_type_variable, list_to_string(), make_functional(), make_type_functional(), make_type_variable(), make_variable(), NIL, pips_debug, type_functional, type_tag, type_undefined_p, type_variable, variable_basic, variable_dimensions, and variable_qualifiers.

+ Here is the call graph for this function:

◆ UpdateType()

type UpdateType ( type  t1,
type  t2 
)

This function replaces the undefined field in t1 by t2.

If t1 is an array type and the basic of t1 is undefined, it is replaced by the basic of t2.

If t1 is a pointer type, if the pointed type is undefined it is replaced by t2.

If t1 is a functional type, if the result type of t1 is undefined, it is replaced by t2.

If t1 is a void type, then either t2 also is a void type or an error is raised.

The function is recursive.

FI: This function used to create sharing between t1 and t2, which creates problems when t2 is later freed. t1 may be updated and returned or a new type may be created.

This may happen when a type is implicitly declared as in "extern m[3];"

We used to use type_unknown when the type was implicit, but type_unknown does not let us store dimension information. We need here a new kind of basic, basic unknown or basic implicit. This would let us be more respectful of the source code, but requires a modification of the internal representation. It is mostly a prettyprint issue. See ticket

Basic pointer

t1 is already fully defined

Redundant update

Could be a pips internal error...

Parameters
t11
t22

Definition at line 1693 of file util.c.

1694 {
1695  if (type_undefined_p(t1)) {
1696  if(!type_undefined_p(t2))
1697  return copy_type(t2);
1698  else
1699  return t2;
1700  }
1701 
1702  if(type_undefined_p(t2)) {
1703  /* This may happen when a type is implicitly declared as in
1704  "extern m[3];" */
1705  /* We used to use type_unknown when the type was implicit, but
1706  type_unknown does not let us store dimension information. We
1707  need here a new kind of basic, basic unknown or basic
1708  implicit. This would let us be more respectful of the source
1709  code, but requires a modification of the internal
1710  representation. It is mostly a prettyprint issue. See ticket
1711  225. */
1713  }
1714 
1715  switch (type_tag(t1))
1716  {
1717  case is_type_variable:
1718  {
1719  variable v = type_variable(t1);
1721  {
1722  pips_assert("type t2 is defined", !type_undefined_p(t2));
1723  if (type_variable_p(t2))
1728  CParserError("t1 is a variable type but not t2\n");
1729  }
1730  else
1731  {
1732  /* Basic pointer */
1734  {
1738  variable_qualifiers(v)));
1739  }
1740  else {
1741  /* t1 is already fully defined */
1742  if(type_equal_p(t1,t2))
1743  return t2;
1744  else if(overloaded_type_p(t1))
1745  return t2;
1746  else
1747  CParserError("This basic has an undefined field?\n");
1748  }
1749  }
1750  break;
1751  }
1752  case is_type_functional:
1753  {
1756  {
1757  type nt = type_undefined;
1758  if (type_undefined_p(t2))
1759  nt = make_type_unknown();
1760  else
1761  nt = copy_type(t2);
1763  }
1765  }
1766  case is_type_void:
1767  {
1768  if(type_void_p(t2)) {
1769  /* Redundant update */
1770  ;
1771  }
1772  else {
1773  /* Could be a pips internal error... */
1774  CParserError("void type to be updated by a non void type...\n");
1775  }
1776  return t1;
1777  }
1778  default:
1779  {
1780  CParserError("t1 has which kind of type?\n");
1781  }
1782  }
1783  return type_undefined;
1784 }
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
bool type_equal_p(type, type)
Definition: type.c:547
#define basic_undefined_p(x)
Definition: ri.h:557

References basic_pointer, basic_pointer_p, basic_undefined_p, copy_basic(), copy_type(), CParserError(), DEFAULT_INTEGER_TYPE_SIZE, f(), functional_parameters, functional_result, gen_full_copy_list(), gen_nconc(), is_type_functional, is_type_variable, is_type_void, make_basic_pointer(), make_functional(), make_scalar_integer_type(), make_type_functional(), make_type_unknown(), make_type_variable(), make_variable(), overloaded_type_p(), pips_assert, type_equal_p(), type_functional, type_tag, type_undefined, type_undefined_p, type_variable, type_variable_p, type_void_p, UpdateType(), variable_basic, variable_dimensions, and variable_qualifiers.

Referenced by UpdateAbstractEntity(), UpdateDerivedEntity(), UpdateEntity(), and UpdateType().

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

◆ UseDummyArguments()

void UseDummyArguments ( entity  f)

If f has regular formal parameters, destroy them.

make a list of formal parameters

Remove the formals from f's declaration list and from the symbol table

FI: The storage might point to another dummy argument (although it should not)

Let's hope there are no other pointers towards dummy formal parameters

Definition at line 2019 of file util.c.

2020 {
2021  value fv = entity_initial(f);
2022 
2023  pips_assert("The function value is defined", !value_undefined_p(fv));
2024  pips_assert("The entity has a functional type", type_functional_p(entity_type(f)));
2025  pips_assert("The entity is not a typedef", !typedef_entity_p(f));
2026 
2027  if(!value_undefined_p(fv)) {
2028  code fc = value_code(fv);
2029  list dl = code_declarations(fc);
2030  list cd = list_undefined;
2031  list formals = NIL;
2032 
2033  pips_assert("the value is code", value_code_p(fv));
2034 
2035  /* make a list of formal parameters */
2036  for(cd = dl; !ENDP(cd); POP(cd)) {
2037  entity v = ENTITY(CAR(cd));
2038  if(entity_formal_p(v)) {
2039  pips_debug(8, "Formal parameter: \"%s\"\n", entity_name(v));
2040  formals = gen_nconc(formals, CONS(ENTITY, v, NIL));
2041  }
2042  }
2043 
2044  /* Remove the formals from f's declaration list and from the
2045  symbol table */
2046  for(cd = formals; !ENDP(cd); POP(cd)) {
2047  entity p = ENTITY(CAR(cd));
2048  storage ps = entity_storage(p);
2049  formal pfs = storage_formal(ps);
2050 
2051  gen_remove(&code_declarations(fc), (void *) p);
2052  /* FI: The storage might point to another dummy argument
2053  (although it should not) */
2055  /* Let's hope there are no other pointers towards dummy formal parameters */
2056  //free_entity(p);
2057  }
2058  gen_free_list(formals);
2059  }
2060 }

References CAR, code_declarations, CONS, ENDP, ENTITY, entity_formal_p(), entity_initial, entity_name, entity_storage, entity_type, entity_undefined, f(), formal_function, gen_free_list(), gen_nconc(), gen_remove(), list_undefined, NIL, pips_assert, pips_debug, POP, storage_formal, type_functional_p, typedef_entity_p(), value_code, value_code_p, and value_undefined_p.

+ Here is the call graph for this function:

◆ UseFormalArguments()

void UseFormalArguments ( entity  f)

If f has dummy formal parameters, replace them by standard formal parameters.

make a list of formal dumy parameters; depending on the kind of function declaration, dummy formal parameters are used (new C function declaration style), or not (old C function declaration style).

FI: Maybe, it would be better to unify the use of summy formal parameter in the parser?

Is it a local function or global function?

mn = strdup(concatenate(entity_module_name(f),entity_local_name(f), NULL));

Remore the dummy formals from f's declaration list (and from the symbol table?) and replace them by equivalent regular formal parameters

Substitute p by new_p in the declaration references for cases such as "foo(n, double a[n])"

This only works if the refs list points to the actual references and not to copies...

sg: this test used to be if e == p, but it missed some cases because reference_variable may have been generated incorectly before using a TOP_LEVEL variable instead of the dummy

A substitution could be performed instead...

FI: The storage might point to another dummy argument (although it should not)

Let's hope there are no other pointers towards dummy formal parameters

Check substitution in formal parameter declarations

FI: just in case?

Do not free the dummy formal parameter variable as they are preserved in the dummy field for accurate prettyprinting

Definition at line 2063 of file util.c.

2064 {
2065  value fv = entity_initial(f);
2066 
2067  pips_assert("The function value is defined", !value_undefined_p(fv));
2068  pips_assert("The entity has a functional type", type_functional_p(entity_type(f)));
2069  pips_assert("The entity is not a typedef", !typedef_entity_p(f));
2070 
2071  if(!value_undefined_p(fv)) {
2072  code fc = value_code(fv);
2074  list cd = list_undefined;
2075  list formals = NIL;
2076  string mn = string_undefined;
2077  // This is a minimal list of references. We need all references.
2078  //list refs1 = extract_references_from_declarations(dl);
2080 
2081  ifdebug(8) {
2082  int l2 = gen_length(refs);
2083 
2084  pips_debug(8, "refs (%d elements):\n", l2);
2085  print_references(refs);
2086  }
2087 
2088  pips_assert("the value is code", value_code_p(fv));
2089 
2090  /* make a list of formal dumy parameters; depending on the kind of
2091  function declaration, dummy formal parameters are used (new C
2092  function declaration style), or not (old C function declaration
2093  style).
2094 
2095  FI: Maybe, it would be better to unify the use of summy formal
2096  parameter in the parser?
2097  */
2098  for(cd = dl; !ENDP(cd); POP(cd)) {
2099  entity v = ENTITY(CAR(cd));
2100  if(entity_formal_p(v)) {
2101  pips_debug(8, "Formal parameter: \"%s\"\n", entity_name(v));
2103  formals = gen_nconc(formals, CONS(ENTITY, v, NIL));
2104  //pips_assert("v is a dummy parameter", dummy_parameter_entity_p(v));
2105  }
2106  }
2107 
2108  /* Is it a local function or global function? */
2109  if(top_level_entity_p(f))
2110  mn = strdup(entity_user_name(f));
2111  else
2112  /* mn = strdup(concatenate(entity_module_name(f),entity_local_name(f), NULL)); */
2113  mn = strdup(entity_local_name(f));
2114 
2115  /* Remore the dummy formals from f's declaration list (and from the
2116  symbol table?) and replace them by equivalent regular formal parameters */
2117  for(cd = formals; !ENDP(cd); POP(cd)) {
2118  entity p = ENTITY(CAR(cd));
2119  const char * pn = entity_user_name(p);
2120  entity new_p = entity_undefined;
2121  //storage ps = entity_storage(p);
2122  //formal pfs = storage_formal(ps);
2123 
2125  new_p = FindOrCreateEntity(mn, pn );
2127  entity_type(new_p) = copy_type(entity_type(p));
2129  pips_debug(8, "Formal dummy parameter \"%s\" is replaced "
2130  "by standard formal parameter \"%s\"\n",
2131  entity_name(p), entity_name(new_p));
2132 
2133  /* Substitute p by new_p in the declaration references for cases
2134  such as "foo(n, double a[n])" */
2135  /* This only works if the refs list points to the actual
2136  references and not to copies... */
2137  FOREACH(REFERENCE, r, refs){
2138  entity e = reference_variable(r);
2139 
2140  /* sg: this test used to be if e == p, but it missed some cases
2141  * because reference_variable may have been generated incorectly before
2142  * using a TOP_LEVEL variable instead of the dummy */
2143  if(same_entity_lname_p(e,p)) {
2144  reference_variable(r) = new_p;
2145  pips_debug(8, "reference %p to \"%s\" changed into reference to \"\%s\"\n",
2146  r, entity_name(p), entity_name(new_p));
2147  }
2148  }
2149 
2150  /* A substitution could be performed instead...*/
2151  gen_remove(&code_declarations(fc), (void *) p);
2153 
2154  /* FI: The storage might point to another dummy argument
2155  (although it should not) */
2156  //formal_function(pfs) = entity_undefined;
2157  /* Let's hope there are no other pointers towards dummy formal parameters */
2158  //free_entity(p); // FI: we may use them in the type data structures in spite of the MAP on refs?
2159  }
2160  }
2161  gen_free_list(dl);
2162 
2163  ifdebug(1) {
2164  dl = module_all_declarations(f);
2165  /* Check substitution in formal parameter declarations */
2166  ifdebug(8) {
2167  pips_debug(8, "list of declared variables:\n");
2168  print_entities(dl);
2169  (void) fprintf(stderr, "\n");
2170  }
2172  MAP(REFERENCE, r, {
2173  entity v = reference_variable(r);
2174  if(dummy_parameter_entity_p(v)) {
2175  pips_debug(8, "Substitution failed for reference %p and variable \"%s\"\n",
2176  r, entity_name(v));
2177  pips_internal_error("Failed substitution");
2178  }
2179  }, refs);
2180  gen_free_list(dl);
2181  }
2182 
2183  /* FI: just in case? */
2184  remove_entity_type_stacks(formals);
2185 
2186  /* Do not free the dummy formal parameter variable as they are
2187  preserved in the dummy field for accurate prettyprinting */
2188  /*
2189  MAP(ENTITY, df, {
2190  free_entity(df);
2191  }, formals);
2192  */
2193 
2194  free(mn);
2195  gen_free_list(formals);
2196  }
2197 }
void print_references(list rl)
Definition: expression.c:163
bool same_entity_lname_p(entity, entity)
Definition: same_names.c:64
list module_all_declarations(entity m)
The function itself is not in its declarations.
Definition: module.c:419
list declaration_supporting_references(list dl)
Find all references in the declaration list.
Definition: module.c:392

References CAR, code_declarations, CONS, copy_storage(), copy_type(), copy_value(), declaration_supporting_references(), dummy_parameter_entity_p(), ENDP, ENTITY, entity_formal_p(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, entity_user_name(), f(), FindOrCreateEntity(), FOREACH, fprintf(), free(), gen_free_list(), gen_length(), gen_nconc(), gen_remove(), get_from_entity_type_stack_table(), ifdebug, list_undefined, MAP, module_all_declarations(), NIL, pips_assert, pips_debug, pips_internal_error, POP, print_entities(), print_references(), REFERENCE, reference_variable, remove_entity_type_stacks(), same_entity_lname_p(), stack_undefined_p, strdup(), string_undefined, top_level_entity_p(), type_functional_p, typedef_entity_p(), value_code, value_code_p, and value_undefined_p.

Referenced by UpdateEntity().

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

Variable Documentation

◆ AllocatableArea

entity AllocatableArea
extern

Definition at line 61 of file area.c.

◆ BlockStack

◆ c__flex_debug

int c__flex_debug
extern

◆ c_char

int c_char
extern

◆ c_debug

int c_debug
extern

◆ c_in

FILE* c_in
extern

Warning! Do not modify this file that is automatically generated!

Modify src/Libs/c_syntax/c_syntax-local.h instead, to add your own modifications. header file built by cproto c_syntax-local.h

Definition at line 291 of file c_syntax.h.

◆ c_leng

int c_leng
extern

◆ C_line_increment

int C_line_increment
extern

from "clex.l"

from "clex.l"

The goal is to reconstruct the line number in the user file and not the line number in the preprocessed file.

This is performed in analyze_preprocessor_line() (util.c)

Definition at line 296 of file c_syntax.h.

Referenced by set_current_C_line_number().

◆ c_lineno

int c_lineno
extern

the file read in by the c_lexer

Definition at line 293 of file c_syntax.h.

◆ c_nerrs

int c_nerrs
extern

◆ c_out

FILE* c_out
extern

◆ c_text

char* c_text
extern

◆ CalledModules

list CalledModules
extern

Definition at line 51 of file c_parser.c.

Referenced by actual_c_parser(), and AddToCalledModules().

◆ compilation_unit_name

◆ compilation_unit_parser_is_running_p

bool compilation_unit_parser_is_running_p
extern

To pass down the information to functions used by the syntactical analyzer.

Definition at line 541 of file c_parser.c.

Referenced by actual_c_parser(), and analyze_preprocessor_line().

◆ ContextStack

◆ derived_counter

int derived_counter
extern

Definition at line 125 of file c_parser.c.

Referenced by actual_c_parser().

◆ DynamicArea

entity DynamicArea
extern

These global variables are declared in ri-util/util.c.

These global variables are declared in ri-util/util.c.

functions for areas Four areas used to allocate variables which are not stored in a Fortran common. These areas are just like Fortran commons, but the dynamic area is the only non-static area according to Fortran standard. The heap and the stack area are used to deal with Fortran ANSI extensions and C, pointers and allocatable arrays, and adjustable arrays (VLA in C). The dynamic area is stack allocated by most compilers but could be statically allocated since the array sizes are known.

Areas are declared for each module. These four global variables are managed by the Fortran and C parsers and used to allocate variables in the current module. Note that the C parser uses more areas at the same time to cope with global variables.

Definition at line 57 of file area.c.

◆ FormalStack

stack FormalStack
extern

◆ FunctionStack

◆ HeapArea

entity HeapArea
extern

Definition at line 59 of file area.c.

◆ LabeledStatements

list LabeledStatements
extern

BlockStack is used to handle block scope.

Definition at line 60 of file statement.c.

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

◆ loop_counter

int loop_counter
extern

Global counter.

Definition at line 124 of file c_parser.c.

Referenced by actual_c_parser().

◆ LoopStack

◆ ModuleStatement

statement ModuleStatement
extern

◆ OffsetStack

stack OffsetStack
extern

◆ removable_extern_entities

list removable_extern_entities
extern

Definition at line 542 of file c_parser.c.

Referenced by actual_c_parser(), and CleanUpEntities().

◆ StackArea

entity StackArea
extern

Definition at line 60 of file area.c.

◆ StaticArea

entity StaticArea
extern

Definition at line 58 of file area.c.

◆ StructNameStack

stack StructNameStack
extern

Definition at line 121 of file c_parser.c.

Referenced by actual_c_parser(), and c_parser_error().

◆ SwitchControllerStack

stack SwitchControllerStack
extern

◆ SwitchGotoStack

stack SwitchGotoStack
extern

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().