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

Go to the source code of this file.

Macros

#define START_COMMENT_LINE   "CcDd*!#\n"
 Warning! Do not modify this file that is automatically generated! More...
 
#define HASH_SIZE   1013
 definition of implementation dependent constants More...
 
#define FORMATLENGTH   (4096)
 
#define LOCAL   static
 
#define abs(v)   (((v) < 0) ? -(v) : (v))
 
#define Warning(f, m)   (user_warning(f,"Warning between lines %d and %d\n%s\n",line_b_I,line_e_I,m) )
 extern char * getenv(); More...
 
#define FatalError(f, m)   (pips_internal_error("Fatal error between lines %d and %d\n%s\n",line_b_I,line_e_I,m))
 

Functions

int syn_lex ()
 
void syn_reset_lex ()
 
int syn_parse ()
 
void syn_error (const char *)
 
int SafeSizeOfArray (entity)
 cproto-generated files More...
 
void InitAreas (void)
 
void save_all_entities (void)
 functions for the SAVE declaration More...
 
void SaveEntity (entity)
 These two functions transform a dynamic variable into a static one. More...
 
void MakeVariableStatic (entity, bool)
 
void ProcessSave (entity)
 
void save_initialized_variable (entity)
 
void SaveCommon (entity)
 this function transforms a dynamic common into a static one. More...
 
void PrintData (cons *, cons *)
 a debugging function, just in case ... More...
 
void AnalyzeData (list, list)
 this function scans at the same time a list of datavar and a list of dataval. More...
 
void MakeDataStatement (list, list)
 Receives as first input an implicit list of references, including implicit DO, and as second input an list of value using pseudo-intrinsic REPEAT_VALUE() to replicate values. More...
 
void DeclarePointer (entity, entity, list)
 
void DeclareVariable (entity, type, list, storage, value)
 void DeclareVariable(e, t, d, s, v): update entity e description as declaration statements are encountered. More...
 
void DeclareIntrinsic (entity)
 Intrinsic e is used in the current module. More...
 
bool fortran_relevant_area_entity_p (entity)
 These tests are needed to check area consistency when dumping or printing a symbol table. More...
 
void initialize_common_size_map (void)
 
void reset_common_size_map (void)
 
void reset_common_size_map_on_error (void)
 
bool common_to_defined_size_p (entity)
 
size_t common_to_size (entity)
 
void set_common_to_size (entity, size_t)
 
void update_common_to_size (entity, size_t)
 
entity MakeCommon (entity)
 MakeCommon: This function creates a common block. More...
 
entity NameToCommon (string)
 
void AddVariableToCommon (entity, entity)
 This function adds a variable v to a common block c. More...
 
int CurrentOffsetOfArea (entity, entity)
 
void update_common_sizes (void)
 
void InitImplicit (void)
 this function initializes the data structure used to compute implicit types More...
 
void cr_implicit (tag, int, int, int)
 this function updates the data structure used to compute implicit types. More...
 
type ImplicitType (entity)
 This function computes the Fortran implicit type of entity e. More...
 
bool implicit_type_p (entity)
 This function checks that entity e has an undefined or an implicit type which can be superseded by another declaration. More...
 
void retype_formal_parameters (void)
 If an IMPLICIT statement is encountered, it must be applied to the formal parameters, and, if the current module is a function, to the function result type and to the variable used internally when a value is assigned to the function (see MakeCurrentFunction) More...
 
type MakeFortranType (tag, value)
 this function creates a type that represents a fortran type. More...
 
int OffsetOfReference (reference)
 This function computes the numerical offset of a variable element from the begining of the variable. More...
 
int ValueOfIthLowerBound (entity, int)
 this function returns the size of the ith lower bound of a variable e. More...
 
int SizeOfRange (range)
 This function computes the size of a range, ie. More...
 
int IsIntegerScalar (entity)
 FI: should be moved in ri-util; this function returns true if e is a zero dimension variable of basic type integer. More...
 
void update_user_common_layouts (entity)
 Check... More...
 
bool update_common_layout (entity, entity)
 (Re)compute offests of all variables allocated in common c from module m and update (if necessary) the size of common c for the whole program or set of modules in the current workspace. More...
 
entity SafeFindOrCreateEntity (const char *, const char *)
 Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a function or subroutine call as functional parameter. More...
 
void add_entity_to_declarations (string, string, enum basic_utype tag, void *)
 FI: I do not understand the naming here, or the parameter. More...
 
entity MakeParameter (entity, expression)
 lint More...
 
expression MakeImpliedDo (syntax, range, cons *)
 expressions from input output lists might contain implied do loops. More...
 
expression loop_to_implieddo (loop)
 
syntax MakeAtom (entity, cons *, expression, expression, int)
 MakeAtom: this function creates a syntax, ie. More...
 
consMakeIoList (cons *)
 This function takes a list of io elements (i, j, t(i,j)), and returns the same list, with a cons cell pointing to a character constant expression 'IOLIST=' before each element of the original list. More...
 
list FortranExpressionList (list)
 Make sure that no call to implied do is in l. More...
 
expression MakeFortranBinaryCall (entity, expression, expression)
 
expression MakeFortranUnaryCall (entity, expression)
 
syntax CheckLeftHandSide (syntax)
 If a left hand side is a call, it should be a substring operator or a macro. More...
 
entity make_Fortran_constant_entity (string, tag, size_t)
 
void ResetChains (void)
 undefine chains between two successives calls to parser More...
 
void SetChains (void)
 initialize chains before each call to the parser More...
 
atom MakeEquivAtom (syntax)
 this function creates an atom of an equivalence chain. More...
 
void StoreEquivChain (chain)
 This function is called when an equivalence chain has been completely parsed. More...
 
void ComputeEquivalences (void)
 This function merges all the equivalence chains to take into account equivalences due to transitivity. More...
 
int AddOrMergeChain (chain)
 this function adds a chain ct to the set of equivalences. More...
 
int ChainIntersection (cons *, cons *)
 this function returns true if the there is a variable that occurs in both atom lists. More...
 
consMergeTwoChains (cons *, cons *)
 this function merges two equivalence chains whose intersection is not empty, ie. More...
 
void PrintChains (equivalences)
 two debugging functions, just in case ... More...
 
void PrintChain (chain)
 
bool entity_in_equivalence_chains_p (entity)
 
bool entity_in_equivalence_chain_p (entity, chain)
 
void ComputeAddresses (void)
 This function computes an address for every variable. More...
 
void SaveChains (void)
 Initialize the shared fields of aliased variables. More...
 
void reset_current_label_string (void)
 
string get_current_label_string (void)
 
void set_current_label_string (string)
 
bool empty_current_label_string_p (void)
 
bool ParserError (const char *, const char *)
 
void BeginingOfParsing (void)
 this function is called for each new file (FI: once?) FI: I do not understand how this works. More...
 
bool hpfc_parser (const string)
 parser for HPFC. More...
 
bool parser (const string)
 
void init_parser_properties (void)
 
void init_ghost_variable_entities (void)
 procedure.c More...
 
void substitute_ghost_variable_in_expression (expression, entity, entity)
 
void substitute_ghost_variable_in_statement (statement, entity, entity)
 
void remove_ghost_variable_entities (bool)
 
void add_ghost_variable_entity (entity)
 
void reify_ghost_variable_entity (entity)
 It is possible to change one's mind and effectively use an entity which was previously assumed useless. More...
 
bool ghost_variable_entity_p (entity)
 
void BeginingOfProcedure (void)
 this function is called each time a new procedure is encountered. More...
 
void update_called_modules (entity)
 
void remove_from_called_modules (entity)
 macros are added, although they should not have been. More...
 
void AbortOfProcedure (void)
 
void EndOfProcedure (void)
 This function is called when the parsing of a procedure is completed. More...
 
void UpdateFunctionalType (entity, list)
 This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction functional type. More...
 
void remove_module_entity (entity)
 
void MakeCurrentFunction (type, int, const char *, list)
 this function creates one entity cf that represents the Fortran function f being analyzed. More...
 
void ResetEntries (void)
 
void AbortEntries (void)
 
bool EmptyEntryListsP (void)
 
void AddEntryLabel (entity)
 
void AddEntryTarget (statement)
 
void AddEntryEntity (entity)
 
void AddEffectiveFormalParameter (entity)
 Keep track of the formal parameters for the current module. More...
 
bool IsEffectiveFormalParameterP (entity)
 
entity SafeLocalToGlobal (entity, type)
 A local entity might have been created but found out later to be global, depending on the order of declaration statements (see MakeExternalFunction()). More...
 
type MakeResultType (entity, type)
 The result type of a function may be carried by e, by r or be implicit. More...
 
entity LocalToGlobal (entity)
 
instruction MakeEntry (entity, list)
 An ENTRY statement is substituted by a labelled continue. More...
 
void ProcessEntries (void)
 
entity NameToFunctionalEntity (string)
 
void TypeFunctionalEntity (entity, type)
 
entity MakeExternalFunction (entity, type)
 
entity DeclareExternalFunction (entity)
 
void MakeFormalParameter (entity, entity, int)
 This function transforms an untyped entity into a formal parameter. More...
 
void ScanFormalParameters (entity, list)
 this function scans the formal parameter list. More...
 
void UpdateFormalStorages (entity, list)
 this function check and set if necessary the storage of formal parameters in lfp. More...
 
void append_data_current_stmt_buffer_to_declarations (void)
 
void parser_reset_all_reader_buffers (void)
 
void init_parser_reader_properties (void)
 
int syn_wrap (void)
 
void ScanNewFile (void)
 La fonction a appeler pour l'analyse d'un nouveau fichier. More...
 
int IsCapKeyword (char *)
 Fonction appelee par sslex sur la reduction de la regle de reconnaissance des mot clefs. More...
 
int PipsGetc (FILE *)
 Routine de lecture pour l'analyseur lexical, lex ou flex. More...
 
int GetChar (FILE *)
 Routine de lecture physique. More...
 
int ReadLine (FILE *)
 All physical lines of a statement are put together in a unique buffer called "line_buffer". More...
 
int ReadStmt (FILE *)
 regroupement des lignes du statement en une unique ligne sans continuation More...
 
void CheckParenthesis (void)
 
int FindDoWhile (void)
 This function is redundant with FindDo() but much easier to understand. More...
 
int FindDo (void)
 
int FindImplicit (void)
 
int FindIfArith (void)
 
void FindIf (void)
 
void FindAutre (void)
 
int FindAssign (void)
 
void FindPoints (void)
 
size_t FindProfZero (int)
 
size_t FindMatchingPar (size_t)
 
int StmtEqualString (char *, int)
 
int CapitalizeStmt (char[], int)
 
int NeedKeyword (void)
 
void dump_current_statement (void)
 
int get_statement_number (void)
 eturn the line number of the statement being parsed More...
 
void parser_reset_StmtHeap_buffer (void)
 statement.c More...
 
statement LabelToStmt (string)
 this functions looks up in table StmtHeap for the statement s whose label is l. More...
 
void CheckAndInitializeStmt (void)
 this function looks for undefined labels. More...
 
void NewStmt (entity, statement)
 this function stores a new association in table StmtHeap: the label of statement s is e. More...
 
void ResetBlockStack (void)
 
bool IsBlockStackEmpty (void)
 
bool IsBlockStackFull (void)
 
void PushBlock (instruction, string)
 
instruction PopBlock (void)
 
entity MakeLabel (const char *)
 
statement MakeNewLabelledStatement (entity, instruction)
 
statement ReuseLabelledStatement (statement, instruction)
 
statement MakeStatement (entity, instruction)
 This function makes a statement. More...
 
void LinkInstToCurrentBlock (instruction, bool)
 this function links the instruction i to the current block of statements. More...
 
instruction MakeEmptyInstructionBlock (void)
 this function creates an empty block More...
 
instruction MakeZeroOrOneArgCallInst (char *, expression)
 this function creates a simple Fortran statement such as RETURN, CONTINUE, ... More...
 
instruction MakeGotoInst (string)
 this function creates a goto instruction. More...
 
instruction make_goto_instruction (entity)
 In a "go to" instruction, the label does not appear explictly. More...
 
instruction MakeComputedGotoInst (list, expression)
 
instruction MakeAssignedGotoInst (list, entity)
 
instruction MakeAssignedOrComputedGotoInst (list, expression, bool)
 
instruction MakeAssignInst (syntax, expression)
 this function creates an affectation statement. More...
 
void update_functional_type_result (entity, type)
 Update of the type returned by function f. More...
 
void update_functional_type_with_actual_arguments (entity, list)
 
instruction MakeCallInst (entity, cons *)
 this function creates a call statement. More...
 
void MakeDoInst (syntax, range, string)
 this function creates a do loop statement. More...
 
void MakeWhileDoInst (expression, string)
 This function creates a while do loop statement. More...
 
expression fix_if_condition (expression)
 
instruction MakeLogicalIfInst (expression, instruction)
 this function creates a logical if statement. More...
 
instruction MakeArithmIfInst (expression, string, string, string)
 this function transforms an arithmetic if statement into a set of regular tests. More...
 
void MakeBlockIfInst (expression, int)
 this function and the two next ones create a block if statement. More...
 
int MakeElseInst (bool)
 This function is used to handle either an ELSE or an ELSEIF construct. More...
 
void MakeEndifInst (void)
 
void MakeEnddoInst (void)
 
string NameOfToken (int)
 
statement make_check_io_statement (string, expression, entity)
 Generate a test to jump to l if flag f is TRUE Used to implement control effects of IO's due to ERR= and END=. More...
 
instruction MakeIoInstA (int, list, list)
 this function creates an IO statement. More...
 
instruction MakeIoInstB (int, expression, expression, expression, expression)
 this function creates a BUFFER IN or BUFFER OUT io statement. More...
 
instruction MakeSimpleIoInst1 (int, expression unit)
 
instruction MakeSimpleIoInst2 (int, expression, list)
 
void reset_first_statement (void)
 
void set_first_format_statement (void)
 
bool first_executable_statement_seen (void)
 
bool first_format_statement_seen (void)
 
void check_in_declarations (void)
 
void check_first_statement (void)
 This function is called each time an executable statement is encountered but is effective the first time only. More...
 
void SubstituteAlternateReturns (const char *)
 return.c More...
 
bool SubstituteAlternateReturnsP (void)
 
entity GetReturnCodeVariable (void)
 
bool ReturnCodeVariableP (entity)
 
void ResetReturnCodeVariable (void)
 
bool uses_alternate_return_p (void)
 
void uses_alternate_return (bool)
 
void set_current_number_of_alternate_returns (void)
 
void reset_current_number_of_alternate_returns (void)
 
int get_current_number_of_alternate_returns (void)
 
list add_formal_return_code (list)
 Update the formal and actual parameter lists by adding the return code variable as last argument. More...
 
list add_actual_return_code (list)
 
void add_alternate_return (string)
 
list get_alternate_returns (void)
 
void set_alternate_returns (void)
 
void reset_alternate_returns (void)
 
void soft_reset_alternate_returns (void)
 ParserError() cannot guess if it has been performed or not, because it is reinitialized before and after each call statement. More...
 
instruction generate_return_code_checks (list)
 
instruction MakeReturn (expression)
 
void GenerateReturn (void)
 Generate a unique call to RETURN per module. More...
 
void print_malloc_info (FILE *)
 malloc-info.c More...
 
void print_full_malloc_info (FILE *)
 
void parser_init_macros_support (void)
 macros.c More...
 
void parser_close_macros_support (void)
 
bool parser_entity_macro_p (entity)
 
void parser_add_a_macro (call, expression)
 
void reset_substitute_expression_in_expression (void)
 
void parser_macro_expansion (expression)
 
void parser_substitute_all_macros (statement)
 
void parser_substitute_all_macros_in_expression (expression)
 
void syn_restart (FILE *)
 
void syn_pop_buffer_state (void)
 
int syn_get_lineno (void)
 
FILE * syn_get_in (void)
 
FILE * syn_get_out (void)
 
int syn_get_leng (void)
 
char * syn_get_text (void)
 
void syn_set_lineno (int)
 
void syn_set_in (FILE *)
 
void syn_set_out (FILE *)
 
int syn_get_debug (void)
 
void syn_set_debug (int)
 
int syn_lex_destroy (void)
 
void * syn_alloc (yy_size_t)
 
void * syn_realloc (void *, yy_size_t)
 
void syn_free (void *)
 

Variables

FILE * syn_in
 lex yacc interface More...
 
entity DynamicArea
 These global variables are declared in ri-util/util.c. More...
 
entity StaticArea
 
entity HeapArea
 
entity StackArea
 
entity AllocatableArea
 
char vcid_syntax_expression []
 expression.c More...
 
char vcid_syntax_equivalence []
 equivalence.c More...
 
char * CurrentFN
 parser.c More...
 
consFormalParameters
 the current function More...
 
const char * CurrentPackage
 the name of the current package, i.e. More...
 
int line_b_I
 Indicates where the current instruction (in fact statement) starts and ends in the input file and gives its label. More...
 
int line_e_I
 
int line_b_C
 
int line_e_C
 
char lab_I [6]
 
char FormatValue [(4096)]
 a string that will contain the value of the format in case of format statement More...
 
bool InParserError
 Parser error handling. More...
 
char * Comm
 reader.c More...
 
char * PrevComm
 
char * CurrComm
 
int iComm
 
int iPrevComm
 
int iCurrComm
 
int ici
 syn_yacc.c More...
 
type CurrentType
 to count control specifications in IO statements More...
 
intptr_t CurrentTypeSize
 the type in a type or dimension or common statement More...
 
int syn_char
 
int syn_nerrs
 
int syn_leng
 scanner.c More...
 
FILE * syn_out
 
int syn_lineno
 
int syn__flex_debug
 
char * syn_text
 

Macro Definition Documentation

◆ abs

#define abs (   v)    (((v) < 0) ? -(v) : (v))

Definition at line 56 of file syntax.h.

◆ FatalError

#define FatalError (   f,
 
)    (pips_internal_error("Fatal error between lines %d and %d\n%s\n",line_b_I,line_e_I,m))

Definition at line 64 of file syntax.h.

◆ FORMATLENGTH

#define FORMATLENGTH   (4096)

Definition at line 52 of file syntax.h.

◆ HASH_SIZE

#define HASH_SIZE   1013

definition of implementation dependent constants

Definition at line 51 of file syntax.h.

◆ LOCAL

#define LOCAL   static

Definition at line 53 of file syntax.h.

◆ START_COMMENT_LINE

#define START_COMMENT_LINE   "CcDd*!#\n"

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

Modify src/Libs/syntax/syntax-local.h instead, to add your own modifications. header file built by cproto syntax-local.h Legal characters to start a comment line

'
' is added to cope with empty lines Empty lines with SPACE and TAB characters are be preprocessed and reduced to an empty line by GetChar().

Definition at line 38 of file syntax.h.

◆ Warning

#define Warning (   f,
 
)    (user_warning(f,"Warning between lines %d and %d\n%s\n",line_b_I,line_e_I,m) )

extern char * getenv();

Definition at line 61 of file syntax.h.

Function Documentation

◆ AbortEntries()

void AbortEntries ( void  )

Useless entities should be reset

the current module statement is used when processing entries

Definition at line 1473 of file procedure.c.

1474 {
1475  /* Useless entities should be reset */
1476 
1477  MAP(ENTITY, el, {
1478  free_entity(el);
1479  }, entry_labels);
1481  entry_labels = NIL;
1482 
1483  MAP(ENTITY, et, {
1484  free_entity(et);
1485  }, entry_targets);
1487  entry_targets = NIL;
1488 
1489  MAP(ENTITY, ee, {
1490  CleanLocalEntities(ee);
1491  free_entity(ee);
1492  }, entry_entities);
1494  entry_entities = NIL;
1495 
1496  MAP(ENTITY, efp, {
1497  free_entity(efp);
1498  }, entry_targets);
1501 
1502  /* the current module statement is used when processing entries */
1504 }
void free_entity(entity p)
Definition: ri.c:2524
void CleanLocalEntities(entity function)
Fortran version.
Definition: clean.c:140
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
static list entry_entities
Definition: procedure.c:1455
static list effective_formal_parameters
Definition: procedure.c:1456
static list entry_labels
Processing of entries: when an ENTRY statement is encountered, it is replaced by a labelled CONTINUE ...
Definition: procedure.c:1453
static list entry_targets
Definition: procedure.c:1454
void error_reset_current_module_statement(void)
To be called by an error management routine only.
Definition: static.c:234
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755

References CleanLocalEntities(), effective_formal_parameters, ENTITY, entry_entities, entry_labels, entry_targets, error_reset_current_module_statement(), free_entity(), gen_free_list(), MAP, and NIL.

Referenced by ParserError().

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

◆ AbortOfProcedure()

void AbortOfProcedure ( void  )

get rid of ghost variable entities

Definition at line 386 of file procedure.c.

387 {
388  /* get rid of ghost variable entities */
391 
392  (void) ResetBlockStack() ;
393 }
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
static list ghost_variable_entities
list of potential local or top-level variables that turned out to be useless.
Definition: procedure.c:67
void remove_ghost_variable_entities(bool substitute_p)
Definition: procedure.c:206
void ResetBlockStack()
Definition: statement.c:203

References ghost_variable_entities, list_undefined_p, remove_ghost_variable_entities(), and ResetBlockStack().

Referenced by ParserError().

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

◆ add_actual_return_code()

list add_actual_return_code ( list  apl)
Parameters
aplpl

Definition at line 222 of file return.c.

223 {
224  list new_apl = apl;
225 
228 
229  new_apl = gen_nconc(apl, CONS(EXPRESSION, entity_to_expression(frc), NIL));
230  }
231 
232  return new_apl;
233 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
static entity GetFullyDefinedReturnCodeVariable()
Definition: return.c:115
static bool hide_rc_p
Definition: return.c:54
list get_alternate_returns()
Definition: return.c:258
static bool substitute_rc_p
Handling of RETURN statements and substitution of alternate returns.
Definition: return.c:52

References CONS, ENDP, entity_to_expression(), EXPRESSION, gen_nconc(), get_alternate_returns(), GetFullyDefinedReturnCodeVariable(), hide_rc_p, NIL, and substitute_rc_p.

Referenced by MakeCallInst().

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

◆ add_alternate_return()

void add_alternate_return ( string  label_name)
Parameters
label_nameabel_name

Definition at line 242 of file return.c.

243 {
245 
246  if(substitute_rc_p) {
247  l = MakeLabel(label_name);
249  }
250  else {
251  pips_user_warning("Lines %d-%d: Alternate return towards label %s not supported. "
252  "Actual label argument internally substituted by a character string.\n",
253  line_b_I, line_e_I, label_name);
254  }
255 }
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
#define pips_user_warning
Definition: misc-local.h:146
#define entity_undefined
Definition: ri.h:2761
int line_e_I
Definition: parser.c:68
int line_b_I
Indicates where the current instruction (in fact statement) starts and ends in the input file and giv...
Definition: parser.c:68
static list alternate_returns
Keep track of the labels used as actual arguments for alternate returns and generate the tests to che...
Definition: return.c:239
entity MakeLabel(char *s) const
This functions creates a label.
Definition: statement.c:257

References alternate_returns, arguments_add_entity(), entity_undefined, line_b_I, line_e_I, MakeLabel(), pips_user_warning, and substitute_rc_p.

+ Here is the call graph for this function:

◆ add_entity_to_declarations()

void add_entity_to_declarations ( string  name,
string  area_name,
enum basic_utype  tag,
void *  val 
)

FI: I do not understand the naming here, or the parameter.

The name of the new variable must be a global name, whereas the name of the area is a local name. And the area does not have to be the stack area...

Why is this variable called "stack area" when it can be any area?

Parameters
nameame
area_namerea_name
valal

Definition at line 1969 of file declaration.c.

1970  {
1971  entity new_e = FindOrCreateTopLevelEntity (name);
1972  basic b = make_basic (tag, val);
1973  variable v = make_variable (b, NIL, NIL);
1974  entity_type (new_e) = make_type_variable (v);
1976  /* Why is this variable called "stack area" when it can be any area? */
1977  entity stack_area = FindEntity(module_name, area_name);
1979  stack_area,
1980  CurrentOffsetOfArea(stack_area, new_e),
1981  NIL));
1982  entity_storage (new_e) = s;
1983  value initial = make_value_unknown ();
1984  entity_initial (new_e) = initial;
1987 }
value make_value_unknown(void)
Definition: ri.c:2847
type make_type_variable(variable _field_)
Definition: ri.c:2715
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
storage make_storage_ram(ram _field_)
Definition: ri.c:2279
int CurrentOffsetOfArea(entity a, entity v)
Definition: declaration.c:1195
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
int tag
TAG.
Definition: newgen_types.h:92
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
entity FindOrCreateTopLevelEntity(const char *name)
Return a top-level entity.
Definition: entity.c:1603
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
void discard_module_declaration_text(entity)
Discard the decls_text string of the module code to make the prettyprinter ignoring the textual decla...
Definition: variable.c:1696
#define entity_storage(x)
Definition: ri.h:2794
#define entity_type(x)
Definition: ri.h:2792
#define entity_initial(x)
Definition: ri.h:2796

References AddEntityToDeclarations(), CurrentOffsetOfArea(), discard_module_declaration_text(), entity_initial, entity_storage, entity_type, FindEntity(), FindOrCreateTopLevelEntity(), get_current_module_entity(), make_basic(), make_ram(), make_storage_ram(), make_type_variable(), make_value_unknown(), make_variable(), module_local_name(), module_name(), and NIL.

+ Here is the call graph for this function:

◆ add_formal_return_code()

list add_formal_return_code ( list  fpl)

Update the formal and actual parameter lists by adding the return code variable as last argument.

To avoid an explicit check in gram.y which is large enough, the additions are conditional to the alternate return substitution.

Type, storage and initial value are set up later in MakeFormalParameter()

Parameters
fplpl

Definition at line 209 of file return.c.

210 {
211  list new_fpl = fpl;
212 
215 
216  /* Type, storage and initial value are set up later in MakeFormalParameter() */
217  new_fpl = gen_nconc(fpl, CONS(ENTITY, frc, NIL));
218  }
219  return new_fpl;
220 }
entity GetReturnCodeVariable()
Definition: return.c:95
bool uses_alternate_return_p()
Definition: return.c:166

References CONS, ENTITY, gen_nconc(), GetReturnCodeVariable(), hide_rc_p, NIL, substitute_rc_p, and uses_alternate_return_p().

Referenced by MakeCurrentFunction().

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

◆ add_ghost_variable_entity()

void add_ghost_variable_entity ( entity  e)

Definition at line 275 of file procedure.c.

276 {
279 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References arguments_add_entity(), ghost_variable_entities, list_undefined_p, and pips_assert.

Referenced by SafeLocalToGlobal().

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

◆ AddEffectiveFormalParameter()

void AddEffectiveFormalParameter ( entity  f)

Keep track of the formal parameters for the current module.

Definition at line 1529 of file procedure.c.

1530 {
1532 }
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15

References arguments_add_entity(), effective_formal_parameters, and f().

Referenced by MakeEntry().

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

◆ AddEntryEntity()

void AddEntryEntity ( entity  e)

Definition at line 1523 of file procedure.c.

1524 {
1526 }

References arguments_add_entity(), and entry_entities.

Referenced by MakeEntry().

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

◆ AddEntryLabel()

void AddEntryLabel ( entity  l)

Definition at line 1513 of file procedure.c.

1514 {
1516 }

References arguments_add_entity(), and entry_labels.

Referenced by MakeEntry().

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

◆ AddEntryTarget()

void AddEntryTarget ( statement  s)

Definition at line 1518 of file procedure.c.

1519 {
1521 }
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References CONS, entry_targets, gen_nconc(), NIL, and STATEMENT.

Referenced by MakeEntry().

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

◆ AddOrMergeChain()

int AddOrMergeChain ( chain  ct)

this function adds a chain ct to the set of equivalences.

if the intersection with all other chains is empty, ct is just added to the set. Otherwise ct is merged with the chain that intersects ct.

Parameters
ctt

Definition at line 269 of file equivalence.c.

271 {
272  cons *pcl, *pcf, *pct;
273 
274  pct = chain_atoms(ct);
275  chain_atoms(ct) = NIL;
276 
277  for (pcl = equivalences_chains(FinalEquivSet); pcl != NIL; pcl=CDR(pcl)) {
278  chain cf;
279 
280  cf = CHAIN(CAR(pcl));
281  pcf = chain_atoms(cf);
282 
283  if (ChainIntersection(pct, pcf)) {
284  chain_atoms(cf) = MergeTwoChains(pct, pcf);
285  return(EQUIMERGE);
286  }
287  }
288 
290  CONS(CHAIN, make_chain(pct),
292 
293  return(EQUIADD);
294 }
chain make_chain(list a)
#define EQUIADD
lint
Definition: equivalence.c:54
#define EQUIMERGE
Definition: equivalence.c:55
cons * MergeTwoChains(cons *opc1, cons *opc2)
this function merges two equivalence chains whose intersection is not empty, ie.
Definition: equivalence.c:322
static equivalences FinalEquivSet
Definition: equivalence.c:60
int ChainIntersection(cons *opc1, cons *opc2)
this function returns true if the there is a variable that occurs in both atom lists.
Definition: equivalence.c:302
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define CHAIN(x)
CHAIN.
#define chain_atoms(x)
#define equivalences_chains(x)

References CAR, CDR, CHAIN, chain_atoms, ChainIntersection(), CONS, EQUIADD, EQUIMERGE, equivalences_chains, FinalEquivSet, make_chain(), MergeTwoChains(), and NIL.

Referenced by ComputeEquivalences().

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

◆ AddVariableToCommon()

void AddVariableToCommon ( entity  c,
entity  v 
)

This function adds a variable v to a common block c.

v's storage must be undefined.

c's size used to be indirectly updated by CurrentOffsetOfArea() but this is meaningless because v's type and dimensions are unknown. The layouts of commons are updated later by update_common_sizes() called from EndOfProcedure().

Definition at line 1108 of file declaration.c.

1109 {
1110  entity new_v = entity_undefined;
1111  type ct = entity_type(c);
1112  area ca = type_area(ct);
1113 
1114  if (entity_storage(v) != storage_undefined) {
1115  if(intrinsic_entity_p(v)) {
1117  entity_local_name(v));
1118  user_warning("AddVariableToCommon",
1119  "Intrinsic %s overloaded by variable %s between line %d and %d\n",
1121  if(type_undefined_p(entity_type(new_v))) {
1122  entity_type(new_v) = ImplicitType(new_v);
1123  }
1124  }
1125  else if(storage_rom_p(entity_storage(v))) {
1126  user_warning("AddVariableToCommon",
1127  "Module or parameter %s declared in common %s between line %d and %d\n",
1129  ParserError("AddVariableToCommon",
1130  "Ill. decl. of function or subroutine in a common\n");
1131  }
1132  else {
1134 
1136  pips_user_warning("Variable %s has conflicting requirements"
1137  " for storage (e.g. it appears in a DATA"
1138  " and in a COMMON statement in a non "
1139  "BLOCKDATA module\n", entity_local_name(v));
1140  ParserError("AddVariableToCommon", "Storage conflict\n");
1141  }
1142  else {
1143  if(entity_blockdata_p(m)) {
1144  pips_user_warning("ANSI extension: specification statements"
1145  " after DATA statement for variable %s\n",
1146  entity_local_name(v));
1147  ParserError("AddVariableToCommon", "Storage conflict\n");
1148  }
1149  else {
1150  user_warning("AddVariableToCommon",
1151  "Storage tag=%d for entity %s\n",
1153  FatalError("AddVariableToCommon", "storage already defined\n");
1154  }
1155  }
1156  }
1157  }
1158  else {
1159  new_v = v;
1160  }
1161 
1162  DeclareVariable(new_v,
1163  type_undefined,
1164  NIL,
1167  0, // UNKNOWN_RAM_OFFSET?
1168  NIL)))),
1169  value_undefined);
1170 
1171  area_layout(ca) = gen_nconc(area_layout(ca), CONS(ENTITY, v, NIL));
1172 }
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
bool value_defined_p(value p)
Definition: ri.c:2797
void DeclareVariable(entity e, type t, list d, storage s, value v)
void DeclareVariable(e, t, d, s, v): update entity e description as declaration statements are encoun...
Definition: declaration.c:670
type ImplicitType(entity e)
This function computes the Fortran implicit type of entity e.
Definition: declaration.c:1311
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
#define user_warning(fn,...)
Definition: misc-local.h:262
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
bool entity_blockdata_p(entity e)
Definition: entity.c:712
#define value_undefined
Definition: ri.h:3016
#define storage_tag(x)
Definition: ri.h:2515
@ is_storage_ram
Definition: ri.h:2492
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_name(x)
Definition: ri.h:2790
#define area_layout(x)
Definition: ri.h:546
#define type_area(x)
Definition: ri.h:2946
#define type_undefined
Definition: ri.h:2883
#define storage_rom_p(x)
Definition: ri.h:2525
#define storage_undefined
Definition: ri.h:2476
#define FatalError(f, m)
Definition: syntax-local.h:56
bool ParserError(const char *f, const char *m)
Definition: parser.c:116

References area_layout, CONS, DeclareVariable(), ENTITY, entity_blockdata_p(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, FatalError, FindOrCreateEntity(), gen_nconc(), get_current_module_entity(), get_current_module_name(), ImplicitType(), intrinsic_entity_p(), is_storage_ram, line_b_I, line_e_I, make_ram(), make_storage(), module_local_name(), NIL, ParserError(), pips_user_warning, storage_rom_p, storage_tag, storage_undefined, type_area, type_undefined, type_undefined_p, user_warning, value_defined_p(), and value_undefined.

+ Here is the call graph for this function:

◆ AnalyzeData()

void AnalyzeData ( list  ldvr,
list  ldvl 
)

this function scans at the same time a list of datavar and a list of dataval.

it tries to match datavar to dataval and to compute initial values for zero dimension variable of basic type integer.

ldvr is a list of datavar.

ldvl is a list of dataval.

FI: this assertion must be usually wrong! pips_assert("AnalyseData", gen_length(ldvr) == gen_length(ldvl));

Variable is in static area or in a user declared common

Variable must be in a user declared common

Variable must be in static area

entity e initial field is set here with the data information.

if (entity_defined_p(e))

Parameters
ldvrdvr
ldvldvl

Definition at line 352 of file declaration.c.

353 {
354  list pcr, pcl;
355  dataval dvl;
356 
357  /* FI: this assertion must be usually wrong!
358  * pips_assert("AnalyseData", gen_length(ldvr) == gen_length(ldvl));
359  */
360 
361  pips_debug(8, "number of reference groups: %td\n", gen_length(ldvr));
362 
363  pcl = ldvl;
364  dvl = DATAVAL(CAR(pcl));
365  for (pcr = ldvr; pcr != NIL && pcl != NIL; pcr = CDR(pcr))
366  {
367  datavar dvr = DATAVAR(CAR(pcr));
368  entity e = datavar_variable(dvr);
369  int i = datavar_nbelements(dvr);
370 
371  if (!entity_undefined_p(e))
372  {
373 
374  pips_debug(8, "Storage for entity %s must be static or made static\n",
375  entity_name(e));
376 
378  entity_storage(e) =
381  StaticArea,
383  NIL)));
384  }
385  else if(storage_ram_p(entity_storage(e))) {
388 
389  if(dynamic_area_p(s)) {
390  if(entity_blockdata_p(m)) {
392  ("Variable %s is declared dynamic in a BLOCKDATA\n",
393  entity_local_name(e));
394  ParserError("AnalyzeData",
395  "No dynamic variables in BLOCKDATA\n");
396  }
397  else {
398  SaveEntity(e);
399  }
400  }
401  else {
402  /* Variable is in static area or in a user declared common */
403  if(entity_blockdata_p(m)) {
404  /* Variable must be in a user declared common */
405  if(static_area_p(s)) {
407  ("DATA for variable %s declared is impossible:"
408  " it should be declared in a COMMON instead\n",
409  entity_local_name(e));
410  ParserError("AnalyzeData",
411  "Improper DATA declaration in BLOCKDATA");
412  }
413  }
414  else {
415  /* Variable must be in static area */
416  if(!static_area_p(s)) {
418  ("DATA for variable %s declared in COMMON %s:"
419  " not standard compliant,"
420  " use a BLOCKDATA\n",
422  if(!get_bool_property("PARSER_ACCEPT_ANSI_EXTENSIONS")) {
423  ParserError("AnalyzeData",
424  "Improper DATA declaration, use a BLOCKDATA"
425  " or set property PARSER_ACCEPT_ANSI_EXTENSIONS");
426  }
427  }
428  }
429  }
430  }
431  else {
432  user_warning("AnalyzeData",
433  "DATA initialization for non RAM variable %s "
434  "(storage tag = %d)\n",
436  ParserError("AnalyzeData",
437  "DATA statement initializes non RAM variable\n");
438  }
439 
440  pips_debug(8, "needs %d elements for entity %s\n",
441  i, entity_name(e));
442 
443  pips_assert("AnalyzeData", dataval_nboccurrences(dvl) > 0);
444 
445  /* entity e initial field is set here with the data information.
446  */
447  if (entity_scalar_p(e))
448  {
449  constant cst = dataval_constant(dvl);
450 
451  pips_assert("AnalyzeData", i == 1);
452 
453  if (constant_int_p(cst) || constant_call_p(cst))
454  {
457  {
458  value old = entity_initial(e);
460  copy_constant(cst));
461  free_value(old);
462  }
463  else
464  {
465  pips_user_warning("Conflicting initial values for variable %s\n",
466  entity_local_name(e));
467  ParserError("AnalyzeData", "Too many initial values");
468  }
469  }
470  else
471  {
472  Warning("AnalyzeData",
473  "Integer scalar variable initialized "
474  "with non-integer constant");
475  }
476  }
477 
478  } /* if (entity_defined_p(e)) */
479 
480  while (i > 0 && pcl != NIL)
481  {
482  if (i <= dataval_nboccurrences(dvl)) {
483  pips_debug(8, "uses %d values out of %td\n",
484  i, dataval_nboccurrences(dvl));
485  dataval_nboccurrences(dvl) -= i;
486  i = 0;
487  }
488  else {
489  pips_debug(8, "satisfies %td references out of %d\n",
490  dataval_nboccurrences(dvl), i);
491  i -= dataval_nboccurrences(dvl);
492  dataval_nboccurrences(dvl) = 0;
493  }
494 
495  if (dataval_nboccurrences(dvl) == 0) {
496  if ((pcl = CDR(pcl)) != NIL) {
497  dvl = DATAVAL(CAR(pcl));
498 
499  pips_debug(8, "use next dataval\n");
500  }
501  }
502  datavar_nbelements(dvr) = i;
503  }
504  }
505 
506  if (pcl != NIL) {
507  Warning("AnalyzeData", "too many initializers\n");
508  }
509 
510  if (pcr != NIL &&
511  (datavar_nbelements(DATAVAR(CAR(pcr))) != 0 || CDR(pcr) != NIL)) {
512  ParserError("AnalyzeData", "too few initializers\n");
513  }
514 }
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
constant copy_constant(constant p)
CONSTANT.
Definition: ri.c:359
void free_value(value p)
Definition: ri.c:2787
entity StaticArea
Definition: area.c:58
void SaveEntity(entity e)
These two functions transform a dynamic variable into a static one.
Definition: declaration.c:178
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
size_t gen_length(const list l)
Definition: list.c:150
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define DATAVAL(x)
DATAVAL.
#define datavar_nbelements(x)
#define dataval_constant(x)
#define DATAVAR(x)
DATAVAR.
#define dataval_nboccurrences(x)
#define datavar_variable(x)
#define UNKNOWN_RAM_OFFSET
bool dynamic_area_p(entity aire)
Definition: area.c:68
bool static_area_p(entity aire)
Definition: area.c:77
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_unknown_p(x)
Definition: ri.h:3077
@ is_value_constant
Definition: ri.h:3033
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define entity_undefined_p(x)
Definition: ri.h:2762
#define constant_int_p(x)
Definition: ri.h:848
#define constant_call_p(x)
Definition: ri.h:860
#define storage_ram(x)
Definition: ri.h:2521
#define storage_undefined_p(x)
Definition: ri.h:2477
#define Warning(f, m)
extern char * getenv();
Definition: syntax-local.h:53

References CAR, CDR, constant_call_p, constant_int_p, copy_constant(), DATAVAL, dataval_constant, dataval_nboccurrences, DATAVAR, datavar_nbelements, datavar_variable, dynamic_area_p(), entity_blockdata_p(), entity_initial, entity_local_name(), entity_name, entity_scalar_p(), entity_storage, entity_undefined_p, free_value(), gen_length(), get_bool_property(), get_current_module_entity(), is_storage_ram, is_value_constant, make_ram(), make_storage(), make_value(), module_local_name(), NIL, ParserError(), pips_assert, pips_debug, pips_user_warning, ram_section, SaveEntity(), static_area_p(), StaticArea, storage_ram, storage_ram_p, storage_tag, storage_undefined_p, UNKNOWN_RAM_OFFSET, user_warning, value_undefined_p, value_unknown_p, and Warning.

+ Here is the call graph for this function:

◆ append_data_current_stmt_buffer_to_declarations()

void append_data_current_stmt_buffer_to_declarations ( void  )

int[]

Definition at line 276 of file reader.c.

277 {
278  size_t i=0, j=0, column=6;
279  char * tmp = (char*) malloc(lStmt+200), * ndecls, * odecls;
281 
282  for (; i<lStmt; i++, j++, column++)
283  {
284  if (column==71)
285  {
286  tmp[j++] = '\n';
287  tmp[j++] = ' ';
288  tmp[j++] = ' ';
289  tmp[j++] = ' ';
290  tmp[j++] = ' ';
291  tmp[j++] = ' ';
292  tmp[j++] = 'x';
293  tmp[j++] = ' ';
294  tmp[j++] = ' ';
295  tmp[j++] = ' ';
296  tmp[j++] = ' ';
297  tmp[j++] = ' ';
298  column = 10;
299  }
300  tmp[j] = (char) stmt_buffer[i]; /* int[] */
301  }
302  stmt_buffer[i]='\0';
303  tmp[j] = '\0';
304 
305  odecls = code_decls_text(c);
306  ndecls = strdup(concatenate(odecls, "! moved up...\n DATA ",
307  tmp+4, 0));
308  free(odecls);
309  free(tmp);
310  code_decls_text(c) = ndecls;
311 }
void * malloc(YYSIZE_T)
void free(void *)
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
static int * stmt_buffer
le buffer contenant le statement courant, l'indice courant et la longueur.
Definition: reader.c:218
static size_t lStmt
Definition: reader.c:243
code EntityCode(entity e)
this function checks that e has an initial value code.
Definition: entity.c:301
#define code_decls_text(x)
Definition: ri.h:786
char * strdup()

References code_decls_text, concatenate(), EntityCode(), free(), get_current_module_entity(), lStmt, malloc(), stmt_buffer, and strdup().

+ Here is the call graph for this function:

◆ BeginingOfParsing()

void BeginingOfParsing ( void  )

this function is called for each new file (FI: once?) FI: I do not understand how this works.

It has an effect only once during a pips process lifetime. The error handling routine resets CurrentPackage to NULL, as it is when the pips process is started.

Should I:

A modify the error handling routine to reset CurrentPackage to TOP_LEVEL_MODULE_NAME?

B reset CurrentPackage to TOP_LEVEL_MODULE_NAME each time the parser is entered?

I choose A.

the current package is initialized

Definition at line 208 of file parser.c.

209 {
210  static bool called = false;
211 
212  if (called)
213  return;
214 
215  /* the current package is initialized */
217  called = true;
218 }
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
const char * CurrentPackage
the name of the current package, i.e.
Definition: parser.c:58

References CurrentPackage, and TOP_LEVEL_MODULE_NAME.

Referenced by the_actual_parser().

+ Here is the caller graph for this function:

◆ BeginingOfProcedure()

void BeginingOfProcedure ( void  )

this function is called each time a new procedure is encountered.

reset_current_module_entity();

Definition at line 301 of file procedure.c.

302 {
303  /* reset_current_module_entity(); */
304  InitImplicit();
306 }
void InitImplicit()
this function initializes the data structure used to compute implicit types
Definition: declaration.c:1271
static list called_modules
list of called subroutines or functions
Definition: procedure.c:57

References called_modules, InitImplicit(), and NIL.

+ Here is the call graph for this function:

◆ CapitalizeStmt()

int CapitalizeStmt ( char  s[],
int  i 
)

la 1ere lettre n'est pas modifiee

Definition at line 1308 of file reader.c.

1309 {
1310  int l = i+strlen(s);
1311 
1312  if ((size_t) l <= lStmt) {
1313  /* la 1ere lettre n'est pas modifiee */
1314  i += 1;
1315  while (i < l) {
1316  stmt_buffer[i] = tolower(stmt_buffer[i]);
1317  i += 1;
1318  }
1319  }
1320  else {
1321  ParserError("CapitalizeStmt",
1322  "[scanner] internal error in CapitalizeStmt\n");
1323  }
1324 
1325  return(i);
1326 }

References lStmt, ParserError(), and stmt_buffer.

Referenced by FindAssign(), FindAutre(), FindDo(), FindDoWhile(), FindIf(), FindIfArith(), FindImplicit(), and NeedKeyword().

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

◆ ChainIntersection()

int ChainIntersection ( cons opc1,
cons opc2 
)

this function returns true if the there is a variable that occurs in both atom lists.

Parameters
opc1pc1
opc2pc2

Definition at line 302 of file equivalence.c.

304 {
305  cons *pc1, *pc2;
306 
307  for (pc1 = opc1; pc1 != NIL; pc1 = CDR(pc1))
308  for (pc2 = opc2; pc2 != NIL; pc2 = CDR(pc2))
309  if (gen_eq((atom_equivar(ATOM(CAR(pc1)))),
310  (atom_equivar(ATOM(CAR(pc2))))))
311  return(true);
312 
313  return(false);
314 }
bool gen_eq(const void *obj1, const void *obj2)
Definition: list.c:111
#define ATOM(x)
newgen_equivalences_domain_defined
#define atom_equivar(x)

References ATOM, atom_equivar, CAR, CDR, gen_eq(), and NIL.

Referenced by AddOrMergeChain().

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

◆ check_first_statement()

void check_first_statement ( void  )

This function is called each time an executable statement is encountered but is effective the first time only.

It mainly copies the declaration text in the symbol table because it is impossible (very difficult) to reproduce it in a user-friendly manner.

The declaration text stops at the first executable statement or at the first FORMAT statement.

dynamic local buffer

we must read the input file from the begining and up to the line_b_I-1 th line, and the texte read must be stored in buffer

declaration_lines = line_b_I-1;

buffer[ibuffer++] = in_comment? c : toupper(c);

Constant strings must be taken care of

Standard version

For Cathare-2, get rid of 100 to 200 MB of declaration text:

strdup(buffer);

free(buffer), buffer=NULL;

kill the first statement's comment because it's already included in the declaration text

FI: I'd rather keep them together!

clean up the declarations

Common sizes are not yet known because ComputeAddresses() has not been called yet

update_common_sizes();

It might seem logical to perform these calls from EndOfProcedure() here. But at least ComputeAddresses() is useful for implictly declared variables. These calls are better located in EndOfProcedure().

Definition at line 2004 of file statement.c.

2005 {
2006  int line_start = true;
2007  int in_comment = false;
2008  int out_of_constant_string = true;
2009  int in_constant_string = false;
2010  int end_of_constant_string = false;
2011  char string_sep = '\000';
2012 
2013  if (! seen)
2014  {
2015  FILE *fd;
2016  int cpt = 0, ibuffer = 0, c;
2017 
2018  /* dynamic local buffer
2019  */
2020  int buffer_size = 1000;
2021  char * buffer = (char*) malloc(buffer_size);
2022  pips_assert("malloc ok", buffer);
2023 
2024  seen = true;
2025 
2026  /* we must read the input file from the begining and up to the
2027  line_b_I-1 th line, and the texte read must be stored in buffer */
2028 
2029  if(!format_seen) {
2030  /* declaration_lines = line_b_I-1; */
2031  debug(8, "check_first_statement", "line_b_C=%d, line_b_I=%d\n",
2032  line_b_C, line_b_I);
2034  }
2035 
2036  fd = safe_fopen(CurrentFN, "r");
2037  while ((c = getc(fd)) != EOF) {
2038  if(line_start == true)
2039  in_comment = strchr(START_COMMENT_LINE,c) != NULL;
2040  /* buffer[ibuffer++] = in_comment? c : toupper(c); */
2041  if(in_comment) {
2042  buffer[ibuffer++] = c;
2043  }
2044  else {
2045  /* Constant strings must be taken care of */
2046  if(out_of_constant_string) {
2047  if(c=='\'' || c == '"') {
2048  string_sep = c;
2049  out_of_constant_string = false;
2050  in_constant_string = true;
2051  buffer[ibuffer++] = c;
2052  }
2053  else {
2054  buffer[ibuffer++] = toupper(c);
2055  }
2056  }
2057  else
2058  if(in_constant_string) {
2059  if(c==string_sep) {
2060  in_constant_string = false;
2061  end_of_constant_string = true;
2062  }
2063  buffer[ibuffer++] = c;
2064  }
2065  else
2066  if(end_of_constant_string) {
2067  if(c==string_sep) {
2068  in_constant_string = true;
2069  end_of_constant_string = false;
2070  buffer[ibuffer++] = c;
2071  }
2072  else {
2073  out_of_constant_string = true;
2074  end_of_constant_string = false;
2075  buffer[ibuffer++] = toupper(c);
2076  }
2077  }
2078  }
2079 
2080  if (ibuffer >= buffer_size-10)
2081  {
2082  pips_assert("buffer initialized", buffer_size>0);
2083  buffer_size*=2;
2084  buffer = (char*) realloc(buffer, buffer_size);
2085  pips_assert("realloc ok", buffer);
2086  }
2087 
2088  if (c == '\n') {
2089  cpt++;
2090  line_start = true;
2091  in_comment = false;
2092  }
2093  else {
2094  line_start = false;
2095  }
2096 
2097  if (cpt == declaration_lines)
2098  break;
2099  }
2100  safe_fclose(fd, CurrentFN);
2101  buffer[ibuffer++] = '\0';
2102  /* Standard version */
2104  buffer = NULL;
2105  /* For Cathare-2, get rid of 100 to 200 MB of declaration text: */
2106  /*
2107  code_decls_text(EntityCode(get_current_module_entity())) = strdup("");
2108  free(buffer);
2109  */
2110  /* strdup(buffer); */
2111  /* free(buffer), buffer=NULL; */
2112 
2113  /* kill the first statement's comment because it's already
2114  included in the declaration text */
2115  /* FI: I'd rather keep them together! */
2116  /*
2117  PrevComm[0] = '\0';
2118  iPrevComm = 0;
2119  */
2120  /*
2121  Comm[0] = '\0';
2122  iComm = 0;
2123  */
2124 
2125  /* clean up the declarations */
2126  /* Common sizes are not yet known because ComputeAddresses() has not been called yet */
2127  /* update_common_sizes(); */
2128 
2129  /* It might seem logical to perform these calls from EndOfProcedure()
2130  * here. But at least ComputeAddresses() is useful for implictly
2131  * declared variables.
2132  * These calls are better located in EndOfProcedure().
2133  */
2134  /*
2135  * UpdateFunctionalType(FormalParameters);
2136  *
2137  * ComputeEquivalences();
2138  * ComputeAddresses();
2139  *
2140  * check_common_layouts(get_current_module_entity());
2141  *
2142  * SaveChains();
2143  */
2144  }
2145 }
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
static int cpt
Definition: stats.c:41
static size_t buffer_size
Definition: string.c:114
static string buffer
Definition: string.c:113
#define START_COMMENT_LINE
Legal characters to start a comment line.
Definition: syntax-local.h:30
char * CurrentFN
Pre-parser for Fortran syntax idiosyncrasy.
Definition: parser.c:49
int line_b_C
Definition: parser.c:68
static int format_seen
Definition: statement.c:1935
static int seen
Are we in the declaration or in the executable part? Have we seen a FORMAT statement before an execut...
Definition: statement.c:1934
#define UNDEF
Well, some constant defined in reader.c and not deserving a promotion in syntax-local....
Definition: statement.c:1941
static int declaration_lines
Definition: statement.c:1936

References buffer, buffer_size, code_decls_text, cpt, CurrentFN, debug(), declaration_lines, EntityCode(), format_seen, get_current_module_entity(), line_b_C, line_b_I, malloc(), pips_assert, safe_fclose(), safe_fopen(), seen, START_COMMENT_LINE, and UNDEF.

+ Here is the call graph for this function:

◆ check_in_declarations()

void check_in_declarations ( void  )

A FORMAT statement has been found in the middle of the declarations

Definition at line 1976 of file statement.c.

1977 {
1978  if(seen) {
1979  ParserError("Syntax",
1980  "Declaration appears after executable statement");
1981  }
1982  else if(format_seen && !seen) {
1983  /* A FORMAT statement has been found in the middle of the declarations */
1984  if(!get_bool_property("PRETTYPRINT_ALL_DECLARATIONS")) {
1985  pips_user_warning("FORMAT statement within declarations. In order to "
1986  "analyze this code, "
1987  "please set property PRETTYPRINT_ALL_DECLARATIONS "
1988  "or move this FORMAT down in executable code.\n");
1989  ParserError("Syntax", "Source cannot be parsed with current properties");
1990  }
1991  }
1992 }

References format_seen, get_bool_property(), ParserError(), pips_user_warning, and seen.

+ Here is the call graph for this function:

◆ CheckAndInitializeStmt()

void CheckAndInitializeStmt ( void  )

this function looks for undefined labels.

a label is undefined if a goto to that label has been encountered and if no statement with this label has been parsed.

Definition at line 113 of file statement.c.

114 {
115  int i;
116  int MustStop = false;
117 
118  for (i = 0; i < CurrentStmt; i++) {
119  statement s = StmtHeap_buffer[i].s;
121  MustStop = true;
122  user_warning("CheckAndInitializeStmt", "Undefined label \"%s\"\n",
124  }
125  }
126 
127  if (MustStop) {
128  ParserError("CheckAndInitializeStmt", "Undefined label(s)\n");
129  }
130  else {
131  CurrentStmt = 0;
132  }
133 }
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
#define instruction_undefined
Definition: ri.h:1454
#define statement_label(x)
Definition: ri.h:2450
#define statement_instruction(x)
Definition: ri.h:2458
statement s
the name of the label
Definition: statement.c:56
static stmt * StmtHeap_buffer
Definition: statement.c:59
static int CurrentStmt
Definition: statement.c:61

References CurrentStmt, instruction_undefined, label_local_name(), ParserError(), stmt::s, statement_instruction, statement_label, StmtHeap_buffer, and user_warning.

Referenced by EndOfProcedure().

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

◆ CheckLeftHandSide()

syntax CheckLeftHandSide ( syntax  s)

If a left hand side is a call, it should be a substring operator or a macro.

If it is a call to an intrinsic with no arguments, the intrinsic is in fact masqued by a local variable.

If s is not OK, it is freed and a new_s is allocated.

OK for substrings: They are processed later by MakeAssignInst()

Oupss... This must be a local variable

A call to an intrinsic cannot be a lhs: statement function? Let's hope it works...

Must be a macro...

Definition at line 542 of file expression.c.

543 {
544  syntax new_s = syntax_undefined;
545 
546  if(syntax_reference_p(s)) {
548  type vt = entity_type(v);
549 
550  if(type_variable_p(vt))
551  new_s = s;
552  else
553  pips_user_error("Illegal assignment to variable %s with type %s\n",
555  }
556  else {
557  call c = syntax_call(s);
558  entity f = call_function(c);
559 
560  if(intrinsic_entity_p(f)) {
561  if(strcmp(entity_local_name(f), SUBSTRING_FUNCTION_NAME)==0) {
562  /* OK for substrings: They are processed later by MakeAssignInst() */
563  pips_debug(7, "Substring assignment detected\n");
564  new_s = s;
565  }
566  else if(ENDP(call_arguments(c))) {
567  /* Oupss... This must be a local variable */
569 
570  user_warning("CheckLeftHandSide",
571  "Name conflict between local variable %s and intrinsics %s\n",
573 
574  free_syntax(s);
577  }
578  else {
579  /* A call to an intrinsic cannot be a lhs: statement function?
580  Let's hope it works... */
581  user_warning("CheckLeftHandSide",
582  "Name conflict between statement function %s and intrinsics %s\n",
584  new_s = s;
585  }
586  }
587  else {
588  /* Must be a macro... */
589  pips_debug(2, "Statement function definition %s\n", entity_name(f));
590  new_s = s;
591  }
592  }
593 
594  return new_s;
595 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void free_syntax(syntax p)
Definition: ri.c:2445
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
#define pips_user_error
Definition: misc-local.h:147
void reify_ghost_variable_entity(entity e)
It is possible to change one's mind and effectively use an entity which was previously assumed useles...
Definition: procedure.c:284
#define SUBSTRING_FUNCTION_NAME
string type_to_string(const type)
type.c
Definition: type.c:51
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
@ is_syntax_reference
Definition: ri.h:2691
#define syntax_call(x)
Definition: ri.h:2736
#define syntax_undefined
Definition: ri.h:2676
#define call_arguments(x)
Definition: ri.h:711
#define type_variable_p(x)
Definition: ri.h:2947

References call_arguments, call_function, ENDP, entity_local_name(), entity_name, entity_type, f(), FindOrCreateEntity(), free_syntax(), get_current_module_name(), intrinsic_entity_p(), is_syntax_reference, make_reference(), make_syntax(), NIL, pips_debug, pips_user_error, reference_variable, reify_ghost_variable_entity(), SUBSTRING_FUNCTION_NAME, syntax_call, syntax_reference, syntax_reference_p, syntax_undefined, type_to_string(), type_variable_p, and user_warning.

+ Here is the call graph for this function:

◆ CheckParenthesis()

void CheckParenthesis ( void  )

Warning("CheckParenthesis",

Definition at line 1032 of file reader.c.

1033 {
1034  register size_t i;
1035  int parenthese = 0;
1036 
1037  ProfZeroVirg = ProfZeroEgal = false;
1038 
1039  for (i = 0; i < lStmt; i++) {
1040  if (!IS_QUOTED(stmt_buffer[i])) {
1041  if (parenthese == 0) {
1042  if (stmt_buffer[i] == ',')
1043  ProfZeroVirg = true;
1044  else if (stmt_buffer[i] == '=')
1045  ProfZeroEgal = true;
1046  }
1047  if(stmt_buffer[i] == '(') parenthese ++;
1048  if(stmt_buffer[i] == ')') parenthese --;
1049  }
1050  }
1051  if(parenthese < 0) {
1052  for (i=0; i < lStmt; i++)
1053  (void) putc((char) stmt_buffer[i], stderr);
1054  /* Warning("CheckParenthesis", */
1055  ParserError("CheckParenthesis",
1056  "unbalanced paranthesis (too many ')')\n"
1057  "Due to line truncation at column 72?\n");
1058  }
1059  if(parenthese > 0) {
1060  for (i=0; i < lStmt; i++)
1061  (void) putc((char) stmt_buffer[i], stderr);
1062  ParserError("CheckParenthesis",
1063  "unbalanced paranthesis (too many '(')\n"
1064  "Due to line truncation at column 72?\n");
1065  }
1066 }
LOCAL int ProfZeroEgal
Definition: reader.c:377
LOCAL int ProfZeroVirg
Definition: reader.c:377
#define IS_QUOTED(c)
Definition: reader.c:122

References IS_QUOTED, lStmt, ParserError(), ProfZeroEgal, ProfZeroVirg, and stmt_buffer.

Referenced by PipsGetc().

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

◆ common_to_defined_size_p()

bool common_to_defined_size_p ( entity  a)

Definition at line 980 of file declaration.c.

981 {
982  bool defined = false;
983 
984  defined = ( (hash_get(common_size_map,(char *) a))
986 
987  return defined;
988 }
static hash_table common_size_map
Definition: declaration.c:935
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

References common_size_map, hash_get(), and HASH_UNDEFINED_VALUE.

Referenced by MakeCommon().

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

◆ common_to_size()

size_t common_to_size ( entity  a)

Definition at line 990 of file declaration.c.

991 {
992  size_t size;
993 
994  if((size = (size_t) hash_get(common_size_map,(char *) a))
995  == (size_t) HASH_UNDEFINED_VALUE) {
996  pips_internal_error("common_size_map uninitialized for common %s",
997  entity_name(a));
998  }
999 
1000  return size;
1001 }
#define pips_internal_error
Definition: misc-local.h:149

References common_size_map, entity_name, hash_get(), HASH_UNDEFINED_VALUE, and pips_internal_error.

Referenced by ComputeAddresses(), CurrentOffsetOfArea(), fortran_relevant_area_entity_p(), update_common_layout(), and update_common_sizes().

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

◆ ComputeAddresses()

void ComputeAddresses ( void  )

This function computes an address for every variable.

Three different cases are adressed: variables in user-declared commons, static variables and dynamic variables.

Variables may have:

  • an undefined storage because they have the default dynamic storage or because they should inherit their storage from an equivalence chain. The inherited storage can be "user-declared common", "static" or even "dynamic".
  • a user-declared common storage. The offsets of these variables can be computed from the common partial layout. Offsets for variables equivalenced to one of them are derived and the layouts are updated.
  • a static storage: the offset must be unknown on entrance in this function.
  • a dynamic storage: this is forbidden because there is no DYNAMIC declaration. The Fortran programmer does not have a way to enforce explictly a dynamic storage. All dynamic variables have an undefined storage upon entrance.
  • a non-ram storage: this obviously is forbidden.

All variables explictly declared in a common have a storage fully defined within this common (see update_common_layout() which must have been called before entering ComputeAddresses()). If such a variable occurs in an equivalence chain, all other variables of this chain will have an address in this common. The exact address depends on the offset stored in the atom.

The variables allocated in the static and dynamic areas are handled differently from variables explicitly declared in a common because the programmer does not have a direct control over the offset as within a common declaration. An arbitrary allocation is performed. The same kind of processing is done for chains containing a static variable or only dynamic variables (i.e. each variable in the chain has an undefined storage).

Static variables obviously have a partially defined storage since they are recognized as static.

Each equivalence chain should be either attached to a user-declared common or to the static area or to the dynamic area of the current module.

Static and dynamic chains are processed in a similar way. The size of each chain is computed and the space for the chain is allocated in the corresponding area. As for user-declared commons (but with no good reason?) only one representant of each chain is added to the layouts of the area.

When the processing of equivalenced variables is completed, non-equivalenced static or dynamic (i.e. variables with undefined storage) variables are allocated.

Finally equivalenced variables are appended to the layouts of the static and dynamic areas. This makes update_common_layout() unapplicable.

As a result, variables declared in the static and dynamic area are not ordered by increasing offsets.

the default section for variables with no address is the dynamic area.

Try to locate the area for the current equivalence chain. Only one variable should have a well-defined storage. Or no variables have one because the equivalence chain is located in the dynamic area.

Compute the total size of the chain. This only should be used for the static and dynamic areas

FI: I do not understand why this assignment is not better guarded. Maybe, because lc's later use is guarded.

A variable may be located in a static area because of a SAVE (?) or a DATA statement and be equivalenced with a variable in a common.

Same as above but in a different order

Let's hope this is due to a DATA and not to a SAVE

Compute the offset and set the storage information for each variable in the equivalence chain that has no storage yet.

check that the offset is positive

Static aliases cannot be added right away because implicitly declared static variables still have to be added whereas aliased variables are assumed to be put behind in the layout list. Except the first one.

Well, I'm not so sure!

Add e in sc'layout and check that sc's size does not have to be increased as for: COMMON /FOO/X REAL Y(100) EQUIVALENCE (X,Y)

Dynamic aliases cannot be added right away because implicitly declared dynamic variables still have to be added whereas aliased variables are assumed to be put behind in the layout list. Except the first one.

If sc really is a common, i.e. neither the dynamic nor the static area, check its size

Varying size arrays must be stack allocated. This is an implicit extension that is not compatible with EQUIVALENCE

This test will fail for stack allocatable varying length character strings because of function SizeOfElements() which cannot indicate failure. Let's wait for the problem...

Try to reallocate in stack area

Formal parameters can have varying sizes

Allocatable arrays can have varying sizes

Could be declared explicitly or implicitly STATIC or be EQUIVALENCEd with such a variable. It could be declared in a COMMON.

The array size is known at compile time. Allocate in synamic area.

All declared variables are scanned and stored in the dynamic area if their storage is still undefined or in the static area if their offsets are still unkown.

This should be the case for all non-aliased static variables and most dynamic variables.

area da = type_area(entity_type(DynamicArea));

area_layout(da) = gen_nconc(area_layout(da), CONS(ENTITY, e, NIL));

area sa = type_area(entity_type(StaticArea));

area_layout(sa) = gen_nconc(area_layout(sa), CONS(ENTITY, e, NIL));

Must be stack area

Add aliased dynamic variables

neither gen_concatenate() nor gen_append() are OK

side effect on area_layout

Add aliased static variables

neither gen_concatenate() nor gen_append() are OK

side effect on area_layout

The sizes of the static and dynamic areas are now known

Definition at line 503 of file equivalence.c.

504 {
505  cons *pcc, *pca, *pcv;
506  entity sc;
507  int lc, l, ac;
508  list dynamic_aliases = NIL;
509  list static_aliases = NIL;
510 
511  pips_debug(1, "Begin\n");
512 
514  for (pcc = equivalences_chains(FinalEquivSet); pcc != NIL;
515  pcc = CDR(pcc)) {
516  chain c = CHAIN(CAR(pcc));
517 
518  /* the default section for variables with no address is the dynamic
519  * area. */
520  sc = DynamicArea;
521  lc = 0;
522  ac = 0;
523 
524  /* Try to locate the area for the current equivalence chain.
525  * Only one variable should have a well-defined storage.
526  * Or no variables have one because the equivalence chain
527  * is located in the dynamic area.
528  */
529  for (pca = chain_atoms(c); pca != NIL; pca = CDR(pca)) {
530  entity e;
531  int o;
532 
533  e = atom_equivar(ATOM(CAR(pca)));
534  o = atom_equioff(ATOM(CAR(pca)));
535 
536  /* Compute the total size of the chain. This only should
537  be used for the static and dynamic areas */
538  /* FI: I do not understand why this assignment is not better guarded.
539  * Maybe, because lc's later use *is* guarded.
540  */
541  if ((l = SafeSizeOfArray(e)) > lc-o)
542  lc = l+o;
543 
544  if (entity_storage(e) != storage_undefined) {
545  if (storage_ram_p(entity_storage(e))) {
547 
548  if (sc != ram_section(r)) {
549  if (sc == DynamicArea) {
550  sc = ram_section(r);
551  ac = ram_offset(r)-o;
552  }
553  else if (sc == StaticArea) {
554  /* A variable may be located in a static area because
555  * of a SAVE (?) or a DATA statement and be equivalenced
556  * with a variable in a common.
557  */
558  pips_assert("ComputeAddresses", ram_section(r) != DynamicArea);
559  sc = ram_section(r);
560  ac = ram_offset(r)-o;
561  }
562  else if(ram_section(r) == StaticArea) {
563  /* Same as above but in a different order */
564  /* Let's hope this is due to a DATA and not to a SAVE */
565  ram_section(r) = sc;
566  }
567  else {
568  user_warning("ComputeAddresses",
569  "Incompatible default area %s and "
570  "area %s requested by equivalence for %s\n",
572  entity_local_name(e));
573  ParserError("ComputeAddresses",
574  "incompatible areas\n");
575  }
576  }
577  }
578  else
579  FatalError("ComputeAddresses", "non ram storage\n");
580  }
581  }
582 
583  /* Compute the offset and set the storage information for each
584  * variable in the equivalence chain that has no storage yet.
585  */
586  for (pca = chain_atoms(c); pca != NIL; pca = CDR(pca)) {
587  entity e;
588  int o, adr;
589 
590  e = atom_equivar(ATOM(CAR(pca)));
591  o = atom_equioff(ATOM(CAR(pca)));
592 
593  if (sc == DynamicArea || sc == StaticArea) {
594  ac = area_size(type_area(entity_type(sc)));
595  }
596 
597  /* check that the offset is positive */
598  if ((adr = ac+o) < 0) {
599  user_warning("ComputeAddresses", "Offset %d for %s in common /%s/.\n",
600  ac+o, entity_local_name(e), entity_local_name(sc));
601  ParserError("ComputeAddresses",
602  "Attempt to extend common backwards. "
603  "Have you checked the code with a Fortran compiler?\n");
604  }
605 
606  if ((entity_storage(e)) != storage_undefined) {
607  ram r;
608  r = storage_ram(entity_storage(e));
609 
610  if (adr != ram_offset(r)) {
612  ram_offset(r) = adr;
613  if(sc == StaticArea && pca != chain_atoms(c)) {
614  /* Static aliases cannot be added right away because
615  * implicitly declared static variables still have to
616  * be added whereas aliased variables are assumed to be
617  * put behind in the layout list. Except the first one.
618  *
619  * Well, I'm not so sure!
620  */
621  static_aliases = arguments_add_entity(static_aliases, e);
622  }
623  else {
624  area a = type_area(entity_type(sc));
625 
627  CONS(ENTITY, e, NIL));
628  }
629  }
630  else if(ram_offset(r)==UNKNOWN_RAM_OFFSET) {
631  ram_offset(r) = adr;
632  }
633  else {
634  user_warning("ComputeAddresses",
635  "Two conflicting offsets for %s: %d and %d\n",
636  entity_local_name(e), adr, ram_offset(r));
637  ParserError("ComputeAddresses", "incompatible addresses\n");
638  }
639  }
640  }
641  else {
642  area a = type_area(entity_type(sc));
643 
644  entity_storage(e) =
647  sc, adr, NIL)));
648  /* Add e in sc'layout and check that sc's size
649  * does not have to be increased as for:
650  * COMMON /FOO/X
651  * REAL Y(100)
652  * EQUIVALENCE (X,Y)
653  */
654  pips_assert("Entity e is not yet in sc's layout",
656  if(sc == DynamicArea && pca != chain_atoms(c)) {
657  /* Dynamic aliases cannot be added right away because
658  * implicitly declared dynamic variables still have to
659  * be added whereas aliased variables are assumed to be
660  * put behind in the layout list. Except the first one.
661  */
662  dynamic_aliases = arguments_add_entity(dynamic_aliases, e);
663  }
664  else {
666  CONS(ENTITY, e, NIL));
667  }
668 
669  /* If sc really is a common, i.e. neither the *dynamic*
670  * nor the *static* area, check its size
671  */
672  if(top_level_entity_p(sc)) {
673  int s = common_to_size(sc);
674  int new_s = adr + SafeSizeOfArray(e);
675  if(s < new_s) {
676  (void) update_common_to_size(sc, new_s);
677  }
678  }
679  }
680  }
681 
682  if (sc == DynamicArea || sc == StaticArea)
683  area_size(type_area(entity_type(sc))) += lc;
684 
685  }
686  }
687 
688  /* Varying size arrays must be stack allocated. This is an implicit
689  extension that is not compatible with EQUIVALENCE */
690 
691  if(get_bool_property("PARSER_ACCEPT_ANSI_EXTENSIONS")) {
692  pips_debug(2, "Process stack variables\n");
693 
695  pcv = CDR(pcv)) {
696  entity a = ENTITY(CAR(pcv));
697  int s;
698 
699  /* This test will fail for stack allocatable varying length
700  character strings because of function SizeOfElements() which
701  cannot indicate failure. Let's wait for the problem... */
704  && !SizeOfArray(a, &s)) {
705  /* Try to reallocate in stack area */
706  s = 0;
710  StackArea,
712  NIL));
713 
714  pips_debug(8, "Variable %s allocated in stack\n", entity_local_name(a));
715  }
716  else if(storage_formal_p(entity_storage(a))) {
717  /* Formal parameters can have varying sizes */
718  ;
719  }
720  else if(storage_ram_p(entity_storage(a))) {
722 
723  if(sec==DynamicArea) {
725  pips_debug(8, "Variable %s reallocated in stack\n", entity_local_name(a));
726  }
727  else if(sec==HeapArea) {
728  /* Allocatable arrays can have varying sizes */
729  ;
730  }
731  else {
732  /* Could be declared explicitly or implicitly STATIC or be
733  EQUIVALENCEd with such a variable. It could be declared
734  in a COMMON. */
735  pips_user_warning("Variable %s with varying dimension cannot be reallocated"
736  " in stack because it has already been allocated in %s\n",
738  ParserError(__FUNCTION__, "Storage cannot be redefined to stack");
739  }
740  }
741  else {
742  pips_internal_error("Unexpected storage for entity %s",
743  entity_local_name(a));
744  }
745  }
746  else {
747  /* The array size is known at compile time. Allocate in synamic
748  area. */
749  ;
750  }
751  }
752  }
753 
754  /* All declared variables are scanned and stored in the dynamic area if their
755  * storage is still undefined or in the static area if their offsets are still
756  * unkown.
757  *
758  * This should be the case for all non-aliased static variables and most dynamic
759  * variables.
760  *
761  */
762 
763  pips_debug(2, "Process left-over dynamic variables\n");
764 
766  pcv = CDR(pcv)) {
767  entity e = ENTITY(CAR(pcv));
768 
769  if (entity_storage(e) == storage_undefined) {
770  /* area da = type_area(entity_type(DynamicArea)); */
771 
772  pips_debug(2, "Add dynamic non-aliased variable %s\n",
773  entity_local_name(e));
774 
775  entity_storage(e) =
778  DynamicArea,
780  e), NIL)));
781  /* area_layout(da) = gen_nconc(area_layout(da), CONS(ENTITY, e, NIL)); */
782  }
783  else if(storage_ram_p(entity_storage(e))) {
786  if(ram_section(r)==StaticArea) {
787  /* area sa = type_area(entity_type(StaticArea)); */
788 
789  pips_debug(2, "Add static non-aliased variable %s\n",
790  entity_local_name(e));
791 
793  /* area_layout(sa) = gen_nconc(area_layout(sa), CONS(ENTITY, e, NIL)); */
794  }
795  else if(ram_section(r)==HeapArea) {
797 
798  pips_debug(2,
799  "Ignore heap variable %s because its address cannot be computed\n",
800  entity_local_name(e));
801  area_layout(ha) = gen_nconc(area_layout(ha), CONS(ENTITY, e, NIL));
802  }
803  else {
804  /* Must be stack area */
806 
807  pips_debug(2,
808  "Ignore stack variable %s because its address cannot be computed\n",
809  entity_local_name(e));
810  area_layout(sa) = gen_nconc(area_layout(sa), CONS(ENTITY, e, NIL));
811  }
812  }
813  }
814  }
815 
816  /* Add aliased dynamic variables */
817  if(!ENDP(dynamic_aliases)) {
818  /* neither gen_concatenate() nor gen_append() are OK */
820 
821  ifdebug(2) {
822  pips_debug(2, "There are dynamic aliased variables:");
823  print_arguments(dynamic_aliases);
824  }
825 
826  pips_assert("aliased dynamic variables imply standard dynamic variables",
827  !ENDP(dynamics));
828  /* side effect on area_layout */
829  (void) gen_nconc(dynamics, dynamic_aliases);
830  }
831 
832  /* Add aliased static variables */
833  if(!ENDP(static_aliases)) {
834  /* neither gen_concatenate() nor gen_append() are OK */
836 
837  ifdebug(2) {
838  pips_debug(2, "There are static aliased variables:");
839  print_arguments(static_aliases);
840  }
841 
842  pips_assert("aliased static variables imply standard static variables",
843  !ENDP(statics));
844  /* side effect on area_layout */
845  (void) gen_nconc(statics, static_aliases);
846  }
847 
848  /* The sizes of the static and dynamic areas are now known */
853 
854  pips_debug(1, "End\n");
855 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
entity DynamicArea
These global variables are declared in ri-util/util.c.
Definition: area.c:57
entity HeapArea
Definition: area.c:59
entity StackArea
Definition: area.c:60
int SafeSizeOfArray(entity a)
This function should not be used outside of the syntax library because it depends on ParserError().
Definition: declaration.c:83
void update_common_to_size(entity a, size_t new_size)
Definition: declaration.c:1010
size_t common_to_size(entity a)
Definition: declaration.c:990
void print_arguments(list args)
Definition: naming.c:228
#define equivalences_undefined
#define atom_equioff(x)
int current_offset_of_area(entity a, entity v)
Definition: area.c:174
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
bool SizeOfArray(entity, int *)
This function computes the total size of a variable in bytes, ie.
Definition: size.c:87
#define storage_formal_p(x)
Definition: ri.h:2522
#define area_size(x)
Definition: ri.h:544
#define code_declarations(x)
Definition: ri.h:784
#define ram_offset(x)
Definition: ri.h:2251
#define ifdebug(n)
Definition: sg.c:47

References area_layout, area_size, arguments_add_entity(), ATOM, atom_equioff, atom_equivar, CAR, CDR, CHAIN, chain_atoms, code_declarations, common_to_size(), CONS, current_offset_of_area(), DynamicArea, ENDP, ENTITY, entity_is_argument_p(), entity_local_name(), entity_name, entity_storage, entity_type, EntityCode(), equivalences_chains, equivalences_undefined, FatalError, FinalEquivSet, gen_nconc(), get_bool_property(), get_current_module_entity(), HeapArea, ifdebug, is_storage_ram, make_ram(), make_storage(), NIL, ParserError(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, print_arguments(), ram_offset, ram_section, SafeSizeOfArray(), SizeOfArray(), StackArea, StaticArea, storage_formal_p, storage_ram, storage_ram_p, storage_undefined, storage_undefined_p, top_level_entity_p(), type_area, type_variable_p, UNKNOWN_RAM_OFFSET, update_common_to_size(), and user_warning.

Referenced by EndOfProcedure().

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

◆ ComputeEquivalences()

void ComputeEquivalences ( void  )

This function merges all the equivalence chains to take into account equivalences due to transitivity.

It is called at the end of the parsing.

They should be properly initialized by SetChains if (FinalEquivSet == equivalences_undefined) { FinalEquivSet = make_equivalences(NIL); }

Definition at line 215 of file equivalence.c.

216 {
217  cons *pc;
218  int again = true;
219 
220  pips_debug(8, "Begin\n");
221 
222  /*
223  if (TempoEquivSet == equivalences_undefined) {
224  pips_debug(8, "Useless call, end\n");
225  return;
226  }
227  */
228 
230  pips_debug(8, "No equivalences to process, end\n");
231  return;
232  }
233 
234  /* They should be properly initialized by SetChains
235  if (FinalEquivSet == equivalences_undefined) {
236  FinalEquivSet = make_equivalences(NIL);
237  }
238  */
239 
240  pips_debug(8, "Initial equivalence chains\n");
242 
243  while (again) {
244  for (pc = equivalences_chains(TempoEquivSet); pc != NIL; pc = CDR(pc))
245  again = (AddOrMergeChain(CHAIN(CAR(pc))) == EQUIMERGE);
246 
247  if (again) {
251 
252  pips_debug(8, "Intermediate equivalence chains\n");
254  }
255  }
256 
257  pips_debug(8, "Resulting equivalence chains\n");
258 
260 
261  pips_debug(8, "End\n");
262 }
void free_equivalences(equivalences p)
equivalences make_equivalences(list a)
static equivalences TempoEquivSet
external variables used by functions from equivalence.c
Definition: equivalence.c:59
void PrintChains(equivalences e)
two debugging functions, just in case ...
Definition: equivalence.c:364
int AddOrMergeChain(chain ct)
this function adds a chain ct to the set of equivalences.
Definition: equivalence.c:269

References AddOrMergeChain(), CAR, CDR, CHAIN, ENDP, EQUIMERGE, equivalences_chains, FinalEquivSet, free_equivalences(), make_equivalences(), NIL, pips_debug, PrintChains(), and TempoEquivSet.

Referenced by EndOfProcedure().

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

◆ cr_implicit()

void cr_implicit ( tag  t,
int  l,
int  lettre_d,
int  lettre_f 
)

this function updates the data structure used to compute implicit types.

the implicit type for the range of letters defined by lettre_d and lettre_f has tag t and length l. tag is_basic_string is temporarely forbidden.

Parameters
lettre_dettre_d
lettre_fettre_f

Definition at line 1284 of file declaration.c.

1288 {
1289  int i;
1290 
1291  /*
1292  if (t == is_basic_string)
1293  ParserError("cr_implicit",
1294  "Unsupported implicit character declaration\n");
1295  */
1296 
1297  if ((! IS_UPPER(lettre_d)) || (! IS_UPPER(lettre_f)))
1298  FatalError("cr_implicit", "bad char\n");
1299 
1300  for (i = lettre_d-'A'; i <= lettre_f-'A'; i += 1) {
1301  tag_implicit[i] = t;
1302  int_implicit[i] = l;
1303  }
1304 }
#define IS_UPPER(c)
Definition: declaration.c:76
static tag tag_implicit[26]
local variables for implicit type implementation
Definition: declaration.c:1264
static size_t int_implicit[26]
Definition: declaration.c:1265

References FatalError, int_implicit, IS_UPPER, and tag_implicit.

Referenced by InitImplicit().

+ Here is the caller graph for this function:

◆ CurrentOffsetOfArea()

int CurrentOffsetOfArea ( entity  a,
entity  v 
)

the local areas are StaticArea, DynamicArea, HeapArea, StackArea

Definition at line 1195 of file declaration.c.

1196 {
1197  int OldOffset;
1198  type ta = entity_type(a);
1199  area aa = type_area(ta);
1200 
1201  if(top_level_entity_p(a)) {
1202  OldOffset = common_to_size(a);
1203  (void) update_common_to_size(a, OldOffset+SafeSizeOfArray(v));
1204  }
1205  else {
1206  /* the local areas are StaticArea, DynamicArea, HeapArea, StackArea */
1207  OldOffset = area_size(aa);
1208  area_size(aa) = OldOffset+SafeSizeOfArray(v);
1209  }
1210 
1211  area_layout(aa) = gen_nconc(area_layout(aa), CONS(ENTITY, v, NIL));
1212  return OldOffset;
1213 }

References area_layout, area_size, common_to_size(), CONS, ENTITY, entity_type, gen_nconc(), NIL, SafeSizeOfArray(), top_level_entity_p(), type_area, and update_common_to_size().

Referenced by add_entity_to_declarations(), and gfc2pips_code2instruction__TOP().

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

◆ DeclareExternalFunction()

entity DeclareExternalFunction ( entity  e)

It might be better to declare an unknown type as result type but I decided to fix the problem later. When a call is later encountered, the result type is set to void.

Parameters
eentity to be turned into external function or subroutine, except if it is a formal functional parameter.

Definition at line 2426 of file procedure.c.

2429 {
2430  entity fe = entity_undefined;
2431 
2436  fe = e;
2437  }
2438  else {
2439  /* It might be better to declare an unknown type as result type but I
2440  decided to fix the problem later. When a call is later encountered,
2441  the result type is set to void. */
2443 
2446  "Name conflict between user declared module %s and intrinsic %s\n",
2448  ParserError("DeclareExternalFunction",
2449  "Name conflict with intrinsic because PIPS does not support"
2450  " a specific name space for intrinsics. "
2451  "Please change your function or subroutine name.");
2452  }
2453  }
2454 
2455  return fe;
2456 }
bool storage_defined_p(storage p)
Definition: ri.c:2241
entity MakeExternalFunction(entity e, type r)
Definition: procedure.c:2372
#define type_functional_p(x)
Definition: ri.h:2950
#define value_intrinsic_p(x)
Definition: ri.h:3074

References entity_initial, entity_storage, entity_type, entity_undefined, MakeExternalFunction(), module_local_name(), ParserError(), pips_user_warning, storage_defined_p(), storage_formal_p, type_functional_p, type_undefined, type_undefined_p, and value_intrinsic_p.

+ Here is the call graph for this function:

◆ DeclareIntrinsic()

void DeclareIntrinsic ( entity  e)

Intrinsic e is used in the current module.

Definition at line 918 of file declaration.c.

919 {
920  pips_assert("entity is defined", e!=entity_undefined && intrinsic_entity_p(e));
921 
923 }

References AddEntityToDeclarations(), entity_undefined, get_current_module_entity(), intrinsic_entity_p(), and pips_assert.

+ Here is the call graph for this function:

◆ DeclarePointer()

void DeclarePointer ( entity  ptr,
entity  pointed_array,
list  decl_dims 
)

It is assumed that decl_tableau can be ignored for EDF examples

A varying dimension is impossible in the dynamic area for address computation. A heap area must be added.

dims = decl_dims;

No specific type for SUN pointers

EDF code contains several declaration for a unique pointer

Parameters
ptrtr
pointed_arrayointed_array
decl_dimsecl_dims

Definition at line 546 of file declaration.c.

547 {
548  /* It is assumed that decl_tableau can be ignored for EDF examples */
549  list dims = list_undefined;
550 
551  if(!get_bool_property("PARSER_ACCEPT_ANSI_EXTENSIONS")) {
552  pips_user_warning("Non-standard pointer declaration. "
553  "Set property PARSER_ACCEPT_ANSI_EXTENSIONS to true.\n");
554  }
555 
556  if(!ENDP(decl_dims)) {
557  /* A varying dimension is impossible in the dynamic area for address
558  * computation. A heap area must be added.
559  */
560 
561  dims =
562  CONS(DIMENSION,
565  NIL),
566  NIL);
567 
568  /* dims = decl_dims; */
569  }
570  else {
571  dims = decl_dims;
572  }
573 
574  pips_user_warning("SUN pointer declaration detected. Integer type used.\n");
575  /* No specific type for SUN pointers */
576  if(type_undefined_p(entity_type(ptr))) {
579  }
580  else if(implicit_type_p(ptr)) {
583  }
584  else {
585  type tp = entity_type(ptr);
586 
587  if(type_variable_p(tp)
589  /* EDF code contains several declaration for a unique pointer */
590  pips_user_warning("%s %s between lines %d and % d\n",
591  "Redefinition of pointer",
593 
594  }
595  else {
596  pips_user_warning("DeclarePointer",
597  "%s %s between lines %d and % d\n",
598  "Redefinition of type for entity",
600  ParserError("Syntax", "Conflicting type declarations\n");
601  }
602  }
603  DeclareVariable(pointed_array, type_undefined, dims,
606  HeapArea,
608  NIL)),
610 }
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
bool implicit_type_p(entity e)
This function checks that entity e has an undefined or an implicit type which can be superseded by an...
Definition: declaration.c:1358
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define UNBOUNDED_DIMENSION_NAME
Definition: ri-util-local.h:74
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
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
expression MakeNullaryCall(entity f)
Creates a call expression to a function with zero arguments.
Definition: expression.c:331
basic MakeBasic(int)
END_EOLE.
Definition: type.c:128
type MakeTypeVariable(basic, cons *)
BEGIN_EOLE.
Definition: type.c:116
@ is_basic_int
Definition: ri.h:571
#define basic_int_p(x)
Definition: ri.h:614
#define type_variable(x)
Definition: ri.h:2949
#define variable_basic(x)
Definition: ri.h:3120

References basic_int_p, CONS, CreateIntrinsic(), DeclareVariable(), DIMENSION, ENDP, entity_local_name(), entity_type, get_bool_property(), get_current_module_entity(), HeapArea, implicit_type_p(), int_to_expression(), is_basic_int, is_storage_ram, line_b_I, line_e_I, list_undefined, make_dimension(), make_ram(), make_storage(), MakeBasic(), MakeNullaryCall(), MakeTypeVariable(), NIL, ParserError(), pips_user_warning, storage_undefined, type_undefined, type_undefined_p, type_variable, type_variable_p, UNBOUNDED_DIMENSION_NAME, UNKNOWN_RAM_OFFSET, value_undefined, and variable_basic.

+ Here is the call graph for this function:

◆ DeclareVariable()

void DeclareVariable ( entity  e,
type  t,
list  d,
storage  s,
value  v 
)

void DeclareVariable(e, t, d, s, v): update entity e description as declaration statements are encountered.

Examples of sequences:

INTEGER*4 T DIMENSION T(10) SAVE T

or COMMON /TOTO/X,Y CHARACTER*30 X DIMENSION X(10)

or EXTERNAL F INTEGER F

The input code is assumed correct. As the standard states, IMPLICIT statements must occur before any declaration.

Parameters: e is an entity which should be either a variable or a funtion; it may already have a type et, of kind variable or functional; the type variable may have a dimension; variable or functional implicit types, as well as undefined type, can be superseded by the new type t; a NIL type dimension can be superseded by d; how should area entities be handled ??? t is a type of kind "variable" (functional types are not accepted; functional declaration are handled by ??? ) or undefined; it should have no dimensions; d is a (possibly) empty list of dimensions; the empty list is handled as the undefined list; each dimension is an expression s is the storage, possibly undefined; v is the initial value, possibly undefined

Most problems occur because of the great number of combinations between the entity type et (undefined, variable, functional) and the entity type dimension etd (NIL ot not) giving 7 cases on one hand, the type t and the dimensions d giving 4 cases on the other hand. That is 28 different behaviors.

No sharing is introduced between t and et. However d and s are directly used in e fields.

no new information: do nothing

update functional type

the old type should be gen_freed...

set dimension etd if NIL

set dimension etd if NIL

update type

I: to check update_common_layout

FI: it should be redefined and the offset be updated, maybe in check_common_area(); 1 Feb. 1994

Exception: since it is a synthetic variable, it is unlikely to be typed explicitly. But it can appear in later PIPS regenerated declarations. Unless there is a clash with a user variable.

No problem, but do not free t because this is performed in gram.y

free_type(t);

If the return variable is retyped, the function must be retyped

the pointed area has just been freed!

Meaningless warning when the result variable is declared the first time with the function itself user_warning("DeclareVariable", "Attempt to retype function %s with result of type " "%s with very same type %s\n", module_local_name(f), basic_to_string(old), basic_to_string(new));

Definition at line 670 of file declaration.c.

676 {
677  type et = entity_type(e);
678  list etd = list_undefined;
679  bool variable_had_implicit_type_p = false;
680 
681  debug(8, "DeclareVariable", "%s\n", entity_name(e));
682  pips_assert("DeclareVariable", t == type_undefined || type_variable_p(t));
683 
684  if(et == type_undefined) {
685  if(t == type_undefined) {
686  entity_type(e) = ImplicitType(e);
688  }
689  else {
690  type nt;
691  nt = MakeTypeVariable
693  d);
694  entity_type(e) = nt;
695  }
696  }
697  else
698  switch(type_tag(et)) {
699  case is_type_functional:
700  if(d!=NIL) {
701  user_warning("DeclareVariable",
702  "%s %s between lines %d and % d\n",
703  "Attempt to dimension functional entity",
705  ParserError("DeclareVariable", "Likely name conflict\n");
706  }
707  if(t == type_undefined)
708  /* no new information: do nothing */
709  ;
710  else
711  if (implicit_type_p(e)) {
712  /* update functional type */
715  NIL);
717  /* the old type should be gen_freed... */
718  }
720  user_warning("DeclareVariable",
721  "%s %s between lines %d and % d\n",
722  "Redefinition of functional type for entity",
724  }
725  else {
726  user_warning("DeclareVariable",
727  "%s %s between lines %d and % d\n",
728  "Modification of functional result type for entity",
730  ParserError("DeclareVariable",
731  "Possible name conflict?\n");
732  }
733  break;
734  case is_type_variable:
736  if(t == type_undefined) {
737  /* set dimension etd if NIL */
738  if(etd==NIL)
740  else if (d==NIL)
741  ;
742  else {
743  user_warning("DeclareVariable",
744  "%s %s between lines %d and % d\n",
745  "Redefinition of dimension for entity",
747  ParserError("DeclareVariable", "Name conflict?\n");
748  }
749  }
750  else {
751  pips_assert("DeclareVariable",
753  if(implicit_type_p(e)){
754  type nt;
755 
756  variable_had_implicit_type_p = true;
757 
758  /* set dimension etd if NIL */
759  if(etd==NIL)
761  else if (d==NIL)
762  ;
763  else {
764  user_warning("DeclareVariable",
765  "%s %s between lines %d and % d\n",
766  "Redefinition of dimension for entity",
768  ParserError("DeclareVariable", "Name conflict?\n");
769  }
770  /* update type */
771  nt = MakeTypeVariable
774 
776  {
777 
778  if(/*FI: to check update_common_layout*/ false &&
783  {
784  user_warning("DeclareVariable",
785  "Storage information for %s is likely to be wrong because its type is "
786  "redefined as a larger type\nType is *not* redefined internally to avoid "
787  "aliasing\n", entity_local_name(e));
788  /* FI: it should be redefined and the offset be updated,
789  * maybe in check_common_area(); 1 Feb. 1994
790  */
791  }
792  else {
793  entity_type(e) = nt;
794  }
795  }
796  else {
797  free_type(nt);
798  }
799  }
800  else {
802  /* Exception: since it is a synthetic variable, it is
803  unlikely to be typed explicitly. But it can appear
804  in later PIPS regenerated declarations. Unless
805  there is a clash with a user variable. */
806  if(type_equal_p(entity_type(e), t)) {
807  /* No problem, but do not free t because this is performed in gram.y */
808  /* free_type(t); */
809  }
810  else {
812  "%s %s between lines %d and % d\n",
813  "Redefinition of type for formal label substitution entity",
815  ParserError("DeclareVariable",
816  "Name conflict for formal label substitution variable? "
817  "Use property PARSER_FORMAL_LABEL_SUBSTITUTE_PREFIX?\n");
818  }
819  }
820  else {
822  "%s %s between lines %d and % d\n",
823  "Redefinition of type for entity",
825  ParserError("DeclareVariable",
826  "Name conflict or declaration ordering "
827  "not supported by PIPS\n"
828  "Late typing of formal parameter and/or "
829  "interference with IMPLICIT\n");
830  }
831  }
832  }
833  break;
834  case is_type_area:
835  user_warning("DeclareVariable",
836  "%s %s between lines %d and % d\n%s\n",
837  "COMMON/VARIABLE homonymy for entity name",
839  "Rename your common.");
840  ParserError("DeclareVariable", "Name conflict\n");
841  break;
842  default:
843  pips_internal_error("unexpected entity type tag: %d",
844  type_tag(et));
845  }
846 
847  if (s != storage_undefined) {
848  if (entity_storage(e) != storage_undefined) {
849  ParserError("DeclareVariable", "storage non implemented\n");
850  }
851  else {
852  entity_storage(e) = s;
853  }
854  }
855 
856  if (v == value_undefined) {
857  if (entity_initial(e) == value_undefined) {
859  }
860  }
861  else {
862  ParserError("DeclareVariable", "value non implemented\n");
863  }
864 
866 
867  /* If the return variable is retyped, the function must be retyped */
868 
872  type tf = entity_type(f);
873  functional func = type_functional(tf);
874  type tr = functional_result(func);
877 
878  pips_assert("Return variable and function must have the same name",
879  strcmp(entity_local_name(e), module_local_name(f)) == 0 );
880  pips_assert("Function must have functional type", type_functional_p(tf));
881  pips_assert("New type must be of kind variable", type_variable_p(t));
882 
883  if(!type_equal_p(tr, t)) {
884  if(variable_had_implicit_type_p) {
885  debug(8, "DeclareVariable", " Type for result of function %s "
886  "changed from %s to %s: ", module_local_name(f),
887  basic_to_string(old), basic_to_string(new));
889  old = basic_undefined; /* the pointed area has just been freed! */
890  functional_result(func) = copy_type(t);
891  ifdebug(8) {
892  fprint_functional(stderr, type_functional(tf));
893  fprintf(stderr, "\n");
894  }
895  }
896  else {
897  user_warning("DeclareVariable",
898  "Attempt to retype function %s with result of type "
899  "%s with new type %s\n", module_local_name(f),
900  basic_to_string(old), basic_to_string(new));
901  ParserError("DeclareVariable", "Illegal retyping");
902  }
903  }
904  else {
905  /* Meaningless warning when the result variable is declared the first time
906  * with the function itself
907  * user_warning("DeclareVariable",
908  * "Attempt to retype function %s with result of type "
909  * "%s with very same type %s\n", module_local_name(f),
910  * basic_to_string(old), basic_to_string(new));
911  */
912  }
913  }
914 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
void free_type(type p)
Definition: ri.c:2658
static bool same_basic_and_scalar_p(type t1, type t2)
type_equal_p -> same_basic_and_scalar_p in latter...
Definition: declaration.c:615
string basic_to_string(basic)
Definition: type.c:87
void fprint_functional(FILE *fd, functional f)
This function is called from c_parse() via ResetCurrentModule() and fprint_environment()
Definition: declarations.c:227
bool formal_label_replacement_p(entity)
Definition: variable.c:1797
int basic_type_size(basic)
See also SizeOfElements()
Definition: type.c:1074
bool type_equal_p(type, type)
Definition: type.c:547
#define functional_result(x)
Definition: ri.h:1444
#define type_tag(x)
Definition: ri.h:2940
#define type_functional(x)
Definition: ri.h:2952
#define basic_undefined
Definition: ri.h:556
#define variable_dimensions(x)
Definition: ri.h:3122
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
@ is_type_area
Definition: ri.h:2899
#define storage_return_p(x)
Definition: ri.h:2516
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References AddEntityToDeclarations(), basic_to_string(), basic_type_size(), basic_undefined, copy_basic(), copy_type(), debug(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, f(), formal_label_replacement_p(), fprint_functional(), fprintf(), free_type(), functional_result, get_current_module_entity(), ifdebug, implicit_type_p(), ImplicitType(), is_type_area, is_type_functional, is_type_variable, line_b_I, line_e_I, list_undefined, make_value_unknown(), MakeTypeVariable(), module_local_name(), NIL, ParserError(), pips_assert, pips_internal_error, pips_user_warning, same_basic_and_scalar_p(), storage_ram_p, storage_return_p, storage_undefined, storage_undefined_p, type_equal_p(), type_functional, type_functional_p, type_tag, type_undefined, type_undefined_p, type_variable, type_variable_p, user_warning, value_undefined, variable_basic, and variable_dimensions.

Referenced by AddVariableToCommon(), DeclarePointer(), MakeAssignedGotoInst(), MakeAtom(), MakeCurrentFunction(), and SaveEntity().

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

◆ dump_current_statement()

void dump_current_statement ( void  )

Preprocessed statement: Spaces have been eliminated as well as continuation lines, keyword have been emphasized and variables capitalized.

Skip the initial lines

line_b_I, line_e_I

Copy the data lines

Definition at line 1354 of file reader.c.

1355 {
1356  int i;
1357  FILE * syn_in = NULL;
1358 
1359  /* Preprocessed statement: Spaces have been eliminated as well as
1360  continuation lines, keyword have been emphasized and variables
1361  capitalized. */
1362  /*
1363  for(i=0; i<lStmt; i++)
1364  fprintf(stderr, "%c", (char) stmt_buffer[i]);
1365  fprintf(stderr,"\n");
1366  */
1367 
1368  syn_in = safe_fopen(CurrentFN, "r");
1369 
1370  /* Skip the initial lines */
1371 
1372  /* line_b_I, line_e_I */
1373  i = 1;
1374  while(i<line_b_I) {
1375  int c;
1376  if((c = getc(syn_in))==(int) '\n') i++;
1377  pips_assert("The end of file cannot be reached", c!=EOF);
1378  }
1379 
1380  /* Copy the data lines */
1381  while(i<=line_e_I) {
1382  int c;
1383  if((c = getc(syn_in))==(int) '\n') i++;
1384  pips_assert("The end of file cannot be reached", c!=EOF);
1385  putc(c, stderr);
1386  }
1387 
1389 }
int line_e_I
Definition: reader.c:452
int line_b_I
Indicates where the current instruction (in fact statement) starts and ends in the input file and giv...
Definition: parser.c:68
FILE * syn_in
lex yacc interface
Definition: syntax.h:325

References CurrentFN, line_b_I, line_e_I, pips_assert, safe_fclose(), safe_fopen(), and syn_in.

+ Here is the call graph for this function:

◆ empty_current_label_string_p()

bool empty_current_label_string_p ( void  )

Definition at line 87 of file parser.c.

88 {
89  bool empty_p = same_string_p(lab_I, "");
90 
91  return empty_p;
92 }
#define same_string_p(s1, s2)
char lab_I[6]
Definition: parser.c:69

References lab_I, and same_string_p.

Referenced by MakeElseInst().

+ Here is the caller graph for this function:

◆ EmptyEntryListsP()

bool EmptyEntryListsP ( void  )

Definition at line 1506 of file procedure.c.

1507 {
1508  bool empty = ((entry_labels==NIL) && (entry_entities==NIL));
1509 
1510  return empty;
1511 }
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64

References empty, entry_entities, entry_labels, and NIL.

Referenced by EndOfProcedure(), MakeEntry(), and the_actual_parser().

+ Here is the caller graph for this function:

◆ EndOfProcedure()

void EndOfProcedure ( void  )

This function is called when the parsing of a procedure is completed.

It performs a few calculations which cannot be done on the fly such as address computations for static and dynamic areas and commons.

And it writes the internal representation of the CurrentFunction with a call to gen_free (?).

get rid of ghost variable entities and substitute them if necessary

we generate the last statement to carry a label or a comment

|| iPrevComm != 0

we generate statement last+1 to eliminate returns

Check the block stack

are there undefined gotos ?

The following calls could be located in check_first_statement() which is called when the first executable statement is encountered. At that point, many declaration related problems should be fixed or fixeable. But additional undeclared variables will be added to the dynamic area and their addresses must be computed. At least, ComputeAddresses() must stay here.. so I keep all these calls together.

Must be performed before equivalence resolution, for user declared commons whose declarations are stronger than equivalences

Use equivalence chains to update storages of equivalenced and of variables implicitly declared in DynamicArea, or implicitly thru DATA or explicitly thru SAVE declared in StaticArea

Initialize the shared field in ram storage

Now that retyping and equivalences have been taken into account:

Why keep it in (apparent) declaration order rather than alphabetical order? Because some later processing may be based on this assumption. Sort can be performed before printouts.

remove hpfc special routines if required.

done here. affects callees and code. FC.

the current package is re-initialized

Definition at line 979 of file procedure.c.

980 {
981  entity CurrentFunction = get_current_module_entity();
982 
983  pips_debug(8, "Begin for module %s\n",
984  entity_name(CurrentFunction));
985 
986  pips_debug(8, "checking code consistency = %d\n",
988 
989  ifdebug(8) {
990  pips_debug(8, "Declarations inherited from module %s:\n",
991  module_local_name(CurrentFunction));
992  dump_arguments(entity_declarations(CurrentFunction));
993  }
994 
995  /* get rid of ghost variable entities and substitute them if necessary */
997 
998  /* we generate the last statement to carry a label or a comment */
999  if (strlen(lab_I) != 0 /* || iPrevComm != 0 */ ) {
1001  }
1002 
1003  /* we generate statement last+1 to eliminate returns */
1004  GenerateReturn();
1005 
1006  uses_alternate_return(false);
1009 
1010  /* Check the block stack */
1011  (void) PopBlock() ;
1012  if (!IsBlockStackEmpty())
1013  ParserError("EndOfProcedure",
1014  "bad program structure: missing ENDDO and/or ENDIF\n");
1015 
1016  /* are there undefined gotos ? */
1018 
1019  /* The following calls could be located in check_first_statement()
1020  * which is called when the first executable statement is
1021  * encountered. At that point, many declaration related
1022  * problems should be fixed or fixeable. But additional
1023  * undeclared variables will be added to the dynamic area
1024  * and their addresses must be computed. At least, ComputeAddresses()
1025  * must stay here.. so I keep all these calls together.
1026  */
1027  UpdateFunctionalType(CurrentFunction,
1029 
1031 
1032  /* Must be performed before equivalence resolution, for user declared
1033  commons whose declarations are stronger than equivalences */
1034  update_user_common_layouts(CurrentFunction);
1035 
1037  /* Use equivalence chains to update storages of equivalenced and of
1038  variables implicitly declared in DynamicArea, or implicitly thru
1039  DATA or explicitly thru SAVE declared in StaticArea */
1040  ComputeAddresses();
1041 
1042  /* Initialize the shared field in ram storage */
1043  SaveChains();
1044 
1045  /* Now that retyping and equivalences have been taken into account: */
1047 
1048  /* Why keep it in (apparent) declaration order rather than
1049  alphabetical order? Because some later processing may be based on
1050  this assumption. Sort can be performed before printouts. */
1051  code_declarations(EntityCode(CurrentFunction)) =
1052  gen_nreverse(code_declarations(EntityCode(CurrentFunction))) ;
1053 
1054  if (get_bool_property("PARSER_DUMP_SYMBOL_TABLE"))
1055  fprint_environment(stderr, CurrentFunction);
1056 
1057  ifdebug(5){
1058  fprintf(stderr, "Parser: checking callees consistency = %d\n",
1060  }
1061 
1062  /* remove hpfc special routines if required.
1063  */
1064  if (get_bool_property("HPFC_FILTER_CALLEES"))
1065  {
1066  list l = NIL;
1067  string s;
1068 
1069  MAPL(cs,
1070  {
1071  s = STRING(CAR(cs));
1072 
1074  {
1075  pips_debug(3, "ignoring %s\n", s);
1076  }
1077  else
1078  l = CONS(STRING, s, l);
1079  },
1080  called_modules);
1081 
1083  called_modules = l;
1084  }
1085 
1086  /* done here. affects callees and code. FC.
1087  */
1090 
1091  if(!EmptyEntryListsP()) {
1093  ProcessEntries();
1095  }
1096 
1098 
1099  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES,
1100  module_local_name(CurrentFunction),
1101  (char*) make_callees(called_modules));
1102 
1103  pips_debug(5, "checking code consistency = %d\n",
1105 
1106  DB_PUT_MEMORY_RESOURCE(DBR_PARSED_CODE,
1107  module_local_name(CurrentFunction),
1108  (char *)function_body);
1109 
1110  /* the current package is re-initialized */
1112  ResetChains();
1116 
1117  pips_debug(5, "checking code consistency after resettings = %d\n",
1119 
1120  pips_debug(8, "End for module %s\n", entity_name(CurrentFunction));
1121 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
callees make_callees(list a)
Definition: ri.c:227
bool callees_consistent_p(callees p)
Definition: ri.c:200
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
void update_user_common_layouts(entity m)
Check...
Definition: declaration.c:1670
void update_common_sizes(void)
Definition: declaration.c:1215
void reset_common_size_map()
Definition: declaration.c:954
void SaveChains()
Initialize the shared fields of aliased variables.
Definition: equivalence.c:859
void ResetChains()
undefine chains between two successives calls to parser
Definition: equivalence.c:65
void ComputeEquivalences()
This function merges all the equivalence chains to take into account equivalences due to transitivity...
Definition: equivalence.c:215
void ComputeAddresses()
This function computes an address for every variable.
Definition: equivalence.c:503
#define STRING(x)
Definition: genC.h:87
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
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
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
void parser_substitute_all_macros(statement s)
Definition: macros.c:294
void parser_close_macros_support(void)
Definition: macros.c:72
void ProcessEntries()
Definition: procedure.c:2171
static statement function_body
statement of current function
Definition: procedure.c:60
static void process_static_initializations()
Definition: procedure.c:945
bool EmptyEntryListsP()
Definition: procedure.c:1506
void UpdateFunctionalType(entity f, list l)
This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction fun...
Definition: procedure.c:1131
#define entity_declarations(e)
MISC: newgen shorthands.
void fprint_environment(FILE *fd, entity m)
Definition: declarations.c:287
bool hpf_directive_string_p(const char *s)
recognize an hpf directive special entity.
Definition: hpfc.c:51
bool keep_directive_in_code_p(const char *s)
whether an entity must be kept in the code.
Definition: hpfc.c:101
cons * FormalParameters
the current function
Definition: parser.c:55
void SubstituteAlternateReturns(const char *option)
return.c
Definition: return.c:59
void uses_alternate_return(bool use)
Definition: return.c:171
void ResetReturnCodeVariable()
Definition: return.c:151
void GenerateReturn()
Generate a unique call to RETURN per module.
Definition: return.c:499
bool IsBlockStackEmpty()
Definition: statement.c:209
void CheckAndInitializeStmt(void)
this function looks for undefined labels.
Definition: statement.c:113
void LinkInstToCurrentBlock(instruction i, bool number_it)
this function links the instruction i to the current block of statements.
Definition: statement.c:529
instruction PopBlock()
Definition: statement.c:238

References called_modules, callees_consistent_p(), CAR, CheckAndInitializeStmt(), code_declarations, ComputeAddresses(), ComputeEquivalences(), CONS, CurrentPackage, DB_PUT_MEMORY_RESOURCE, dump_arguments(), DynamicArea, EmptyEntryListsP(), entity_declarations, entity_name, entity_undefined, EntityCode(), FormalParameters, fprint_environment(), fprintf(), function_body, gen_free_list(), gen_nreverse(), GenerateReturn(), get_bool_property(), get_current_module_entity(), hpf_directive_string_p(), ifdebug, IsBlockStackEmpty(), keep_directive_in_code_p(), lab_I, LinkInstToCurrentBlock(), make_callees(), make_continue_instruction(), MAPL, module_local_name(), NIL, parser_close_macros_support(), parser_substitute_all_macros(), ParserError(), pips_debug, PopBlock(), process_static_initializations(), ProcessEntries(), remove_ghost_variable_entities(), reset_common_size_map(), reset_current_module_entity(), reset_current_module_statement(), ResetChains(), ResetReturnCodeVariable(), SaveChains(), set_current_module_statement(), statement_consistent_p(), StaticArea, STRING, SubstituteAlternateReturns(), TOP_LEVEL_MODULE_NAME, update_common_sizes(), update_user_common_layouts(), UpdateFunctionalType(), and uses_alternate_return().

+ Here is the call graph for this function:

◆ entity_in_equivalence_chain_p()

bool entity_in_equivalence_chain_p ( entity  e,
chain  c 
)

Definition at line 420 of file equivalence.c.

421 {
422  cons *pca;
423  atom a;
424  bool is_in_p = false;
425 
426  pips_debug(9, "Begin for entity %s \n", entity_name(e));
427 
428  for (pca = chain_atoms(c); !ENDP(pca) && !is_in_p; POP(pca)) {
429  a = ATOM(CAR(pca));
430 
431  is_in_p = (atom_equivar(a) == e);
432  }
433  pips_debug(9, "End\n");
434  return is_in_p;
435 }
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59

References ATOM, atom_equivar, CAR, chain_atoms, ENDP, entity_name, pips_debug, and POP.

Referenced by entity_in_equivalence_chains_p().

+ Here is the caller graph for this function:

◆ entity_in_equivalence_chains_p()

bool entity_in_equivalence_chains_p ( entity  e)

Apparently, TempoEquivSet stays undefined when there are no equivalences

Definition at line 403 of file equivalence.c.

404 {
405  equivalences equiv = TempoEquivSet;
406  list pcc;
407  bool is_in_p = false;
408 
409  /* Apparently, TempoEquivSet stays undefined when there are no equivalences */
410  if(!equivalences_undefined_p(equiv)) {
411  for (pcc = equivalences_chains(equiv); !ENDP(pcc) && !is_in_p; POP(pcc)) {
412  is_in_p = entity_in_equivalence_chain_p(e, CHAIN(CAR(pcc)));
413  }
414  }
415 
416  return is_in_p;
417 }
bool entity_in_equivalence_chain_p(entity e, chain c)
Definition: equivalence.c:420
#define equivalences_undefined_p(x)

References CAR, CHAIN, ENDP, entity_in_equivalence_chain_p(), equivalences_chains, equivalences_undefined_p, POP, and TempoEquivSet.

Referenced by remove_ghost_variable_entities().

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

◆ FindAssign()

int FindAssign ( void  )

Definition at line 1197 of file reader.c.

1198 {
1199  int result = false;
1200 
1201  if (!ProfZeroEgal && StmtEqualString("ASSIGN", iStmt)) {
1202  register size_t i = iStmt+6;
1203 
1204  if (isdigit(stmt_buffer[i])) {
1205  while (i < lStmt && isdigit(stmt_buffer[i]))
1206  i++;
1207 
1208  if (StmtEqualString("TO", i)) {
1209  (void) CapitalizeStmt("ASSIGN", iStmt);
1210  (void) CapitalizeStmt("TO", i);
1211  result = true;
1212  }
1213  }
1214  }
1215 
1216  return(result);
1217 }
static size_t iStmt
indexes in the buffer...
Definition: reader.c:243
int CapitalizeStmt(char s[], int i)
Definition: reader.c:1308
int StmtEqualString(char *s, int i)
Definition: reader.c:1290

References CapitalizeStmt(), iStmt, lStmt, ProfZeroEgal, stmt_buffer, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindAutre()

void FindAutre ( void  )

Definition at line 1169 of file reader.c.

1170 {
1171  if (!ProfZeroEgal) {
1172  int i = NeedKeyword();
1173 
1174  /*
1175  * on detecte le cas tordu: INTEGER FUNCTION(...) ou encore
1176  * plus tordu: CHARACTER*89 FUNCTION(...)
1177  */
1178  if (StmtEqualString("Integer", iStmt) ||
1179  StmtEqualString("Real", iStmt) ||
1180  StmtEqualString("Character", iStmt) ||
1181  StmtEqualString("Complex", iStmt) ||
1182  StmtEqualString("Doubleprecision", iStmt) ||
1183  StmtEqualString("Logical", iStmt)) {
1184  if (stmt_buffer[i] == '*' && isdigit(stmt_buffer[i+1])) {
1185  i += 2;
1186  while (isdigit(stmt_buffer[i]))
1187  i++;
1188  }
1189  if (StmtEqualString("FUNCTION", i)) {
1190  (void) CapitalizeStmt("FUNCTION", i);
1191  }
1192  }
1193  }
1194 }
int NeedKeyword(void)
Definition: reader.c:1329

References CapitalizeStmt(), iStmt, NeedKeyword(), ProfZeroEgal, stmt_buffer, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindDo()

int FindDo ( void  )

Let's skip a loop label to look for a while construct

Definition at line 1087 of file reader.c.

1088 {
1089  int result = false;
1090 
1091  if(StmtEqualString("DO", iStmt)) {
1092  if (ProfZeroVirg && ProfZeroEgal) {
1093  (void) CapitalizeStmt("DO", iStmt);
1094  result = true;
1095  }
1096  else if (!ProfZeroVirg && !ProfZeroEgal) {
1097  /* Let's skip a loop label to look for a while construct */
1098  int i = iStmt+2;
1099  while (isdigit(stmt_buffer[i]))
1100  i++;
1101 
1102  if (StmtEqualString("WHILE", i)) {
1103  (void) CapitalizeStmt("DO", iStmt);
1104  (void) CapitalizeStmt("WHILE", i);
1105  result = true;
1106  }
1107  }
1108  }
1109 
1110  return(result);
1111 }

References CapitalizeStmt(), iStmt, ProfZeroEgal, ProfZeroVirg, stmt_buffer, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindDoWhile()

int FindDoWhile ( void  )

This function is redundant with FindDo() but much easier to understand.

I leave it as documentation. FI.

Definition at line 1073 of file reader.c.

1074 {
1075  int result = false;
1076 
1077  if (!ProfZeroEgal && StmtEqualString("DOWHILE", iStmt)) {
1078  (void) CapitalizeStmt("DO", iStmt);
1079  (void) CapitalizeStmt("WHILE", iStmt+2);
1080  result = true;
1081  }
1082 
1083  return(result);
1084 }

References CapitalizeStmt(), iStmt, ProfZeroEgal, and StmtEqualString().

+ Here is the call graph for this function:

◆ FindIf()

void FindIf ( void  )

Definition at line 1150 of file reader.c.

1151 {
1152  if (StmtEqualString("IF(", iStmt)) {
1153  int i = FindMatchingPar(iStmt+2)+1;
1154  if (stmt_buffer[i] != '=') {
1155  (void) CapitalizeStmt("IF", iStmt);
1156  iStmt = i;
1157  }
1158  }
1159  else if (StmtEqualString("ELSEIF(", iStmt)) {
1160  int i = FindMatchingPar(iStmt+6)+1;
1161  if (stmt_buffer[i] != '=') {
1162  (void) CapitalizeStmt("ELSEIF", iStmt);
1163  iStmt = i;
1164  }
1165  }
1166 }
size_t FindMatchingPar(size_t i)
Definition: reader.c:1267

References CapitalizeStmt(), FindMatchingPar(), iStmt, stmt_buffer, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindIfArith()

int FindIfArith ( void  )

Definition at line 1134 of file reader.c.

1135 {
1136  int result = false;
1137 
1138  if (StmtEqualString("IF(", iStmt)) {
1139  int i = FindMatchingPar(iStmt+2)+1;
1140  if ('0' <= stmt_buffer[i] && stmt_buffer[i] <= '9') {
1141  (void) CapitalizeStmt("IF", iStmt);
1142  result = true;
1143  }
1144  }
1145 
1146  return(result);
1147 }

References CapitalizeStmt(), FindMatchingPar(), iStmt, stmt_buffer, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindImplicit()

int FindImplicit ( void  )

Definition at line 1114 of file reader.c.

1115 {
1116  int result = false;
1117 
1118  if (!ProfZeroEgal && StmtEqualString("IMPLICIT", iStmt)) {
1119  iStmt = CapitalizeStmt("IMPLICIT", iStmt);
1120  while (iStmt < lStmt) {
1121  iStmt = NeedKeyword();
1122  if ((iStmt = FindProfZero((int) ',')) == SIZE_UNDEF)
1123  iStmt = lStmt;
1124  else
1125  iStmt += 1;
1126  }
1127  result = true;
1128  }
1129 
1130  return(result);
1131 }
#define SIZE_UNDEF
Definition: reader.c:244
size_t FindProfZero(int c)
Definition: reader.c:1248

References CapitalizeStmt(), FindProfZero(), iStmt, lStmt, NeedKeyword(), ProfZeroEgal, SIZE_UNDEF, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindMatchingPar()

size_t FindMatchingPar ( size_t  i)

Definition at line 1267 of file reader.c.

1268 {
1269  int parenthese;
1270 
1271  pips_assert("FindMatchingPar",
1272  stmt_buffer[i] == '(' && !IS_QUOTED(stmt_buffer[i]));
1273 
1274  i += 1;
1275  parenthese = 1;
1276 
1277  while (i < lStmt && parenthese > 0) {
1278  if (!IS_QUOTED(stmt_buffer[i])) {
1279  if(stmt_buffer[i] == '(') parenthese ++;
1280  if(stmt_buffer[i] == ')') parenthese --;
1281  }
1282  i += 1;
1283  }
1284 
1285  return (i == lStmt) ? SIZE_UNDEF : i-1;
1286 }

References IS_QUOTED, lStmt, pips_assert, SIZE_UNDEF, and stmt_buffer.

Referenced by FindIf(), and FindIfArith().

+ Here is the caller graph for this function:

◆ FindPoints()

void FindPoints ( void  )

Definition at line 1220 of file reader.c.

1221 {
1222  register size_t i = iStmt;
1223 
1224  while (i < lStmt) {
1225  if (stmt_buffer[i] == '.' && isalpha(stmt_buffer[i+1])) {
1226  register int j = 0;
1227 
1228  while (OperateurPoints[j] != NULL) {
1229  if (StmtEqualString(OperateurPoints[j], i)) {
1230  stmt_buffer[i] = '%';
1231  i += strlen(OperateurPoints[j]);
1232  stmt_buffer[i-1] = '%';
1233  break;
1234  }
1235  j += 1;
1236  }
1237 
1238  if (OperateurPoints[j] == NULL)
1239  i += 2;
1240  }
1241  else {
1242  i += 1;
1243  }
1244  }
1245 }
static char * OperateurPoints[]
La table des operateurs du type '.XX.
Definition: reader.c:381

References iStmt, lStmt, OperateurPoints, stmt_buffer, and StmtEqualString().

Referenced by PipsGetc().

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

◆ FindProfZero()

size_t FindProfZero ( int  c)

Definition at line 1248 of file reader.c.

1249 {
1250  register size_t i;
1251  int parenthese = 0;
1252 
1253  for (i = iStmt; i < lStmt; i++) {
1254  if (!IS_QUOTED(stmt_buffer[i])) {
1255  if (parenthese == 0 && stmt_buffer[i] == c)
1256  break;
1257 
1258  if(stmt_buffer[i] == '(') parenthese ++;
1259  if(stmt_buffer[i] == ')') parenthese --;
1260  }
1261  }
1262 
1263  return (i == lStmt) ? SIZE_UNDEF : i;
1264 }

References IS_QUOTED, iStmt, lStmt, SIZE_UNDEF, and stmt_buffer.

Referenced by FindImplicit().

+ Here is the caller graph for this function:

◆ first_executable_statement_seen()

bool first_executable_statement_seen ( void  )

Definition at line 1964 of file statement.c.

1965 {
1966  return seen;
1967 }

References seen.

◆ first_format_statement_seen()

bool first_format_statement_seen ( void  )

Definition at line 1970 of file statement.c.

1971 {
1972  return format_seen;
1973 }

References format_seen.

◆ fix_if_condition()

expression fix_if_condition ( expression  e)

with the f77 compiler, this is equivalent to e.NE.0 if e is an integer expression.

Definition at line 1293 of file statement.c.

1294 {
1296 
1297  if(!logical_expression_p(e)) {
1298  /* with the f77 compiler, this is equivalent to e.NE.0 if e is an
1299  integer expression. */
1300  if(integer_expression_p(e)) {
1302  e, int_to_expression(0));
1303  pips_user_warning("IF condition between lines %d and %d is not a logical expression.\n",
1304  line_b_I,line_e_I);
1305  }
1306  else {
1307  ParserError("MakeBlockIfInst", "IF condition is neither logical nor integer.\n");
1308  }
1309  }
1310  else {
1311  cond = e;
1312  }
1313  return cond;
1314 }
#define NON_EQUAL_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
bool logical_expression_p(expression e)
Definition: expression.c:610
bool integer_expression_p(expression e)
Definition: expression.c:601
#define expression_undefined
Definition: ri.h:1223

References entity_intrinsic(), expression_undefined, int_to_expression(), integer_expression_p(), line_b_I, line_e_I, logical_expression_p(), MakeBinaryCall(), NON_EQUAL_OPERATOR_NAME, ParserError(), and pips_user_warning.

Referenced by MakeBlockIfInst(), and MakeLogicalIfInst().

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

◆ fortran_relevant_area_entity_p()

bool fortran_relevant_area_entity_p ( entity  c)

These tests are needed to check area consistency when dumping or printing a symbol table.

Definition at line 940 of file declaration.c.

941 {
943  && !heap_area_p(c)
944  && !stack_area_p(c));
945 }
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
bool stack_area_p(entity aire)
Definition: area.c:104
bool heap_area_p(entity aire)
Definition: area.c:86

References common_size_map, common_to_size(), hash_table_undefined, heap_area_p(), and stack_area_p().

+ Here is the call graph for this function:

◆ FortranExpressionList()

list FortranExpressionList ( list  l)

Make sure that no call to implied do is in l.

Definition at line 492 of file expression.c.

493 {
494  MAP(EXPRESSION, e, {
496  ParserError("FortranExpressionList", "Unexpected implied DO\n");
497  }, l);
498  return l;
499 }
bool expression_implied_do_p(e)
Definition: expression.c:817

References EXPRESSION, expression_implied_do_p(), MAP, and ParserError().

+ Here is the call graph for this function:

◆ generate_return_code_checks()

instruction generate_return_code_checks ( list  labels)

The reset is controlled from gram.y, as is the set

reset_alternate_returns();

ifdebug(2) {

pips_debug(2, "Additional statement generated for hide_rc_p:\n");

print_statement(s_init_rcv);

}

Parameters
labelsabels

Definition at line 337 of file return.c.

338 {
340  list lln = NIL;
343 
344  pips_assert("The label list is not empty", !ENDP(labels));
345 
346 
347 
348  ercv = entity_to_expression(rcv);
349 
350  FOREACH(ENTITY, l, labels) {
351  lln = CONS(STRING, (char*)label_local_name(l), lln);
352  }
353 
354  i = MakeComputedGotoInst(lln, ercv);
355 
356  /* The reset is controlled from gram.y, as is the set */
357  /* reset_alternate_returns(); */
358  gen_free_list(lln);
359 
361 
362  if(hide_rc_p) {
364 
365  /* ifdebug(2) { */
366  /* pips_debug(2, "Additional statement generated for hide_rc_p:\n"); */
367  /* print_statement(s_init_rcv); */
368  /* } */
369  pips_assert("i is a sequence", instruction_block_p(i));
370  instruction_block(i) = CONS(STATEMENT, s_init_rcv, instruction_block(i));
372  }
373 
374  return i;
375 }
bool instruction_consistent_p(instruction p)
Definition: ri.c:1124
#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 instruction_block_p(i)
#define instruction_block(i)
static statement make_get_rc_statement(expression rc_ref)
Definition: return.c:291
instruction MakeComputedGotoInst(list ll, expression e)
Definition: statement.c:727

References CONS, ENDP, ENTITY, entity_to_expression(), expression_undefined, FOREACH, gen_free_list(), GetFullyDefinedReturnCodeVariable(), hide_rc_p, instruction_block, instruction_block_p, instruction_consistent_p(), instruction_undefined, label_local_name(), make_get_rc_statement(), MakeComputedGotoInst(), NIL, pips_assert, STATEMENT, and STRING.

Referenced by MakeCallInst().

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

◆ GenerateReturn()

void GenerateReturn ( void  )

Generate a unique call to RETURN per module.

statement c = MakeStatement(l, make_continue_instruction());

Definition at line 499 of file return.c.

500 {
502  /* statement c = MakeStatement(l, make_continue_instruction()); */
503 
504 
511 
514  /*
515  statement_number(jmp) = get_statement_number();
516  (void) get_next_statement_number();
517  */
520  }
521  else {
522  strcpy(lab_I, end_label_local_name);
524  }
525 
526  LinkInstToCurrentBlock(inst, true);
527 }
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
#define src(name, suf)
HPFC by Fabien Coelho, May 1993 and later...
Definition: compile.c:41
int get_statement_number()
eturn the line number of the statement being parsed
Definition: reader.c:1392
#define statement_number(x)
Definition: ri.h:2452
#define statement_undefined
Definition: ri.h:2419
LOCAL char * end_label_local_name
Definition: return.c:387
static statement make_set_rc_statement(expression e)
The return code may be directly assigned or indirectly through a PIPS run-time function call.
Definition: return.c:421
statement MakeStatement(entity l, instruction i)
This function makes a statement.
Definition: statement.c:431
instruction MakeZeroOrOneArgCallInst(char *s, expression e)
this function creates a simple Fortran statement such as RETURN, CONTINUE, ...
Definition: statement.c:669

References CONS, end_label_local_name, expression_undefined, get_statement_number(), instruction_consistent_p(), instruction_undefined, int_to_expression(), lab_I, LinkInstToCurrentBlock(), make_instruction_block(), make_set_rc_statement(), MakeLabel(), MakeStatement(), MakeZeroOrOneArgCallInst(), NIL, src, STATEMENT, statement_number, statement_undefined, strdup(), substitute_rc_p, and uses_alternate_return_p().

Referenced by EndOfProcedure().

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

◆ get_alternate_returns()

list get_alternate_returns ( void  )

Definition at line 258 of file return.c.

259 {
260  return alternate_returns;
261 }

References alternate_returns.

Referenced by add_actual_return_code(), and MakeCallInst().

+ Here is the caller graph for this function:

◆ get_current_label_string()

string get_current_label_string ( void  )

Definition at line 76 of file parser.c.

77 {
78  return lab_I;
79 }

References lab_I.

Referenced by MakeElseInst().

+ Here is the caller graph for this function:

◆ get_current_number_of_alternate_returns()

int get_current_number_of_alternate_returns ( void  )

Definition at line 197 of file return.c.

198 {
200 }
static int current_number_of_alternate_returns
The current number of alternate returns is used to process a module declaration.
Definition: return.c:164

References current_number_of_alternate_returns.

◆ get_statement_number()

int get_statement_number ( void  )

eturn the line number of the statement being parsed

Definition at line 1392 of file reader.c.

1392  {
1393  return StmtLineNumber - 1;
1394 }
LOCAL int StmtLineNumber
Definition: reader.c:371

References StmtLineNumber.

Referenced by GenerateReturn(), make_get_rc_statement(), MakeArithmIfInst(), MakeAssignedOrComputedGotoInst(), MakeCallInst(), MakeLogicalIfInst(), MakeNewLabelledStatement(), MakeReturn(), MakeStatement(), and ReuseLabelledStatement().

+ Here is the caller graph for this function:

◆ GetChar()

int GetChar ( FILE *  fp)

Routine de lecture physique.

In case an error occurs, buffer must be emptied. Since i_getchar and l_getchar cannot be touched by the error handling routine, changes of fp are tracked in GetChar() and dynamically tested. Kludge suggested by Fabien Coelho to avoid adding more global variables. (FI)

Empty (or rather invisible) lines made of TAB and SPACE characters are replaced by the string "\n".

This section (probably) is made obsolete by the new function parser_reset_all_reader_buffers(). The user_warning() is replaced by a pips_error(). Test: Cachan/bug10

If a file has just been opened

if the buffer is not empty, which may never occur if previous_fp == NULL, perform a buffer reset

A whole input line is read to process TABs and empty lines

large for expansion

Fortran has a limited character set. See standard section 3.1. This cannot be handled here as you do not know if you are in a string constant or not. You cannot convert the double quote into a simple quote because you may generate an illegal string constant. Maybe the best would be to uncomment the next test. FI, 21 February 1992 if( c == '"') FatalError("GetChar","Illegal double quote character"); "

FI: let's delay and do it in ReadLine: if (islower(c)) c = toupper(c);

for (i = 0; i < (8-Column%8); i++) {

Ignore carriage returns introduced by VMS, MSDOS or MACOS...

buffer[l_getchar++] = (col > 72) ? ' ' : c;

buffer[l_getchar++] = (col > 72) ? '
' : c;

last columns cannot be copied because we might be inside a character string

i_getchar = l_getchar = UNDEF;

LineNumber += 1;

Parameters
fpp

Definition at line 614 of file reader.c.

615 {
616  int c = UNDEF;
617  static int col = 0;
618  static FILE * previous_fp = NULL;
619 
621 
622  /* This section (probably) is made obsolete by the new function
623  * parser_reset_all_reader_buffers(). The user_warning() is replaced
624  * by a pips_error(). Test: Cachan/bug10
625  */
626  if( previous_fp != fp ) {
627  /* If a file has just been opened */
628  if( i_getchar < l_getchar ) {
629  /* if the buffer is not empty, which may never occur if
630  * previous_fp == NULL, perform a buffer reset
631  */
633  pips_internal_error("Unexpected buffer reset."
634  "A parser error must have occured previously.\n");
635  }
636  previous_fp = fp;
637  }
638 
639  /* A whole input line is read to process TABs and empty lines */
640  while (i_getchar >= l_getchar && c != EOF) {
641  int EmptyBuffer = true;
642  int LineTooLong = false;
643  bool first_column = true;
644  bool in_comment = false;
645 
646  i_getchar = l_getchar = 0;
647 
648  while ((c = getc(fp)) != '\n' && c != EOF) {
649 
650  if (l_getchar>getchar_buffer_size-20) /* large for expansion */
652 
653  if(first_column) {
654  in_comment = (strchr(START_COMMENT_LINE, (char) c)!= NULL);
655  first_column = false;
656  }
657 
658  /* Fortran has a limited character set. See standard section 3.1.
659  This cannot be handled here as you do not know if you are
660  in a string constant or not. You cannot convert the double
661  quote into a simple quote because you may generate an illegal
662  string constant. Maybe the best would be to uncomment the
663  next test. FI, 21 February 1992
664  if( c == '\"')
665  FatalError("GetChar","Illegal double quote character");
666  " */
667  /* FI: let's delay and do it in ReadLine:
668  * if (islower(c)) c = toupper(c);
669  */
670 
671  if (c == '\t') {
672  int i;
673  int nspace = 8-col%8;
674  /* for (i = 0; i < (8-Column%8); i++) { */
675  for (i = 0; i < nspace; i++) {
676  col += 1;
677  getchar_buffer[l_getchar++] = ' ';
678  }
679  } else if (c == '\r') {
680  /* Ignore carriage returns introduced by VMS, MSDOS or MACOS...*/
681  ;
682  }
683  else {
684  col += 1;
685  if(col > 72 && !LineTooLong && !in_comment &&
686  parser_warn_for_columns_73_80 && !(c==' ' || c=='\t')) {
687  user_warning("GetChar",
688  "Line %d truncated, col=%d and l_getchar=%d\n",
690  LineTooLong = true;
691  }
692  /* buffer[l_getchar++] = (col > 72) ? ' ' : c; */
693  /* buffer[l_getchar++] = (col > 72) ? '\n' : c; */
694  if(col <= 72 || in_comment) {
695  /* last columns cannot be copied because we might be
696  * inside a character string
697  */
698  getchar_buffer[l_getchar++] = c;
699  }
700  if (c != ' ')
701  EmptyBuffer = false;
702  }
703  }
704 
705  if (c == EOF) {
706  if (!EmptyBuffer) {
707  user_warning("GetChar",
708  "incomplete last line !!!\n");
709  c = '\n';
710  }
711  }
712  else {
713  if (EmptyBuffer) {
714  /* i_getchar = l_getchar = UNDEF; */
715  debug(8, "GetChar", "An empty line has been detected\n");
716  i_getchar = l_getchar = 0;
717  getchar_buffer[l_getchar++] = '\n';
718  col = 0;
719  /* LineNumber += 1; */
720  }
721  else {
722  col = 0;
723  getchar_buffer[l_getchar++] = '\n';
724  }
725  }
726  ifdebug(8) {
727  int i;
728 
729  if(l_getchar==UNDEF) {
730  debug(8, "GetChar",
731  "Input line after tab expansion is empty:\n");
732  }
733  else {
734  debug(8, "GetChar",
735  "Input line after tab expansion l_getchar=%d, col=%d:\n",
736  l_getchar, col);
737  }
738  for (i=0; i < l_getchar; i++) {
739  (void) putc((char) getchar_buffer[i], stderr);
740  }
741  if(l_getchar<=0) {
742  (void) putc('\n', stderr);
743  }
744  }
745  }
746 
747  if (c != EOF) {
748  if ((c = getchar_buffer[i_getchar++]) == '\n') {
749  Column = 1;
750  LineNumber += 1;
751  }
752  else {
753  Column += 1;
754  }
755  }
756 
757  return(c);
758 }
static int * getchar_buffer
Definition: reader.c:186
static bool parser_warn_for_columns_73_80
memoization des properties
Definition: reader.c:431
static int l_getchar
Definition: reader.c:211
LOCAL int LineNumber
Definition: reader.c:365
LOCAL int Column
Definition: reader.c:365
static int i_getchar
Definition: reader.c:211
static void init_getchar_buffer(void)
number of elements in the array
Definition: reader.c:190
#define UNDEF
Definition: reader.c:132
static void resize_getchar_buffer(void)
Definition: reader.c:200
static int getchar_buffer_size
Definition: reader.c:187

References Column, debug(), getchar_buffer, getchar_buffer_size, i_getchar, ifdebug, init_getchar_buffer(), l_getchar, LineNumber, parser_warn_for_columns_73_80, pips_internal_error, resize_getchar_buffer(), START_COMMENT_LINE, UNDEF, and user_warning.

Referenced by ReadLine().

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

◆ GetReturnCodeVariable()

entity GetReturnCodeVariable ( void  )

Cannot be asserted because the return_code_variable may either be a formal parameter if the current module uses multiple return, or a dynamic variable if it does not and if it calls a subroutine using alternate returns

Definition at line 95 of file return.c.

96 {
97  const char* rc_name = get_string_property("PARSER_RETURN_CODE_VARIABLE");
98  /* Cannot be asserted because the return_code_variable may either be a
99  * formal parameter if the current module uses multiple return, or
100  * a dynamic variable if it does not and if it calls a subroutine
101  * using alternate returns
102  */
103  /*
104  pips_assert("entity return_code_variable is undefined",
105  entity_undefined_p(return_code_variable));
106  */
110  }
111 
112  return return_code_variable;
113 }
char * get_string_property(const char *)
static entity return_code_variable
Variable used to carry return code replacing the alternate returns.
Definition: return.c:93

References entity_undefined_p, FindEntity(), FindOrCreateEntity(), get_current_module_name(), get_string_property(), and return_code_variable.

Referenced by add_formal_return_code(), GetFullyDefinedReturnCodeVariable(), and make_set_rc_statement().

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

◆ ghost_variable_entity_p()

bool ghost_variable_entity_p ( entity  e)

Definition at line 292 of file procedure.c.

293 {
295 
297 }

References entity_is_argument_p(), ghost_variable_entities, list_undefined_p, and pips_assert.

Referenced by NameToFunctionalEntity(), and SafeFindOrCreateEntity().

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

◆ hpfc_parser()

bool hpfc_parser ( const string  module)

parser for HPFC.

just a different input file not to touch the original source file. this parser should be selected/activated automatically.

Parameters
moduleodule

Definition at line 286 of file parser.c.

287 {
288  return the_actual_parser(module, DBR_HPFC_FILTERED_FILE);
289 }
static char * module
Definition: pips.c:74
static bool the_actual_parser(string module, string dbr_file)
parse "module.dbr_file"
Definition: parser.c:223

References module, and the_actual_parser().

+ Here is the call graph for this function:

◆ implicit_type_p()

bool implicit_type_p ( entity  e)

This function checks that entity e has an undefined or an implicit type which can be superseded by another declaration.

The first letter of e's name is used to determine the implicit type. The implicit type of a functional entity is its result type.

ASSERT

to please gcc

Definition at line 1358 of file declaration.c.

1359 {
1360  int i;
1361  const char* s = entity_local_name(e);
1362  type t = entity_type(e);
1363  basic b;
1364 
1365  if(t == type_undefined)
1366  return true;
1367 
1368  if(type_functional_p(t))
1370 
1371  if (s[0] == '_')
1372  s++;
1373  if (!(IS_UPPER((int)s[0]))) {
1374  pips_internal_error("bad name: %s", s);
1375  FatalError("implicit_type_p", "\n");
1376  }
1377  i = (int) (s[0] - 'A');
1378 
1379  /* ASSERT */
1380  if (!type_variable_p(t))
1381  pips_internal_error("expecting a variable for %s, got tag %d",
1382  entity_name(e), type_tag(t));
1383 
1384  b = variable_basic(type_variable(t));
1385 
1386  if((tag)basic_tag(b) != tag_implicit[i])
1387  return false;
1388 
1389  switch(basic_tag(b)) {
1390  case is_basic_int: return (size_t)basic_int(b)==int_implicit[i];
1391  case is_basic_float: return (size_t)basic_float(b)==int_implicit[i];
1392  case is_basic_logical: return (size_t)basic_logical(b)==int_implicit[i];
1393  case is_basic_complex: return (size_t)basic_complex(b)==int_implicit[i];
1394  case is_basic_overloaded:
1395  pips_internal_error("unexpected overloaded basic tag");
1396  case is_basic_string:
1397  return (size_t)constant_int(value_constant(basic_string(b)))==
1398  int_implicit[i];
1399  default:
1400  pips_internal_error("illegal basic tag");
1401  }
1402  return false; /* to please gcc */
1403 }
void const char const char const int
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_logical
Definition: ri.h:573
@ is_basic_complex
Definition: ri.h:575
#define value_constant(x)
Definition: ri.h:3073
#define basic_int(x)
Definition: ri.h:616
#define constant_int(x)
Definition: ri.h:850
#define basic_tag(x)
Definition: ri.h:613
#define basic_logical(x)
Definition: ri.h:622
#define basic_float(x)
Definition: ri.h:619
#define basic_complex(x)
Definition: ri.h:628
#define basic_string(x)
Definition: ri.h:631

References basic_complex, basic_float, basic_int, basic_logical, basic_string, basic_tag, constant_int, entity_local_name(), entity_name, entity_type, FatalError, functional_result, int, int_implicit, is_basic_complex, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_string, IS_UPPER, pips_internal_error, tag_implicit, type_functional, type_functional_p, type_tag, type_undefined, type_variable, type_variable_p, value_constant, and variable_basic.

Referenced by DeclarePointer(), DeclareVariable(), retype_formal_parameters(), and TypeFunctionalEntity().

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

◆ ImplicitType()

type ImplicitType ( entity  e)

This function computes the Fortran implicit type of entity e.

The first letter of e's name is used.

It should be now called FortranImplicitType()

Definition at line 1311 of file declaration.c.

1312 {
1313  int i;
1314  const char* s = entity_local_name(e);
1315  type t = type_undefined;
1316  value v = value_undefined;
1317 
1318  if (s[0] == '_')
1319  s++;
1320 
1321  if (!(IS_UPPER((int)s[0]))) {
1322  pips_internal_error("[ImplicitType] bad name: %s", s);
1323  FatalError("ImplicitType", "\n");
1324  }
1325 
1326  i = (int) (s[0] - 'A');
1327 
1328  switch(tag_implicit[i]) {
1329  case is_basic_int:
1330  case is_basic_float:
1331  case is_basic_logical:
1332  case is_basic_complex:
1333  t = MakeTypeVariable(make_basic(tag_implicit[i], (void *) int_implicit[i]), NIL);
1334  break;
1335  case is_basic_string:
1339  break;
1340  case is_basic_overloaded:
1341  FatalError("ImplicitType", "Unsupported overloaded tag for basic\n");
1342  default:
1343  FatalError("ImplicitType", "Illegal tag for basic\n");
1344  }
1345  /*
1346  return(MakeTypeVariable(make_basic(tag_implicit[i], int_implicit[i]), NIL));
1347  */
1348  return t;
1349 }
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
@ is_constant_int
Definition: ri.h:817

References entity_local_name(), FatalError, int, int_implicit, is_basic_complex, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_string, is_constant_int, IS_UPPER, is_value_constant, make_basic(), make_constant(), make_value(), MakeTypeVariable(), NIL, pips_internal_error, tag_implicit, type_undefined, and value_undefined.

Referenced by AddVariableToCommon(), DeclareVariable(), MakeAtom(), MakeCurrentFunction(), MakeFormalParameter(), MakeParameter(), MakeResultType(), mpi_type_mpi_comm(), mpi_type_mpi_request(), mpi_type_mpi_status(), retype_formal_parameters(), TypeFunctionalEntity(), and UpdateFunctionalType().

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

◆ init_ghost_variable_entities()

void init_ghost_variable_entities ( void  )

procedure.c

Definition at line 69 of file procedure.c.

70 {
73 }

References ghost_variable_entities, list_undefined_p, NIL, and pips_assert.

◆ init_parser_properties()

void init_parser_properties ( void  )

Definition at line 296 of file parser.c.

297 {
299 }
void init_parser_reader_properties()
Definition: reader.c:434

References init_parser_reader_properties().

Referenced by the_actual_parser().

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

◆ init_parser_reader_properties()

void init_parser_reader_properties ( void  )

Definition at line 434 of file reader.c.

435 {
437  get_bool_property("PARSER_WARN_FOR_COLUMNS_73_80");
439 }
static void init_comment_buffers(void)
lazy initialization of the comment buffer
Definition: reader.c:160

References get_bool_property(), init_comment_buffers(), and parser_warn_for_columns_73_80.

Referenced by init_parser_properties().

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

◆ InitAreas()

void InitAreas ( void  )

Definition at line 100 of file declaration.c.

101 {
109 
117 
125 
133 }
storage make_storage_rom(void)
Definition: ri.c:2285
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
void set_common_to_size(entity a, size_t size)
Definition: declaration.c:1004
#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
#define entity_kind(x)
Definition: ri.h:2798

References ABSTRACT_LOCATION, AddEntityToDeclarations(), CurrentPackage, 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(), HEAP_AREA_LOCAL_NAME, HeapArea, is_type_area, make_area(), make_storage_rom(), make_type(), make_value_unknown(), NIL, set_common_to_size(), STACK_AREA_LOCAL_NAME, StackArea, STATIC_AREA_LOCAL_NAME, and StaticArea.

Referenced by gfc2pips_namespace(), and MakeCurrentFunction().

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

◆ initialize_common_size_map()

void initialize_common_size_map ( void  )

Definition at line 947 of file declaration.c.

948 {
949  pips_assert("common_size_map is undefined",
952 }
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
@ hash_pointer
Definition: newgen_hash.h:32

References common_size_map, hash_pointer, hash_table_make(), hash_table_undefined, and pips_assert.

Referenced by gfc2pips_namespace(), and MakeCurrentFunction().

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

◆ InitImplicit()

void InitImplicit ( void  )

this function initializes the data structure used to compute implicit types

Definition at line 1271 of file declaration.c.

1272 {
1276 }
int DefaultLengthOfBasic(tag t)
Deals with constant expressions and constant entities.
Definition: constant.c:44
void cr_implicit(tag t, int l, int lettre_d, int lettre_f)
this function updates the data structure used to compute implicit types.
Definition: declaration.c:1284

References cr_implicit(), DefaultLengthOfBasic(), is_basic_float, and is_basic_int.

Referenced by BeginingOfProcedure().

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

◆ IsBlockStackEmpty()

bool IsBlockStackEmpty ( void  )

Definition at line 209 of file statement.c.

210 {
211  return(CurrentBlock == 0);
212 }
LOCAL int CurrentBlock
Definition: statement.c:200

References CurrentBlock.

Referenced by EndOfProcedure(), LinkInstToCurrentBlock(), and PopBlock().

+ Here is the caller graph for this function:

◆ IsBlockStackFull()

bool IsBlockStackFull ( void  )

Definition at line 215 of file statement.c.

216 {
217  return(CurrentBlock == MAXBLOCK);
218 }
#define MAXBLOCK
The purpose of the following data structure is to build the control structure of the procedure being ...
Definition: statement.c:189

References CurrentBlock, and MAXBLOCK.

Referenced by PushBlock().

+ Here is the caller graph for this function:

◆ IsCapKeyword()

int IsCapKeyword ( char *  s)

Fonction appelee par sslex sur la reduction de la regle de reconnaissance des mot clefs.

Elle recherche si le mot 's' est un mot clef, retourne sa valeur si oui, et indique une erreur si non.

la chaine s est mise en majuscules

just to avoid a gcc warning

OTREACHED

Definition at line 515 of file reader.c.

516 {
517  register int i, c;
518  char *kwcour, *t;
519  char buffer[32];
520 
521  debug(9, "IsCapKeyword", "%s\n", s);
522 
523  pips_assert("not too long keyword", strlen(s)<32);
524 
525  /* la chaine s est mise en majuscules */
526  t = buffer;
527  while ( (c = *s++) ) {
528  if (islower(c))
529  c = toupper(c);
530  *t++ = c;
531  }
532  *t = '\0';
533 
534  i = keywidx[(int) buffer[0]-'A'];
535 
536  if (i != UNDEF) {
537  while ((kwcour = keywtbl[i].keywstr)!=0 && kwcour[0]==buffer[0]) {
538  if (strcmp(buffer, kwcour) == 0) {
539  debug(9, "IsCapKeyword", "%s %d\n", kwcour, i);
540  return(keywtbl[i].keywval);
541  }
542 
543  i += 1;
544  }
545  }
546 
547  user_warning("IsCapKeyword", "[scanner] keyword expected near %s\n",
548  buffer);
549  ParserError("IsCapKeyword", "Missing keyword.\n");
550 
551  return(-1); /* just to avoid a gcc warning */
552  /*NOTREACHED*/
553 }
static struct Skeyword keywtbl[]
CE FICHIER A ETE GENERE AUTOMATIQUEMENT.
Definition: keywtbl.h:33
static int keywidx[26]
Une table pour accelerer les recherche des keywords.
Definition: reader.c:418

References buffer, debug(), int, keywidx, keywtbl, ParserError(), pips_assert, UNDEF, and user_warning.

+ Here is the call graph for this function:

◆ IsEffectiveFormalParameterP()

bool IsEffectiveFormalParameterP ( entity  f)

Definition at line 1534 of file procedure.c.

1535 {
1537 }

References effective_formal_parameters, entity_is_argument_p(), and f().

Referenced by MakeEntry().

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

◆ IsIntegerScalar()

int IsIntegerScalar ( entity  e)

FI: should be moved in ri-util; this function returns true if e is a zero dimension variable of basic type integer.

Definition at line 1647 of file declaration.c.

1649 {
1650  if (type_variable_p(entity_type(e))) {
1652 
1654  return(true);
1655  }
1656 
1657  return(false);
1658 }

References basic_int_p, entity_type, NIL, type_variable, type_variable_p, variable_basic, and variable_dimensions.

◆ LabelToStmt()

statement LabelToStmt ( string  l)

this functions looks up in table StmtHeap for the statement s whose label is l.

Definition at line 94 of file statement.c.

96 {
97  int i;
98 
99  for (i = 0; i < CurrentStmt; i++)
100  if (strcmp(l, StmtHeap_buffer[i].l) == 0)
101  return(StmtHeap_buffer[i].s);
102 
103  return(statement_undefined);
104 }

References CurrentStmt, statement_undefined, and StmtHeap_buffer.

Referenced by make_goto_instruction(), MakeStatement(), and NewStmt().

+ Here is the caller graph for this function:

◆ LinkInstToCurrentBlock()

void LinkInstToCurrentBlock ( instruction  i,
bool  number_it 
)

this function links the instruction i to the current block of statements.

if i is the last instruction of the block (i and the block have the same label), the current block is popped from the stack. in fortran, one instruction migth end more than one block.

A label cannot be used twice

a CONTINUE instruction must be added to carry the label, because blocks cannot be labelled

The above continue is not a user statement an should not be numbered

OK, an argument could be added to MakeStatement()...

decrement_statement_number();

instruction_block(i) = CONS (STATEMENT, c, ls);

pips_assert("Why do you want to number a block?!?", false);

OK, let's be cool and ignore this request to save the caller a test

s = MakeStatement(entity_empty_label(), i);

s = instruction_to_statement(i);

s = instruction_to_statement(i);

Because of labelled loop desugaring, new_i may be different from i

Only desugared constructs such as labelled loop, computed go to or IO with error handling should produce blocks. Such blocks should be non-empty and not commented.

Sometimes, we generate blocks with only one statement in it. E.g. alternate returns pips_assert("The block has at least two statements", !ENDP(CDR(instruction_block(new_i))));

For keeping pragma attached to a loop attached to it, we have to find the loop instruction within the block

while i is the last instruction of the current block ...

Parameters
number_itumber_it

Definition at line 529 of file statement.c.

532 {
533  statement s;
534  cons * pc;
535  entity l = MakeLabel(lab_I);
536 
537  pips_debug(8, "Begin for instruction %s with label \"%s\"\n",
539 
540  /* A label cannot be used twice */
542 
543  if (IsBlockStackEmpty())
544  ParserError("LinkInstToCurrentBlock", "no current block\n");
545 
547  /* a CONTINUE instruction must be added to carry the label,
548  because blocks cannot be labelled */
549  /*
550  list ls = instruction_block(i);
551  statement c = MakeStatement(l, make_continue_instruction());
552  */
553  /* The above continue is not a user statement an should not be numbered */
554  /* OK, an argument could be added to MakeStatement()... */
555  /* decrement_statement_number(); */
556 
557  /* instruction_block(i) = CONS (STATEMENT, c, ls); */
558  if(number_it) {
559  /* pips_assert("Why do you want to number a block?!?", false); */
560  /* OK, let's be cool and ignore this request to save the caller a test */
561  /* s = MakeStatement(entity_empty_label(), i); */
562  /* s = instruction_to_statement(i); */
563  ;
564  }
565  else{
566  /* s = instruction_to_statement(i); */
567  ;
568  }
569  s = MakeStatement(l, i);
570  }
571  else {
572  s = MakeStatement(l, i);
573  }
574 
575  if (iPrevComm != 0) {
576  /* Because of labelled loop desugaring, new_i may be different from i */
578  if(instruction_block_p(new_i)) {
579  statement fs = statement_undefined; // first statement of the block
580  statement ss = statement_undefined; // second statement, if it exist
581  statement cs = statement_undefined; // commented statement
582 
583  /* Only desugared constructs such as labelled loop, computed go to or IO with
584  * error handling should produce blocks. Such blocks should be
585  * non-empty and not commented.
586  */
587  pips_assert("The block is non empty", !ENDP(instruction_block(new_i)));
588  /* Sometimes, we generate blocks with only one statement in it. E.g. alternate returns
589  pips_assert("The block has at least two statements", !ENDP(CDR(instruction_block(new_i))));
590  */
591 
592  fs = STATEMENT(CAR(instruction_block(new_i)));
593  /* For keeping pragma attached to a loop attached to it,
594  we have to find the loop instruction within the
595  block */
596  if(!ENDP(CDR(instruction_block(new_i)))) {
597  ss = STATEMENT(CAR(CDR(instruction_block(new_i))));
598 
600  cs = ss;
601  else
602  cs = fs;
603  }
604  else {
605  cs = fs;
606  }
607  /*
608  pips_assert("The first statement has no comments",
609  statement_comments(cs) == empty_comments);
610  */
612  user_log("Current comment of chosen statement: \"%s\"\n",
613  statement_comments(cs));
614  user_log("Block comment to be carried by first statement: \"%s\"\n",
615  PrevComm);
616  pips_internal_error("The first statement of the block should have no comments");
617  }
618 
619  pips_assert("The chosen statement is not a block",
621 
623  }
624  else {
626  }
627  PrevComm[0] = '\0';
628  iPrevComm = 0;
629  }
630 
631  pc = CONS(STATEMENT, s, NULL);
632 
633  if (BlockStack[CurrentBlock-1].c == NULL) {
635  }
636  else {
637  CDR(BlockStack[CurrentBlock-1].c) = pc;
638  }
639  BlockStack[CurrentBlock-1].c = pc;
640 
641  /* while i is the last instruction of the current block ... */
642  while (BlockStack[CurrentBlock-1].l != NULL &&
643  strcmp(label_local_name(l), BlockStack[CurrentBlock-1].l) == 0)
644  PopBlock();
645 
646  pips_debug(8, "End for instruction %s with label \"%s\"\n",
648 }
void user_log(const char *format,...)
Definition: message.c:234
stack BlockStack
Attention, the null statement in C is represented as the continue statement in Fortran (make_continue...
Definition: statement.c:58
bool statement_loop_p(statement s)
Definition: statement.c:349
bool continue_statement_p(statement s)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
string instruction_identification(instruction i)
Return a constant string representing symbolically the instruction type.
Definition: instruction.c:284
char * PrevComm
Definition: reader.c:152
int iPrevComm
Definition: reader.c:153
#define empty_comments
Empty comments (i.e.
bool entity_empty_label_p(entity e)
Definition: entity.c:666
#define statement_comments(x)
Definition: ri.h:2456
void reset_current_label_string()
Definition: parser.c:71

References BlockStack, CAR, CDR, CONS, continue_statement_p(), CurrentBlock, empty_comments, ENDP, entity_empty_label_p(), instruction_block, instruction_block_p, instruction_identification(), iPrevComm, IsBlockStackEmpty(), lab_I, label_local_name(), MakeLabel(), MakeStatement(), ParserError(), pips_assert, pips_debug, pips_internal_error, PopBlock(), PrevComm, reset_current_label_string(), STATEMENT, statement_comments, statement_instruction, statement_loop_p(), statement_undefined, strdup(), and user_log().

Referenced by EndOfProcedure(), GenerateReturn(), MakeBlockIfInst(), MakeDoInst(), MakeElseInst(), MakeEnddoInst(), MakeEndifInst(), and MakeWhileDoInst().

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

◆ LocalToGlobal()

entity LocalToGlobal ( entity  e)

Definition at line 1801 of file procedure.c.

1802 {
1803  return SafeLocalToGlobal(e, type_undefined);
1804 }
entity SafeLocalToGlobal(entity e, type r)
A local entity might have been created but found out later to be global, depending on the order of de...
Definition: procedure.c:1681

References SafeLocalToGlobal(), and type_undefined.

Referenced by MakeEntry(), and MakeExternalFunction().

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

◆ loop_to_implieddo()

expression loop_to_implieddo ( loop  l)

Fix last parameter

Definition at line 167 of file expression.c.

167  {
169  range r = loop_range(l);
170 
171 
172  /* Fix last parameter */
173  statement body = loop_body(l);
174  instruction ibody = statement_instruction(body);
175  list args = NIL;
176  if(instruction_sequence_p(ibody)) {
177  sequence seq = instruction_sequence(ibody);
179  args = make_arg_from_stmt(stmt, args);
180  }
181  args = gen_nreverse(args);
182  } else {
183  args = make_arg_from_stmt(body, args);
184  }
185  return MakeImpliedDo(index, r, args);
186 }
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
#define loop_body(x)
Definition: ri.h:1644
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define sequence_statements(x)
Definition: ri.h:2360
#define instruction_sequence(x)
Definition: ri.h:1514
#define loop_range(x)
Definition: ri.h:1642
#define loop_index(x)
Definition: ri.h:1640
Definition: statement.c:54
expression MakeImpliedDo(syntax v, range r, cons *l)
expressions from input output lists might contain implied do loops.
Definition: expression.c:115
static list make_arg_from_stmt(statement stmt, list args)
this used to be a nested function, but compilation on macos dislikes nested functions ....
Definition: expression.c:148

References FOREACH, gen_nreverse(), instruction_sequence, instruction_sequence_p, loop_body, loop_index, loop_range, make_arg_from_stmt(), make_reference(), make_syntax_reference(), MakeImpliedDo(), NIL, sequence_statements, and statement_instruction.

Referenced by gfc2pips_code2instruction_(), and make_arg_from_stmt().

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

◆ make_check_io_statement()

statement make_check_io_statement ( string  n,
expression  u,
entity  l 
)

Generate a test to jump to l if flag f is TRUE Used to implement control effects of IO's due to ERR= and END=.

Should not use MakeStatement() directly or indirectly to avoid counting these pseudo-instructions

Definition at line 1691 of file statement.c.

1692 {
1700 
1701  statement_consistent_p(check);
1702 
1703  return check;
1704 }
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
statement instruction_to_statement(instruction instr)
Build a statement from a give instruction.
Definition: statement.c:597
statement make_empty_block_statement()
Build an empty statement (block/sequence)
Definition: statement.c:625
#define IO_EFFECTS_PACKAGE_NAME
Implicit variables to handle IO effetcs.
expression reference_to_expression(reference r)
Definition: expression.c:196
@ is_instruction_test
Definition: ri.h:1470
instruction make_goto_instruction(entity l)
In a "go to" instruction, the label does not appear explictly.
Definition: statement.c:706

References CONS, EXPRESSION, FindEntity(), instruction_to_statement(), IO_EFFECTS_PACKAGE_NAME, is_instruction_test, make_empty_block_statement(), make_goto_instruction(), make_instruction(), make_reference(), make_test(), NIL, reference_to_expression(), and statement_consistent_p().

Referenced by MakeIoInstA().

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

◆ make_Fortran_constant_entity()

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

Definition at line 597 of file expression.c.

600 {
601  return make_C_or_Fortran_constant_entity(name, bt, size, true, ParserError);
602 }
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 make_C_or_Fortran_constant_entity(), and ParserError().

+ Here is the call graph for this function:

◆ make_goto_instruction()

instruction make_goto_instruction ( entity  l)

In a "go to" instruction, the label does not appear explictly.

It is replaced by the statement to be jumped at. If the statement carrying the label has been encountered before, everything is fine. Else the target statement has to be synthesized blindly ahead of time.

Definition at line 706 of file statement.c.

707 {
710 
711  if (s == statement_undefined) {
712  s = make_statement(l,
716  instruction_undefined, NIL, NULL,
718  NewStmt(l, s);
719  }
720 
722 
723  return g;
724 }
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
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define STATEMENT_NUMBER_UNDEFINED
default values
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
@ is_instruction_goto
Definition: ri.h:1473
statement LabelToStmt(string l)
this functions looks up in table StmtHeap for the statement s whose label is l.
Definition: statement.c:94
void NewStmt(entity e, statement s)
this function stores a new association in table StmtHeap: the label of statement s is e.
Definition: statement.c:141

References empty_comments, empty_extensions(), entity_name, instruction_undefined, is_instruction_goto, LabelToStmt(), make_instruction(), make_statement(), make_synchronization_none(), NewStmt(), NIL, STATEMENT_NUMBER_UNDEFINED, STATEMENT_ORDERING_UNDEFINED, and statement_undefined.

Referenced by make_check_io_statement(), and MakeGotoInst().

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

◆ MakeArithmIfInst()

instruction MakeArithmIfInst ( expression  e,
string  l1,
string  l2,
string  l3 
)

this function transforms an arithmetic if statement into a set of regular tests.

long but easy to understand without comments.

e is the test expression. e is inserted in the instruction returned (beware of sharing)

l1, l2, l3 are the three labels of the original if statement.

  IF (E) 10, 20, 30

becomes

  IF (E .LT. 0) THEN
     GOTO 10
  ELSE
     IF (E .EQ. 0) THEN
        GOTO 20
     ELSE
        GOTO 30
     ENDIF
  ENDIF

FI: Should be improved by testing equality between l1, l2 and l3 Cases observed: l1 == l2 l2 == l3 l1 == l3 Plus, just in case, l1==l2==l3

This must be quite unusual, but the variables in e have to be dereferenced to respect the use-def chains, e may have side effects,...

If the optimizer is very good, the absolute value of e should be checked positive?

General case

Parameters
l11
l22
l33

Definition at line 1399 of file statement.c.

1402 {
1403  expression e1, e2;
1404  statement s1, s2, s3, s;
1406 
1407  /* FI: Should be improved by testing equality between l1, l2 and l3
1408  * Cases observed:
1409  * l1 == l2
1410  * l2 == l3
1411  * l1 == l3
1412  * Plus, just in case, l1==l2==l3
1413  */
1414 
1415  if(strcmp(l1,l2)==0) {
1416  if(strcmp(l2,l3)==0) {
1417  /* This must be quite unusual, but the variables in e have to be dereferenced
1418  * to respect the use-def chains, e may have side effects,...
1419  *
1420  * If the optimizer is very good, the absolute value of e
1421  * should be checked positive?
1422  */
1423  e1 = MakeUnaryCall(CreateIntrinsic("ABS"), e);
1424  e2 = MakeBinaryCall(CreateIntrinsic(".GE."),
1425  e1, int_to_expression(0));
1426 
1429 
1431  make_test(e2,s1,s2));
1432  }
1433  else {
1434  e1 = MakeBinaryCall(CreateIntrinsic(".LE."),
1435  e, int_to_expression(0));
1436 
1439 
1441  make_test(e1,s1,s3));
1442  }
1443  }
1444  else if(strcmp(l1,l3)==0) {
1445  e1 = MakeBinaryCall(CreateIntrinsic(".EQ."),
1446  e, int_to_expression(0));
1447 
1450 
1452  make_test(e1,s2,s1));
1453  }
1454  else if(strcmp(l2,l3)==0) {
1455  e1 = MakeBinaryCall(CreateIntrinsic(".LT."),
1456  e, int_to_expression(0));
1457 
1460 
1462  make_test(e1,s1,s2));
1463  }
1464  else {
1465  /* General case */
1466  e1 = MakeBinaryCall(CreateIntrinsic(".LT."),
1467  e, int_to_expression(0));
1468  e2 = MakeBinaryCall(CreateIntrinsic(".EQ."),
1470 
1474 
1476  make_test(e2,s2,s3)));
1478 
1480  }
1481 
1482  return ifarith;
1483 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
s1
Definition: set.c:247
instruction MakeGotoInst(string n)
this function creates a goto instruction.
Definition: statement.c:686

References copy_expression(), CreateIntrinsic(), get_statement_number(), instruction_to_statement(), instruction_undefined, int_to_expression(), is_instruction_test, make_empty_block_statement(), make_instruction(), make_test(), MakeBinaryCall(), MakeGotoInst(), MakeUnaryCall(), s1, and statement_number.

+ Here is the call graph for this function:

◆ MakeAssignedGotoInst()

instruction MakeAssignedGotoInst ( list  ll,
entity  i 
)
Parameters
lll

Definition at line 734 of file statement.c.

735 {
736  instruction inst;
738 
740 
741  inst = MakeAssignedOrComputedGotoInst(ll, expr, true);
742 
743  return inst;
744 }
instruction MakeAssignedOrComputedGotoInst(list ll, expression ce, bool assigned)
Definition: statement.c:747

References DeclareVariable(), entity_to_expression(), MakeAssignedOrComputedGotoInst(), NIL, storage_undefined, type_undefined, and value_undefined.

+ Here is the call graph for this function:

◆ MakeAssignedOrComputedGotoInst()

instruction MakeAssignedOrComputedGotoInst ( list  ll,
expression  ce,
bool  assigned 
)

ce might have side effects

ce can be used several times without side effects

We cannot know yet if ce has side effects

expression_intrinsic_operation_p(ce): a user call may be hidden at a lower level and some intrinsics may have side effects and it might be more efficient not to recompute a complex expression several times

Prefix starts with I to avoid an explicit declaration and a regeneration of declarations by the prettyprinter.

Assigned GO TO: if the current label is not in the list, this is an error in Fortran 90. ISO/IEC 1539 Section 8.2.4 page 108. Same in Fortran 77 standard, Section 11-2.

Update the statement numbers of all possibly allocated statements

MakeStatement won't increment the current statement number because this is a block... so it has to be done here

FatalError("parser", "computed goto statement prohibited\n");

Parameters
lll
cee
assignedssigned

Definition at line 747 of file statement.c.

748 {
750  list cs = NIL;
751  int l = 0;
752  list cl = list_undefined;
754  syntax sce = expression_syntax(ce);
756 
757  /* ce might have side effects */
758  if(syntax_reference_p(sce)) {
759  /* ce can be used several times without side effects */
760  e = ce;
761  }
762  else if(syntax_call_p(sce)) {
763  if(call_constant_p(syntax_call(sce))) {
764  e = ce;
765  }
766  else {
767  /* We cannot know yet if ce has side effects */
768  /* expression_intrinsic_operation_p(ce): a user call may be hidden
769  at a lower level and some intrinsics may have side effects and
770  it might be more efficient not to recompute a complex
771  expression several times */
772  /* Prefix starts with I to avoid an explicit declaration and a
773  regeneration of declarations by the prettyprinter. */
776  make_basic(is_basic_int, (void*) 4));
778 
779  e = entity_to_expression(tmp);
780  }
781  }
782  else {
783  pips_internal_error("No range expected", false);
784  }
785 
786 
787  for(l = gen_length(ll), cl = ll; !ENDP(cl); l--, POP(cl)) {
788  string ln = STRING(CAR(cl));
789  instruction g = MakeGotoInst(ln);
790  expression cond =
795  entity_domain),
796  copy_expression(e),
797  int_to_expression(assigned? atoi(ln):l));
798  /* Assigned GO TO: if the current label is not in the list, this is an error
799  * in Fortran 90. ISO/IEC 1539 Section 8.2.4 page 108. Same in Fortran 77
800  * standard, Section 11-2.
801  */
802  statement may_stop = (assigned && (cl==ll)) ?
805  :
807  instruction iif =
809  make_test(cond,
811  may_stop));
813 
814  s = instruction_to_statement(iif);
815 
816  /* Update the statement numbers of all possibly allocated statements */
818  if(stop_statement_p(may_stop))
820 
821  cs = CONS(STATEMENT, s, cs);
822  }
823 
825  cs = CONS(STATEMENT, s_init, cs);
826 
827  /* MakeStatement won't increment the current statement number
828  * because this is a block... so it has to be done here
829  */
830  // (void) get_next_statement_number();
831  ins = make_instruction_block(cs);
832 
833  (void) instruction_consistent_p(ins);
834 
835  /* FatalError("parser", "computed goto statement prohibited\n"); */
836 
837  return ins;
838 }
string make_entity_fullname(const char *module_name, const char *local_name)
END_EOLE.
Definition: entity_names.c:230
#define call_constant_p(C)
Definition: flint_check.c:51
statement make_assign_statement(expression l, expression r)
Definition: statement.c:583
bool stop_statement_p(statement s)
Test if a statement is a Fortran STOP.
Definition: statement.c:263
static expression s_init
must take care not to substitute in an inserted expression
Definition: macros.c:177
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define EQUAL_OPERATOR_NAME
#define STOP_FUNCTION_NAME
#define make_empty_statement
An alias for make_empty_block_statement.
entity make_new_scalar_variable_with_prefix(const char *, entity, basic)
Create a new scalar variable of type b in the given module.
Definition: variable.c:592
#define syntax_call_p(x)
Definition: ri.h:2734
#define statement_undefined_p(x)
Definition: ri.h:2420
#define expression_syntax(x)
Definition: ri.h:1247
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410

References call_constant_p, CAR, CONS, copy_expression(), ENDP, entity_domain, entity_to_expression(), EQUAL_OPERATOR_NAME, expression_syntax, expression_undefined, gen_find_tabulated(), gen_length(), get_current_module_entity(), get_statement_number(), instruction_consistent_p(), instruction_to_statement(), instruction_undefined, int_to_expression(), is_basic_int, is_instruction_test, list_undefined, make_assign_statement(), make_basic(), make_empty_statement, make_entity_fullname(), make_instruction(), make_instruction_block(), make_new_scalar_variable_with_prefix(), make_test(), MakeBinaryCall(), MakeGotoInst(), MakeZeroOrOneArgCallInst(), NIL, pips_internal_error, POP, s_init, STATEMENT, statement_number, statement_undefined, statement_undefined_p, STOP_FUNCTION_NAME, stop_statement_p(), STRING, syntax_call, syntax_call_p, syntax_reference_p, and TOP_LEVEL_MODULE_NAME.

Referenced by MakeAssignedGotoInst(), and MakeComputedGotoInst().

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

◆ MakeAssignInst()

instruction MakeAssignInst ( syntax  l,
expression  e 
)

this function creates an affectation statement.

l is a reference (the left hand side).

e is an expression (the right hand side).

Let us keep the statement function definition somewhere.

Preserve the current comments as well as the information about the macro substitution

FI: we stumble here when a Fortran macro is used.

FI: we stumble here when a Fortran PARAMETER is used as lhs.

Definition at line 848 of file statement.c.

849 {
852 
853  if(syntax_reference_p(l)) {
855  i = make_assign_instruction(lhs, e);
856  }
857  else
858  {
859  if(syntax_call_p(l) &&
862  {
863  list lexpr = CONS(EXPRESSION, e, NIL);
864  list asub = call_arguments(syntax_call(l));
865 
867  free_syntax(l);
868 
871  gen_append(asub, lexpr)));
872  }
873  else
874  {
875  if (syntax_call_p(l) &&
877  {
878  if (get_bool_property("PARSER_EXPAND_STATEMENT_FUNCTIONS"))
879  {
880  /* Let us keep the statement function definition somewhere.
881  */
882  /* Preserve the current comments as well as the information
883  about the macro substitution */
886 
887  pips_debug(5, "considering %s as a macro\n",
889 
891  statement_comments(stmt2) =
892  strdup(concatenate("C$PIPS STATEMENT FUNCTION ",
894  " SUBSTITUTED\n", 0));
896  CONS(STATEMENT, stmt2, NIL)));
897  }
898  else
899  {
900  /* FI: we stumble here when a Fortran macro is used. */
901  user_warning("MakeAssignInst", "%s() appears as lhs\n",
903  ParserError("MakeAssignInst",
904  "bad lhs (function call or undeclared array)"
905  " or PIPS unsupported Fortran macro\n"
906  "you might consider switching the "
907  "PARSER_EXPAND_STATEMENT_FUNCTIONS property,\n"
908  "in the latter, at your own risk...\n");
909  }
910  }
911  else {
912  if(syntax_call_p(l)) {
913  /* FI: we stumble here when a Fortran PARAMETER is used as lhs. */
914  user_warning("MakeAssignInst", "PARAMETER %s appears as lhs\n",
916  ParserError("MakeAssignInst",
917  "Illegal lhs\n");
918  }
919  else {
920  FatalError("MakeAssignInst", "Unexpected syntax tag\n");
921  }
922  }
923  }
924  }
925 
926  return i;
927 }
call make_call(entity a1, list a2)
Definition: ri.c:269
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
instruction make_assign_instruction(expression l, expression r)
Definition: instruction.c:87
list gen_append(list l1, const list l2)
Definition: list.c:471
statement make_continue_statement(entity l)
Definition: statement.c:953
void parser_add_a_macro(call c, expression e)
Definition: macros.c:113
#define ASSIGN_SUBSTRING_FUNCTION_NAME
entity entity_empty_label(void)
Definition: entity.c:1105
#define normalized_undefined
Definition: ri.h:1745
@ is_instruction_call
Definition: ri.h:1474
#define value_symbolic_p(x)
Definition: ri.h:3068

References ASSIGN_SUBSTRING_FUNCTION_NAME, call_arguments, call_function, concatenate(), CONS, entity_empty_label(), entity_initial, entity_intrinsic(), entity_local_name(), entity_name, EXPRESSION, expression_undefined, FatalError, free_syntax(), gen_append(), get_bool_property(), instruction_undefined, is_instruction_call, make_assign_instruction(), make_call(), make_continue_statement(), make_expression(), make_instruction(), make_instruction_block(), NIL, normalized_undefined, parser_add_a_macro(), ParserError(), pips_debug, STATEMENT, statement_comments, strdup(), SUBSTRING_FUNCTION_NAME, syntax_call, syntax_call_p, syntax_reference_p, user_warning, and value_symbolic_p.

+ Here is the call graph for this function:

◆ MakeAtom()

syntax MakeAtom ( entity  e,
cons indices,
expression  fc,
expression  lc,
int  HasParenthesis 
)

MakeAtom: this function creates a syntax, ie.

a reference, a call or a range.

there are a few good cases: e is a variable and its dimensionality is equal to the number of expressions in indices, e is a function, e is a constant or a symbolic constant.

there are a few bad cases: e is a zero dimension variable and indices is not equal to NIL (see comments of MakeExternalFunction), e is not known and the list indices is not empty (it is a call to a user function), e is not known and the list indices is empty (it is an implicit declaration).

in this function, we first try to transform bad cases into good ones, and then to create a syntax.

e is a variable or a function.

indices is a list of expressions (arguments or indices).

fc and lc are substring bound expressions.

HasParenthesis is a bool that tells if the reference to e was done with () or not. this is mandatory to make the difference between a call to a function and a reference to a function.

  • MakeAtom in expression.c fixed to generate the proper message when the substring operator is used (Francois Irigoin, 6 June 1995). See lcart2.f in Validation.

checking errors ...

It can be a PARAMETER or a functional variable or...

Not enough information to decide to stop or not.

ParserError("MakeAtom", "unsupported use of a functional entity\n");

fixing bad cases

FI: to handle parameterless function calls like t= second() - 11 March 1993

if (indices == NULL) {

It has already been declared and should not be redeclared because it may be an entry formal parameter which is not declared in the current module. If e represents an entry formal parameter (although its top-level name is the current module), it does not belong to the declarations of the current module. Hence, it is hard to assert something here.

However, e has to be typed and valued.

e = MakeExternalFunction(e, type_undefined);

use expression list to compute argument types

FI: same as in previous paragraph

if (variable_dimensions(type_variable(te))==NULL && indices!=NULL) {

if (variable_dimensions(type_variable(te))==NULL && (indices!=NULL || HasParenthesis)) {

use expression list to compute argument types

FI: probleme here for character returning function! You have to know if you are dealing with a substring operator or a function call.

Fortunately, according to SUN f77 compiler, you are not allowed to take the substring of a function call!

In fact, only check compatability... if requested!

here, bad cases have been transformed into good ones.

substring

pips_assert("Substring can only be applied to a string", basic_string_p(bt));

Probably an extension we would have liked to have for the DREAM-UP project.

The upper bound may be unknown for formal parameters and for allocatable arrays and cannot be retrieved from the type declaration

ParserError("MakeAtom", "Substrings are not implemented\n");

e is either called or passed as argument to a function. It cannot be a PARAMETER or its value would be known.

e is either called or passed as argument to a function, or it is a PARAMETER, in which case, it must really be called.

Parameters
indicesndices
fcc
lcc
HasParenthesisasParenthesis

Definition at line 222 of file expression.c.

227 {
229  type te;
230 
231  te = entity_type(e);
232 
233  /* checking errors ... */
234  if (te != type_undefined) {
235  if (type_statement_p(te)) {
236  FatalError("MakeAtom", "label dans une expression\n");
237  }
238  else if (type_area_p(te)) {
239  FatalError("MakeAtom", "area dans une expression\n");
240  }
241  else if (type_void_p(te)) {
242  FatalError("MakeAtom", "void dans une expression\n");
243  }
244  else if (type_unknown_p(te)) {
245  FatalError("MakeAtom", "unknown dans une expression\n");
246  }
247  else if (type_functional_p(te)) {
248  if(!HasParenthesis) {
249  /* It can be a PARAMETER or a functional variable or... */
250  value iv = entity_initial(e);
251  if(!value_undefined_p(iv) && value_code_p(iv)) {
252  user_warning("MakeAtom", "reference to functional entity %s\n",
253  entity_name(e));
254  /* Not enough information to decide to stop or not. */
255  /* ParserError("MakeAtom",
256  "unsupported use of a functional entity\n"); */
257  }
258  }
259  }
260  }
261 
262  /* fixing bad cases */
263  if (te == type_undefined) {
264  /* FI: to handle parameterless function calls like t= second() - 11 March 1993 */
265  /* if (indices == NULL) { */
266  if (indices == NULL && !HasParenthesis) {
268  debug(2, "MakeAtom", "implicit declaration of scalar variable: %s\n",
269  entity_name(e));
272  }
273  else if(storage_formal_p(entity_storage(e))) {
274  pips_debug(2, "reference to a functional parameter: %s\n",
275  entity_name(e));
276  /* It has already been declared and should not be
277  redeclared because it may be an entry formal parameter
278  which is not declared in the current module. If e
279  represents an entry formal parameter (although its
280  top-level name is the current module), it does not
281  belong to the declarations of the current
282  module. Hence, it is hard to assert something here.
283 
284  However, e has to be typed and valued. */
285  if(type_undefined_p(entity_type(e))) {
286  entity_type(e) = ImplicitType(e);
287  }
290  }
291  }
292  else {
293  debug(2, "MakeAtom", "implicit type declaration of scalar variable: %s\n",
294  entity_name(e));
297  }
298  }
299  else {
300  type tr = ImplicitType(e);
301 
302  debug(2, "MakeAtom", "new user function: %s\n",
303  entity_name(e));
304  /* e = MakeExternalFunction(e, type_undefined); */
305  e = MakeExternalFunction(e, tr);
306 
307  /* use expression list to compute argument types */
309  }
310  }
311  else if (type_variable_p(te)) {
312  /* FI: same as in previous paragraph */
313  /* if (variable_dimensions(type_variable(te))==NULL && indices!=NULL) { */
314  /* if (variable_dimensions(type_variable(te))==NULL
315  && (indices!=NULL || HasParenthesis)) { */
316  if (variable_dimensions(type_variable(te))==NULL
317  && (indices!=NULL || HasParenthesis)) {
319  /*
320  if( !basic_string_p(variable_basic(type_variable(te)))
321  || (fc==expression_undefined && lc==expression_undefined)) */ {
323 
324  /* use expression list to compute argument types */
326 
327  /* FI: probleme here for character returning function! You have to know if
328  * you are dealing with a substring operator or a function call.
329  *
330  * Fortunately, according to SUN f77 compiler, you are not allowed to
331  * take the substring of a function call!
332  */
333  }
334  }
335  }
336  else if (type_functional_p(te) && HasParenthesis) {
337  /* In fact, only check compatability... if requested! */
339  }
340 
341  /* here, bad cases have been transformed into good ones. */
342  te = entity_type(e);
343 
344  if (type_variable_p(te)) {
345  if((gen_length(indices)==0) ||
346  (gen_length(indices)==
348  if (lc == expression_undefined && fc == expression_undefined) {
350  make_reference(e, indices));
351  }
352  else {
353  /* substring */
354  expression ref =
356  make_reference(e, indices)),
360  list lexpr = NIL;
363 
364  if(!basic_string_p(bt)) {
365  /* pips_assert("Substring can only be applied to a string",
366  basic_string_p(bt)); */
367  if(!get_bool_property("PARSER_ACCEPT_ARRAY_RANGE_EXTENSION"))
368  ParserError("MakeAtom",
369  "Substring operations can only be applied to "
370  "strings in Fortran 77\n");
371  else {
372  /* Probably an extension we would have liked to have
373  for the DREAM-UP project. */
374  pips_internal_error("Not implemented yet");
375  }
376  }
377 
378  if(fc == expression_undefined)
379  fce = int_to_expression(1);
380  else
381  fce = fc;
382 
383  if(lc == expression_undefined) {
384  /* The upper bound may be unknown for formal
385  parameters and for allocatable arrays and cannot be
386  retrieved from the type declaration */
387  value ub = basic_string(bt);
388 
389  if(value_unknown_p(ub)) {
391  }
392  else {
394  }
395  }
396  else
397  lce = lc;
398 
399  lexpr = CONS(EXPRESSION, ref,
400  CONS(EXPRESSION, fce,
401  CONS(EXPRESSION, lce, NIL)));
402  s = make_syntax(is_syntax_call, make_call(substr, lexpr));
403  /* ParserError("MakeAtom", "Substrings are not implemented\n"); */
404  }
405  }
406  else {
407  user_warning("MakeAtom",
408  "Too many or too few subscript expressions"
409  " for reference to %s\n",
410  entity_local_name(e));
411  ParserError("MakeAtom", "Illegal array reference\n");
412  }
413 
414  }
415  else if (type_functional_p(te)) {
417  /* e is either called or passed as argument to a function.
418  It cannot be a PARAMETER or its value would be known. */
419  if (indices == NIL && HasParenthesis == false) {
421  }
422  else {
425  }
426  }
427  else {
428  if (value_code_p(entity_initial(e))) {
430  }
431 
432  /* e is either called or passed as argument to a function, or
433  it is a PARAMETER, in which case, it must really be
434  called. */
435  if (indices == NIL && !HasParenthesis
438  }
439  else {
441  }
442  }
443  }
444  else {
445  ParserError("MakeAtom", "unexpected type\n");
446  }
447 
448  return(s);
449 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static list indices
Definition: icm.c:204
void update_called_modules(entity e)
Definition: procedure.c:308
#define value_code_p(x)
Definition: ri.h:3065
#define type_unknown_p(x)
Definition: ri.h:2956
#define type_statement_p(x)
Definition: ri.h:2941
@ is_syntax_call
Definition: ri.h:2693
#define type_void_p(x)
Definition: ri.h:2959
#define type_area_p(x)
Definition: ri.h:2944
#define basic_string_p(x)
Definition: ri.h:629
void update_functional_type_with_actual_arguments(entity e, list l)
Definition: statement.c:971

References basic_string, basic_string_p, basic_type_size(), CONS, CreateIntrinsic(), debug(), DeclareVariable(), entity_initial, entity_intrinsic(), entity_local_name(), entity_name, entity_storage, entity_type, EXPRESSION, expression_undefined, FatalError, gen_length(), get_bool_property(), ImplicitType(), indices, int_to_expression(), is_syntax_call, is_syntax_reference, make_call(), make_expression(), make_reference(), make_syntax(), make_value_unknown(), MakeExternalFunction(), MakeNullaryCall(), NIL, normalized_undefined, ParserError(), pips_debug, pips_internal_error, ref, storage_formal_p, storage_undefined, storage_undefined_p, SUBSTRING_FUNCTION_NAME, syntax_undefined, type_area_p, type_functional_p, type_statement_p, type_undefined, type_undefined_p, type_unknown_p, type_variable, type_variable_p, type_void_p, UNBOUNDED_DIMENSION_NAME, update_called_modules(), update_functional_type_with_actual_arguments(), user_warning, value_code_p, value_symbolic_p, value_undefined, value_undefined_p, value_unknown_p, variable_basic, and variable_dimensions.

+ Here is the call graph for this function:

◆ MakeBlockIfInst()

void MakeBlockIfInst ( expression  e,
int  elsif 
)

this function and the two next ones create a block if statement.

the true and the else part of the test are two empty blocks. e is the test expression.

the true block is pushed on the stack. it will contain the next statements, and will end with a else statement or an endif statement.

if a else statement is reached, the true block is popped and the false block is pushed to gather the false part statements. if no else statement is found, the true block will be popped with the endif statement and the false block will remain empty.

Parameters
elsiflsif

Definition at line 1498 of file statement.c.

1501 {
1502  instruction bt, bf, i;
1503  expression cond = fix_if_condition(e);
1504 
1507 
1509  make_test(cond,
1510  MakeStatement(MakeLabel(""), bt),
1511  MakeStatement(MakeLabel(""), bf)));
1512 
1513  LinkInstToCurrentBlock(i, true);
1514 
1515  PushBlock(bt, "ELSE");
1516  BlockStack[CurrentBlock-1].elsifs = elsif ;
1517 }
void PushBlock(instruction i, string l)
Definition: statement.c:221
instruction MakeEmptyInstructionBlock()
this function creates an empty block
Definition: statement.c:654
expression fix_if_condition(expression e)
Definition: statement.c:1293

References BlockStack, CurrentBlock, fix_if_condition(), is_instruction_test, LinkInstToCurrentBlock(), make_instruction(), make_test(), MakeEmptyInstructionBlock(), MakeLabel(), MakeStatement(), and PushBlock().

+ Here is the call graph for this function:

◆ MakeCallInst()

instruction MakeCallInst ( entity  e,
cons l 
)

this function creates a call statement.

e is the called function. l is the argument list, a list of expressions.

ParserError("MakeCallInst", "Formal functional parameters are not supported " "by PIPS.\n");

FI: Before you can proceed to update_functional_type_result(), you may have to fix the type of e. Basically, if its type is not functional, it should be made functional with result void. I do not fix the problem in the parser because tons of other problems are going to appear, at least one for each PIPS analysis, starting with effects, proper, cumulated, regions, transformers, preconditions,... No quick fix, but a special effort made after an explicit decision.

The following assertion is no longer true when fucntions are passed as actual arguments.

pips_assert("e itself is returned", MakeExternalFunction(e, MakeTypeVoid()) == e);

Parameters
lcallee list of actual parameters

Definition at line 1091 of file statement.c.

1095 {
1097  list ar = get_alternate_returns();
1098  list ap = add_actual_return_code(l);
1099  storage s = entity_storage(e);
1100  bool ffp_p = false;
1101  entity fe = e;
1102 
1103  if(!storage_undefined_p(s)) {
1104  if(storage_formal_p(s)) {
1105  ffp_p = true;
1106  pips_user_warning("entity %s is a formal functional parameter\n",
1107  entity_name(e));
1108  /* ParserError("MakeCallInst",
1109  "Formal functional parameters are not supported "
1110  "by PIPS.\n"); */
1111  /* FI: Before you can proceed to
1112  update_functional_type_result(), you may have to fix
1113  the type of e. Basically, if its type is not
1114  functional, it should be made functional with result
1115  void. I do not fix the problem in the parser because
1116  tons of other problems are going to appear, at least
1117  one for each PIPS analysis, starting with effects,
1118  proper, cumulated, regions, transformers,
1119  preconditions,... No quick fix, but a special effort
1120  made after an explicit decision. */
1121  }
1122  }
1123 
1124  if(!ffp_p) {
1126 
1127  /* The following assertion is no longer true when fucntions are
1128  passed as actual arguments. */
1129  /* pips_assert("e itself is returned",
1130  MakeExternalFunction(e, MakeTypeVoid()) == e); */
1132  }
1133 
1136 
1137  if(!ENDP(ar)) {
1140 
1142  pips_assert("Alternate return substitution required\n", SubstituteAlternateReturnsP());
1144  pips_assert("Must be a sequence", instruction_block_p(i));
1146  s,
1147  instruction_block(i));
1148  }
1149  else {
1151  }
1152 
1153  return i;
1154 }
#define UU
Definition: newgen_types.h:98
type MakeTypeVoid(void)
Definition: type.c:102
@ is_type_void
Definition: ri.h:2904
bool SubstituteAlternateReturnsP()
Definition: return.c:81
list add_actual_return_code(list apl)
Definition: return.c:222
instruction generate_return_code_checks(list labels)
Definition: return.c:337
void update_functional_type_result(entity f, type nt)
Update of the type returned by function f.
Definition: statement.c:932

References add_actual_return_code(), CONS, ENDP, entity_name, entity_storage, generate_return_code_checks(), get_alternate_returns(), get_statement_number(), instruction_block, instruction_block_p, instruction_to_statement(), instruction_undefined, is_instruction_call, is_type_void, make_call(), make_instruction(), make_type(), MakeExternalFunction(), MakeTypeVoid(), pips_assert, pips_user_warning, STATEMENT, statement_number, storage_formal_p, storage_undefined_p, SubstituteAlternateReturnsP(), update_called_modules(), update_functional_type_result(), update_functional_type_with_actual_arguments(), and UU.

+ Here is the call graph for this function:

◆ MakeCommon()

entity MakeCommon ( entity  e)

MakeCommon: This function creates a common block.

pips creates static common blocks. This is not true in the ANSI standard stricto sensu, but true in most implementations.

A common declaration can be made out of several common statements. MakeCommon() is called for each common statement, although it only is useful the first time.

common e may already exist because it was encountered in another module but not have been registered as known by the current module. It may also already exist because it was encountered in the same module, but AddEntityToDeclarations() does not duplicate declarations.

FI: for a while, common sizes were always reset to 0, even when several common statements were encountered in the same module for the same common. This did not matter because offsets in commons are recomputed once variable types and dimensions are all known.

Definition at line 1047 of file declaration.c.

1048 {
1049  e = make_common_entity(e);
1050 
1051  /* common e may already exist because it was encountered
1052  * in another module
1053  * but not have been registered as known by the current module.
1054  * It may also already exist because it was encountered in
1055  * the *same* module, but AddEntityToDeclarations() does not
1056  * duplicate declarations.
1057  */
1059 
1060  /* FI: for a while, common sizes were *always* reset to 0, even when
1061  * several common statements were encountered in the same module for
1062  * the same common. This did not matter because offsets in commons are
1063  * recomputed once variable types and dimensions are all known.
1064  */
1065  if(!common_to_defined_size_p(e))
1066  set_common_to_size(e, 0);
1067 
1068  return e;
1069 }
static entity make_common_entity(entity c)
updates the common entity if necessary with the common prefix
Definition: declaration.c:1018
bool common_to_defined_size_p(entity a)
Definition: declaration.c:980

References AddEntityToDeclarations(), common_to_defined_size_p(), get_current_module_entity(), make_common_entity(), and set_common_to_size().

Referenced by MakeEntryCommon(), and NameToCommon().

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

◆ MakeComputedGotoInst()

instruction MakeComputedGotoInst ( list  ll,
expression  e 
)
Parameters
lll

Definition at line 727 of file statement.c.

728 {
729  instruction inst = MakeAssignedOrComputedGotoInst(ll, e, false);
730 
731  return inst;
732 }

References MakeAssignedOrComputedGotoInst().

Referenced by generate_return_code_checks().

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

◆ MakeCurrentFunction()

void MakeCurrentFunction ( type  t,
int  msf,
const char *  cfn,
list  lfp 
)

this function creates one entity cf that represents the Fortran function f being analyzed.

if f is a Fortran FUNCTION, a second entity is created; this entity represents the variable that is used in the function body to return a value. both entities share the same name and the type of the result entity is equal to the type of cf's result.

t is the type of the function result if it has been given by the programmer as in INTEGER FUNCTION F(A,B,C)

msf indicates if f is a main, a subroutine or a function.

cf is the current function

lfp is the list of formal parameters

current function

the body of the current function

the second entity, used to store the function result

to split the entity name space between mains, commons, blockdatas and regular modules

full current function name

global entity with conflicting name

Check that there is no such common: This test is obsolete because the standard does not prohibit the use of the same name for a common and a function. However, it is not a good programming practice

if(!type_undefined_p(entity_type(cf)) || ! storage_undefined_p(entity_storage(cf)) || !value_undefined_p(entity_initial(cf)))

Clean up existing local entities in case of a recompilation.

A block data may be declared in an EXTERNAL statement, see Standard 8-9

remove_variable_entity(ce);

Let's hope cf is not an intrinsic

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.

set ghost variable entities to NIL

This procedure is called when the whole module declaration statement has been parsed. The formal parameters have already been declared and the ghost variables checked. The call was moved in gram.y, reduction rule for psf_keyword.

init_ghost_variable_entities();

initialize equivalence chain lists to NIL

the intended result type t for a main or a subroutine should be undefined

The parameters part of cf's functional type is not created because the types of formal parameters are not known yet. This is performed later by UpdateFunctionalType().

If a call to the function has been encountered before, it's already typed. However, this information is discarded.

a function has a rom storage

a function has an initial value 'code' that contains an empty block

FI: This NULL string is a catastrophy for the strcmp used later to check the content of the stack. Any string, including the empty string "", would be better. icf is used to link new instructions/statement to the current block. Only the first block is not pushed for syntactic reasons. The later blocks will be pushed for DO's and IF's.

PushBlock(icf, (string) NULL);

No common has yet been declared

Generic areas are created for memory allocation.

Formal parameters are created. Alternate returns can be ignored or substituted.

a result entity is created

esult = FindOrCreateEntity(CurrentPackage, entity_local_name(cf));

CleanLocalEntities() does not remove any entity

Parameters
msfsf
cfnfn
lfpfp

Definition at line 1239 of file procedure.c.

1243 {
1244  entity cf = entity_undefined; /* current function */
1245  instruction icf; /* the body of the current function */
1246  entity result; /* the second entity, used to store the function result */
1247  /* to split the entity name space between mains, commons, blockdatas and regular modules */
1248  string prefix = string_undefined;
1249  string fcfn = string_undefined; /* full current function name */
1250  entity ce = entity_undefined; /* global entity with conflicting name */
1251 
1252  /* Check that there is no such common: This test is obsolete because
1253  * the standard does not prohibit the use of the same name for a
1254  * common and a function. However, it is not a good programming practice
1255  */
1258  COMMON_PREFIX, cfn, NULL),
1260  {
1261  pips_user_warning("global name %s used for a module and for a common\n",
1262  cfn);
1263  /*
1264  ParserError("MakeCurrentFunction",
1265  "Name conflict between a "
1266  "subroutine and/or a function and/or a common\n");
1267  */
1268  }
1269 
1270  if(msf==TK_PROGRAM) {
1271  prefix = MAIN_PREFIX;
1272  }
1273  else if(msf==TK_BLOCKDATA) {
1275  }
1276  else {
1277  prefix = "";
1278  }
1279  fcfn = strdup(concatenate(prefix, cfn, NULL));
1281  free(fcfn);
1282 
1283  /* if(!type_undefined_p(entity_type(cf))
1284  || ! storage_undefined_p(entity_storage(cf))
1285  || !value_undefined_p(entity_initial(cf))) */
1286 
1287  if(!value_undefined_p(entity_initial(cf))) {
1288  if(value_code_p(entity_initial(cf))) {
1289  code c = value_code(entity_initial(cf));
1290  if(!code_undefined_p(c) && !ENDP(code_declarations(c))) {
1291  /* Clean up existing local entities in case of a recompilation. */
1292  CleanLocalEntities(cf);
1293  }
1294  }
1295  }
1296 
1297  ce = FindEntity(TOP_LEVEL_MODULE_NAME, cfn);
1298  if(!entity_undefined_p(ce) && ce!=cf) {
1299  if(!value_undefined_p(entity_initial(cf)) || msf!=TK_BLOCKDATA) {
1300  user_warning("MakeCurrentFunction", "Global name %s used for a function or subroutine"
1301  " and for a %s\n", cfn, msf==TK_BLOCKDATA? "blockdata" : "main");
1302  ParserError("MakeCurrentFunction", "Name conflict\n");
1303  }
1304  else {
1305  /* A block data may be declared in an EXTERNAL statement, see Standard 8-9 */
1306  pips_debug(1, "Entity \"%s\" does not really exist."
1307  " A blockdata is declared in an EXTERNAL statement.",
1308  entity_name(ce));
1309  /* remove_variable_entity(ce); */
1311  }
1312  }
1313 
1314  /* Let's hope cf is not an intrinsic */
1315  if( entity_type(cf) != type_undefined
1316  && intrinsic_entity_p(cf) ) {
1317  user_warning("MakeCurrentFunction",
1318  "Intrinsic %s redefined.\n"
1319  "This is not supported by PIPS. Please rename %s\n",
1321  /* Unfortunately, an intrinsics cannot be redefined, just like a user function
1322  * or subroutine after editing because intrinsics are not handled like
1323  * user functions or subroutines. They are not added to the called_modules
1324  * list of other modules, unless the redefining module is parsed FIRST.
1325  * There is not mechanism in PIPS to control the parsing order.
1326  */
1327  ParserError("MakeCurrentFunction",
1328  "Name conflict between a "
1329  "subroutine and/or a function and an intrinsic\n");
1330  }
1331 
1332  /* set ghost variable entities to NIL */
1333  /* This procedure is called when the whole module declaration
1334  statement has been parsed. The formal parameters have already been
1335  declared and the ghost variables checked. The call was moved in
1336  gram.y, reduction rule for psf_keyword. */
1337  /* init_ghost_variable_entities(); */
1338 
1339  /* initialize equivalence chain lists to NIL */
1340  SetChains();
1341 
1342  if (msf == TK_FUNCTION) {
1343  if (t == type_undefined) {
1344  t = ImplicitType(cf);
1345  }
1346  }
1347  else {
1348  if (t == type_undefined) {
1349  t = make_type(is_type_void, UU);
1350  }
1351  else {
1352  /* the intended result type t for a main or a subroutine should be undefined */
1353  FatalError("MakeCurrentFunction", "bad type\n");
1354  }
1355  }
1356 
1357  /* The parameters part of cf's functional type is not created because
1358  the types of formal parameters are not known yet. This is performed
1359  later by UpdateFunctionalType().
1360 
1361  If a call to the function has been encountered before, it's already
1362  typed. However, this information is discarded. */
1363  if(!type_undefined_p(entity_type(cf))) {
1364  free_type(entity_type(cf));
1365  }
1367 
1368  /* a function has a rom storage */
1370 
1371  /* a function has an initial value 'code' that contains an empty block */
1372  icf = MakeEmptyInstructionBlock();
1373 
1374  /* FI: This NULL string is a catastrophy for the strcmp used later
1375  * to check the content of the stack. Any string, including
1376  * the empty string "", would be better. icf is used to link new
1377  * instructions/statement to the current block. Only the first
1378  * block is not pushed for syntactic reasons. The later blocks
1379  * will be pushed for DO's and IF's.
1380  */
1381  /* PushBlock(icf, (string) NULL); */
1382  PushBlock(icf, "INITIAL");
1383 
1385  entity_initial(cf) =
1387  make_code(NIL, NULL, make_sequence(NIL),NIL,
1389 
1391 
1392  /* No common has yet been declared */
1394 
1395  /* Generic areas are created for memory allocation. */
1396  InitAreas();
1397 
1398  /* Formal parameters are created. Alternate returns can be ignored
1399  * or substituted.
1400  */
1402  (get_string_property("PARSER_SUBSTITUTE_ALTERNATE_RETURNS"));
1404 
1405  if (msf == TK_FUNCTION) {
1406  /* a result entity is created */
1407  /*result = FindOrCreateEntity(CurrentPackage, entity_local_name(cf));*/
1408  /*
1409  result = make_entity(strdup(concatenate(CurrentPackage,
1410  MODULE_SEP_STRING,
1411  module_local_name(cf),
1412  NULL)),
1413  type_undefined,
1414  storage_undefined,
1415  value_undefined);
1416  */
1417  /* CleanLocalEntities() does not remove any entity */
1419  module_local_name(cf));
1421  value_undefined);
1422  AddEntityToDeclarations(result, cf);
1423  }
1424 }
functional make_functional(list a1, type a2)
Definition: ri.c:1109
language make_language_fortran(void)
Definition: ri.c:1250
code make_code(list a1, string a2, sequence a3, list a4, language a5)
Definition: ri.c:353
sequence make_sequence(list a)
Definition: ri.c:2125
void InitAreas()
Definition: declaration.c:100
void initialize_common_size_map()
Definition: declaration.c:947
void SetChains()
initialize chains before each call to the parser
Definition: equivalence.c:76
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
#define COMMON_PREFIX
Definition: naming-local.h:34
#define MAIN_PREFIX
Definition: naming-local.h:32
#define BLOCKDATA_PREFIX
Definition: naming-local.h:35
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define string_undefined
Definition: newgen_types.h:40
void ScanFormalParameters(entity m, list l)
this function scans the formal parameter list.
Definition: procedure.c:2503
void remove_module_entity(entity m)
Definition: procedure.c:1188
static const char * prefix
#define code_undefined_p(x)
Definition: ri.h:758
@ is_value_code
Definition: ri.h:3031
@ is_storage_return
Definition: ri.h:2491
#define value_code(x)
Definition: ri.h:3067
#define TK_FUNCTION
Definition: syn_yacc.c:310
#define TK_PROGRAM
Definition: syn_yacc.c:325
#define TK_BLOCKDATA
Definition: syn_yacc.c:284
list add_formal_return_code(list fpl)
Update the formal and actual parameter lists by adding the return code variable as last argument.
Definition: return.c:209

References add_formal_return_code(), AddEntityToDeclarations(), BLOCKDATA_PREFIX, CleanLocalEntities(), code_declarations, code_undefined_p, COMMON_PREFIX, concatenate(), CurrentPackage, DeclareVariable(), ENDP, entity_domain, entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, entity_undefined_p, FatalError, FindEntity(), FindOrCreateEntity(), free(), free_type(), function_body, gen_find_tabulated(), get_string_property(), ImplicitType(), InitAreas(), initialize_common_size_map(), instruction_to_statement(), intrinsic_entity_p(), is_storage_return, is_type_functional, is_type_void, is_value_code, MAIN_PREFIX, make_code(), make_functional(), make_language_fortran(), make_sequence(), make_storage(), make_storage_rom(), make_type(), make_value(), MakeEmptyInstructionBlock(), module_local_name(), MODULE_SEP_STRING, NIL, ParserError(), pips_debug, pips_user_warning, prefix, PushBlock(), remove_module_entity(), ScanFormalParameters(), set_current_module_entity(), SetChains(), strdup(), string_undefined, SubstituteAlternateReturns(), TK_BLOCKDATA, TK_FUNCTION, TK_PROGRAM, TOP_LEVEL_MODULE_NAME, type_undefined, type_undefined_p, user_warning, UU, value_code, value_code_p, value_undefined, and value_undefined_p.

+ Here is the call graph for this function:

◆ MakeDataStatement()

void MakeDataStatement ( list  ldr,
list  ldv 
)

Receives as first input an implicit list of references, including implicit DO, and as second input an list of value using pseudo-intrinsic REPEAT_VALUE() to replicate values.

Generates a call statement to STATIC-INITIALIZATION(), with a call to DATA_LIST to prefix ldr (unlike IO list). Processes the information as AnalyzeData() used to do it. Add the new data call statement to the initializations field of the current module.

Parameters
ldrdr
ldvdv

Definition at line 524 of file declaration.c.

525 {
530 
531  pips_assert("The static initialization pseudo-intrinsic is defined",
532  !entity_undefined_p(dl));
533 
534  pldr = make_call_expression(dl, ldr);
536  gen_nconc(CONS(EXPRESSION, pldr, NIL), ldv),
538  strdup(PrevComm));
539  PrevComm[0] = '\0';
540  iPrevComm = 0;
541 
544 }
statement make_call_statement(string, list, entity, string)
This function is limited to intrinsics calls...
Definition: statement.c:1274
#define STATIC_INITIALIZATION_NAME
Definition: ri-util-local.h:79
#define DATA_LIST_FUNCTION_NAME
Definition: ri-util-local.h:81
code entity_code(entity e)
Definition: entity.c:1098
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
#define code_initializations(x)
Definition: ri.h:788

References code_initializations, CONS, DATA_LIST_FUNCTION_NAME, entity_code(), entity_undefined, entity_undefined_p, EXPRESSION, expression_undefined, FindEntity(), gen_nconc(), get_current_module_entity(), iPrevComm, make_call_expression(), make_call_statement(), NIL, pips_assert, PrevComm, sequence_statements, STATEMENT, statement_undefined, STATIC_INITIALIZATION_NAME, strdup(), and TOP_LEVEL_MODULE_NAME.

+ Here is the call graph for this function:

◆ MakeDoInst()

void MakeDoInst ( syntax  s,
range  r,
string  l 
)

this function creates a do loop statement.

s is a reference to the do variable.

r is the range of the do loop.

l is the label of the last statement of the loop.

This free is not nice for the caller! Nor for the debugger.

Let's build a sequence with loop range assignments

Definition at line 1167 of file statement.c.

1171 {
1172  instruction ido, instblock_do;
1173  statement stmt_do;
1174  entity dovar, dolab;
1175 
1176  if (!syntax_reference_p(s))
1177  FatalError("MakeDoInst", "function call as DO variable\n");
1178 
1179  if (reference_indices(syntax_reference(s)) != NULL)
1180  FatalError("MakeDoInst", "variable reference as DO variable\n");
1181 
1184  /* This free is not nice for the caller! Nor for the debugger. */
1185  free_syntax(s);
1186 
1187  dolab = MakeLabel((strcmp(l, "BLOCKDO") == 0) ? "" : l);
1188 
1189  instblock_do = MakeEmptyInstructionBlock();
1190  stmt_do = instruction_to_statement(instblock_do);
1191 
1192  if(get_bool_property("PARSER_LINEARIZE_LOOP_BOUNDS")) {
1196 
1199  make_loop(dovar, r, stmt_do, dolab,
1201  UU),
1202  NIL));
1203  }
1204  else {
1205  /* Let's build a sequence with loop range assignments */
1207  make_loop(dovar, r, stmt_do, dolab,
1209  UU),
1210  NIL));
1212 
1213  if(!normalized_linear_p(ni)) {
1216  make_basic(is_basic_int, (void*) 4));
1220  }
1221 
1222  if(!normalized_linear_p(nu)) {
1225  make_basic(is_basic_int, (void*) 4));
1229  }
1230 
1231  if(!normalized_linear_p(nl)) {
1234  make_basic(is_basic_int, (void*) 4));
1238  }
1239  ido = make_instruction_block(a);
1240  }
1241  }
1242  else {
1244  make_loop(dovar, r, stmt_do, dolab,
1246  UU),
1247  NIL));
1248  }
1249 
1250  LinkInstToCurrentBlock(ido, true);
1251 
1252  PushBlock(instblock_do, l);
1253 }
execution make_execution(enum execution_utype tag, void *val)
Definition: ri.c:838
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
#define NORMALIZE_EXPRESSION(e)
#define normalized_linear_p(x)
Definition: ri.h:1779
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
@ is_instruction_loop
Definition: ri.h:1471
#define reference_indices(x)
Definition: ri.h:2328
#define range_lower(x)
Definition: ri.h:2288
@ is_execution_sequential
Definition: ri.h:1189

References CONS, entity_to_expression(), entity_undefined, FatalError, free_syntax(), get_bool_property(), get_current_module_entity(), instruction_to_statement(), is_basic_int, is_execution_sequential, is_instruction_loop, LinkInstToCurrentBlock(), make_assign_instruction(), make_basic(), make_execution(), make_instruction(), make_instruction_block(), make_loop(), make_new_scalar_variable_with_prefix(), MakeEmptyInstructionBlock(), MakeLabel(), NIL, NORMALIZE_EXPRESSION, normalized_linear_p, PushBlock(), range_increment, range_lower, range_upper, reference_indices, reference_variable, STATEMENT, syntax_reference, syntax_reference_p, and UU.

+ Here is the call graph for this function:

◆ MakeElseInst()

int MakeElseInst ( bool  is_else_p)

This function is used to handle either an ELSE or an ELSEIF construct.

No open block can be closed by this ELSE

Generate a CONTINUE to carry the comments but not the label because the ELSE is not represented in the IR and cannot carry comments. The ELSEIF is transformed into an IF which can carry comments and label but the prettyprint of structured code is nicer if the comments are carried by a CONTINUE in the previous block. Of course, this is not good for unstructured code since comments end up far from their intended target or attached to a dead CONTINUE if the previous block ends up with a GO TO.

The current label is temporarily hidden.

generate a CONTINUE to carry the label because the ELSE is not represented in the IR

Parameters
is_else_ps_else_p

Definition at line 1522 of file statement.c.

1523 {
1524  statement if_stmt;
1525  test if_test;
1526  int elsifs;
1527  bool has_comments_p = (iPrevComm != 0);
1528 
1529  if(CurrentBlock==0) {
1530  /* No open block can be closed by this ELSE */
1531  ParserError("MakeElseInst", "unexpected ELSE statement\n");
1532  }
1533 
1534  elsifs = BlockStack[CurrentBlock-1].elsifs ;
1535 
1536  if (strcmp("ELSE", BlockStack[CurrentBlock-1].l))
1537  ParserError("MakeElseInst", "block if statement badly nested\n");
1538 
1539  if (has_comments_p) {
1540  /* Generate a CONTINUE to carry the comments but not the label
1541  because the ELSE is not represented in the IR and cannot carry
1542  comments. The ELSEIF is transformed into an IF which can carry
1543  comments and label but the prettyprint of structured code is
1544  nicer if the comments are carried by a CONTINUE in the previous
1545  block. Of course, this is not good for unstructured code since
1546  comments end up far from their intended target or attached to
1547  a dead CONTINUE if the previous block ends up with a GO TO.
1548 
1549  The current label is temporarily hidden. */
1550  string ln = strdup(get_current_label_string());
1554  free(ln);
1555  }
1556 
1557  (void) PopBlock();
1558 
1559  if_stmt = STATEMENT(CAR(BlockStack[CurrentBlock-1].c));
1560 
1561  if (! instruction_test_p(statement_instruction(if_stmt)))
1562  FatalError("MakeElseInst", "no block if statement\n");
1563 
1564  if_test = instruction_test(statement_instruction(if_stmt));
1565 
1566  PushBlock(statement_instruction(test_false(if_test)), "ENDIF");
1567 
1568  if (is_else_p && !empty_current_label_string_p()) {
1569  /* generate a CONTINUE to carry the label because the ELSE is not
1570  represented in the IR */
1572  }
1573 
1574  return( BlockStack[CurrentBlock-1].elsifs = elsifs ) ;
1575 }
#define test_false(x)
Definition: ri.h:2837
#define instruction_test_p(x)
Definition: ri.h:1515
#define instruction_test(x)
Definition: ri.h:1517
void set_current_label_string(string ln)
Definition: parser.c:81
string get_current_label_string()
Definition: parser.c:76
bool empty_current_label_string_p()
Definition: parser.c:87

References BlockStack, CAR, CurrentBlock, empty_current_label_string_p(), FatalError, free(), get_current_label_string(), instruction_test, instruction_test_p, iPrevComm, LinkInstToCurrentBlock(), make_continue_instruction(), ParserError(), PopBlock(), PushBlock(), reset_current_label_string(), set_current_label_string(), STATEMENT, statement_instruction, strdup(), and test_false.

Referenced by MakeEndifInst().

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

◆ MakeEmptyInstructionBlock()

instruction MakeEmptyInstructionBlock ( void  )

this function creates an empty block

Definition at line 654 of file statement.c.

655 {
656  return(make_instruction_block(NIL));
657 }

References make_instruction_block(), and NIL.

Referenced by MakeBlockIfInst(), MakeCurrentFunction(), MakeDoInst(), and MakeWhileDoInst().

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

◆ MakeEnddoInst()

void MakeEnddoInst ( void  )

inkInstToCurrentBlock(MakeZeroOrOneArgCallInst("ENDDO", expression_undefined));

Although it is not really an instruction, the ENDDO statement may carry comments and be labelled when closing a DO label structure.

An unlabelled ENDDO can only close one loop. This cannot be performed by LinkInstToCurrentBlock().

Definition at line 1611 of file statement.c.

1612 {
1613  if(CurrentBlock<=1) {
1614  ParserError("MakeEnddoInst", "Unexpected ENDDO statement\n");
1615  }
1616 
1617  if (strcmp("BLOCKDO", BlockStack[CurrentBlock-1].l)
1618  &&strcmp(lab_I, BlockStack[CurrentBlock-1].l))
1619  ParserError("MakeEnddoInst", "block do statement badly nested\n");
1620 
1621  /*LinkInstToCurrentBlock(MakeZeroOrOneArgCallInst("ENDDO",
1622  expression_undefined));*/
1623  /* Although it is not really an instruction, the ENDDO statement may
1624  * carry comments and be labelled when closing a DO label structure.
1625  */
1627 
1628  /* An unlabelled ENDDO can only close one loop. This cannot be
1629  * performed by LinkInstToCurrentBlock().
1630  */
1631  if (strcmp("BLOCKDO", BlockStack[CurrentBlock-1].l)==0)
1632  (void) PopBlock();
1633 }

References BlockStack, CurrentBlock, lab_I, LinkInstToCurrentBlock(), make_continue_instruction(), ParserError(), and PopBlock().

+ Here is the call graph for this function:

◆ MakeEndifInst()

void MakeEndifInst ( void  )

generate a CONTINUE to carry the comments

Definition at line 1578 of file statement.c.

1579 {
1580  int elsifs = -1;
1581 
1582  if(CurrentBlock==0) {
1583  ParserError("MakeEndifInst", "unexpected ENDIF statement\n");
1584  }
1585 
1586  if (iPrevComm != 0) {
1587  /* generate a CONTINUE to carry the comments */
1589  }
1590 
1591  if (BlockStack[CurrentBlock-1].l != NULL &&
1592  strcmp("ELSE", BlockStack[CurrentBlock-1].l) == 0) {
1593  elsifs = MakeElseInst(true);
1595  }
1596  if (BlockStack[CurrentBlock-1].l == NULL ||
1597  strcmp("ENDIF", BlockStack[CurrentBlock-1].l)) {
1598  ParserError("MakeEndifInst", "block if statement badly nested\n");
1599  }
1600  else {
1601  elsifs = BlockStack[CurrentBlock-1].elsifs ;
1602  }
1603  pips_assert( "MakeEndifInst", elsifs >= 0 ) ;
1604 
1605  do {
1606  (void) PopBlock();
1607  } while( elsifs-- != 0 ) ;
1608 }
int MakeElseInst(bool is_else_p)
This function is used to handle either an ELSE or an ELSEIF construct.
Definition: statement.c:1522

References BlockStack, CurrentBlock, iPrevComm, LinkInstToCurrentBlock(), make_continue_instruction(), MakeElseInst(), ParserError(), pips_assert, and PopBlock().

+ Here is the call graph for this function:

◆ MakeEntry()

instruction MakeEntry ( entity  e,
list  lfp 
)

An ENTRY statement is substituted by a labelled continue.

The ENTRY entity is created as in MakeExternalFunction() and MakeCurrentFunction(). list of formal parameters

current module cm

The parser expects an instruction and not a statement. I use a block wrapping to avoid tampering with lab_I.

entity e = FindOrCreateEntity(cmn, en);

result type

current chunk (temporary)

list of effective formal parameters

Name conflicts could be checked here as in MakeCurrentFunction()

Keep track of the effective formal parameters of the current module cm at the first call to MakeEntry and reallocate static variables.

Check if the static area is empty and define a specific common if not.

Too early: StaticArea is not defined yet. Postpone to ProcessEntry. if(area_size(type_area(entity_type(StaticArea)))!=0) { MakeEntryCommon(cm, StaticArea); }

Compute the result type and make sure a functional entity is being used.

In case of previous declaration in the current module

Entity e must not be destroyed if fe is a function because e must carry the result.

In case of previous declaration in the current module

Entry fe may have been encountered earlier and typed from the parameter list

This depends on what has been done in LocalToGlobal and SafeLocalToGlobal

This depends on what has been done in LocalToGlobal and SafeLocalToGlobal

A call site for fe has been encountered in another module

Should now be the normal case...

The entry formal parameters should be removed if they are not formal parameters of the current module... but they are referenced. They cannot be preserved although useless because they may be dimensionned by expressions legal for this entry but not for the current module. They should be removed later when dead code elimination let us know which variables are used by each entry.

Temporarily, the formal parameters of entry fe are declared in cm to keep the code consistent but they are supposedly not added to cm's declarations... because FindOrCreateEntity() does not update declarations. MakeAtom() does not redeclare formal parameters.

Let's assume it works for undefined storages..

Should it really be officially declared?

Remove it from the declaration list

fp may appear in a type statement and/or an executable statement: the information is now lost.

Request some post-processing

Parameters
lfpentry, local to retrieve potential explicit typing

Definition at line 1810 of file procedure.c.

1813 {
1814  entity cm = get_current_module_entity(); /* current module cm */
1815  entity l = make_new_label(cm);
1817  /* The parser expects an instruction and not a statement. I use
1818  * a block wrapping to avoid tampering with lab_I.
1819  */
1821  /* entity e = FindOrCreateEntity(cmn, en); */
1822  entity fe = entity_undefined;
1823  bool is_a_function = entity_function_p(get_current_module_entity());
1824  type rt = type_undefined; /* result type */
1825  list cc = list_undefined; /* current chunk (temporary) */
1826  list lefp = list_undefined; /* list of effective formal parameters */
1827 
1828  pips_debug(1, "Begin for entry %s\n", entity_name(e));
1829 
1830  /* Name conflicts could be checked here as in MakeCurrentFunction() */
1831 
1832  /* Keep track of the effective formal parameters of the current module cm
1833  * at the first call to MakeEntry and reallocate static variables.
1834  */
1835  if(EmptyEntryListsP()) {
1836  MAP(ENTITY, fp, {
1840  }, entity_declarations(cm));
1841 
1842  /* Check if the static area is empty and define a specific common
1843  * if not.
1844  */
1845  /* Too early: StaticArea is not defined yet. Postpone to ProcessEntry.
1846  if(area_size(type_area(entity_type(StaticArea)))!=0) {
1847  MakeEntryCommon(cm, StaticArea);
1848  }
1849  */
1850  }
1851 
1852  /* Compute the result type and make sure a functional entity is being
1853  * used.
1854  */
1855  if(is_a_function) {
1856  rt = MakeResultType(e, type_undefined);
1857  /* In case of previous declaration in the current module */
1858  /* Entity e must not be destroyed if fe is a function because e
1859  * must carry the result.
1860  */
1861  fe = SafeLocalToGlobal(e, rt);
1862  }
1863  else {
1864  rt = make_type(is_type_void, UU);
1865  /* In case of previous declaration in the current module */
1866  fe = LocalToGlobal(e);
1867  }
1868 
1869  lefp = TranslateEntryFormals(fe, lfp);
1870  UpdateFormalStorages(fe, lefp);
1871 
1872  /* Entry fe may have been encountered earlier and typed from the
1873  parameter list */
1874  if(!type_undefined_p(entity_type(fe))) {
1875  free_type(entity_type(fe));
1877  }
1878  TypeFunctionalEntity(fe, rt);
1879  UpdateFunctionalType(fe, lefp);
1880 
1881  /* This depends on what has been done in LocalToGlobal and SafeLocalToGlobal */
1884  }
1885  else {
1886  pips_assert("storage must be rom", storage_rom_p(entity_storage(fe)));
1887  }
1888 
1889  /* This depends on what has been done in LocalToGlobal and SafeLocalToGlobal */
1892  }
1893  else {
1894  value val = entity_initial(fe);
1895  code c = code_undefined;
1896 
1897  if(value_unknown_p(val)) {
1898  /* A call site for fe has been encountered in another module */
1901  }
1902  else {
1903  pips_assert("value is code", value_code_p(val));
1904  c = value_code(entity_initial(fe));
1905  if(code_undefined_p(c)) {
1907  }
1908  else if(ENDP(code_declarations(c))) {
1909  /* Should now be the normal case... */
1910  code_declarations(c) = lefp;
1911  }
1912  else {
1913  pips_internal_error("Code should not (yet) be defined for entry fe...");
1914  }
1915  }
1916  }
1917 
1918  /* The entry formal parameters should be removed if they are not
1919  * formal parameters of the current module... but they are referenced.
1920  * They cannot be preserved although useless because they may be
1921  * dimensionned by expressions legal for this entry but not for the
1922  * current module. They should be removed later when dead code elimination
1923  * let us know which variables are used by each entry.
1924  *
1925  * Temporarily, the formal parameters of entry fe are declared in cm
1926  * to keep the code consistent but they are supposedly not added to
1927  * cm's declarations... because FindOrCreateEntity() does not update
1928  * declarations. MakeAtom() does not redeclare formal parameters.
1929  */
1930  for(cc = lfp; !ENDP(cc); POP(cc)) {
1931  entity fp = ENTITY(CAR(cc));
1932  storage fps = entity_storage(fp);
1933 
1934  if(storage_undefined_p(fps) || !storage_formal_p(fps)) {
1935  /* Let's assume it works for undefined storages.. */
1936  free_storage(fps);
1938  make_formal(cm, 0));
1939  /* Should it really be officially declared? */
1940  if(!IsEffectiveFormalParameterP(fp)) {
1941  /* Remove it from the declaration list */
1942  /*
1943  entity_declarations(cm) =
1944  arguments_rm_entity(entity_declarations(cm), fp);
1945  */
1947  pips_debug(1, "Entity %s removed from declarations for %s\n",
1948  entity_name(fp), module_local_name(cm));
1949  gen_remove(&entity_declarations(cm), fp);
1950  pips_user_warning("Variable %s seems to be used before it is declared"
1951  " as a formal parameter for entry %s. It is legal "
1952  "if it only appears in a type statement.\n",
1953  entity_local_name(fp), entity_name(e));
1954  /* fp may appear in a type statement and/or an
1955  executable statement: the information is now
1956  lost. */
1957  /*
1958  ParserError("MakeEntry",
1959  "Formal parameters of entries cannot appear textually"
1960  " in executable statements before they are declared"
1961  " (Fortran 77 Standard, 15.7.4, pp. 15-13)");
1962  */
1963  }
1964  }
1965  }
1966  }
1967 
1968  /* Request some post-processing */
1969  AddEntryLabel(l);
1970  AddEntryTarget(s);
1971  AddEntryEntity(fe);
1972 
1973  ifdebug(2) {
1974  (void) fprintf(stderr, "Declarations of formal parameters for entry %s:\n",
1975  entity_name(fe));
1977  (void) fprintf(stderr, "Declarations for current module %s:\n",
1978  entity_name(cm));
1980  }
1981 
1982  pips_debug(1, "End for entry %s\n", entity_name(fe));
1983 
1984  return i;
1985 }
void free_storage(storage p)
Definition: ri.c:2231
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
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
void AddEntryLabel(entity l)
Definition: procedure.c:1513
type MakeResultType(entity e, type r)
The result type of a function may be carried by e, by r or be implicit.
Definition: procedure.c:1754
entity LocalToGlobal(entity e)
Definition: procedure.c:1801
bool IsEffectiveFormalParameterP(entity f)
Definition: procedure.c:1534
void AddEntryTarget(statement s)
Definition: procedure.c:1518
void AddEffectiveFormalParameter(entity f)
Keep track of the formal parameters for the current module.
Definition: procedure.c:1529
static list TranslateEntryFormals(entity e, list lfp)
list of formal parameters wrongly declared in current module
Definition: procedure.c:1539
void UpdateFormalStorages(entity m, list lfp)
this function check and set if necessary the storage of formal parameters in lfp.
Definition: procedure.c:2522
void AddEntryEntity(entity e)
Definition: procedure.c:1523
void TypeFunctionalEntity(entity fe, type r)
Definition: procedure.c:2257
bool entity_function_p(entity e)
Definition: entity.c:724
entity make_new_label(entity module)
This function returns a new label.
Definition: entity.c:357
#define code_undefined
Definition: ri.h:757
@ is_storage_formal
Definition: ri.h:2493

References AddEffectiveFormalParameter(), AddEntryEntity(), AddEntryLabel(), AddEntryTarget(), CAR, code_declarations, code_undefined, code_undefined_p, CONS, dump_arguments(), EmptyEntryListsP(), ENDP, ENTITY, entity_declarations, entity_function_p(), entity_initial, entity_is_argument_p(), entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, fprintf(), free_storage(), free_type(), gen_remove(), get_current_module_entity(), ifdebug, is_storage_formal, is_type_void, is_value_code, IsEffectiveFormalParameterP(), list_undefined, LocalToGlobal(), make_code(), make_continue_statement(), make_formal(), make_instruction_block(), make_language_fortran(), make_new_label(), make_sequence(), make_storage(), make_storage_rom(), make_type(), make_value(), MakeResultType(), MAP, module_local_name(), NIL, pips_assert, pips_debug, pips_internal_error, pips_user_warning, POP, SafeLocalToGlobal(), STATEMENT, storage_formal_p, storage_rom_p, storage_undefined_p, strdup(), TranslateEntryFormals(), type_undefined, type_undefined_p, TypeFunctionalEntity(), UpdateFormalStorages(), UpdateFunctionalType(), UU, value_code, value_code_p, value_undefined_p, and value_unknown_p.

+ Here is the call graph for this function:

◆ MakeEquivAtom()

atom MakeEquivAtom ( syntax  s)

this function creates an atom of an equivalence chain.

s is a reference to a variable.

reference offset

substring offset

Equivalenced variables cannot be initialized by a DATA statement: false

In case, the entity is not of type variable, reject it.

In case an adjustable array which is not a formal parameter has been encountered, reject it.

what is the offset of this reference ?

Definition at line 89 of file equivalence.c.

91 {
93  entity e;
94  int o = 0; /* reference offset */
95  int so = 0; /* substring offset */
96 
97  if (!syntax_reference_p(s)) {
98  pips_assert("This is syntax is a call", syntax_call_p(s));
100  SUBSTRING_FUNCTION_NAME) == 0) {
101  list args = call_arguments(syntax_call(s));
102  syntax ss = expression_syntax(EXPRESSION(CAR(args)));
103  expression lb = EXPRESSION(CAR(CDR(args)));
104 
105  pips_assert("syntax is reference",syntax_reference_p(ss));
106 
107  r = syntax_reference(ss);
108  if(expression_constant_p(lb)) {
109  so = expression_to_int(lb)-1;
110  }
111  else {
112  ParserError("MakeEquivAtom",
113  "Non constant substring lower bound in equivalence chain\n");
114  }
115  }
116  else {
117  pips_user_warning("A function call to %s has been identified by the parser "
118  "in an EQUIVALENCE statement. Maybe an array declaration "
119  "should be moved up ahead of the EQUIVALENCE\n",
121  ParserError("MakeEquivAtom", "function call in equivalence chain\n");
122  }
123  }
124  else {
125  r = syntax_reference(s);
126  so = 0;
127  }
128 
129  e = reference_variable(r);
130 
132  pips_user_warning("Formal parameter %s appears in EQUIVALENCE declaration\n",
133  entity_local_name(e));
134  ParserError("MakeEquivAtom", "Formal parameter in equivalence chain\n");
135  }
136 
137  /* Equivalenced variables cannot be initialized by a DATA statement: false */
138  /*
139  if(value_defined_p(entity_initial(e))) {
140  pips_user_warning("Initialized variable %s appears in EQUIVALENCE declaration\n",
141  entity_local_name(e));
142  ParserError("MakeEquivAtom", "Initialized variable in equivalence chain\n");
143  }
144  */
145 
146  /* In case, the entity is not of type variable, reject it. */
147  if(!type_variable_p(entity_type(e))) {
148  pips_user_warning("Illegal symbol %s appears in EQUIVALENCE declaration\n",
149  entity_local_name(e));
150  ParserError("MakeEquivAtom", "Functional variable (?) in equivalence chain.\n");
151  }
152 
153  /* In case an adjustable array which is not a formal parameter has
154  been encountered, reject it. */
156  pips_user_warning("Adjustable array %s appears in EQUIVALENCE declaration\n",
157  entity_local_name(e));
158  ParserError("MakeEquivAtom", "Adjustable array in equivalence chain\n");
159  }
160 
161  /* what is the offset of this reference ? */
162  o = so + OffsetOfReference(r);
163 
164  pips_debug(8, "Offset %d for reference to %s\n",
165  o, entity_local_name(e));
166 
167  return(make_atom(e, o));
168 }
atom make_atom(entity a1, intptr_t a2)
int OffsetOfReference(reference r)
This function computes the numerical offset of a variable element from the begining of the variable.
Definition: declaration.c:1565
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
bool array_with_numerical_bounds_p(entity)
bool array_with_numerical_bounds_p(entity a) input : an array entity output : true if all bounds of a...
Definition: variable.c:1266
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define reference_undefined
Definition: ri.h:2302

References array_with_numerical_bounds_p(), call_arguments, call_function, CAR, CDR, entity_local_name(), entity_storage, entity_type, EXPRESSION, expression_constant_p(), expression_syntax, expression_to_int(), formal_parameter_p(), make_atom(), module_local_name(), OffsetOfReference(), ParserError(), pips_assert, pips_debug, pips_user_warning, reference_undefined, reference_variable, storage_undefined_p, SUBSTRING_FUNCTION_NAME, syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, and type_variable_p.

+ Here is the call graph for this function:

◆ MakeExternalFunction()

entity MakeExternalFunction ( entity  e,
type  r 
)

Assertion: fe is a (functional) global entity and the type of its result is new_r, or it is a formal functional parameter

a function has a rom storage, except for formal functions

an external function has an unknown initial value, else code would be temporarily undefined which is avoided (theoretically forbidden) in PIPS.

fe is added to CurrentFunction's entities

Parameters
rentity to be turned into external function type of result

Definition at line 2372 of file procedure.c.

2375 {
2376  entity fe = entity_undefined;
2377  type new_r = type_undefined;
2378 
2379  pips_debug(8, "Begin for %s\n", entity_name(e));
2380 
2381  if(entity_blockdata_p(e)) {
2382  pips_debug(8, "End for blockdata %s\n", entity_name(e));
2383  return e;
2384  }
2385 
2386  new_r = MakeResultType(e, r);
2387 
2388  pips_debug(9, "external function %s declared\n", entity_name(e));
2389 
2390  fe = LocalToGlobal(e);
2391 
2392  /* Assertion: fe is a (functional) global entity and the type of its
2393  result is new_r, or it is a formal functional parameter */
2394 
2395  TypeFunctionalEntity(fe, new_r);
2396 
2397  /* a function has a rom storage, except for formal functions */
2398 
2401  else
2402  if (! storage_formal_p(entity_storage(e)))
2404  else {
2405  pips_user_warning("unsupported formal function %s\n",
2406  entity_name(fe));
2407  /*
2408  ParserError("MakeExternalFunction",
2409  "Formal functions are not supported by PIPS.\n"); */
2410  }
2411 
2412  /* an external function has an unknown initial value, else code would
2413  * be temporarily undefined which is avoided (theoretically forbidden)
2414  * in PIPS. */
2415  if(entity_initial(fe) == value_undefined)
2417 
2418  /* fe is added to CurrentFunction's entities */
2420 
2421  pips_debug(8, "End for %s\n", entity_name(fe));
2422 
2423  return fe;
2424 }

References AddEntityToDeclarations(), entity_blockdata_p(), entity_initial, entity_name, entity_storage, entity_undefined, get_current_module_entity(), LocalToGlobal(), make_storage_rom(), make_value_unknown(), MakeResultType(), pips_debug, pips_user_warning, storage_formal_p, storage_undefined, type_undefined, TypeFunctionalEntity(), and value_undefined.

Referenced by DeclareExternalFunction(), MakeAtom(), and MakeCallInst().

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

◆ MakeFormalParameter()

void MakeFormalParameter ( entity  m,
entity  fp,
int  nfp 
)

This function transforms an untyped entity into a formal parameter.

fp is an entity generated by FindOrCreateEntity() for instance, and nfp is its rank in the formal parameter list.

A specific type is used for the return code variable which may be adde by the parser to handle alternate returns. See return.c offset (i.e. rank) of formal parameter

Parameters
fpmodule of formal parameter
nfpformal parameter

Definition at line 2466 of file procedure.c.

2470 {
2471  // pips_assert("type is undefined", entity_type(fp) == type_undefined);
2472  if(!type_undefined_p(entity_type(fp))) {
2473  pips_user_warning("Formal parameter \"%s\" may be used several times\n",
2474  entity_local_name(fp));
2475  ParserError("MakeFormalParameter",
2476  "formal parameter should not be already typed");
2477  }
2478 
2482  make_value_unknown()),
2483  NIL,NIL));
2484  }
2487  }
2488  else {
2489  entity_type(fp) = ImplicitType(fp);
2490  }
2491 
2492  entity_storage(fp) =
2494 
2496 }
bool ReturnCodeVariableP(entity rcv)
Definition: return.c:145

References entity_initial, entity_local_name(), entity_storage, entity_type, formal_label_replacement_p(), ImplicitType(), is_basic_int, is_basic_string, is_storage_formal, is_type_variable, make_basic(), make_formal(), make_storage(), make_type(), make_value_unknown(), make_variable(), MakeTypeVariable(), NIL, ParserError(), pips_user_warning, ReturnCodeVariableP(), SubstituteAlternateReturnsP(), and type_undefined_p.

Referenced by ScanFormalParameters().

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

◆ MakeFortranBinaryCall()

expression MakeFortranBinaryCall ( entity  op,
expression  e1,
expression  e2 
)
Parameters
opp
e11
e22

Definition at line 502 of file expression.c.

506 {
508 
510  ParserError("MakeFortranBinaryCall", "Unexpected implied DO\n");
511  }
512 
513  e = MakeBinaryCall(op, e1, e2);
514 
515  return e;
516 }

References expression_implied_do_p(), expression_undefined, MakeBinaryCall(), and ParserError().

+ Here is the call graph for this function:

◆ MakeFortranType()

type MakeFortranType ( tag  t,
value  v 
)

this function creates a type that represents a fortran type.

its basic is an int (the length of the fortran type) except in case of strings where the type might be unknown, as in:

  CHARACTER*(*) PF

t is a tag, eg: INTEGER, REAL, ...

v is a value that represents the length in bytes of the type.

Check compatibility between type and byte length

Accept INTEGER*1 for SIMD parallelizer and INTEGER*2 for legacy code and INTEGER*8 for 64 bit machines

Definition at line 1505 of file declaration.c.

1508 {
1509  basic b;
1510  size_t l;
1511 
1512  if (t == is_basic_string) {
1513  if (v == value_undefined) {
1514  l = DefaultLengthOfBasic(t);
1516  make_constant(is_constant_int, (void *) l));
1517  }
1518  b = make_basic(t, v);
1519  }
1520  else {
1521  bool ok = false;
1522  l = (v == value_undefined) ? DefaultLengthOfBasic(t) :
1524 
1525  /* Check compatibility between type and byte length */
1526  switch (t)
1527  {
1528  case is_basic_int:
1529  if(get_bool_property("PARSER_ACCEPT_ANSI_EXTENSIONS"))
1530  /* Accept INTEGER*1 for SIMD parallelizer and INTEGER*2 for
1531  legacy code and INTEGER*8 for 64 bit machines */
1532  ok = l==1 || l==2 || l==4 || l==8;
1533  else
1534  ok = l==4;
1535  break;
1536  case is_basic_float:
1537  ok = l==4 || l==8;
1538  break;
1539  case is_basic_logical:
1540  ok = l==1 || l==2 || l==4 || l==8;
1541  break;
1542  case is_basic_complex:
1543  ok = l==8 || l==16;
1544  break;
1545  case is_basic_string:
1546  break;
1547  case is_basic_overloaded:
1548  default: break;
1549  }
1550  if(!ok) {
1551  ParserError("Declaration", "incompatible type length");
1552  }
1553  b = make_basic(t, (void *) l);
1554  }
1555 
1556  return(MakeTypeVariable(b, NIL));
1557 }
static bool ok

References constant_int, DefaultLengthOfBasic(), get_bool_property(), is_basic_complex, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_string, is_constant_int, is_value_constant, make_basic(), make_constant(), make_value(), MakeTypeVariable(), NIL, ok, ParserError(), value_constant, and value_undefined.

+ Here is the call graph for this function:

◆ MakeFortranUnaryCall()

expression MakeFortranUnaryCall ( entity  op,
expression  e1 
)
Parameters
opp
e11

Definition at line 519 of file expression.c.

522 {
524 
525  if(expression_implied_do_p(e1)) {
526  ParserError("MakeFortranUnaryCall", "Unexpected implied DO\n");
527  }
528 
529  e = MakeUnaryCall(op, e1);
530 
531  return e;
532 }

References expression_implied_do_p(), expression_undefined, MakeUnaryCall(), and ParserError().

Referenced by gfc2pips_expr2expression(), gfc2pips_int2expression(), and gfc2pips_real2expression().

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

◆ MakeGotoInst()

instruction MakeGotoInst ( string  n)

this function creates a goto instruction.

n is the target label.

Definition at line 686 of file statement.c.

688 {
691 
692  l = MakeLabel(n);
693 
694  i = make_goto_instruction(l);
695 
696  return i;
697 }

References entity_undefined, instruction_undefined, make_goto_instruction(), and MakeLabel().

Referenced by MakeArithmIfInst(), MakeAssignedOrComputedGotoInst(), and MakeReturn().

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

◆ MakeImpliedDo()

expression MakeImpliedDo ( syntax  v,
range  r,
cons l 
)

expressions from input output lists might contain implied do loops.

with our internal representation, implied do loops are stored as calls to a special intrinsic function whose name is IMPLIED_DO_NAME and whose first argument is the range of the loop.

v is a reference to the do variable.

r is the range of the loop.

l is the list of expressions which are to be read or written according to this implied do loop.

the range is enclosed in an expression

Definition at line 115 of file expression.c.

119 {
120  call c;
121  expression er;
122 
123  if (!syntax_reference_p(v))
124  FatalError("MakeImpliedDo", "function call as DO variable\n");
125 
126  if (reference_indices(syntax_reference(v)) != NULL)
127  FatalError("MakeImpliedDo", "variable reference as DO variable\n");
128 
129  /* the range is enclosed in an expression */
132 
134  CONS(EXPRESSION, er, l));
135 
139 }
#define IMPLIED_DO_NAME
Definition: ri-util-local.h:75
@ is_syntax_range
Definition: ri.h:2692

References CONS, CreateIntrinsic(), EXPRESSION, FatalError, IMPLIED_DO_NAME, is_syntax_call, is_syntax_range, make_call(), make_expression(), make_syntax(), normalized_undefined, reference_indices, syntax_reference, and syntax_reference_p.

Referenced by loop_to_implieddo().

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

◆ MakeIoInstA()

instruction MakeIoInstA ( int  keyword,
list  lci,
list  lio 
)

this function creates an IO statement.

keyword indicates which io statement is to be built (READ, WRITE, ...).

lci is a list of 'control specifications'. its has the following format:

    ("UNIT=", 6, "FMT=", "*", "RECL=", 80, "ERR=", 20)

lio is the list of expressions to write or references to read.

The composite IO with potential branches for ERR and END

The pure io itself

virtual tests to implement ERR= and END= clauses

we scan the list of specifications to detect labels (such as in ERR=20, END=30, FMT=50, etc.), that were stored as integer constants (20, 30, 50) and that must be replaced by labels (_20, _30, _50).

here is a label

UNIT is not defined for INQUIRE (et least) Let's use LUN 0 by default for END et ERR.

Parameters
keywordeyword
lcici
lioio

Definition at line 1715 of file statement.c.

1716 {
1717  cons *l;
1718  /* The composite IO with potential branches for ERR and END */
1720  /* The pure io itself */
1722  /* virtual tests to implement ERR= and END= clauses */
1723  statement io_err = statement_undefined;
1724  statement io_end = statement_undefined;
1726 
1727  for (l = lci; l != NULL; l = CDR(CDR(l))) {
1728  syntax s1;
1729  entity e1;
1730 
1732 
1733  e1 = call_function(syntax_call(s1));
1734 
1735  if (strcmp(entity_local_name(e1), "UNIT=") == 0) {
1736  if( ! expression_undefined_p(unit) )
1738  unit = EXPRESSION(CAR(CDR(l)));
1739  }
1740  }
1741 
1742  /* we scan the list of specifications to detect labels (such as in
1743  ERR=20, END=30, FMT=50, etc.), that were stored as integer constants
1744  (20, 30, 50) and that must be replaced by labels (_20, _30, _50). */
1745  for (l = lci; l != NULL; l = CDR(CDR(l))) {
1746  syntax s1, s2;
1747  entity e1, e2;
1748 
1750  s2 = expression_syntax(EXPRESSION(CAR(CDR(l))));
1751 
1752  pips_assert("syntax is a call", syntax_call_p(s1));
1753  e1 = call_function(syntax_call(s1));
1754  pips_assert("value is constant", value_constant_p(entity_initial(e1)));
1755  pips_assert("constant is not int (thus litteral or call)",
1757 
1758  if (strcmp(entity_local_name(e1), "ERR=") == 0 ||
1759  strcmp(entity_local_name(e1), "END=") == 0 ||
1760  strcmp(entity_local_name(e1), "FMT=") == 0) {
1761  if (syntax_call_p(s2)) {
1762  e2 = call_function(syntax_call(s2));
1763  if (value_constant_p(entity_initial(e2))) {
1765  /* here is a label */
1766  call_function(syntax_call(s2)) =
1768  }
1769  }
1770  e2 = call_function(syntax_call(s2));
1771  if (strcmp(entity_local_name(e1), "FMT=") != 0
1773  /* UNIT is not defined for INQUIRE (et least)
1774  * Let's use LUN 0 by default for END et ERR.
1775  */
1776  unit = int_to_expression(0);
1777  }
1778  if (strcmp(entity_local_name(e1), "ERR=") == 0) {
1780  }
1781  else if (strcmp(entity_local_name(e1), "END=") == 0) {
1783  }
1784  else {
1785  //free_expression(unit);
1786  ;
1787  }
1788  }
1789  }
1790  }
1791 
1792  /*
1793  for (l = lci; CDR(l) != NULL; l = CDR(l)) ;
1794 
1795  CDR(l) = lio;
1796  l = lci;
1797  */
1798 
1799  lci = gen_nconc(lci, lio);
1800 
1803  lci));
1804 
1805  if(statement_undefined_p(io_err) && statement_undefined_p(io_end)) {
1806  io = io_call;
1807  }
1808  else {
1809  list ls = NIL;
1810  if(!statement_undefined_p(io_err)) {
1811  ls = CONS(STATEMENT, io_err, ls);
1812  }
1813  if(!statement_undefined_p(io_end)) {
1814  ls = CONS(STATEMENT, io_end, ls);
1815  }
1816  ls = CONS(STATEMENT, MakeStatement(entity_empty_label(), io_call), ls);
1819  }
1820 
1821  return io;
1822 }
void free_expression(expression p)
Definition: ri.c:853
int unit
UNIT.
Definition: newgen_types.h:97
#define IO_EOF_ARRAY_NAME
array of end of file codes
#define IO_ERROR_ARRAY_NAME
array of error codes for LUNs
#define value_constant_p(x)
Definition: ri.h:3071
@ is_instruction_sequence
Definition: ri.h:1469
#define expression_undefined_p(x)
Definition: ri.h:1224
statement make_check_io_statement(string n, expression u, entity l)
Generate a test to jump to l if flag f is TRUE Used to implement control effects of IO's due to ERR= ...
Definition: statement.c:1691
string NameOfToken(int token)
Definition: statement.c:1636

References call_function, CAR, CDR, CONS, constant_int_p, CreateIntrinsic(), entity_empty_label(), entity_initial, entity_local_name(), EXPRESSION, expression_syntax, expression_undefined, expression_undefined_p, free_expression(), gen_nconc(), instruction_consistent_p(), instruction_undefined, int_to_expression(), IO_EOF_ARRAY_NAME, IO_ERROR_ARRAY_NAME, is_instruction_call, is_instruction_sequence, make_call(), make_check_io_statement(), make_instruction(), make_sequence(), MakeLabel(), MakeStatement(), NameOfToken(), NIL, pips_assert, s1, STATEMENT, statement_undefined, statement_undefined_p, syntax_call, syntax_call_p, value_constant, and value_constant_p.

Referenced by MakeSimpleIoInst1().

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

◆ MakeIoInstB()

instruction MakeIoInstB ( int  keyword,
expression  e1,
expression  e2,
expression  e3,
expression  e4 
)

this function creates a BUFFER IN or BUFFER OUT io statement.

this is not ansi fortran.

e1 is the logical unit.

nobody known the exact meaning of e2

e3 et e4 are references that indicate which variable elements are to be buffered in or out.

Parameters
keywordeyword
e11
e22
e33
e44

Definition at line 1837 of file statement.c.

1840 {
1841  cons * l;
1842 
1843  l = CONS(EXPRESSION, e1,
1844  CONS(EXPRESSION, e2,
1845  CONS(EXPRESSION, e3,
1846  CONS(EXPRESSION, e4, NULL))));
1847 
1850  l)));
1851 }

References CONS, CreateIntrinsic(), EXPRESSION, is_instruction_call, make_call(), make_instruction(), and NameOfToken().

+ Here is the call graph for this function:

◆ MakeIoList()

cons* MakeIoList ( cons l)

This function takes a list of io elements (i, j, t(i,j)), and returns the same list, with a cons cell pointing to a character constant expression 'IOLIST=' before each element of the original list.

(i , j , t(i,j)) becomes ('IOLIST=' , i , 'IOLIST=' , j , 'IOLIST=' , t(i,j))

This IO list is later concatenated to the IO control list to form the argument of an IO function. The tagging is necessary because of this concatenation.

The IOLIST call used to be shared within one IO list. Since sharing is avoided in the PIPS internal representation, they are now duplicated.

to walk thru l

result list

Definition at line 468 of file expression.c.

470 {
471  cons *pc; /* to walk thru l */
472  cons *lr = NIL; /* result list */
473 
474  pc = l;
475  while (pc != NULL) {
477  cons *p = CONS(EXPRESSION, e, NIL);
478 
479  CDR(p) = pc;
480  pc = CDR(pc);
481  CDR(CDR(p)) = NIL;
482 
483  lr = gen_nconc(p, lr);
484  }
485 
486  return(lr);
487 }
expression MakeCharacterConstantExpression(string s)
END_EOLE.
Definition: constant.c:573
#define IO_LIST_STRING_NAME
Definition: ri-util-local.h:82

References CDR, CONS, EXPRESSION, gen_nconc(), IO_LIST_STRING_NAME, MakeCharacterConstantExpression(), and NIL.

+ Here is the call graph for this function:

◆ MakeLabel()

entity MakeLabel ( const char *  )

◆ MakeLogicalIfInst()

instruction MakeLogicalIfInst ( expression  e,
instruction  i 
)

this function creates a logical if statement.

the true part of the test is a block with only one instruction (i), and the false part is an empty block.

Modifications:

  • there is no need for a block in the true branch, any statement can do
  • there is no need for a CONTINUE statement in the false branch, an empty block is plenty
  • MakeStatement() cannot be used for the true and false branches because it disturbs the statement numering

It is not easy to number bt because Yacc reduction order does not help...

Instruction i should not be a block, unless:

  • an alternate return
  • a computed GO TO
  • an assigned GO TO has been desugared.

If the logical IF is labelled, the label has been stolen by the first statement in the block. This shows that label should only be affected by MakeStatement and not by desugaring routines.

statement first = STATEMENT(CAR(l));

Only the alternate return case assert: pips_assert("Block of two instructions or call with return code checks", (gen_length(l)==2 && assignment_statement_p(first)) || (statement_call_p(first)) );

Definition at line 1329 of file statement.c.

1332 {
1333  /* It is not easy to number bt because Yacc reduction order does not help... */
1336  expression cond = fix_if_condition(e);
1338  make_test(cond, bt, bf));
1339 
1340  if (i == instruction_undefined)
1341  FatalError("MakeLogicalIfInst", "bad instruction\n");
1342 
1343  /* Instruction i should not be a block, unless:
1344  * - an alternate return
1345  * - a computed GO TO
1346  * - an assigned GO TO
1347  * has been desugared.
1348  *
1349  * If the logical IF is labelled, the label has been stolen by the
1350  * first statement in the block. This shows that label should only
1351  * be affected by MakeStatement and not by desugaring routines.
1352  */
1353  if(instruction_block_p(i)) {
1354  list l = instruction_block(i);
1355  /* statement first = STATEMENT(CAR(l)); */
1356  /* Only the alternate return case assert:
1357  pips_assert("Block of two instructions or call with return code checks",
1358  (gen_length(l)==2 && assignment_statement_p(first))
1359  ||
1360  (statement_call_p(first))
1361  );
1362  */
1363  MAP(STATEMENT, s, {
1365  }, l);
1366  }
1367  else {
1369  }
1370 
1371  return ti;
1372 }

References FatalError, fix_if_condition(), get_statement_number(), instruction_block, instruction_block_p, instruction_to_statement(), instruction_undefined, is_instruction_test, make_empty_block_statement(), make_instruction(), make_test(), MAP, STATEMENT, and statement_number.

+ Here is the call graph for this function:

◆ MakeNewLabelledStatement()

statement MakeNewLabelledStatement ( entity  l,
instruction  i 
)

Associate label to the first statement in the block because block cannot be labelled.

Definition at line 289 of file statement.c.

292 {
293  statement s;
294 
295  debug(9, "MakeNewLabelledStatement", "begin for label \"%s\" and instruction %s\n",
297 
298  if(instruction_loop_p(i) && get_bool_property("PARSER_SIMPLIFY_LABELLED_LOOPS")) {
301 
302  statement_number(ls) = get_statement_number();//get_next_statement_number();
303  NewStmt(l, c);
305  CONS(STATEMENT, ls, NIL)));
306  }
307  else if(instruction_block_p(i)) {
308  /* Associate label to the first statement in the block because
309  * block cannot be labelled.
310  */
312 
313  statement_label(s1) = l;
314  NewStmt(l, s1);
320  }
321  else {
322  s = make_statement(l,
323  (instruction_goto_p(i))?
324  STATEMENT_NUMBER_UNDEFINED : get_statement_number(),//get_next_statement_number(),
328  NewStmt(l, s);
329  }
330 
331  debug(9, "MakeNewLabelledStatement", "end for label \"%s\"\n",
332  label_local_name(l));
333 
334  return s;
335 }
statement make_block_statement(list body)
Make a block statement from a list of statement.
Definition: statement.c:616
#define instruction_loop_p(x)
Definition: ri.h:1518
#define instruction_goto_p(x)
Definition: ri.h:1524

References CAR, CONS, debug(), empty_comments, empty_extensions(), entity_empty_label(), get_bool_property(), get_statement_number(), instruction_block, instruction_block_p, instruction_goto_p, instruction_identification(), instruction_loop_p, instruction_to_statement(), label_local_name(), make_block_statement(), make_continue_statement(), make_statement(), make_synchronization_none(), NewStmt(), NIL, s1, STATEMENT, statement_label, statement_number, STATEMENT_NUMBER_UNDEFINED, and STATEMENT_ORDERING_UNDEFINED.

Referenced by MakeStatement().

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

◆ MakeParameter()

entity MakeParameter ( entity  e,
expression  x 
)

lint

this function creates a PARAMETER, ie a symbolic constant.

e is an entity.

x is an expression that represents the value of e.

Take the integer part of the floating point constant

Definition at line 52 of file expression.c.

53 {
54  type tp;
55 
56  tp = (entity_type(e) != type_undefined) ? entity_type(e) : ImplicitType(e);
60  }
61  else {
63  user_warning("MakeParameter", "Variable %s redefined as parameter\n",
65  ParserError("MakeParameter", "A variable cannot be redefined as a parameter\n");
66  }
67  else {
68  user_warning("MakeParameter", "Symbol %s redefined as parameter\n",
70  ParserError("MakeParameter", "A symbol cannot be redefined as a parameter\n");
71  }
72  }
75  symbolic s = value_symbolic(v);
78  entity_initial(e) = v;
79  else if(constant_float_p(c) && float_type_p(tp))
80  entity_initial(e) = v;
81  else if(constant_float_p(c) && scalar_integer_type_p(tp)) {
82  /* Take the integer part of the floating point constant */
83  double fval = constant_float(c);
84  long long int ival = (long long int) fval;
86  constant_int(c) = ival;
87  entity_initial(e) = v;
88  }
89  else
90  entity_initial(e) = v;
91  }
92  else {
93  user_warning("MakeParameter", "Initial value for variable %s redefined\n",
95  FatalError("MakeParameter", "An initial value cannot be redefined by parameter\n");
96  }
97 
98  return(e);
99 }
value MakeValueSymbolic(expression e)
this function creates a value for a symbolic constant.
Definition: constant.c:581
bool scalar_integer_type_p(type)
Definition: type.c:3276
bool float_type_p(type)
Definition: type.c:3263
#define constant_tag(x)
Definition: ri.h:847
#define constant_float_p(x)
Definition: ri.h:851
#define symbolic_constant(x)
Definition: ri.h:2599
#define value_symbolic(x)
Definition: ri.h:3070
#define constant_float(x)
Definition: ri.h:853
static char * x
Definition: split_file.c:159

References constant_float, constant_float_p, constant_int, constant_int_p, constant_tag, entity_initial, entity_local_name(), entity_storage, entity_type, FatalError, float_type_p(), ImplicitType(), int, is_constant_int, is_type_functional, make_functional(), make_storage_rom(), make_type(), MakeValueSymbolic(), NIL, ParserError(), scalar_integer_type_p(), storage_ram_p, storage_undefined_p, symbolic_constant, type_undefined, user_warning, value_symbolic, value_undefined_p, value_unknown_p, and x.

Referenced by step_parameter().

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

◆ MakeResultType()

type MakeResultType ( entity  e,
type  r 
)

The result type of a function may be carried by e, by r or be implicit.

A new type structure is allocated, unless r is used as new result type.

e is a function that was implicitly declared as a variable. this may happen in Fortran.

pips_assert("undefined type", r == type_undefined);

The variable may have been typed, for instance implicitly, but then it appears in a CALL statement and its new type is void. Added for formal parameters.

Well... this should be useless because e is already typed. FI: I do not believe copy_type() is necessary in spite of the non orthogonality...

Definition at line 1754 of file procedure.c.

1757 {
1758  type te = entity_type(e);
1759  type new_r = type_undefined;
1760 
1761  if (te != type_undefined) {
1762  if (type_variable_p(te)) {
1763  /* e is a function that was implicitly declared as a variable.
1764  this may happen in Fortran. */
1765  pips_debug(2, "variable --> fonction\n");
1766  /* pips_assert("undefined type", r == type_undefined); */
1767  if(type_undefined_p(r))
1768  new_r = copy_type(te);
1769  else {
1770  /* The variable may have been typed, for instance
1771  implicitly, but then it appears in a CALL statement and
1772  its new type is void. Added for formal parameters. */
1773  pips_assert("The new result type is void", type_void_p(r));
1774  new_r = r;
1775  }
1776  }
1777  else if (type_functional_p(te)) {
1778  /* Well... this should be useless because e is already typed.
1779  * FI: I do not believe copy_type() is necessary in spite of
1780  * the non orthogonality...
1781  */
1782  new_r = functional_result(type_functional(te));
1783  }
1784  else {
1785  pips_internal_error("Unexpected type %s for entity %s",
1786  type_to_string(te), entity_name(e));
1787  }
1788  }
1789  else {
1790  if(type_undefined_p(r)) {
1791  new_r = ImplicitType(e);
1792  }
1793  else {
1794  new_r = r;
1795  }
1796  }
1797  pips_assert("type new_r is defined", !type_undefined_p(new_r));
1798  return new_r;
1799 }

References copy_type(), entity_name, entity_type, functional_result, ImplicitType(), pips_assert, pips_debug, pips_internal_error, type_functional, type_functional_p, type_to_string(), type_undefined, type_undefined_p, type_variable_p, and type_void_p.

Referenced by MakeEntry(), and MakeExternalFunction().

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

◆ MakeReturn()

instruction MakeReturn ( expression  e)

Assign e to the return code variable, but be sure not to count this assignment as a user instruction. Wrap if with the Go To in a block and return the block instruction.

See how code is synthesized for computed goto's...

Let's try to provide more useful information to the user

inst = MakeZeroOrOneArgCallInst("STOP", e);

Definition at line 445 of file return.c.

446 {
448 
450  user_error("MakeReturn",
451  "Lines %d-%d: Alternate return not supported. "
452  "Standard return generated\n",
454  }
455 
456  if (end_label == entity_undefined) {
458  }
459 
461  /* Assign e to the return code variable, but be sure not to count
462  * this assignment as a user instruction. Wrap if with the Go To
463  * in a block and return the block instruction.
464  *
465  * See how code is synthesized for computed goto's...
466  */
469 
472  // (void) get_next_statement_number();
475  }
477  /* Let's try to provide more useful information to the user */
478  /* inst = MakeZeroOrOneArgCallInst("STOP", e); */
479  if(expression_call_p(e)) {
480  const char* mn = get_current_module_name();
482 
484  ("STOP",
485  MakeCharacterConstantExpression(strdup(concatenate("\"", sn, " in ", mn, "\"", NULL))));
486  }
487  else {
488  pips_internal_error("unexpected argument type for RETURN");
489  }
490  }
491  else {
493  }
494 
495  return inst;
496 }
#define user_error(fn,...)
Definition: misc-local.h:265
bool expression_call_p(expression e)
Definition: expression.c:415
static bool substitute_stop_p
Definition: return.c:53
LOCAL entity end_label
This function creates a goto instruction to label end_label.
Definition: return.c:386

References call_function, concatenate(), CONS, end_label, end_label_local_name, entity_local_name(), entity_undefined, expression_call_p(), expression_syntax, expression_undefined_p, get_current_module_name(), get_statement_number(), instruction_consistent_p(), instruction_to_statement(), instruction_undefined, line_b_I, line_e_I, make_instruction_block(), make_set_rc_statement(), MakeCharacterConstantExpression(), MakeGotoInst(), MakeLabel(), MakeZeroOrOneArgCallInst(), NIL, pips_internal_error, src, STATEMENT, statement_number, strdup(), substitute_rc_p, substitute_stop_p, syntax_call, user_error, and uses_alternate_return_p().

+ Here is the call graph for this function:

◆ MakeSimpleIoInst1()

instruction MakeSimpleIoInst1 ( int  keyword,
expression  unit 
)

Functionally PRINT is a special case of WRITE

Parameters
keywordeyword

Definition at line 1854 of file statement.c.

1855 {
1857  expression std, format, unite;
1858  cons * lci;
1859 
1860  switch(keyword) {
1861  case TK_READ:
1862  case TK_PRINT:
1865  unite = MakeCharacterConstantExpression("UNIT=");
1866  format = MakeCharacterConstantExpression("FMT=");
1867 
1868  lci = CONS(EXPRESSION, unite,
1869  CONS(EXPRESSION, std,
1870  CONS(EXPRESSION, format,
1871  CONS(EXPRESSION, unit, NULL))));
1872  /* Functionally PRINT is a special case of WRITE */
1873  inst = MakeIoInstA((keyword==TK_PRINT)?TK_WRITE:TK_READ,
1874  lci, NIL);
1875  break;
1876  case TK_WRITE:
1877  case TK_OPEN:
1878  case TK_CLOSE:
1879  case TK_INQUIRE:
1880  ParserError("Syntax",
1881  "Illegal syntax in IO statement, "
1882  "Parentheses and arguments required");
1883  break;
1884  case TK_BACKSPACE:
1885  case TK_REWIND:
1886  case TK_ENDFILE:
1887  unite = MakeCharacterConstantExpression("UNIT=");
1888  lci = CONS(EXPRESSION, unite,
1889  CONS(EXPRESSION, unit, NULL));
1890  inst = MakeIoInstA(keyword, lci, NIL);
1891  break;
1892  default:
1893  ParserError("Syntax","Unexpected token in IO statement");
1894  }
1895  return inst;
1896 }
#define LIST_DIRECTED_FORMAT_NAME
Definition: naming-local.h:97
#define TK_CLOSE
Definition: syn_yacc.c:289
#define TK_ENDFILE
Definition: syn_yacc.c:301
#define TK_BACKSPACE
Definition: syn_yacc.c:282
#define TK_WRITE
Definition: syn_yacc.c:337
#define TK_REWIND
Definition: syn_yacc.c:329
#define TK_OPEN
Definition: syn_yacc.c:320
#define TK_PRINT
Definition: syn_yacc.c:324
#define TK_READ
Definition: syn_yacc.c:326
#define TK_INQUIRE
Definition: syn_yacc.c:315
instruction MakeIoInstA(int keyword, list lci, list lio)
this function creates an IO statement.
Definition: statement.c:1715

References CONS, CreateIntrinsic(), EXPRESSION, instruction_undefined, LIST_DIRECTED_FORMAT_NAME, MakeCharacterConstantExpression(), MakeIoInstA(), MakeNullaryCall(), NIL, ParserError(), TK_BACKSPACE, TK_CLOSE, TK_ENDFILE, TK_INQUIRE, TK_OPEN, TK_PRINT, TK_READ, TK_REWIND, and TK_WRITE.

+ Here is the call graph for this function:

◆ MakeSimpleIoInst2()

instruction MakeSimpleIoInst2 ( int  keyword,
expression  f,
list  io_list 
)
Parameters
keywordeyword
io_listo_list

Definition at line 1899 of file statement.c.

1900 {
1902  //expression std, format, unite;
1903  //list cil;
1904 
1905  switch(keyword) {
1906  case TK_READ:
1907  inst = make_simple_Fortran_io_instruction(true, f, io_list);
1908  break;
1909  case TK_PRINT:
1910  inst = make_simple_Fortran_io_instruction(false, f, io_list);
1911  break;
1912  case TK_WRITE:
1913  case TK_OPEN:
1914  case TK_CLOSE:
1915  case TK_INQUIRE:
1916  case TK_BACKSPACE:
1917  case TK_REWIND:
1918  case TK_ENDFILE:
1919  ParserError("Syntax",
1920  "Illegal syntax in IO statement, Parentheses are required");
1921  break;
1922  default:
1923  ParserError("Syntax","Unexpected token in IO statement");
1924  }
1925  return inst;
1926 }
instruction make_simple_Fortran_io_instruction(bool is_read_p, expression f, list io_list)
Derived from the Fortran parser code.
Definition: statement.c:807

References f(), instruction_undefined, make_simple_Fortran_io_instruction(), ParserError(), TK_BACKSPACE, TK_CLOSE, TK_ENDFILE, TK_INQUIRE, TK_OPEN, TK_PRINT, TK_READ, TK_REWIND, and TK_WRITE.

Referenced by make_print_statement().

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

◆ MakeStatement()

statement MakeStatement ( entity  l,
instruction  i 
)

This function makes a statement.

l is the label and i the instruction. We make sure that the label is not declared twice.

Comments are added by LinkInstToCurrentBlock() which calls MakeStatement() because it links the instruction by linking its statement..

GO TO statements are numbered like other statements although they are destroyed by the controlizer. To be changed.

There is an actual label

Well, there is no easy solution to handle labels when Fortran constructs such as alternate returns, computed gotos and assigned gotos are desugared because they may be part of a logical IF, unknowingly.

FI, PJ: the "rice" phase does not handle labels on DO like 100 in: 100 DO 200 I = 1, N

This should be trapped by "rice" when loops are checked to see if Allen/Kennedy's algorithm is applicable

There is not forward reference to the this label. A new statement can be safely allocated.

A forward reference has been encountered and the corresponding statement has been allocated and has been referenced by at least one go to statement.

The CONTINUE slot can be re-used. It is likely to be an artificial CONTINUE added to carry a comment. Maybe it would be better to manage lab_I in a more consistent way by resetting it as soon as it is used. But I did not find the reset!

}

No actual label, no problem

Definition at line 431 of file statement.c.

434 {
435  statement s;
436 
437  debug(5, "MakeStatement", "Begin for label %s and instruction %s\n",
439 
440  pips_assert("MakeStatement", type_statement_p(entity_type(l)));
441  pips_assert("MakeStatement", storage_rom_p(entity_storage(l)));
442  pips_assert("MakeStatement", value_constant_p(entity_initial(l)));
443  pips_assert("MakeStatement",
445 
446  if (!entity_empty_label_p(l)) {
447  /* There is an actual label */
448 
449  /* Well, there is no easy solution to handle labels when Fortran
450  * constructs such as alternate returns, computed gotos and
451  * assigned gotos are desugared because they may be part of a
452  * logical IF, unknowingly.
453  */
454  /*
455  if (instruction_block_p(i))
456  ParserError("makeStatement", "a block must have no label\n");
457  */
458 
459  /* FI, PJ: the "rice" phase does not handle labels on DO like 100 in:
460  * 100 DO 200 I = 1, N
461  *
462  * This should be trapped by "rice" when loops are checked to see
463  * if Allen/Kennedy's algorithm is applicable
464  */
465  if (instruction_loop_p(i)) {
466  if(!get_bool_property("PARSER_SIMPLIFY_LABELLED_LOOPS")) {
467  user_warning("MakeStatement",
468  "DO loop reachable by GO TO via label %s "
469  "cannot be parallelized by PIPS\n",
470  entity_local_name(l));
471  }
472  }
473 
474  if ((s = LabelToStmt(entity_name(l))) == statement_undefined) {
475  /* There is not forward reference to the this label. A new statement
476  * can be safely allocated.
477  */
478  s = MakeNewLabelledStatement(l,i);
479  }
480  else {
481  /* A forward reference has been encountered and the corresponding
482  * statement has been allocated and has been referenced by at least
483  * one go to statement.
484  */
485 
487  /* The CONTINUE slot can be re-used. It is likely to
488  be an artificial CONTINUE added to carry a
489  comment. Maybe it would be better to manage lab_I in a
490  more consistent way by resetting it as soon as it is
491  used. But I did not find the reset! */
492  /*
493  if(statement_continue_p(s)) {
494  free_instruction(statement_instruction(s));
495  statement_instruction(s) = instruction_undefined;
496  statement_number(s) = STATEMENT_NUMBER_UNDEFINED;
497  }
498  else {
499  */
500  user_warning("MakeStatement", "Label %s may be used twice\n",
501  entity_local_name(l));
502  ParserError("MakeStatement", "Same label used twice\n");
503  /* } */
504  }
505  s = ReuseLabelledStatement(s, i);
506  }
507  }
508  else {
509  /* No actual label, no problem */
510  s = make_statement(l,
512  STATEMENT_NUMBER_UNDEFINED : get_statement_number(), //get_next_statement_number(),
516  }
517 
518  return(s);
519 }
#define constant_litteral_p(x)
Definition: ri.h:857
statement ReuseLabelledStatement(statement s, instruction i)
Definition: statement.c:338
statement MakeNewLabelledStatement(entity l, instruction i)
Definition: statement.c:289

References constant_litteral_p, debug(), empty_comments, empty_extensions(), entity_empty_label_p(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, get_bool_property(), get_statement_number(), instruction_block_p, instruction_goto_p, instruction_identification(), instruction_loop_p, instruction_undefined, LabelToStmt(), make_statement(), make_synchronization_none(), MakeNewLabelledStatement(), NIL, ParserError(), pips_assert, ReuseLabelledStatement(), statement_instruction, STATEMENT_NUMBER_UNDEFINED, STATEMENT_ORDERING_UNDEFINED, statement_undefined, storage_rom_p, type_statement_p, user_warning, value_constant, and value_constant_p.

Referenced by GenerateReturn(), LinkInstToCurrentBlock(), MakeBlockIfInst(), and MakeIoInstA().

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

◆ MakeVariableStatic()

void MakeVariableStatic ( entity  v,
bool  force_it 
)

v may have become static because of a DATA statement (OK) or because of another SAVE (NOK)

Could be the stack or the heap area or any common

Parameters
force_itorce_it

Definition at line 245 of file declaration.c.

246 {
248  SaveEntity(v);
249  }
250  else if(storage_ram_p(entity_storage(v))) {
252  if(a==DynamicArea) {
253  SaveEntity(v);
254  }
255  else if(a==StaticArea) {
256  /* v may have become static because of a DATA statement (OK)
257  * or because of another SAVE (NOK)
258  */
259  }
260  else {
261  /* Could be the stack or the heap area or any common */
262  if(force_it) {
263  user_warning("ProcessSave", "Variable %s has already been declared static "
264  "by appearing in Common %s\n",
266  ParserError("parser", "SAVE statement incompatible with previous"
267  " COMMON declaration\n");
268  }
269  else {
270  }
271  }
272  }
273  else {
274  user_warning("parser", "Variable %s cannot be declared static "
275  "be cause of its storage class (tag=%d)\n",
277  ParserError("parser", "SAVE statement incompatible with previous"
278  " declaration (e.g. EXTERNAL).\n");
279  }
280 }

References DynamicArea, entity_local_name(), entity_storage, module_local_name(), ParserError(), ram_section, SaveEntity(), StaticArea, storage_ram, storage_ram_p, storage_tag, storage_undefined, and user_warning.

Referenced by ProcessSave(), and save_initialized_variable().

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

◆ MakeWhileDoInst()

void MakeWhileDoInst ( expression  c,
string  l 
)

This function creates a while do loop statement.

c is the loop condition l is the label of the last statement of the loop.

with the f77 compiler, this is equivalent to c.NE.0

Definition at line 1262 of file statement.c.

1263 {
1264  instruction iwdo, instblock_do;
1265  statement stmt_do;
1266  entity dolab;
1268 
1269  if(!logical_expression_p(c)) {
1270  /* with the f77 compiler, this is equivalent to c.NE.0*/
1272  c, int_to_expression(0));
1273  pips_user_warning("WHILE condition between lines %d and %d is not a logical expression.\n",
1274  line_b_I,line_e_I);
1275  }
1276  else {
1277  cond = c;
1278  }
1279 
1280  dolab = MakeLabel((strcmp(l, "BLOCKDO") == 0) ? "" : l);
1281 
1282  instblock_do = MakeEmptyInstructionBlock();
1283  stmt_do = instruction_to_statement(instblock_do);
1284 
1286  make_whileloop(cond, stmt_do, dolab,make_evaluation_before()));
1287 
1288  LinkInstToCurrentBlock(iwdo, true);
1289 
1290  PushBlock(instblock_do, l);
1291 }
evaluation make_evaluation_before(void)
Definition: ri.c:786
whileloop make_whileloop(expression a1, statement a2, entity a3, evaluation a4)
Definition: ri.c:2937
@ is_instruction_whileloop
Definition: ri.h:1472

References entity_intrinsic(), expression_undefined, instruction_to_statement(), int_to_expression(), is_instruction_whileloop, line_b_I, line_e_I, LinkInstToCurrentBlock(), logical_expression_p(), make_evaluation_before(), make_instruction(), make_whileloop(), MakeBinaryCall(), MakeEmptyInstructionBlock(), MakeLabel(), NON_EQUAL_OPERATOR_NAME, pips_user_warning, and PushBlock().

+ Here is the call graph for this function:

◆ MakeZeroOrOneArgCallInst()

instruction MakeZeroOrOneArgCallInst ( char *  s,
expression  e 
)

this function creates a simple Fortran statement such as RETURN, CONTINUE, ...

s is the name of the intrinsic function.

e is one optional argument (might be equal to expression_undefined).

la liste d'arguments

Definition at line 669 of file statement.c.

672 {
673  cons *l; /* la liste d'arguments */
674 
675  l = (e == expression_undefined) ? NIL : CONS(EXPRESSION, e, NIL);
676 
678  make_call(CreateIntrinsic(s), l)));
679 }

References CONS, CreateIntrinsic(), EXPRESSION, expression_undefined, is_instruction_call, make_call(), make_instruction(), and NIL.

Referenced by GenerateReturn(), gfc2pips_code2instruction__TOP(), MakeAssignedOrComputedGotoInst(), and MakeReturn().

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

◆ MergeTwoChains()

cons* MergeTwoChains ( cons opc1,
cons opc2 
)

this function merges two equivalence chains whose intersection is not empty, ie.

one variable occurs in both chains.

Parameters
opc1pc1
opc2pc2

Definition at line 322 of file equivalence.c.

324 {
325  int deltaoff;
326  cons *pctemp, *pc1, *pc2=NIL;
327 
328  for (pc1 = opc1; pc1 != NIL; pc1 = CDR(pc1)) {
329  for (pc2 = opc2; pc2 != NIL; pc2 = CDR(pc2)) {
330  if (gen_eq((atom_equivar(ATOM(CAR(pc1)))),
331  (atom_equivar(ATOM(CAR(pc2)))))) {
332  break;
333  }
334  }
335  if (pc2 != NIL)
336  break;
337  }
338 
339  if (pc1 == NIL || pc2 == NIL)
340  FatalError("MergeTwoChains", "empty intersection\n");
341 
342  deltaoff = atom_equioff(ATOM(CAR(pc1)))-atom_equioff(ATOM(CAR(pc2)));
343 
344  if (deltaoff < 0) {
345  pctemp = opc2; opc2 = opc1; opc1 = pctemp;
346  }
347  pc1 = opc1;
348  pc2 = opc2;
349 
350  while (1) {
351  atom_equioff(ATOM(CAR(pc2))) += abs(deltaoff);
352  if (CDR(pc2) == NIL)
353  break;
354  pc2 = CDR(pc2);
355  }
356 
357  CDR(pc2) = pc1;
358  return(opc2);
359 }
#define abs(v)
Definition: syntax-local.h:48

References abs, ATOM, atom_equioff, atom_equivar, CAR, CDR, FatalError, gen_eq(), and NIL.

Referenced by AddOrMergeChain().

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

◆ NameOfToken()

string NameOfToken ( int  token)

just to avoid a gcc warning

Parameters
tokenoken

Definition at line 1636 of file statement.c.

1638 {
1639  string name;
1640 
1641  switch (token) {
1642  case TK_BUFFERIN:
1643  name = "BUFFERIN";
1644  break;
1645  case TK_BUFFEROUT:
1646  name = "BUFFEROUT";
1647  break;
1648  case TK_INQUIRE:
1649  name = "INQUIRE";
1650  break;
1651  case TK_OPEN:
1652  name = "OPEN";
1653  break;
1654  case TK_CLOSE:
1655  name = "CLOSE";
1656  break;
1657  case TK_PRINT:
1658  name = "PRINT";
1659  break;
1660  case TK_READ:
1661  name = "READ";
1662  break;
1663  case TK_REWIND:
1664  name = "REWIND";
1665  break;
1666  case TK_WRITE:
1667  name = "WRITE";
1668  break;
1669  case TK_ENDFILE:
1670  name = "ENDFILE";
1671  break;
1672  case TK_BACKSPACE:
1673  name = "BACKSPACE";
1674  break;
1675  default:
1676  FatalError("NameOfToken", "unknown token\n");
1677  name = string_undefined; /* just to avoid a gcc warning */
1678  break;
1679  }
1680 
1681  return(name);
1682 }
#define TK_BUFFEROUT
Definition: syn_yacc.c:286
#define TK_BUFFERIN
Definition: syn_yacc.c:285

References FatalError, string_undefined, TK_BACKSPACE, TK_BUFFERIN, TK_BUFFEROUT, TK_CLOSE, TK_ENDFILE, TK_INQUIRE, TK_OPEN, TK_PRINT, TK_READ, TK_REWIND, and TK_WRITE.

Referenced by MakeIoInstA(), and MakeIoInstB().

+ Here is the caller graph for this function:

◆ NameToCommon()

entity NameToCommon ( string  n)

Check for potential conflicts

Definition at line 1071 of file declaration.c.

1072 {
1073  string c_name = strdup(concatenate(COMMON_PREFIX, n, NULL));
1075  string prefixes[] = {"", MAIN_PREFIX, BLOCKDATA_PREFIX, NULL};
1076  string nature[] = {"function or subroutine", "main", "block data"};
1077  int i = 0;
1078 
1079  c = MakeCommon(c);
1080  free(c_name);
1081 
1082  /* Check for potential conflicts */
1083  for(i=0; prefixes[i]!=NULL; i++) {
1084  string name = strdup(concatenate(prefixes[i], n, NULL));
1086 
1087  if(!entity_undefined_p(ce)) {
1088  user_warning("NameToCommon", "Identifier %s used for a common and for a %s\n",
1089  n, nature[i]);
1090  }
1091 
1092  free(name);
1093  }
1094 
1095  return c;
1096 }
entity MakeCommon(entity e)
MakeCommon: This function creates a common block.
Definition: declaration.c:1047
static string prefixes[]
Definition: entity.c:1433

References BLOCKDATA_PREFIX, COMMON_PREFIX, concatenate(), entity_undefined_p, FindEntity(), FindOrCreateEntity(), free(), MAIN_PREFIX, MakeCommon(), prefixes, strdup(), TOP_LEVEL_MODULE_NAME, and user_warning.

+ Here is the call graph for this function:

◆ NameToFunctionalEntity()

entity NameToFunctionalEntity ( string  name)

Ignore ghost variables, they are not in the current scope

The functional entity must be a formal parameter

The current declaration is wrong and should be fixed later, i.e. by MakeExternalFunction() or MakeCallInst()

It is the name of a blockdata

Parameters
nameame

Definition at line 2217 of file procedure.c.

2218 {
2221  BLOCKDATA_PREFIX, name, NULL),
2222  entity_domain);
2223 
2224  if(entity_undefined_p(f)) {
2227  entity_domain);
2228 
2229  /* Ignore ghost variables, they are *not* in the current scope */
2231 
2232  if(entity_undefined_p(f)) {
2234  }
2237  /* The functional entity must be a formal parameter */
2238  ;
2239  }
2240  else if(storage_undefined_p(entity_storage(f))) {
2241  /* The current declaration is wrong and should be fixed
2242  * later, i.e. by MakeExternalFunction() or MakeCallInst()
2243  */
2244  ;
2245  }
2246  else {
2247  pips_assert("Unexpected kind of functional entity!", true);
2248  }
2249  }
2250  else {
2251  /* It is the name of a blockdata */
2252  ;
2253  }
2254  return f;
2255 }
bool ghost_variable_entity_p(entity e)
Definition: procedure.c:292

References BLOCKDATA_PREFIX, concatenate(), CurrentPackage, entity_domain, entity_storage, entity_undefined, entity_undefined_p, f(), FindOrCreateEntity(), gen_find_tabulated(), ghost_variable_entity_p(), MODULE_SEP_STRING, pips_assert, storage_formal_p, storage_undefined_p, and TOP_LEVEL_MODULE_NAME.

+ Here is the call graph for this function:

◆ NeedKeyword()

int NeedKeyword ( void  )

just to avoid a gcc warning

OTREACHED

Definition at line 1329 of file reader.c.

1330 {
1331  register int i, j;
1332  char * kwcour;
1333 
1334  i = keywidx[(int) stmt_buffer[iStmt]-'A'];
1335 
1336  if (i != UNDEF) {
1337  while ((kwcour = keywtbl[i].keywstr)!=0 &&
1338  kwcour[0]==stmt_buffer[iStmt]) {
1339  if (StmtEqualString(kwcour, iStmt) != false) {
1340  j = CapitalizeStmt(kwcour, iStmt);
1341  return(j);
1342  }
1343  i += 1;
1344  }
1345  }
1346 
1347  ParserError("NeedKeyword", "[scanner] keyword expected\n");
1348 
1349  return(-1); /* just to avoid a gcc warning */
1350 
1351  /*NOTREACHED*/
1352 }

References CapitalizeStmt(), int, iStmt, keywidx, keywtbl, ParserError(), stmt_buffer, StmtEqualString(), and UNDEF.

Referenced by FindAutre(), and FindImplicit().

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

◆ NewStmt()

void NewStmt ( entity  e,
statement  s 
)

this function stores a new association in table StmtHeap: the label of statement s is e.

Definition at line 141 of file statement.c.

144 {
146 
147  pips_assert("The empty label is not associated to a statement",
149 
150  pips_assert("Label e is the label of statement s", e==statement_label(s));
151 
153  user_log("NewStmt: duplicate label: %s\n", entity_name(e));
154  ParserError("NewStmt", "duplicate label\n");
155  }
156 
159 
162  CurrentStmt += 1;
163 }
string l
Definition: statement.c:55
static void init_StmtHeap_buffer(void)
Definition: statement.c:64
static int StmtHeap_buffer_size
Definition: statement.c:60
static void resize_StmtHeap_buffer(void)
Definition: statement.c:74

References CurrentStmt, entity_empty_label_p(), entity_name, init_StmtHeap_buffer(), stmt::l, LabelToStmt(), ParserError(), pips_assert, resize_StmtHeap_buffer(), stmt::s, statement_label, statement_undefined, StmtHeap_buffer, StmtHeap_buffer_size, and user_log().

Referenced by make_goto_instruction(), and MakeNewLabelledStatement().

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

◆ OffsetOfReference()

int OffsetOfReference ( reference  r)

This function computes the numerical offset of a variable element from the begining of the variable.

The variable must have numerical bounds for this function to work. It core dumps for adjustable arrays such as formal parameters.

Use a trick to retrieve the size in bytes of one array element and use the size of the previous dimension

Definition at line 1565 of file declaration.c.

1567 {
1568  cons *pi;
1569  int idim, iindex, pid, o, ilowerbound;
1570 
1571  pi = reference_indices(r);
1572 
1573  for (idim = 0, pid = 1, o = 0; pi != NULL; idim++, pi = CDR(pi)) {
1574  iindex = ExpressionToInt(EXPRESSION(CAR(pi)));
1575  ilowerbound = ValueOfIthLowerBound((reference_variable(r)), idim+1);
1576  /* Use a trick to retrieve the size in bytes of one array element
1577  * and use the size of the previous dimension
1578  */
1579  pid *= SizeOfIthDimension((reference_variable(r)), idim);
1580  o += ((iindex-ilowerbound)*pid);
1581  }
1582 
1583  return(o);
1584 }
int ValueOfIthLowerBound(entity e, int i)
this function returns the size of the ith lower bound of a variable e.
Definition: declaration.c:1591
int ExpressionToInt(expression)
this function computes the value of an integer constant expression and returns it to the calling func...
Definition: size.c:562
int SizeOfIthDimension(entity, int)
this function returns the size of the ith dimension of a variable e.
Definition: size.c:453

References CAR, CDR, EXPRESSION, ExpressionToInt(), reference_indices, reference_variable, SizeOfIthDimension(), and ValueOfIthLowerBound().

Referenced by MakeEquivAtom().

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

◆ parser()

bool parser ( const  string)
Parameters
stringodule

Definition at line 291 of file parser.c.

292 {
293  return the_actual_parser(module, DBR_SOURCE_FILE);
294 }

References module, and the_actual_parser().

+ Here is the call graph for this function:

◆ parser_add_a_macro()

void parser_add_a_macro ( call  c,
expression  e 
)

resize!

expand macros in the macro! It is ok, because referenced macros must appear in preceding lines (F77 15-5, line 3-5).

store the result.

Definition at line 113 of file macros.c.

114 {
115  entity macro = call_function(c);
116 
117  pips_debug(5, "adding macro %s\n", entity_name(macro));
118  pips_assert("macros support initialized", current_macros_size>0);
119 
120  if (current_macro_index>=current_macros_size) /* resize! */
121  {
123  current_macros = (macro_t*)
124  realloc(current_macros, sizeof(macro_t)*current_macros_size);
125  pips_assert("realloc ok", current_macros);
126  }
127 
128  if (find_entity_macro(macro) != NULL) {
129  pips_user_warning("Macro \"%s\" is not yet defined.\n",
130  entity_name(macro));
131  ParserError("parser_add_a_macro",
132  "It may be an undeclared array.\n");
133  }
134 
135  /* expand macros in the macro! It is ok, because
136  * referenced macros must appear in preceding lines (F77 15-5, line 3-5).
137  */
139 
140  /* store the result.
141  */
145 }
static int current_macros_size
Definition: macros.c:54
void parser_substitute_all_macros_in_expression(expression e)
Definition: macros.c:302
static int current_macro_index
Definition: macros.c:55
static macro_t * current_macros
Definition: macros.c:53
static macro_t * find_entity_macro(entity e)
Definition: macros.c:98
Definition: macros.c:48
call lhs
Definition: macros.c:49
expression rhs
Definition: macros.c:50

References call_function, current_macro_index, current_macros, current_macros_size, entity_name, find_entity_macro(), macro_t::lhs, parser_substitute_all_macros_in_expression(), ParserError(), pips_assert, pips_debug, pips_user_warning, and macro_t::rhs.

Referenced by MakeAssignInst().

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

◆ parser_close_macros_support()

void parser_close_macros_support ( void  )

what about the entity? It might exist such a real top-level entity... what if added as a callee... the entity should be destroyed... best would be to have it as a local entity, and have the calles and top-level updates delayed.

Definition at line 72 of file macros.c.

73 {
74  pips_debug(5, "closing macro-expansion support stuff\n");
75 
77  {
78  call c;
79  entity macro;
80 
83 
84  macro = call_function(c);
85  free_call(c);
86 
87  /* what about the entity?
88  * It might exist such a real top-level entity...
89  * what if added as a callee...
90  * the entity should be destroyed...
91  * best would be to have it as a local entity,
92  * and have the calles and top-level updates delayed.
93  */
95  }
96 }
void free_call(call p)
Definition: ri.c:236
void remove_from_called_modules(entity e)
macros are added, although they should not have been.
Definition: procedure.c:354

References call_function, current_macro_index, current_macros, free_call(), free_expression(), macro_t::lhs, pips_debug, and remove_from_called_modules().

Referenced by EndOfProcedure().

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

◆ parser_entity_macro_p()

bool parser_entity_macro_p ( entity  e)

Definition at line 108 of file macros.c.

109 {
110  return find_entity_macro(e)==NULL;
111 }

References find_entity_macro().

+ Here is the call graph for this function:

◆ parser_init_macros_support()

void parser_init_macros_support ( void  )

macros.c

macros.c

??? memory leak...

Definition at line 57 of file macros.c.

58 {
59  pips_debug(5, "initializing macro-expansion support stuff\n");
60 
61  current_macro_index = 0; /* ??? memory leak... */
62 
63  if (current_macros_size==0)
64  {
68  pips_assert("malloc ok", current_macros);
69  }
70 }

References current_macro_index, current_macros, current_macros_size, malloc(), pips_assert, and pips_debug.

Referenced by the_actual_parser().

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

◆ parser_macro_expansion()

void parser_macro_expansion ( expression  e)

of expression

get the macro definition.

duplicated, for latter subs.

replace each formal by its actual.

MUST be a simple reference

if the replacement is a constant, or a reference without calls to external functions, it should be safe

it is important to keep the same expression, for gen_recurse use.

Definition at line 224 of file macros.c.

225 {
226  bool warned = false;
227  macro_t * def;
228  call c, lhs;
229  entity macro;
230  expression rhs;
231  list /* of expression */ lactuals, lformals;
232 
233  if (!expression_call_p(e)) return;
234 
236  macro = call_function(c);
237  lactuals = call_arguments(c);
238 
239  /* get the macro definition. */
240  def = find_entity_macro(macro);
241 
242  if (def==NULL) {
243  pips_debug(5, "no macro definition for %s\n", entity_name(macro));
244  return;
245  }
246 
247  lhs = def->lhs;
248  rhs = copy_expression(def->rhs); /* duplicated, for latter subs. */
249 
250  pips_assert("right macro function", macro == call_function(lhs));
251 
252  lformals = call_arguments(lhs);
253 
254  pips_assert("same #args", gen_length(lactuals)==gen_length(lformals));
255 
257 
258  /* replace each formal by its actual.
259  */
260  for (; !ENDP(lactuals); POP(lactuals), POP(lformals))
261  {
262  expression actu, form;
263 
264  form = EXPRESSION(CAR(lformals)); /* MUST be a simple reference */
265  pips_assert("dummy arg ok",
266  expression_reference_p(form) &&
268 
269  /* if the replacement is a constant, or a reference without
270  * calls to external functions, it should be safe
271  */
272  actu = EXPRESSION(CAR(lactuals));
273 
274  if (!warned && untrusted_call_p(actu)) {
275  pips_user_warning("maybe non safe substitution of macro %s!\n",
276  module_local_name(macro));
277  warned = true;
278  }
279 
280  substitute_expression_in_expression(rhs, form, actu);
281  }
282 
284 
285  /* it is important to keep the same expression, for gen_recurse use.
286  */
290  free(rhs);
291 }
void reset_substitute_expression_in_expression(void)
Definition: macros.c:218
static bool untrusted_call_p(expression e)
Definition: macros.c:164
static void substitute_expression_in_expression(expression tree, expression initial, expression replacement)
substitutes occurences of initial by replacement in tree
Definition: macros.c:197
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528

References call_arguments, call_function, CAR, copy_expression(), ENDP, entity_name, EXPRESSION, expression_call_p(), expression_reference_p(), expression_syntax, find_entity_macro(), free(), free_syntax(), gen_length(), macro_t::lhs, module_local_name(), pips_assert, pips_debug, pips_user_warning, POP, reference_indices, reset_substitute_expression_in_expression(), macro_t::rhs, substitute_expression_in_expression(), syntax_call, syntax_reference, syntax_undefined, and untrusted_call_p().

Referenced by parser_substitute_all_macros().

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

◆ parser_reset_all_reader_buffers()

void parser_reset_all_reader_buffers ( void  )

Definition at line 313 of file reader.c.

314 {
315  iLine = 0, lLine = 0;
316  iStmt = 0, lStmt = 0;
317  iCurrComm = 0;
318  iComm = 0;
319  iPrevComm = 0;
321  EofSeen = false;
322 }
static int iLine
Definition: reader.c:274
int iCurrComm
Definition: reader.c:153
static int lLine
Definition: reader.c:274
static int EofSeen
Definition: reader.c:155
int iComm
Definition: reader.c:153

References EofSeen, i_getchar, iComm, iCurrComm, iLine, iPrevComm, iStmt, l_getchar, lLine, lStmt, and UNDEF.

Referenced by ParserError().

+ Here is the caller graph for this function:

◆ parser_reset_StmtHeap_buffer()

void parser_reset_StmtHeap_buffer ( void  )

statement.c

Definition at line 85 of file statement.c.

86 {
87  CurrentStmt = 0;
88 }

References CurrentStmt.

Referenced by ParserError().

+ Here is the caller graph for this function:

◆ parser_substitute_all_macros()

void parser_substitute_all_macros ( statement  s)

Definition at line 294 of file macros.c.

295 {
296  if (current_macro_index>0 &&
297  get_bool_property("PARSER_EXPAND_STATEMENT_FUNCTIONS"))
299 }
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
void parser_macro_expansion(expression e)
Definition: macros.c:224
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154

References current_macro_index, expression_domain, gen_recurse, gen_true(), get_bool_property(), and parser_macro_expansion().

Referenced by EndOfProcedure(), and parser_substitute_all_macros_in_expression().

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

◆ parser_substitute_all_macros_in_expression()

void parser_substitute_all_macros_in_expression ( expression  e)

Definition at line 302 of file macros.c.

303 {
305 }

References parser_substitute_all_macros().

Referenced by parser_add_a_macro().

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

◆ ParserError()

bool ParserError ( const char *  f,
const char *  m 
)

Maybe a routine called by ParserError() may call ParserError() e.g. AbortOfProcedure() thru remove_ghost_variables()

Get rid of partly declared variables...

Callers may already have pointers towards this function. The prettyprinter core dumps if entity_initial is destroyed. Maybe, I should clean the declarations field in code, as well as decls_text.

The error may occur before the current module entity is defined

GetChar() will reinitialize its own buffer when called

Because of the strange behavior of BeginingOfParsing

CurrentPackage = NULL;

Too bad for memory leak...

FI: let catch_error() take care of this in pipsmake since debug_on() was not activated in ParserError

debug_off();

Should never be executed

Definition at line 116 of file parser.c.

117 {
119 
120  /* Maybe a routine called by ParserError() may call ParserError()
121  * e.g. AbortOfProcedure() thru remove_ghost_variables()
122  */
123  if(InParserError)
124  return false;
125 
126  InParserError = true;
127 
128  uses_alternate_return(false);
131 
132  syn_reset_lex();
133 
134  ResetBlockStack();
135 
136  /* Get rid of partly declared variables... */
137  if(mod!=entity_undefined) {
138  /* Callers may already have pointers towards this function.
139  * The prettyprinter core dumps if entity_initial is
140  * destroyed. Maybe, I should clean the declarations field
141  * in code, as well as decls_text.
142  */
143  /*
144  entity_type(mod) = type_undefined;
145  entity_storage(mod) = storage_undefined;
146  entity_initial(mod) = value_undefined;
147  */
148  value v = entity_initial(mod);
149  code c = value_code(v);
150  code_declarations(c) = NIL;
152 
153  CleanLocalEntities(mod);
154  }
155 
156  /* The error may occur before the current module entity is defined */
159  free(CurrentFN);
160  CurrentFN = NULL;
161 
162  /* GetChar() will reinitialize its own buffer when called */
163 
164  /* Because of the strange behavior of BeginingOfParsing*/
165  /* CurrentPackage = NULL; */
167  /* Too bad for memory leak... */
176  ResetChains();
177  AbortEntries();
179 
180  InParserError = false;
181 
182  /* FI: let catch_error() take care of this in pipsmake since debug_on()
183  was not activated in ParserError */
184  /* debug_off(); */
185  user_error(f,"Parser error between lines %d and %d\n%s\n",
186  line_b_I,line_e_I,m);
187 
188  /* Should never be executed */
189  return true;
190 }
void reset_common_size_map_on_error()
Definition: declaration.c:972
void AbortEntries()
Definition: procedure.c:1473
void AbortOfProcedure()
Definition: procedure.c:386
void parser_reset_all_reader_buffers(void)
Definition: reader.c:313
void error_reset_current_module_entity(void)
To be called by an error management routine only.
Definition: static.c:109
void syn_reset_lex()
static void reset_parser_recursive_call()
Safety for recursive calls of parser required to process entries.
Definition: parser.c:101
bool InParserError
Parser error handling.
Definition: parser.c:113
void soft_reset_alternate_returns()
ParserError() cannot guess if it has been performed or not, because it is reinitialized before and af...
Definition: return.c:284
void parser_reset_StmtHeap_buffer(void)
statement.c
Definition: statement.c:85

References AbortEntries(), AbortOfProcedure(), CleanLocalEntities(), code_declarations, code_decls_text, CurrentFN, CurrentPackage, DynamicArea, entity_initial, entity_undefined, error_reset_current_module_entity(), f(), free(), get_current_module_entity(), HeapArea, InParserError, line_b_I, line_e_I, NIL, parser_reset_all_reader_buffers(), parser_reset_StmtHeap_buffer(), reset_common_size_map_on_error(), reset_parser_recursive_call(), ResetBlockStack(), ResetChains(), ResetReturnCodeVariable(), safe_fclose(), soft_reset_alternate_returns(), StaticArea, string_undefined, SubstituteAlternateReturns(), syn_in, syn_reset_lex(), TOP_LEVEL_MODULE_NAME, user_error, uses_alternate_return(), and value_code.

Referenced by AddVariableToCommon(), AnalyzeData(), CapitalizeStmt(), check_in_declarations(), CheckAndInitializeStmt(), CheckParenthesis(), ComputeAddresses(), DeclareExternalFunction(), DeclarePointer(), DeclareVariable(), EndOfProcedure(), EvalCall(), EvalSyntax(), expression_reference_number(), find_target_position(), fix_if_condition(), fix_storage(), FortranExpressionList(), IsCapKeyword(), LinkInstToCurrentBlock(), make_Fortran_constant_entity(), MakeAssignInst(), MakeAtom(), MakeCurrentFunction(), MakeDataValueSet(), MakeElseInst(), MakeEnddoInst(), MakeEndifInst(), MakeEntryCommon(), MakeEquivAtom(), MakeFormalParameter(), MakeFortranBinaryCall(), MakeFortranType(), MakeFortranUnaryCall(), MakeParameter(), MakeSimpleIoInst1(), MakeSimpleIoInst2(), MakeStatement(), MakeVariableStatic(), NeedKeyword(), NewStmt(), parser_add_a_macro(), PopBlock(), process_static_initialization(), process_value_list(), PushBlock(), ReadLine(), ReadStmt(), remove_ghost_variable_entities(), reset_common_size_map(), SafeSizeOfArray(), SaveChains(), SaveEntity(), store_initial_value(), SubstituteAlternateReturns(), TypeFunctionalEntity(), update_called_modules(), update_functional_type_result(), uses_alternate_return(), and ValueOfIthLowerBound().

+ Here is the call graph for this function:

◆ PipsGetc()

int PipsGetc ( FILE *  fp)

Routine de lecture pour l'analyseur lexical, lex ou flex.

Parameters
fpp

Definition at line 557 of file reader.c.

558 {
559  int eof = false;
560  int c;
561 
562  if (iStmt == SIZE_UNDEF || iStmt >= lStmt) {
563  /*
564  * le statement est vide. On lit et traite le suivant.
565  */
566  if (ReadStmt(fp) == EOF) {
567  eof = true;
568  }
569  else {
570  /*
571  * verifie les parentheses et on recherche les '=' et
572  * les ',' de profondeur zero.
573  */
575 
576  /*
577  * on recherche les operateurs du genre .eq.
578  */
579  FindPoints();
580 
581  if (!FindDo()) {
582  if (!FindImplicit()) {
583  if (!FindIfArith()) {
584  FindIf();
585 
586  if (!FindAssign()) {
587  FindAutre();
588  }
589  }
590  }
591  }
592 
593  iStmt = 0;
594  }
595  }
596 
597  c = stmt_buffer[iStmt++];
598  return((eof) ? EOF : UNQUOTE(c));
599 }
int FindIfArith(void)
Definition: reader.c:1134
void FindPoints()
Definition: reader.c:1220
void CheckParenthesis()
Definition: reader.c:1032
void FindAutre()
Definition: reader.c:1169
int FindAssign(void)
Definition: reader.c:1197
int FindImplicit(void)
Definition: reader.c:1114
int FindDo(void)
Definition: reader.c:1087
#define UNQUOTE(c)
Definition: reader.c:124
int ReadStmt(FILE *fp)
regroupement des lignes du statement en une unique ligne sans continuation
Definition: reader.c:942
void FindIf()
Definition: reader.c:1150

References CheckParenthesis(), FindAssign(), FindAutre(), FindDo(), FindIf(), FindIfArith(), FindImplicit(), FindPoints(), iStmt, lStmt, ReadStmt(), SIZE_UNDEF, stmt_buffer, and UNQUOTE.

+ Here is the call graph for this function:

◆ PopBlock()

instruction PopBlock ( void  )

Definition at line 238 of file statement.c.

239 {
240  if (IsBlockStackEmpty())
241  ParserError("PopBlock", "bottom of stack reached\n");
242 
243  return(BlockStack[--CurrentBlock].i);
244 }

References BlockStack, CurrentBlock, IsBlockStackEmpty(), and ParserError().

Referenced by EndOfProcedure(), LinkInstToCurrentBlock(), MakeElseInst(), MakeEnddoInst(), and MakeEndifInst().

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

◆ print_full_malloc_info()

void print_full_malloc_info ( FILE *  )

◆ print_malloc_info()

void print_malloc_info ( FILE *  )

◆ PrintChain()

void PrintChain ( chain  c)

Definition at line 382 of file equivalence.c.

384 {
385  cons *pca;
386  atom a;
387 
388  ifdebug(9) {
389  pips_debug(9, "Begin: ");
390 
391  for (pca = chain_atoms(c); pca != NIL; pca = CDR(pca)) {
392  a = ATOM(CAR(pca));
393 
394  (void) fprintf(stderr, "(%s,%td) ; ",
396  }
397  (void) fprintf(stderr, "\n");
398  pips_debug(9, "End\n");
399  }
400 }

References ATOM, atom_equioff, atom_equivar, CAR, CDR, chain_atoms, entity_name, fprintf(), ifdebug, NIL, and pips_debug.

Referenced by PrintChains().

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

◆ PrintChains()

void PrintChains ( equivalences  e)

two debugging functions, just in case ...

Definition at line 364 of file equivalence.c.

366 {
367  cons *pcc;
368 
369  if(ENDP(equivalences_chains(e))) {
370  ifdebug(9) {
371  (void) fprintf(stderr, "Empty list of equivalence chains\n");
372  }
373  }
374  else {
375  for (pcc = equivalences_chains(e); pcc != NIL; pcc = CDR(pcc)) {
376  PrintChain(CHAIN(CAR(pcc)));
377  }
378  }
379 }
void PrintChain(chain c)
Definition: equivalence.c:382

References CAR, CDR, CHAIN, ENDP, equivalences_chains, fprintf(), ifdebug, NIL, and PrintChain().

Referenced by ComputeEquivalences().

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

◆ PrintData()

void PrintData ( cons ldvr,
cons ldvl 
)

a debugging function, just in case ...

Parameters
ldvrdvr
ldvldvl

Definition at line 310 of file declaration.c.

312 {
313  cons *pc;
314 
315  debug(7, "PrintData", "Begin\n");
316 
317  for (pc = ldvr; pc != NIL; pc = CDR(pc)) {
318  datavar dvr = DATAVAR(CAR(pc));
319 
320  debug(7, "PrintData", "(%s,%d), ", entity_name(datavar_variable(dvr)),
321  datavar_nbelements(dvr));
322 
323  }
324  debug(7, "PrintData", "\n");
325 
326  for (pc = ldvl; pc != NIL; pc = CDR(pc)) {
327  dataval dvl = DATAVAL(CAR(pc));
328 
329  if (constant_int_p(dataval_constant(dvl))) {
330  debug(7, "PrintData", "(%d,%d), ", constant_int(dataval_constant(dvl)),
331  dataval_nboccurrences(dvl));
332  }
333  else {
334  debug(7, "PrintData", "(x,%d), ", dataval_nboccurrences(dvl));
335  }
336 
337  }
338  debug(7, "PrintData", "End\n\n");
339 }

References CAR, CDR, constant_int, constant_int_p, DATAVAL, dataval_constant, dataval_nboccurrences, DATAVAR, datavar_nbelements, datavar_variable, debug(), entity_name, and NIL.

+ Here is the call graph for this function:

◆ ProcessEntries()

void ProcessEntries ( void  )

To avoid an include of the prettyprint library and/or a compiler warning.

The declarations for cm are likely to be incorrect. They must be synthesized by the prettyprinter.

Regenerate a SOURCE_FILE .f without entries for the module itself

To avoid warnings about column 73 when the code is parsed again

Not ot duplicate DATA statements for static variables and common variables in every entry

Process each entry

Postponed to the_actual_parser() which needs to know entries were encountered

ResetEntries();

Definition at line 2171 of file procedure.c.

2172 {
2174  code c = entity_code(cm);
2175  list ce = NIL;
2176  list cl = NIL;
2177  list ct = NIL;
2178  text txt = text_undefined;
2179  bool line_numbering_p = get_bool_property("PRETTYPRINT_STATEMENT_NUMBER");
2180  bool data_statements_p = get_bool_property("PRETTYPRINT_DATA_STATEMENTS");
2181  /* To avoid an include of the prettyprint library and/or a
2182  compiler warning. */
2183  /* The declarations for cm are likely to be incorrect. They must be
2184  * synthesized by the prettyprinter.
2185  */
2186  free(code_decls_text(c));
2187  code_decls_text(c) = strdup("");
2188  /* Regenerate a SOURCE_FILE .f without entries for the module itself */
2189  /* To avoid warnings about column 73 when the code is parsed again */
2190  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", false);
2192  make_text_resource_and_free(module_local_name(cm), DBR_SOURCE_FILE, ".f",
2193  txt);
2194 
2195  /* Not ot duplicate DATA statements for static variables and
2196  common variables in every entry */
2197  set_bool_property("PRETTYPRINT_DATA_STATEMENTS", false);
2198 
2199  /* Process each entry */
2200  for(ce = entry_entities, cl = entry_labels, ct = entry_targets;
2201  !ENDP(ce) && !ENDP(cl) && !ENDP(ct); POP(ce), POP(cl), POP(ct)) {
2202  entity e = ENTITY(CAR(ce));
2203  entity l = ENTITY(CAR(cl));
2204  statement t = STATEMENT(CAR(ct));
2205 
2206  pips_assert("Target and label match", l==statement_label(t));
2207 
2208  ProcessEntry(cm, e, t);
2209  }
2210  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", line_numbering_p);
2211  set_bool_property("PRETTYPRINT_DATA_STATEMENTS", data_statements_p);
2212  /* Postponed to the_actual_parser() which needs to know entries were
2213  encountered */
2214  /* ResetEntries(); */
2215 }
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
text text_named_module(entity, entity, statement)
bool make_text_resource_and_free(const char *, const char *, const char *, text)
Definition: print.c:82
static void ProcessEntry(entity cm, entity e, statement t)
Definition: procedure.c:2036
void set_bool_property(const char *, bool)
#define text_undefined
Definition: text.h:91

References CAR, code_decls_text, ENDP, ENTITY, entity_code(), entry_entities, entry_labels, entry_targets, free(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), make_text_resource_and_free(), module_local_name(), NIL, pips_assert, POP, ProcessEntry(), set_bool_property(), STATEMENT, statement_label, strdup(), text_named_module(), and text_undefined.

Referenced by EndOfProcedure().

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

◆ ProcessSave()

void ProcessSave ( entity  v)

Definition at line 282 of file declaration.c.

283 {
284  MakeVariableStatic(v, true);
285 }
void MakeVariableStatic(entity v, bool force_it)
Definition: declaration.c:245

References MakeVariableStatic().

+ Here is the call graph for this function:

◆ PushBlock()

void PushBlock ( instruction  i,
string  l 
)

Definition at line 221 of file statement.c.

224 {
225  if (IsBlockStackFull())
226  ParserError("PushBlock", "top of stack reached\n");
227 
228  pips_assert("PushBlock", instruction_block_p(i));
229 
230  BlockStack[CurrentBlock].i = i;
231  BlockStack[CurrentBlock].l = l;
232  BlockStack[CurrentBlock].c = NULL;
233  BlockStack[CurrentBlock].elsifs = 0;
234  CurrentBlock += 1;
235 }
bool IsBlockStackFull()
Definition: statement.c:215

References BlockStack, CurrentBlock, instruction_block_p, IsBlockStackFull(), ParserError(), and pips_assert.

Referenced by MakeBlockIfInst(), MakeCurrentFunction(), MakeDoInst(), MakeElseInst(), and MakeWhileDoInst().

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

◆ ReadLine()

int ReadLine ( FILE *  fp)

All physical lines of a statement are put together in a unique buffer called "line_buffer".

Each character in each physical line is retrieved with GetChar().

on entre dans ReadLine avec Column = 1

Read all comment lines you can

Read label

Check continuation character

Keep track of the first and last comment lines and of the first and last statement lines. These two intervals may intersect.

Append current comment CurrComm to Comm if it is a continuation. Save Comm in PrevComm and CurrComm in Comm if it is a first statement line.

FI: this is all wrong

Why destroy comments because there are continuation lines?

tmp_b_C = tmp_e_C = UNDEF;

Read the rest of the line, skipping SPACEs but handling string constants

Parameters
fpp

Definition at line 765 of file reader.c.

766 {
767  static char QuoteChar = '\000';
768  int TypeOfLine;
769  int i, c;
770  char label[6];
771  int ilabel = 0;
772 
773  /* on entre dans ReadLine avec Column = 1 */
774  pips_assert("ReadLine", Column == 1);
775 
777 
778  /* Read all comment lines you can */
779  while (strchr(START_COMMENT_LINE,(c = GetChar(fp))) != NULL) {
780  if (tmp_b_C == UNDEF)
781  tmp_b_C = (c=='\n')?LineNumber-1:LineNumber;
782 
783  ifdebug(8) {
784  if(c=='\n')
785  debug(8, "ReadLine",
786  "Empty comment line detected at line %d "
787  "for comment starting at line %d\n",
788  LineNumber-1, tmp_b_C);
789  }
790 
791  while(c!=EOF) {
792  if (iCurrComm >= CommSize-2)
794  CurrComm[iCurrComm++] = c;
795  if(c=='\n') break;
796  c = GetChar(fp);
797  }
798  }
799 
800  CurrComm[iCurrComm] = '\0';
801 
802  pips_debug(7, "comment CurrComm: (%d) --%s--\n", iCurrComm, CurrComm);
803 
804  if (c != EOF) {
805  /* Read label */
806  for (i = 0; i < 5; i++) {
807  if (c != ' ') {
808  if (isdigit(c)) {
809  label[ilabel++] = c;
810  }
811  else {
812  pips_user_warning("Unexpected character '%c' (0x%x)\n",
813  c, (int) c);
814  ParserError("ReadLine",
815  "non numeric character in label!\n");
816  }
817  }
818  c = GetChar(fp);
819  }
820 
821  if (ilabel > 0) {
822  label[ilabel] = '\0';
823  strcpy(tmp_lab_I, label);
824  }
825  else
826  strcpy(tmp_lab_I, "");
827 
828  /* Check continuation character */
829  TypeOfLine = (c != ' ' && c!= '0') ? CONTINUATION_LINE : FIRST_LINE;
830 
831  /* Keep track of the first and last comment lines and of the first and
832  * last statement lines. These two intervals may intersect.
833  *
834  * Append current comment CurrComm to Comm if it is a continuation. Save Comm
835  * in PrevComm and CurrComm in Comm if it is a first statement line.
836  */
837  if (TypeOfLine == FIRST_LINE) {
838  if(iComm!=0) {
839  Comm[iComm] = '\0';
840  (void) strcpy(PrevComm, Comm);
841  Comm[0] = '\0';
842  }
843  else {
844  PrevComm[0] = '\0';
845  }
846  iPrevComm = iComm;
847 
848  (void) strcpy(Comm, CurrComm);
849  iComm = iCurrComm;
850  iCurrComm = 0;
851  CurrComm[0] = '\0';
852 
853  if (tmp_b_C != UNDEF)
854  tmp_e_C = LineNumber - 1;
856  }
857  else if (TypeOfLine == CONTINUATION_LINE){
858  if (iCurrComm+iComm >= CommSize-2)
860  (void) strcat(Comm, CurrComm);
861  iComm += iCurrComm;
862  iCurrComm = 0;
863  CurrComm[0] = '\0';
864 
865  /* FI: this is all wrong */
866  /* Why destroy comments because there are continuation lines? */
867  /* tmp_b_C = tmp_e_C = UNDEF; */
868  }
869 
870  pips_debug(7, "comment Comm: (%d) --%s--\n", iComm, Comm);
871  pips_debug(7, "comment PrevComm: (%d) --%s--\n", iPrevComm, PrevComm);
872 
873  /* Read the rest of the line, skipping SPACEs but handling string constants */
874 
875  while ((c = GetChar(fp)) != '\n') {
876  if (c == '\'' || c == '"') {
877  if (EtatQuotes == INQUOTES) {
878  if(c == QuoteChar)
880  else {
881  if (EtatQuotes == INQUOTEQUOTE)
883  }
884  }
885  else if(EtatQuotes == INQUOTEBACKSLASH)
887  else {
889  QuoteChar = c;
890  }
891  }
892  else {
893  if (EtatQuotes == INQUOTEQUOTE)
895  else if(EtatQuotes == INQUOTES && c == '\\')
897  else if(EtatQuotes == INQUOTEBACKSLASH)
899  }
900 
901  if (lLine>line_buffer_size-5)
903 
904  if (EtatQuotes == NONINQUOTES) {
905  if (c != ' ') {
906  line_buffer[lLine++] = islower(c)? toupper(c) : c;
907  }
908  }
909  else {
910  line_buffer[lLine++] = QUOTE(c);
911  }
912 
913  }
914 
915  if (EtatQuotes == INQUOTEQUOTE)
917  }
918  else {
919  TypeOfLine = EOF_LINE;
920  if (tmp_b_C != UNDEF)
921  tmp_e_C = LineNumber - 1;
923 
924  if(iComm!=0) {
925  Comm[iComm] = '\0';
926  (void) strcpy(PrevComm, Comm);
927  Comm[0] = '\0';
928  }
929  else {
930  PrevComm[0] = '\0';
931  }
932  iPrevComm = iComm;
933  }
934 
935  pips_debug(9, "Aggregation of continuation lines: '%s'\n", (char*)line_buffer);
936 
937  return(TypeOfLine);
938 }
#define FIRST_LINE
Definition: reader.c:134
char * Comm
reader.c
Definition: reader.c:152
char * CurrComm
Definition: reader.c:152
static void init_line_buffer(void)
Definition: reader.c:255
static int tmp_e_C
Definition: reader.c:424
#define CONTINUATION_LINE
Definition: reader.c:135
#define INQUOTEBACKSLASH
Definition: reader.c:360
static int line_buffer_size
Definition: reader.c:252
#define EOF_LINE
Definition: reader.c:136
static void resize_comment_buffers(void)
Definition: reader.c:172
static char tmp_lab_I[6]
Definition: reader.c:425
static int tmp_b_I
Variables qui serviront a mettre a jour les numeros de la premiere et de la derniere ligne de comment...
Definition: reader.c:424
#define NONINQUOTES
Definition: reader.c:357
static int CommSize
Definition: reader.c:154
#define QUOTE(c)
Definition: reader.c:123
#define INQUOTES
Definition: reader.c:358
static int tmp_b_C
Definition: reader.c:424
int GetChar(FILE *fp)
Routine de lecture physique.
Definition: reader.c:614
static int * line_buffer
le buffer contenant la ligne que l'on doit lire en avance pour se rendre compte qu'on a finit de lire...
Definition: reader.c:251
static void resize_line_buffer(void)
Definition: reader.c:265
static int EtatQuotes
Definition: reader.c:356
#define INQUOTEQUOTE
Definition: reader.c:359

References Column, Comm, CommSize, CONTINUATION_LINE, CurrComm, debug(), EOF_LINE, EtatQuotes, FIRST_LINE, GetChar(), iComm, iCurrComm, ifdebug, init_line_buffer(), INQUOTEBACKSLASH, INQUOTEQUOTE, INQUOTES, iPrevComm, line_buffer, line_buffer_size, LineNumber, lLine, NONINQUOTES, ParserError(), pips_assert, pips_debug, pips_user_warning, PrevComm, QUOTE, resize_comment_buffers(), resize_line_buffer(), START_COMMENT_LINE, tmp_b_C, tmp_b_I, tmp_e_C, tmp_lab_I, and UNDEF.

Referenced by ReadStmt().

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

◆ ReadStmt()

int ReadStmt ( FILE *  fp)

regroupement des lignes du statement en une unique ligne sans continuation

It would be nice to move the current comments from Comm to PrevComm, but it is just too late because of the repeat until control structure down: ReadLine() has already been called and read the first line of the next statement. Hence, CurrComm is needed.

Memorize the line number before to find next Statement

Update the current final lines for instruction and comments

Initialize temporary beginning and end line numbers

Parameters
fpp

Definition at line 942 of file reader.c.

943 {
944  int TypeOfLine;
945  int result;
946 
948 
949  if (EofSeen == true) {
950  /*
951  * on a rencontre EOF, et on a deja purge le dernier
952  * statement. On arrete.
953  */
954  EofSeen = false;
955  result = EOF;
956  }
957  else {
958  /*
959  * on a deja lu la 1ere ligne sauf au moment de l'initialisation
960  */
961  if (lLine == UNDEF) {
962  lLine = 0;
963 
964  tmp_b_I = tmp_e_I = UNDEF;
965  tmp_b_C = tmp_e_C = UNDEF;
966 
967  if ((TypeOfLine = ReadLine(fp)) == CONTINUATION_LINE) {
968  ParserError("ReadStmt",
969  "[scanner] incorrect continuation line as first line\n");
970  }
971  else if (TypeOfLine == FIRST_LINE) {
972  /* It would be nice to move the current comments from
973  * Comm to PrevComm, but it is just too late because of
974  * the repeat until control structure down: ReadLine()
975  * has already been called and read the first line of
976  * the next statement. Hence, CurrComm is needed.
977  */
978  }
979  else if (TypeOfLine == EOF_LINE) {
980  result = EOF;
981  }
982  }
983 
984  line_b_I = tmp_b_I;
985  line_b_C = tmp_b_C;
986  strcpy(lab_I, tmp_lab_I);
987 
988  lStmt = 0;
989  /* Memorize the line number before to find next Statement*/
991  do {
992  iLine = 0;
993  while (iLine < lLine) {
994  if (lStmt>stmt_buffer_size-20)
997  }
998  lLine = 0;
999 
1000  /* Update the current final lines for instruction and comments */
1001  line_e_I = tmp_e_I;
1002  line_e_C = tmp_e_C;
1003 
1004  /* Initialize temporary beginning and end line numbers */
1005  tmp_b_I = tmp_e_I = UNDEF;
1006  tmp_b_C = tmp_e_C = UNDEF;
1007 
1008  } while ((TypeOfLine = ReadLine(fp)) == CONTINUATION_LINE) ;
1009 
1010  stmt_buffer[lStmt++] = '\n';
1011  iStmt = 0;
1012 
1013  line_e_I = (tmp_b_C == UNDEF) ? tmp_b_I-1 : tmp_b_C-1;
1014 
1015  if (TypeOfLine == EOF_LINE)
1016  EofSeen = true;
1017 
1018  result = 1;
1019 
1020  ifdebug(7) {
1021  size_t i;
1022  pips_debug(7, "stmt: (%td)\n", lStmt);
1023  for(i=0; i<lStmt; i++)
1024  putc((int) stmt_buffer[i], stderr);
1025  }
1026  }
1027 
1028  return(result);
1029 }
static int tmp_e_I
Definition: reader.c:424
int line_e_C
Definition: reader.c:452
int ReadLine(FILE *fp)
All physical lines of a statement are put together in a unique buffer called "line_buffer".
Definition: reader.c:765
int line_b_C
Definition: reader.c:452
char lab_I[]
Definition: parser.c:69
static size_t stmt_buffer_size
Definition: reader.c:219
static void init_stmt_buffer(void)
Definition: reader.c:222
static void resize_stmt_buffer(void)
Definition: reader.c:232

References CONTINUATION_LINE, EOF_LINE, EofSeen, FIRST_LINE, ifdebug, iLine, init_stmt_buffer(), iStmt, lab_I, line_b_C, line_b_I, line_buffer, line_e_C, line_e_I, LineNumber, lLine, lStmt, ParserError(), pips_debug, ReadLine(), resize_stmt_buffer(), stmt_buffer, stmt_buffer_size, StmtLineNumber, tmp_b_C, tmp_b_I, tmp_e_C, tmp_e_I, tmp_lab_I, and UNDEF.

Referenced by PipsGetc().

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

◆ reify_ghost_variable_entity()

void reify_ghost_variable_entity ( entity  e)

It is possible to change one's mind and effectively use an entity which was previously assumed useless.

Definition at line 284 of file procedure.c.

285 {
289 }
cons * arguments_rm_entity(cons *a, entity e)
Definition: arguments.c:94

References arguments_rm_entity(), entity_is_argument_p(), ghost_variable_entities, list_undefined_p, and pips_assert.

Referenced by CheckLeftHandSide().

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

◆ remove_from_called_modules()

void remove_from_called_modules ( entity  e)

macros are added, although they should not have been.

Definition at line 354 of file procedure.c.

355 {
356  bool found = false;
357  list l = called_modules;
358  const char* name = module_local_name(e);
359 
360  if (!called_modules) return;
361 
362  if (same_string_p(name, STRING(CAR(called_modules)))) {
364  found = true;
365  } else {
366  list lp = called_modules;
367  l = CDR(called_modules);
368 
369  for(; !ENDP(l); POP(l), POP(lp)) {
370  if (same_string_p(name, STRING(CAR(l)))) {
371  CDR(lp) = CDR(l);
372  found = true;
373  break;
374  }
375  }
376  }
377 
378  if (found) {
379  pips_debug(3, "removing %s from callees\n", entity_name(e));
380  CDR(l) = NIL;
381  free(STRING(CAR(l)));
382  gen_free_list(l);
383  }
384 }

References called_modules, CAR, CDR, ENDP, entity_name, free(), gen_free_list(), module_local_name(), NIL, pips_debug, POP, same_string_p, and STRING.

Referenced by parser_close_macros_support().

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

◆ remove_ghost_variable_entities()

void remove_ghost_variable_entities ( bool  substitute_p)

The debugging message must use the variable name before it is freed

We already are in ParserError()! Too bad for the memory leak

Parameters
substitute_pubstitute_p

Definition at line 206 of file procedure.c.

207 {
209  MAP(ENTITY, e,
210  {
211  /* The debugging message must use the variable name before it is freed
212  */
213  pips_debug(1, "entity '%s'\n", entity_name(e));
214  pips_assert("Entity e is defined and has type \"variable\" if substitution is required\n",
215  !substitute_p
216  || (!entity_undefined_p(e)
219  user_warning("remove_ghost_variable_entities",
220  "Entity \"%s\" does not really exist but appears"
221  " in an equivalence chain!\n",
222  entity_name(e));
223  if(!ParserError("remove_ghost_variable_entities",
224  "Cannot remove still accessible ghost variable\n")) {
225  /* We already are in ParserError()! Too bad for the memory leak */
227  return;
228  }
229  }
230  else {
232 
233  if(entity_undefined_p(fe)) {
234  pips_assert("Entity fe cannot be undefined", false);
235  }
236  else if(type_undefined_p(entity_type(fe))) {
237  pips_assert("Type for entity fe cannot be undefined", false);
238  }
239  else if(type_functional_p(entity_type(fe))) {
241 
242 
243  /*
244  if(intrinsic_entity_p(fe)) {
245  user_warning("remove_ghost_variable_entities",
246  "Intrinsic %s is probably declared in a strange useless way\n",
247  module_local_name(fe));
248  }
249  */
250 
251 
252  if(substitute_p) {
253  pips_debug(1,
254  "Start substitution of variable %s by module %s\n",
255  entity_name(e), entity_name(fe));
257  pips_debug(1,
258  "End for substitution of variable %s by module %s\n",
259  entity_name(e), entity_name(fe));
260  }
261  }
262  else {
263  pips_assert("Type t for entity fe should be functional", false);
264  }
265 
267  }
268  pips_debug(1, "destroyed\n");
269  },
271 
273 }
bool entity_in_equivalence_chains_p(entity e)
Definition: equivalence.c:403
void substitute_ghost_variable_in_statement(statement stmt, entity v, entity f)
Definition: procedure.c:139
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
void remove_variable_entity(entity)
Definition: variable.c:1306

References ENTITY, entity_in_equivalence_chains_p(), entity_local_name(), entity_name, entity_type, entity_undefined_p, function_body, ghost_variable_entities, list_undefined, list_undefined_p, local_name_to_top_level_entity(), MAP, ParserError(), pips_assert, pips_debug, remove_variable_entity(), substitute_ghost_variable_in_statement(), type_functional_p, type_undefined_p, type_variable_p, and user_warning.

Referenced by AbortOfProcedure(), and EndOfProcedure().

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

◆ remove_module_entity()

void remove_module_entity ( entity  m)

It is assumed that neither variables nor areas have been declared in m but that m may have been declared by EXTERNAL in other modules.

Definition at line 1188 of file procedure.c.

1189 {
1190  /* It is assumed that neither variables nor areas have been declared in m
1191  * but that m may have been declared by EXTERNAL in other modules.
1192  */
1193  gen_array_t modules = db_get_module_list();
1194  int module_list_length = gen_array_nitems(modules);
1195  int i = 0;
1196 
1197  for(i = 0; i < module_list_length; i++) {
1199 
1200  if(!entity_undefined_p(om)) {
1201  value v = entity_initial(om);
1202 
1203  if(!value_undefined_p(v) && !value_unknown_p(v)) {
1204  code c = value_code(v);
1205 
1206  if(!code_undefined_p(c)) {
1207  ifdebug(1) {
1208  if(gen_in_list_p(m, code_declarations(c))) {
1209  pips_debug(1,
1210  "Declaration of module %s removed from %s's declarations",
1211  entity_name(m), entity_name(om));
1212  }
1213  }
1214  gen_remove(&code_declarations(c), m);
1215  }
1216  }
1217  }
1218  }
1219  gen_array_full_free(modules);
1220  free_entity(m);
1221 }
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void gen_array_full_free(gen_array_t a)
Definition: array.c:77
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
gen_array_t db_get_module_list(void)
Get an array of all the modules (functions, procedures and compilation units) of a workspace.
Definition: database.c:1266

References code_declarations, code_undefined_p, db_get_module_list(), entity_initial, entity_name, entity_undefined_p, free_entity(), gen_array_full_free(), gen_array_item(), gen_array_nitems(), gen_in_list_p(), gen_remove(), ifdebug, local_name_to_top_level_entity(), pips_debug, value_code, value_undefined_p, and value_unknown_p.

Referenced by MakeCurrentFunction().

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

◆ reset_alternate_returns()

void reset_alternate_returns ( void  )

Definition at line 272 of file return.c.

273 {
274  pips_assert("alternate return list is defined", !list_undefined_p(alternate_returns));
278 }

References alternate_returns, current_number_of_alternate_returns, gen_free_list(), list_undefined, list_undefined_p, and pips_assert.

Referenced by soft_reset_alternate_returns().

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

◆ reset_common_size_map()

void reset_common_size_map ( void  )

Problems:

  • this routine may be called from ParserError()... which should not be called recursively
  • but it maight also be called from somewhere else and ParserError() then should be called A second reset routine must be defined.

Definition at line 954 of file declaration.c.

955 {
959  }
960  else {
961  /* Problems:
962  * - this routine may be called from ParserError()... which should not
963  * be called recursively
964  * - but it maight also be called from somewhere else and ParserError()
965  * then should be called
966  * A second reset routine must be defined.
967  */
968  ParserError("reset_common_size_map", "Resetting a resetted variable!\n");
969  }
970 }
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327

References common_size_map, hash_table_free(), hash_table_undefined, and ParserError().

Referenced by EndOfProcedure(), and gfc2pips_namespace().

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

◆ reset_common_size_map_on_error()

void reset_common_size_map_on_error ( void  )

Definition at line 972 of file declaration.c.

References common_size_map, hash_table_free(), and hash_table_undefined.

Referenced by ParserError().

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

◆ reset_current_label_string()

void reset_current_label_string ( void  )

Definition at line 71 of file parser.c.

72 {
73  strcpy(lab_I, "");
74 }

References lab_I.

Referenced by LinkInstToCurrentBlock(), and MakeElseInst().

+ Here is the caller graph for this function:

◆ reset_current_number_of_alternate_returns()

void reset_current_number_of_alternate_returns ( void  )

Definition at line 192 of file return.c.

193 {
195 }

References current_number_of_alternate_returns.

◆ reset_first_statement()

void reset_first_statement ( void  )

Definition at line 1944 of file statement.c.

1945 {
1946  seen = false;
1947  format_seen = false;
1948  declaration_lines = -1;
1949 }

References declaration_lines, format_seen, and seen.

◆ reset_substitute_expression_in_expression()

void reset_substitute_expression_in_expression ( void  )

Definition at line 218 of file macros.c.

219 {
221  already_subs = NIL;
222 }
static list already_subs
of expression
Definition: macros.c:178

References already_subs, gen_free_list(), and NIL.

Referenced by parser_macro_expansion().

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

◆ ResetBlockStack()

void ResetBlockStack ( void  )

Definition at line 203 of file statement.c.

204 {
205  CurrentBlock = 0;
206 }

References CurrentBlock.

Referenced by AbortOfProcedure(), and ParserError().

+ Here is the caller graph for this function:

◆ ResetChains()

void ResetChains ( void  )

undefine chains between two successives calls to parser

Definition at line 65 of file equivalence.c.

References equivalences_undefined, FinalEquivSet, free_equivalences(), and TempoEquivSet.

Referenced by EndOfProcedure(), gfc2pips_namespace(), and ParserError().

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

◆ ResetEntries()

void ResetEntries ( void  )

Definition at line 1458 of file procedure.c.

References effective_formal_parameters, entry_entities, entry_labels, entry_targets, gen_free_list(), and NIL.

Referenced by the_actual_parser().

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

◆ ResetReturnCodeVariable()

void ResetReturnCodeVariable ( void  )

Definition at line 151 of file return.c.

152 {
154 }

References entity_undefined, and return_code_variable.

Referenced by EndOfProcedure(), and ParserError().

+ Here is the caller graph for this function:

◆ ReturnCodeVariableP()

bool ReturnCodeVariableP ( entity  rcv)
Parameters
rcvcv

Definition at line 145 of file return.c.

146 {
147  return rcv == return_code_variable;
148 }

References return_code_variable.

Referenced by MakeFormalParameter().

+ Here is the caller graph for this function:

◆ retype_formal_parameters()

void retype_formal_parameters ( void  )

If an IMPLICIT statement is encountered, it must be applied to the formal parameters, and, if the current module is a function, to the function result type and to the variable used internally when a value is assigned to the function (see MakeCurrentFunction)

If the current module is a function, its type should be updated.

The function signature is computed later by UpdateFunctionalType() called from EndOfProcedure: there should be no parameters in the type.

Update type of internal variable used to store the function result

nothing to be done: subroutine or main

Definition at line 1411 of file declaration.c.

1412 {
1415  type tm = entity_type(m);
1416  type tr = type_undefined;
1417 
1418  pips_debug(8, "Begin for module %s\n",
1419  module_local_name(m));
1420 
1421  MAP(ENTITY, v, {
1423  if(!implicit_type_p(v)) {
1424  free_type(entity_type(v));
1425  entity_type(v) = ImplicitType(v);
1426 
1427  pips_debug(8, "Retype formal parameter %s\n",
1428  entity_local_name(v));
1429  }
1430  }
1434  {
1435  pips_debug(8, "Cannot retype entity %s: warning!!!\n",
1436  entity_local_name(v));
1437  pips_user_warning("Cannot retype variable or function %s."
1438  " Move up the implicit statement at the beginning of declarations.\n",
1439  entity_local_name(v));
1440  }
1441  else {
1442  pips_debug(8, "Ignore entity %s\n",
1443  entity_local_name(v));
1444  }
1445  }, vars);
1446 
1447  /* If the current module is a function, its type should be updated. */
1448 
1449  pips_assert("Should be a functional type", type_functional_p(tm));
1450 
1451  /* The function signature is computed later by UpdateFunctionalType()
1452  * called from EndOfProcedure: there should be no parameters in the type.
1453  */
1454  pips_assert("Parameter type list should be empty",
1456 
1458  if(type_variable_p(tr)) {
1459  if(!implicit_type_p(m)) {
1461  free_type(tr);
1463  pips_debug(8, "Retype result of function %s\n",
1464  module_local_name(m));
1465 
1466  /* Update type of internal variable used to store the function result */
1468  != entity_undefined) {
1469  free_type(entity_type(r));
1470  entity_type(r) = ImplicitType(r);
1471  pips_assert("Result and function result types should be equal",
1473  entity_type(r)));
1474  }
1475  else {
1476  pips_internal_error("Result entity should exist!");
1477  }
1478  }
1479  }
1480  else if (type_void_p(tr)) {
1481  /* nothing to be done: subroutine or main */
1482  }
1483  else
1484  pips_internal_error("Unexpected type with tag = %d",
1485  type_tag(tr));
1486 
1487  pips_assert("Parameter type list should still be empty",
1489 
1490  pips_debug(8, "End for module %s\n",
1491  module_local_name(m));
1492 }
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
#define functional_parameters(x)
Definition: ri.h:1442

References code_declarations, ENDP, ENTITY, entity_function_p(), entity_initial, entity_local_name(), entity_storage, entity_type, entity_undefined, FindEntity(), formal_parameter_p(), free_type(), functional_parameters, functional_result, get_current_module_entity(), implicit_type_p(), ImplicitType(), MAP, module_local_name(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, storage_ram_p, storage_rom_p, storage_undefined_p, type_equal_p(), type_functional, type_functional_p, type_tag, type_undefined, type_variable_p, type_void_p, value_code, and variable_entity_p().

+ Here is the call graph for this function:

◆ ReuseLabelledStatement()

statement ReuseLabelledStatement ( statement  s,
instruction  i 
)

Comments probably are lost...

Here, you are in trouble because the label cannot be carried by the block. It should be carried by the first statement of the block... which has already been allocated. This only should occur with desugared constructs because they must bypass the MakeStatement() module to handle statement numbering properly.

Reuse s1, the first statement of the block, to contain the whole block. Reuse s to contain the first instruction of the block.

s only has got a label

statement_number(s) = (instruction_goto_p(i))? STATEMENT_NUMBER_UNDEFINED : get_next_statement_number();

Let's number labelled GOTO because a CONTINUE is derived later from them

Definition at line 338 of file statement.c.

341 {
343 
344  debug(9, "ReuseLabelledStatement", "begin for label \"%s\"\n",
346 
347  pips_assert("Should have no number",
349  pips_assert("The statement instruction should be undefined",
351 
352  if(instruction_loop_p(i) && get_bool_property("PARSER_SIMPLIFY_LABELLED_LOOPS")) {
353  /* Comments probably are lost... */
356 
357  statement_number(ls) = get_statement_number();//get_next_statement_number();
358  statement_instruction(s) = c;
359 
360  new_s = instruction_to_statement(
363  CONS(STATEMENT, ls, NIL)))));
364  }
365  else if(instruction_block_p(i)) {
366  /* Here, you are in trouble because the label cannot be carried
367  * by the block. It should be carried by the first statement of
368  * the block... which has already been allocated.
369  * This only should occur with desugared constructs because they
370  * must bypass the MakeStatement() module to handle statement
371  * numbering properly.
372  *
373  * Reuse s1, the first statement of the block, to contain the
374  * whole block. Reuse s to contain the first instruction of the
375  * block.
376  */
378 
379  pips_assert("The first statement of the block is not a block",
381 
382  /* s only has got a label */
387 
393 
395  CDR(instruction_block(i)));
396 
397  pips_assert("The first statement of block s1 must be s\n",
399  == s);
400 
401  new_s = s1;
402  }
403  else {
404  statement_instruction(s) = i;
405  /*
406  statement_number(s) = (instruction_goto_p(i))?
407  STATEMENT_NUMBER_UNDEFINED : get_next_statement_number();
408  */
409  /* Let's number labelled GOTO because a CONTINUE is derived later from them */
410  statement_number(s) = get_statement_number(); //get_next_statement_number();
411  new_s = s;
412  }
413 
414  debug(9, "ReuseLabelledStatement", "end for label \"%s\"\n",
416 
417  return new_s;
418 }
#define statement_block_p(stat)
#define statement_ordering(x)
Definition: ri.h:2454
#define instruction_undefined_p(x)
Definition: ri.h:1455

References CAR, CDR, CONS, debug(), empty_comments, entity_empty_label(), get_bool_property(), get_statement_number(), instruction_block, instruction_block_p, instruction_loop_p, instruction_to_statement(), instruction_undefined_p, is_instruction_sequence, label_local_name(), make_continue_instruction(), make_instruction(), make_sequence(), NIL, pips_assert, s1, STATEMENT, statement_block_p, statement_comments, statement_instruction, statement_label, statement_number, STATEMENT_NUMBER_UNDEFINED, statement_ordering, STATEMENT_ORDERING_UNDEFINED, and statement_undefined.

Referenced by MakeStatement().

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

◆ SafeFindOrCreateEntity()

entity SafeFindOrCreateEntity ( const char *  package,
const char *  name 
)

Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a function or subroutine call as functional parameter.

FindOrCreateEntity() will return a local variable which already is or will be in the ghost variable list. When ghost variables are eliminated the data structure using this local variable contain a pointer to nowhere.

However, SafeFindOrCreateEntity() does not solve this problem entirely. The call with a functional parameter may occur before a call to this functional parameter lets us find out it is indeed functional.

Morevover, SafeFindOrCreateEntity() does create new problem because intrinsic overloading is ignored. Fortran does not use reserved words and a local variable may have the same name as an intrinsics. The intrinsic entity returned by this function must later be converted into a local variable when it is found out that the user really wanted a local variable, for instance because it appears in a lhs. So intrinsics are not searched anymore.

This is yet another reason to split the building of the internal representation into three phases. The first phase should not assume any default type or storage. Then, type and storage are consolidated together and default type and storage are only used when no information is available. The last phase should be kind of a link edit. The references to really global variables and intrinsics have to be fixed by scanning the intermediate representation.

See also FindOrCreateEntity().

This is a request for a global variable

May be a local or a global entity

This is a request for a local or a global variable. If a local variable with name "name" exists, return it.

No such local variable yet.

Does a global variable with the same name exist and is it in the package's scope?

let s hope concatenate s buffer lasts long enough...

There is no such global variable. Let's make a new local variable

A global entity with the same local name exists.

There is such a global variable and it is in the proper scope

Here comes the mistake if the current_module_entity is not yet defined as is the case when formal parameters are parsed. Intrinsics may wrongly picked out. See capture01.f, variable DIM.

The global variable is not be in the scope.

A local variable must be created. It is later replaced by a global variable if necessary and becomes a ghost variable.

A local variable has been found

le is not a ghost variable

Parameters
packageackage
namele nom du package le nom de l'entite

Definition at line 1891 of file declaration.c.

1894 {
1896 
1897  if(strcmp(package, TOP_LEVEL_MODULE_NAME) == 0) {
1898  /* This is a request for a global variable */
1899  e = FindEntity(package , name );
1900  }
1901  else { /* May be a local or a global entity */
1902  /* This is a request for a local or a global variable. If a local
1903  variable with name "name" exists, return it. */
1904  string full_name = concatenate(package, MODULE_SEP_STRING, name, NULL);
1906 
1907  if(entity_undefined_p(le)) { /* No such local variable yet. */
1908  /* Does a global variable with the same name exist and is it
1909  in the package's scope? */
1910 
1911  /* let s hope concatenate s buffer lasts long enough... */
1912  string full_top_name = concatenate(TOP_LEVEL_MODULE_NAME,
1913  MODULE_SEP_STRING, name, NULL);
1914 
1915  entity fe = gen_find_tabulated(full_top_name, entity_domain);
1916 
1917  if(entity_undefined_p(fe)) {
1918  /* There is no such global variable. Let's make a new local variable */
1922  }
1923  else { /* A global entity with the same local name exists. */
1925  && entity_is_argument_p(fe,
1927  /* There is such a global variable and it is in the proper scope */
1928  e = fe;
1929  }
1930  else if(false && intrinsic_entity_p(fe)) {
1931  /* Here comes the mistake if the current_module_entity is not
1932  yet defined as is the case when formal parameters are
1933  parsed. Intrinsics may wrongly picked out. See capture01.f, variable DIM. */
1934  e = fe;
1935  }
1936  else { /* The global variable is not be in the scope. */
1937  /* A local variable must be created. It is later replaced by a
1938  global variable if necessary and becomes a ghost variable. */
1942  }
1943  }
1944  }
1945  else { /* A local variable has been found */
1946  if(ghost_variable_entity_p(le)) {
1947  string full_top_name = concatenate(TOP_LEVEL_MODULE_NAME,
1948  MODULE_SEP_STRING, name, NULL);
1949 
1950  entity fe = gen_find_tabulated(full_top_name, entity_domain);
1951 
1952  pips_assert("Entity fe must be defined", !entity_undefined_p(fe));
1953  e = fe;
1954  }
1955  else { /* le is not a ghost variable */
1956  e = le;
1957  }
1958  }
1959  }
1960 
1961  return e;
1962 }
static char * package
The package name in which functions will be defined.
Definition: genLisp.c:59
#define full_name(dir, name)
Definition: compile.c:414
#define make_entity(n, t, s, i)

References code_declarations, concatenate(), entity_code(), entity_domain, entity_is_argument_p(), entity_undefined, entity_undefined_p, FindEntity(), full_name, gen_find_tabulated(), get_current_module_entity(), ghost_variable_entity_p(), intrinsic_entity_p(), make_entity, MODULE_SEP_STRING, package, pips_assert, storage_undefined, strdup(), TOP_LEVEL_MODULE_NAME, type_undefined, and value_undefined.

+ Here is the call graph for this function:

◆ SafeLocalToGlobal()

entity SafeLocalToGlobal ( entity  e,
type  r 
)

A local entity might have been created but found out later to be global, depending on the order of declaration statements (see MakeExternalFunction()).

The local entity e is (marked as) destroyed and replaced by functional entity fe.

Should we anticipate the value code, since we know it has to be a value code for a function and it may be tested later after the parsing phase of the caller but before the parsing phase of the callee, or should we wait till the code is really known?

entity_initial(fe) = make_value(is_value_unknown, UU);

FI: I need to destroy a virtual entity which does not appear in the program and wich was temporarily created by the parser when it recognized a name; however, I've no way to know if the same entity does not appear for good somewhere else in the code; does the Fortran standard let you write: LOG = LOG(3.) If yes, PIPS will core dump... PIPS also core dumps with ALOG(ALOG(X))... (8 July 1993)

remove_variable_entity(e);

ParserError("LocalToGlobal", "Formal functional parameters are not supported " "by PIPS.\n");

Definition at line 1681 of file procedure.c.

1682 {
1683  entity fe = entity_undefined;
1684 
1685  if(!top_level_entity_p(e)) {
1686  storage s = entity_storage(e);
1687  if(s == storage_undefined || storage_ram_p(s)) {
1688 
1690  entity_local_name(e));
1693  }
1694  else if(!storage_rom_p(entity_storage(fe))) {
1695  FatalError("SafeLocalToGlobal",
1696  "Unexpected storage class for top level entity\n");
1697  }
1699  /* Should we anticipate the value code, since we know it has
1700  to be a value code for a function and it may be tested
1701  later after the parsing phase of the caller but before
1702  the parsing phase of the callee, or should we wait till
1703  the code is really known? */
1704  /* entity_initial(fe) = make_value(is_value_unknown, UU); */
1708  }
1709 
1710  pips_debug(1, "external function %s re-declared as %s\n",
1711  entity_name(e), entity_name(fe));
1712  /* FI: I need to destroy a virtual entity which does not
1713  * appear in the program and wich was temporarily created by
1714  * the parser when it recognized a name; however, I've no way
1715  * to know if the same entity does not appear for good
1716  * somewhere else in the code; does the Fortran standard let
1717  * you write: LOG = LOG(3.) If yes, PIPS will core dump...
1718  * PIPS also core dumps with ALOG(ALOG(X))... (8 July 1993) */
1719  /* remove_variable_entity(e); */
1720  if(type_undefined_p(r)) {
1722  pips_debug(1, "entity %s to be destroyed\n", entity_name(e));
1723  }
1724  else {
1725  pips_debug(1, "entity %s to be preserved to carry function result\n",
1726  entity_name(e));
1727  }
1728  }
1729  else if(storage_formal_p(s)){
1730  pips_user_warning("Variable %s is a formal functional parameter.\n"
1731  "They are not (yet) supported by PIPS.\n",
1732  entity_name(e));
1733  /* ParserError("LocalToGlobal",
1734  "Formal functional parameters are not supported "
1735  "by PIPS.\n"); */
1736  fe = e;
1737  }
1738  else {
1739  pips_internal_error("entity %s has an unexpected storage %d",
1740  entity_name(e), storage_tag(s));
1741  }
1742  }
1743  else {
1744  fe = e;
1745  }
1746  pips_assert("Entity is global or it is a formal functional parameter",
1748  return fe;
1749 }
void add_ghost_variable_entity(entity e)
Definition: procedure.c:275
@ is_storage_rom
Definition: ri.h:2494

References add_ghost_variable_entity(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_undefined, FatalError, FindOrCreateEntity(), is_storage_rom, is_value_code, make_code(), make_language_fortran(), make_sequence(), make_storage(), make_value(), NIL, pips_assert, pips_debug, pips_internal_error, pips_user_warning, storage_formal_p, storage_ram_p, storage_rom_p, storage_tag, storage_undefined, storage_undefined_p, strdup(), top_level_entity_p(), TOP_LEVEL_MODULE_NAME, type_undefined_p, UU, and value_undefined_p.

Referenced by LocalToGlobal(), and MakeEntry().

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

◆ SafeSizeOfArray()

int SafeSizeOfArray ( entity  a)

cproto-generated files

declaration.c

cproto-generated files

See ri-util/size.c: array_size()

Definition at line 83 of file declaration.c.

84 {
85  int s;
86 
87  if (!SizeOfArray(a, &s)) {
88  pips_user_warning("Varying size of array \"%s\": An integer PARAMETER may "
89  "have been initialized with a real value?\n",
90  entity_name(a));
91  ParserError(__FUNCTION__,
92  "Fortran standard prohibit varying size array\n"
93  "Set property PARSER_ACCEPT_ANSI_EXTENSIONS to true.\n");
94  }
95 
96  return s;
97 }

References entity_name, ParserError(), pips_user_warning, and SizeOfArray().

Referenced by ComputeAddresses(), CurrentOffsetOfArea(), and update_common_layout().

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

◆ save_all_entities()

void save_all_entities ( void  )

functions for the SAVE declaration

FI: all variables previously allocated should be reallocated

FI: This is pretty crude... Let's hope it works

Definition at line 138 of file declaration.c.

139 {
142 
143  pips_assert("save_all_entities", StaticArea != entity_undefined);
144  pips_assert("save_all_entities", DynamicArea != entity_undefined);
145 
146  /* FI: all variables previously allocated should be reallocated */
147 
148  MAP(ENTITY, e, {
149  storage s;
150  if((s=entity_storage(e))!= storage_undefined) {
153  entity_storage(e) =
155  (make_ram(mod,
156  StaticArea,
158  NIL)));
159  }
160  }
161  }, vars);
162 
163  /* FI: This is pretty crude... Let's hope it works */
165 }

References code_declarations, current_offset_of_area(), DynamicArea, ENTITY, entity_initial, entity_storage, entity_undefined, free_storage(), get_current_module_entity(), is_storage_ram, make_ram(), make_storage(), MAP, NIL, pips_assert, ram_section, StaticArea, storage_ram, storage_ram_p, storage_undefined, and value_code.

+ Here is the call graph for this function:

◆ save_initialized_variable()

void save_initialized_variable ( entity  v)

Definition at line 287 of file declaration.c.

288 {
289  MakeVariableStatic(v, false);
290 }

References MakeVariableStatic().

+ Here is the call graph for this function:

◆ SaveChains()

void SaveChains ( void  )

Initialize the shared fields of aliased variables.

shared = CONS(ENTITY, atom_equivar(ATOM(CAR(pa))), shared);

Check conflicting intializations

Definition at line 859 of file equivalence.c.

860 {
861  pips_debug(8, "Begin\n");
862 
864  pips_debug(8, "No equivalence to process. End\n");
865  return;
866  }
867 
868  MAPL(pc, {
869  cons *shared = NIL;
870  chain c = CHAIN(CAR(pc));
871 
872  pips_debug(8, "Process an equivalence chain:\n");
873 
874  MAPL(pa, {
875  shared = gen_once(atom_equivar(ATOM(CAR(pa))), shared);
876  /* shared = CONS(ENTITY, atom_equivar(ATOM(CAR(pa))), shared); */
877  }, chain_atoms(c));
878 
879  pips_assert("SaveChains", !ENDP(shared));
880 
881  MAPL(pa, {
882  atom a = ATOM(CAR(pa));
883  entity e = atom_equivar(a);
884  storage se = entity_storage(e);
885  ram re = storage_ram(se);
886 
887  pips_debug(8, "\talias %s\n", entity_name(e));
888 
889  ram_shared(re) = gen_copy_seq(shared);
890 
891  }, chain_atoms(c));
892 
893  /* Check conflicting intializations */
894  MAPL(pa, {
895  atom a = ATOM(CAR(pa));
896  entity e = atom_equivar(a);
897  storage se = entity_storage(e);
898  ram re = storage_ram(se);
899  list lce = ram_shared(re);
900 
903  pips_debug(8,
904  "\tCheck initalization consistency for %s\n",
905  entity_name(e));
906  MAP(ENTITY, ce, {
907  if(e!=ce && variable_entities_may_conflict_p(e, ce)) {
909  && !value_unknown_p(entity_initial(ce))) {
910  pips_user_warning("Overlapping initializations for %s and %s\n",
912  ParserError("SaveChains",
913  "ANSI extension: overlapping initializations\n");
914  }
915  }
916  }, lce);
917  }
918 
919  }, chain_atoms(c));
920 
922 
923  pips_debug(8, "End\n");
924 }
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
bool variable_entities_may_conflict_p(entity, entity)
Definition: size.c:689
#define ram_shared(x)
Definition: ri.h:2253

References ATOM, atom_equivar, CAR, CHAIN, chain_atoms, ENDP, ENTITY, entity_initial, entity_local_name(), entity_name, entity_storage, equivalences_chains, equivalences_undefined, FinalEquivSet, gen_copy_seq(), gen_once(), MAP, MAPL, NIL, ParserError(), pips_assert, pips_debug, pips_user_warning, ram_shared, storage_ram, value_defined_p(), value_unknown_p, and variable_entities_may_conflict_p().

Referenced by EndOfProcedure().

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

◆ SaveCommon()

void SaveCommon ( entity  c)

this function transforms a dynamic common into a static one.


Definition at line 295 of file declaration.c.

297 {
298  pips_assert("SaveCommon",type_area_p(entity_type(c)));
299 
300  Warning("SaveCommon", "common blocks are automatically saved\n");
301 
302  return;
303 }

References entity_type, pips_assert, type_area_p, and Warning.

◆ SaveEntity()

void SaveEntity ( entity  e)

These two functions transform a dynamic variable into a static one.

They are called to handle SAVE and DATA statements.

Because equivalence chains have not yet been processed, it is not possible to assign an offset or to chain the variable to the static area layout. These two updates are performed by ComputeAddresses() only called by EndOfProcedure() to make sure that all non-declared variables have been taken into account.

Let's hope functions and subroutines called are listed in the declaration list.

This cannot be done before the equivalences have been processed

Not much can be said. Maybe it is redundant, but...

Maybe the standard claims that you are not allowed to save a common variable?

The type and dimensions are still unknown

Definition at line 178 of file declaration.c.

179 {
181 
182  if(!entity_undefined_p(g)
183  /* Let's hope functions and subroutines called are listed in the
184  * declaration list.
185  */
187  user_warning("SaveEntity",
188  "Ambiguity between external %s and local %s forbidden by Fortran standard\n",
189  entity_name(g), entity_name(e));
190  ParserError("SaveEntity", "Name conflict\n");
191  }
192 
193  if (entity_type(e) == type_undefined) {
196  }
197 
198  if (entity_storage(e) != storage_undefined) {
199  if (storage_ram_p(entity_storage(e))) {
200  ram r;
201 
202  r = storage_ram(entity_storage(e));
203 
204  if (ram_section(r) == DynamicArea) {
205  /* This cannot be done before the equivalences have been processed */
206  /*
207  area a = type_area(entity_type(StaticArea));
208  area_layout(a) = gen_nconc(area_layout(a),
209  CONS(ENTITY, e, NIL));
210  */
211  ram_section(r) = StaticArea;
213  }
214  else {
215  /* Not much can be said. Maybe it is redundant, but... */
216  /* Maybe the standard claims that you are not allowed
217  * to save a common variable?
218  */
219  /*
220  user_warning("SaveEntity", "Variable %s has already been declared static "
221  "by SAVE, by DATA or by appearing in a common declaration\n",
222  entity_local_name(e));
223  */
224  }
225  }
226  else {
227  user_warning("SaveEntity",
228  "Cannot save variable %s with non RAM storage (storage tag = %d)\n",
231  ParserError("SaveEntity", "Cannot save this variable");
232  }
233  }
234  else {
235  entity_storage(e) =
238  StaticArea,
239  /* The type and dimensions are still unknown */
241  NIL)));
242  }
243 }

References code_declarations, DeclareVariable(), DynamicArea, entity_initial, entity_is_argument_p(), entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined_p, get_current_module_entity(), is_storage_ram, local_name_to_top_level_entity(), make_ram(), make_storage(), NIL, ParserError(), ram_offset, ram_section, StaticArea, storage_ram, storage_ram_p, storage_tag, storage_undefined, type_undefined, UNKNOWN_RAM_OFFSET, user_warning, value_code, and value_undefined.

Referenced by AnalyzeData(), fix_storage(), and MakeVariableStatic().

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

◆ ScanFormalParameters()

void ScanFormalParameters ( entity  m,
list  l 
)

this function scans the formal parameter list.

each formal parameter is created with an implicit type, and then is added to CurrentFunction's declarations.

le parametre formel

son rang dans la liste

Definition at line 2503 of file procedure.c.

2504 {
2505  list pc;
2506  entity fp; /* le parametre formel */
2507  int nfp; /* son rang dans la liste */
2508 
2509  FormalParameters = l;
2510 
2511  for (pc = l, nfp = 1; pc != NULL; pc = CDR(pc), nfp += 1) {
2512  fp = ENTITY(CAR(pc));
2513 
2514  MakeFormalParameter(m, fp, nfp);
2515 
2516  AddEntityToDeclarations(fp, m);
2517  }
2518 }
void MakeFormalParameter(entity m, entity fp, int nfp)
This function transforms an untyped entity into a formal parameter.
Definition: procedure.c:2466

References AddEntityToDeclarations(), CAR, CDR, ENTITY, FormalParameters, and MakeFormalParameter().

Referenced by MakeCurrentFunction().

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

◆ ScanNewFile()

void ScanNewFile ( void  )

La fonction a appeler pour l'analyse d'un nouveau fichier.

on initialise la table keywidx

on met a jour la table keywidx en fonction des keywords

premier keyword commencant par keywcour[0]

on initialise les variables externes locales et non locales

Definition at line 474 of file reader.c.

475 {
476  register int i;
477  static int FirstCall = true;
478  char letcour, *keywcour;
479 
480 
481  if (FirstCall) {
482  FirstCall = false;
483 
484  /* on initialise la table keywidx */
485  for (i = 0; i < 26; i += 1)
486  keywidx[i] = UNDEF;
487 
488  /* on met a jour la table keywidx en fonction des keywords */
489  letcour = ' ';
490  i = 0;
491  while ((keywcour = keywtbl[i].keywstr) != NULL) {
492  if (keywcour[0] != letcour) {
493  /* premier keyword commencant par keywcour[0] */
494  keywidx[(int) keywcour[0]-'A'] = i;
495  letcour = keywcour[0];
496  }
497  i += 1;
498  }
499  }
500 
501  /* on initialise les variables externes locales et non locales */
502  LineNumber = 1;
503  Column = 1;
504  StmtLineNumber = 1;
506  iStmt = lStmt = SIZE_UNDEF;
507  iLine = lLine = UNDEF;
508 }

References Column, EtatQuotes, iLine, int, iStmt, keywidx, keywtbl, LineNumber, lLine, lStmt, NONINQUOTES, SIZE_UNDEF, StmtLineNumber, and UNDEF.

Referenced by the_actual_parser().

+ Here is the caller graph for this function:

◆ set_alternate_returns()

void set_alternate_returns ( void  )

Definition at line 264 of file return.c.

265 {
266  pips_assert("alternate return list is undefined", list_undefined_p(alternate_returns));
269 }

References alternate_returns, current_number_of_alternate_returns, list_undefined_p, NIL, and pips_assert.

◆ set_common_to_size()

void set_common_to_size ( entity  a,
size_t  size 
)
Parameters
sizeize

Definition at line 1004 of file declaration.c.

1005 {
1006  (void) hash_put(common_size_map, (char *) a, (char *) (size));
1007 }
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

References common_size_map, and hash_put().

Referenced by gfc2pips_computeAdressesOfArea(), gfc2pips_namespace(), InitAreas(), and MakeCommon().

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

◆ set_current_label_string()

void set_current_label_string ( string  ln)
Parameters
lnn

Definition at line 81 of file parser.c.

82 {
83  pips_assert("Label name is at most 5 characters long", strlen(ln)<=5);
84  strcpy(lab_I, ln);
85 }

References lab_I, and pips_assert.

Referenced by MakeElseInst().

+ Here is the caller graph for this function:

◆ set_current_number_of_alternate_returns()

void set_current_number_of_alternate_returns ( void  )

Definition at line 187 of file return.c.

188 {
190 }

References current_number_of_alternate_returns.

Referenced by gfc2pips_args().

+ Here is the caller graph for this function:

◆ set_first_format_statement()

void set_first_format_statement ( void  )

declaration_lines = line_b_I-1;

Definition at line 1952 of file statement.c.

1953 {
1954  if(!format_seen && !seen) {
1955  format_seen = true;
1956  /* declaration_lines = line_b_I-1; */
1957  debug(8, "set_first_format_statement", "line_b_C=%d, line_b_I=%d\n",
1958  line_b_C, line_b_I);
1960  }
1961 }

References debug(), declaration_lines, format_seen, line_b_C, line_b_I, seen, and UNDEF.

+ Here is the call graph for this function:

◆ SetChains()

void SetChains ( void  )

initialize chains before each call to the parser

Definition at line 76 of file equivalence.c.

77 {
78  pips_assert("TempoEquivSet is undefined", equivalences_undefined_p(TempoEquivSet));
79  pips_assert("FinalEquivSet is undefined", equivalences_undefined_p(FinalEquivSet));
82 }

References equivalences_undefined_p, FinalEquivSet, make_equivalences(), NIL, pips_assert, and TempoEquivSet.

Referenced by MakeCurrentFunction().

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

◆ SizeOfRange()

int SizeOfRange ( range  r)

This function computes the size of a range, ie.

the number of iterations that would be done by a loop with this range.

See also range_count().

Definition at line 1619 of file declaration.c.

1621 {
1622  int ir, il, iu, ii;
1623 
1624  il = ExpressionToInt(range_lower(r));
1625  iu = ExpressionToInt(range_upper(r));
1627 
1628  if (ii == 0)
1629  FatalError("SizeOfRange", "null increment\n");
1630 
1631  ir = ((iu-il)/ii)+1;
1632 
1633  if (ir < 0)
1634  FatalError("SizeOfRange", "negative value\n");
1635 
1636  return(ir);
1637 }

References ExpressionToInt(), FatalError, range_increment, range_lower, and range_upper.

+ Here is the call graph for this function:

◆ soft_reset_alternate_returns()

void soft_reset_alternate_returns ( void  )

ParserError() cannot guess if it has been performed or not, because it is reinitialized before and after each call statement.

If the error occurs within a call, alternate returns must be reset. Else they should not be reset.

Definition at line 284 of file return.c.

285 {
288  }
289 }
void reset_alternate_returns()
Definition: return.c:272

References alternate_returns, list_undefined_p, and reset_alternate_returns().

Referenced by ParserError().

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

◆ StmtEqualString()

int StmtEqualString ( char *  s,
int  i 
)

Definition at line 1290 of file reader.c.

1291 {
1292  int result = false;
1293 
1294  if (strlen(s) <= lStmt-i) {
1295  while (*s)
1296  if (*s != stmt_buffer[i++])
1297  break;
1298  else
1299  s++;
1300 
1301  result = (*s) ? false : i;
1302  }
1303 
1304  return result;
1305 }
#define false
Definition: newgen_types.h:80

References false, lStmt, and stmt_buffer.

Referenced by FindAssign(), FindAutre(), FindDo(), FindDoWhile(), FindIf(), FindIfArith(), FindImplicit(), FindPoints(), and NeedKeyword().

+ Here is the caller graph for this function:

◆ StoreEquivChain()

void StoreEquivChain ( chain  c)

This function is called when an equivalence chain has been completely parsed.

It looks for the atom with the biggest offset, and then substracts this maximum offset from all atoms. The result is that each atom has its offset from the begining of the chain.

Definition at line 176 of file equivalence.c.

178 {
179  cons * pc;
180  int maxoff;
181 
182  maxoff = 0;
183  for (pc = chain_atoms(c); pc != NIL; pc = CDR(pc)) {
184  int o = atom_equioff(ATOM(CAR(pc)));
185 
186  if (o > maxoff)
187  maxoff = o;
188  }
189 
190  pips_debug(9, "maxoff %d\n", maxoff);
191 
192  if (maxoff > 0) {
193  for (pc = chain_atoms(c); pc != NIL; pc = CDR(pc)) {
194  atom a = ATOM(CAR(pc));
195 
196  atom_equioff(a) = abs(atom_equioff(a)-maxoff);
197  }
198  }
199 
200  /*
201  if (TempoEquivSet == equivalences_undefined) {
202  TempoEquivSet = make_equivalences(NIL);
203  }
204  */
205  pips_assert("The TempoEquivSet is defined", !equivalences_undefined_p(TempoEquivSet));
206 
209 }

References abs, ATOM, atom_equioff, CAR, CDR, CHAIN, chain_atoms, CONS, equivalences_chains, equivalences_undefined_p, NIL, pips_assert, pips_debug, and TempoEquivSet.

◆ substitute_ghost_variable_in_expression()

void substitute_ghost_variable_in_expression ( expression  expr,
entity  v,
entity  f 
)

It is assumed that v and f are defined entities and that v is of type variable and f of type functional.

ParserError() is going to request ghost variable substitution recursively and we do not want this to happen because it is going to fail again. Well, substitution won't be tried from AbortOfProcedure()...

ghost_variable_entities = NIL;

ParserError("substitute_ghost_variable_in_expression", "Functional parameters are not (yet) supported by PIPS\n");

Parameters
exprxpr

Definition at line 75 of file procedure.c.

79 {
80  /* It is assumed that v and f are defined entities and that v is of
81  type variable and f of type functional. */
82  syntax s = expression_syntax(expr);
84  range rng = range_undefined;
85  call c = call_undefined;
86 
87  ifdebug(8) {
88  pips_debug(8, "Begin for expression: ");
89  print_expression(expr);
90  }
91 
92  switch(syntax_tag(s)) {
94  ref = syntax_reference(s);
95  if(reference_variable(ref)==v) {
96  pips_debug(1,
97  "Reference to formal functional entity %s to be substituted\n",
98  entity_name(f));
99  /* ParserError() is going to request ghost variable
100  substitution recursively and we do not want this to happen
101  because it is going to fail again. Well, substitution won't be
102  tried from AbortOfProcedure()... */
103  /* ghost_variable_entities = NIL; */
105  "Functional variable %s is used as an actual argument\n"
106  "This is not yet fully supported by PIPS.\n",
108  /* ParserError("substitute_ghost_variable_in_expression",
109  "Functional parameters are not (yet) supported by PIPS\n"); */
111  }
112  MAP(EXPRESSION, e, {
114  }, reference_indices(ref));
115  break;
116  case is_syntax_range:
117  rng = syntax_range(s);
121  break;
122  case is_syntax_call:
123  c = syntax_call(s);
124  pips_assert("Called entities are not substituted", call_function(c)!= v);
125  MAP(EXPRESSION, e, {
127  }, call_arguments(c));
128  break;
129  default:
130  break;
131  }
132 
133  ifdebug(8) {
134  pips_debug(8, "End for expression: ");
135  print_expression(expr);
136  }
137 }
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
void substitute_ghost_variable_in_expression(expression expr, entity v, entity f)
Definition: procedure.c:75
#define syntax_tag(x)
Definition: ri.h:2727
#define range_undefined
Definition: ri.h:2263
#define syntax_range(x)
Definition: ri.h:2733
#define call_undefined
Definition: ri.h:685

References call_arguments, call_function, call_undefined, entity_name, EXPRESSION, expression_syntax, f(), ifdebug, is_syntax_call, is_syntax_range, is_syntax_reference, MAP, module_local_name(), pips_assert, pips_debug, pips_user_warning, print_expression(), range_increment, range_lower, range_undefined, range_upper, ref, reference_indices, reference_undefined, reference_variable, syntax_call, syntax_range, syntax_reference, and syntax_tag.

Referenced by substitute_ghost_variable_in_statement().

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

◆ substitute_ghost_variable_in_statement()

void substitute_ghost_variable_in_statement ( statement  stmt,
entity  v,
entity  f 
)

It is assumed that v and f are defined entities and that v is of type variable and f of type functional.

gen_recurse() is not used to control the context better

unstructured u = unstructured_undefined;

Local variables should also be checked

Local variables should also be checked

nothing to do

Parameters
stmttmt

Definition at line 139 of file procedure.c.

143 {
144  /* It is assumed that v and f are defined entities and that v is of
145  type variable and f of type functional. */
146 
147  /* gen_recurse() is not used to control the context better */
148 
151  loop l = loop_undefined;
153  test t = test_undefined;
154  call c = call_undefined;
155  /* unstructured u = unstructured_undefined; */
156 
157  pips_assert("Labels are not substituted", sl!= v);
158 
159  switch(instruction_tag(i)) {
161  MAP(STATEMENT, s, {
163  }, instruction_block(i));
164  break;
165  case is_instruction_loop:
166  l = instruction_loop(i);
167  pips_assert("Loop indices are not substituted", loop_index(l)!= v);
168  pips_assert("Loop labels are not substituted", loop_label(l)!= v);
173  /* Local variables should also be checked */
174  break;
176  w = instruction_whileloop(i);
177  pips_assert("WHILE loop labels are not substituted", whileloop_label(w)!= v);
180  /* Local variables should also be checked */
181  break;
182  case is_instruction_test:
183  t = instruction_test(i);
187  break;
188  case is_instruction_goto:
189  /* nothing to do */
190  break;
191  case is_instruction_call:
192  c = instruction_call(i);
193  pips_assert("Called entities are not substituted", call_function(c)!= v);
194  MAP(EXPRESSION, e, {
196  }, call_arguments(c));
197  break;
199  pips_assert("The parser should not have to know about unstructured\n", false);
200  break;
201  default:
202  FatalError("substitute_ghost_variable_in_statement", "Unexpected instruction tag");
203  }
204 }
#define loop_undefined
Definition: ri.h:1612
#define test_undefined
Definition: ri.h:2808
#define instruction_loop(x)
Definition: ri.h:1520
@ is_instruction_unstructured
Definition: ri.h:1475
#define instruction_tag(x)
Definition: ri.h:1511
#define whileloop_label(x)
Definition: ri.h:3164
#define test_true(x)
Definition: ri.h:2835
#define loop_label(x)
Definition: ri.h:1646
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define whileloop_body(x)
Definition: ri.h:3162
#define instruction_call(x)
Definition: ri.h:1529
#define whileloop_condition(x)
Definition: ri.h:3160
#define whileloop_undefined
Definition: ri.h:3134

References call_arguments, call_function, call_undefined, EXPRESSION, f(), FatalError, instruction_block, instruction_call, instruction_loop, instruction_tag, instruction_test, instruction_whileloop, is_instruction_call, is_instruction_goto, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, loop_body, loop_index, loop_label, loop_range, loop_undefined, MAP, pips_assert, range_increment, range_lower, range_upper, STATEMENT, statement_instruction, statement_label, substitute_ghost_variable_in_expression(), test_condition, test_false, test_true, test_undefined, whileloop_body, whileloop_condition, whileloop_label, and whileloop_undefined.

Referenced by remove_ghost_variable_entities().

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

◆ SubstituteAlternateReturns()

void SubstituteAlternateReturns ( const char *  option)

return.c

Parameters
optionption

Definition at line 59 of file return.c.

60 {
61  substitute_rc_p = (strcmp(option, "RC")==0) || (strcmp(option, "HRC")==0) ;
62  hide_rc_p = (strcmp(option, "HRC")==0) ;
63  substitute_stop_p = (strcmp(option, "STOP")==0);
64 
65  if(!(substitute_rc_p || substitute_stop_p || strcmp(option, "NO")==0)) {
66  user_log("Unknown option \"%s\" for property "
67  "PARSER_SUBSTITUTE_ALTERNATE_RETURNS.\n"
68  "Three options are available for alternate return handling: "
69  "\"NO\", \"RC\" and \"STOP\"\n", option);
70  ParserError("SubstituteAlternateReturns", "Illegal property value");
71  }
72 
74  && !get_bool_property("PRETTYPRINT_ALL_DECLARATIONS"))
75  user_warning("SubstituteAlternateReturns",
76  "Module declarations should be regenerated."
77  " Set property PRETTYPRINT_ALL_DECLARATIONS.\n");
78 }

References get_bool_property(), hide_rc_p, ParserError(), substitute_rc_p, substitute_stop_p, user_log(), and user_warning.

Referenced by EndOfProcedure(), MakeCurrentFunction(), and ParserError().

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

◆ SubstituteAlternateReturnsP()

bool SubstituteAlternateReturnsP ( void  )

Definition at line 81 of file return.c.

82 {
83  return substitute_rc_p;
84 }

References substitute_rc_p.

Referenced by MakeCallInst(), and MakeFormalParameter().

+ Here is the caller graph for this function:

◆ syn_alloc()

void* syn_alloc ( yy_size_t  )

◆ syn_error()

void syn_error ( const char *  )

◆ syn_free()

void syn_free ( void *  )

◆ syn_get_debug()

int syn_get_debug ( void  )

◆ syn_get_in()

FILE* syn_get_in ( void  )

◆ syn_get_leng()

int syn_get_leng ( void  )

◆ syn_get_lineno()

int syn_get_lineno ( void  )

◆ syn_get_out()

FILE* syn_get_out ( void  )

◆ syn_get_text()

char* syn_get_text ( void  )

◆ syn_lex()

int syn_lex ( )

◆ syn_lex_destroy()

int syn_lex_destroy ( void  )

◆ syn_parse()

int syn_parse ( )

◆ syn_pop_buffer_state()

void syn_pop_buffer_state ( void  )

◆ syn_realloc()

void* syn_realloc ( void *  ,
yy_size_t   
)

◆ syn_reset_lex()

void syn_reset_lex ( )

◆ syn_restart()

void syn_restart ( FILE *  )

◆ syn_set_debug()

void syn_set_debug ( int  )

◆ syn_set_in()

void syn_set_in ( FILE *  )

◆ syn_set_lineno()

void syn_set_lineno ( int  )

◆ syn_set_out()

void syn_set_out ( FILE *  )

◆ syn_wrap()

int syn_wrap ( void  )

Definition at line 466 of file reader.c.

467 {
468  return(1);
469 }

◆ TypeFunctionalEntity()

void TypeFunctionalEntity ( entity  fe,
type  r 
)

this is wrong, because we do not know if we are handling an EXTERNAL declaration, in which case the result type is type_undefined, or a function call appearing somewhere, in which case the ImplicitType should be used; maybe the unknown type should be used?

a bug is detected here: MakeExternalFunction, as its name implies, always makes a FUNCTION, even when the symbol appears in an EXTERNAL statement; the result type is infered from ImplicitType() - see just above -; let's use implicit_type_p() again, whereas the unknown type should have been used

ignore r

someone used a subroutine as a function. this happens in hpfc for declaring "pure" routines. thus I make this case being ignored. warning? FC.

memory leak of tr

This may be an undeclared formal functional argument, initially assumed to be a variable. Since it is not declared as an array but appears with arguments, it must be a functional entity.

I do not know how to get the argument types. Let's hope it's performed later...

Parameters
fee

Definition at line 2257 of file procedure.c.

2259 {
2260  type tfe = entity_type(fe);
2261 
2262  if(tfe == type_undefined) {
2263  /* this is wrong, because we do not know if we are handling
2264  an EXTERNAL declaration, in which case the result type
2265  is type_undefined, or a function call appearing somewhere,
2266  in which case the ImplicitType should be used;
2267  maybe the unknown type should be used? */
2270  (r == type_undefined) ?
2271  ImplicitType(fe) :
2272  r));
2273  }
2274  else if (type_functional_p(tfe))
2275  {
2277  if(r != type_undefined && !type_equal_p(tr, r)) {
2278 
2279  /* a bug is detected here: MakeExternalFunction, as its name
2280  implies, always makes a FUNCTION, even when the symbol
2281  appears in an EXTERNAL statement; the result type is
2282  infered from ImplicitType() - see just above -;
2283  let's use implicit_type_p() again, whereas the unknown type
2284  should have been used
2285  */
2286  if(intrinsic_entity_p(fe)) {
2287  /* ignore r */
2288  } else if (type_void_p(tr)) {
2289  /* someone used a subroutine as a function.
2290  * this happens in hpfc for declaring "pure" routines.
2291  * thus I make this case being ignored. warning? FC.
2292  */
2293  } else if (implicit_type_p(fe) || overloaded_type_p(tr)) {
2294  /* memory leak of tr */
2296  } else {
2297  user_warning("TypeFunctionalEntity",
2298  "Type redefinition of result for function %s\n",
2299  entity_name(fe));
2300  if(type_variable_p(tr)) {
2301  user_warning("TypeFunctionalEntity",
2302  "Currently declared result is %s\n",
2304  }
2305  if(type_variable_p(r)) {
2306  user_warning("TypeFunctionalEntity",
2307  "Redeclared result is %s\n",
2309  }
2310  ParserError("TypeFunctionalEntity",
2311  "Functional type redefinition.\n");
2312  }
2313  }
2314  } else if (type_variable_p(tfe)) {
2315  /* This may be an undeclared formal functional argument, initially
2316  assumed to be a variable. Since it is not declared as an array
2317  but appears with arguments, it must be a functional entity. */
2318  storage sfe = entity_storage(fe);
2319 
2320  if(storage_formal_p(sfe)) {
2321  /* I do not know how to get the argument types. Let's hope it's
2322  performed later...*/
2323  free_type(entity_type(fe));
2325  make_functional(NIL, r));
2326  }
2327  else {
2328  pips_internal_error("Fortran does not support global variables");
2329  }
2330  } else {
2331  pips_internal_error("Unexpected type for a global name %s",
2332  entity_name(fe));
2333  }
2334 }
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666

References basic_to_string(), entity_name, entity_storage, entity_type, free_type(), functional_result, implicit_type_p(), ImplicitType(), intrinsic_entity_p(), is_type_functional, make_functional(), make_type(), NIL, overloaded_type_p(), ParserError(), pips_internal_error, storage_formal_p, type_equal_p(), type_functional, type_functional_p, type_undefined, type_variable, type_variable_p, type_void_p, user_warning, and variable_basic.

Referenced by MakeEntry(), and MakeExternalFunction().

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

◆ update_called_modules()

void update_called_modules ( entity  e)

Self recursive calls are not allowed

do not count intrinsics; user function should not be named like intrinsics

FI, 20/01/92: maybe, initializations of global entities should be more precise (storage, initial value, etc...); for the time being, I choose to ignore the potential problems with other executions of the parser and the linker

pips_internal_error("unexpected case");

Definition at line 308 of file procedure.c.

310 {
311  bool already_here = false;
312  const char* n = entity_local_name(e);
313  string nom;
315 
316  /* Self recursive calls are not allowed */
317  if(e==cm) {
318  pips_user_warning("Recursive call from %s to %s\n",
320  ParserError("update_called_modules",
321  "Recursive call are not supported\n");
322  }
323 
324  /* do not count intrinsics; user function should not be named
325  like intrinsics */
328  if(entity_initial(e) == value_undefined) {
329  /* FI, 20/01/92: maybe, initializations of global entities
330  should be more precise (storage, initial value, etc...);
331  for the time being, I choose to ignore the potential
332  problems with other executions of the parser and the linker */
333  /* pips_internal_error("unexpected case"); */
334  }
335  else if(value_intrinsic_p(entity_initial(e)))
336  return;
337  }
338 
339  MAPL(ps, {
340  if (strcmp(n, STRING(CAR(ps))) == 0) {
341  already_here = true;
342  break;
343  }
344  }, called_modules);
345 
346  if (! already_here) {
347  pips_debug(1, "adding %s\n", n);
349  }
350 }

References called_modules, CAR, concatenate(), CONS, entity_domain, entity_initial, entity_local_name(), entity_undefined, gen_find_tabulated(), get_current_module_entity(), MAPL, MODULE_SEP_STRING, ParserError(), pips_debug, pips_user_warning, strdup(), STRING, TOP_LEVEL_MODULE_NAME, value_intrinsic_p, and value_undefined.

Referenced by make_get_rc_statement(), MakeAtom(), MakeCallInst(), and set_rc_function().

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

◆ update_common_layout()

bool update_common_layout ( entity  m,
entity  c 
)

(Re)compute offests of all variables allocated in common c from module m and update (if necessary) the size of common c for the whole program or set of modules in the current workspace.

As a consequence, warning messages unfortunately depend on the parsing order.

Offsets used to be computed a first time when the common declaration is encountered, but the variables may be typed or dimensionned later.

This function is correct only if no equivalenced variables have been added to the layout. It should not be used for the static and dynamic areas (see below).

It is assumed that:

  • each variable appears only once
  • variables appears in their declaration order
  • all variables that belong to the same module appear contiguously (i.e. declarations are concatenated on a module basis)
  • variables wich are located in the common thru an EQUIVALENCE statement are not (yet) in its layout It also was wrongly assumed that each common would have at least two members.

the layout field does not seem to be filled in for STATIC and DYNAMIC

skip variables which do not belong to the module of interest

This should now always be the case. The offset within the common is no longer computed on the fly.

If c really is a common, check its size because it may have increased. Note that decreases are not taken into account although they might occur as well.

Too late, if the common only contains one element because the MAPL has not been entered at all if we are dealing wih te last parsed module... which is always the case up to now!

Variables declared in the static and dynamic areas were assigned offsets dynamically. The result may be ok.

Special case: only one element in the common for the current procedure (and the current procedure is last one declared - which is not so special)

If c really is a common, check its size because it may have increased. Note that decreases are not taken into account although they might occur as well.

Definition at line 1746 of file declaration.c.

1749 {
1750  /* It is assumed that:
1751  * - each variable appears only once
1752  * - variables appears in their declaration order
1753  * - all variables that belong to the same module appear contiguously
1754  * (i.e. declarations are concatenated on a module basis)
1755  * - variables wich are located in the common thru an EQUIVALENCE statement
1756  * are *not* (yet) in its layout
1757  * It also was wrongly assumed that each common would have at least two members.
1758  */
1759 
1760  list members = area_layout(type_area(entity_type(c)));
1761  entity previous = entity_undefined;
1762  bool updated = false;
1763  list cm = list_undefined;
1764 
1765  ifdebug(8) {
1766  debug(8, "update_common_layout",
1767  "Begin for common /%s/ with members\n", module_local_name(c));
1768  print_arguments(members);
1769  }
1770 
1771  /* the layout field does not seem to be filled in for STATIC and DYNAMIC */
1772  if(!ENDP(members)) {
1773  /* skip variables which do not belong to the module of interest */
1774  /*
1775  for(previous = ENTITY(CAR(members)); !ENDP(members) && !variable_in_module_p(previous, m);
1776  POP(members))
1777  previous = ENTITY(CAR(members));
1778  */
1779  do {
1780  previous = ENTITY(CAR(members));
1781  POP(members);
1782  } while(!ENDP(members) && !variable_in_module_p(previous, m));
1783 
1784  for(cm = members; !ENDP(cm); POP(cm)) {
1785  entity current = ENTITY(CAR(cm));
1786 
1787  pips_assert("update_common_layout",
1789 
1790  if(!variable_in_module_p(current, m)) {
1791  break;
1792  }
1793 
1794  if(ram_offset(storage_ram(entity_storage(previous)))+SafeSizeOfArray(previous) >
1796  /* This should now always be the case. The offset within the common is
1797  * no longer computed on the fly.
1798  */
1800  ram_offset(storage_ram(entity_storage(previous)))+SafeSizeOfArray(previous);
1801 
1802  /* If c really is a common, check its size because it may have increased.
1803  * Note that decreases are not taken into account although they might
1804  * occur as well.
1805  */
1806  /* Too late, if the common only contains one element because the MAPL
1807  * has not been entered at all if we are dealing wih te last parsed
1808  * module... which is always the case up to now!
1809  */
1811  int s = common_to_size(c);
1814  if(s < new_s) {
1815  (void) update_common_to_size(c, new_s);
1816  }
1817  }
1818  updated = true;
1819  }
1820  else {
1821  /* Variables declared in the static and dynamic areas were
1822  assigned offsets dynamically. The result may be
1823  ok. */
1824  pips_assert("Offsets should always be updated",entity_special_area_p(c));
1825  }
1826 
1827  previous = current;
1828  }
1829 
1830 
1831  /* Special case: only one element in the common for the current procedure
1832  * (and the current procedure is last one declared - which is not so
1833  * special)
1834  */
1835  if(ENDP(members)) {
1836  pips_assert("Previous must in declared in the current module",
1837  variable_in_module_p(previous, m));
1838  /* If c really is a common, check its size because it may have increased.
1839  * Note that decreases are not taken into account although they might
1840  * occur as well.
1841  */
1842  if(top_level_entity_p(c)) {
1843  int s = common_to_size(c);
1844  int new_s = ram_offset(storage_ram(entity_storage(previous)))
1845  +SafeSizeOfArray(previous);
1846  if(s < new_s) {
1847  (void) update_common_to_size(c, new_s);
1848  updated = true;
1849  }
1850  }
1851  }
1852  }
1853  debug(8, "update_common_layout",
1854  "End for common /%s/: updated=%s\n",
1855  module_local_name(c), bool_to_string(updated));
1856 
1857  return updated;
1858 }
string bool_to_string(bool)
Definition: string.c:243
bool entity_special_area_p(entity e)
Definition: area.c:154
bool variable_in_module_p(entity, entity)
This test can only be applied to variables, not to functions, subroutines or commons visible from a m...
Definition: variable.c:1610
static size_t current
Definition: string.c:115

References area_layout, bool_to_string(), CAR, common_to_size(), current, debug(), ENDP, ENTITY, entity_special_area_p(), entity_storage, entity_type, entity_undefined, ifdebug, list_undefined, module_local_name(), pips_assert, POP, print_arguments(), ram_offset, SafeSizeOfArray(), storage_ram, storage_ram_p, top_level_entity_p(), type_area, update_common_to_size(), and variable_in_module_p().

Referenced by update_user_common_layouts().

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

◆ update_common_sizes()

void update_common_sizes ( void  )

I'm afraid this warning might be printed because area_size is given a wrong value by CurrentOffsetOfArea().

reset_common_size_map();

Definition at line 1215 of file declaration.c.

1216 {
1217  list commons = NIL;
1218 
1219  HASH_MAP(k, v,{
1220  entity c = (entity) k;
1221  commons = arguments_add_entity(commons, c);
1222  },
1223  common_size_map);
1224 
1225  sort_list_of_entities(commons);
1226 
1227  FOREACH(ENTITY, c, commons)
1228  {
1229  intptr_t s = common_to_size(c);
1230  type tc = entity_type(c);
1231  area ac = type_area(tc);
1232 
1233  pips_assert("update_common_sizes", s != (intptr_t) HASH_UNDEFINED_VALUE);
1234 
1235  if(area_size(ac) == 0) {
1236  area_size(ac) = s;
1237  pips_debug(1, "set size %zd for common %s\n", s, entity_name(c));
1238  }
1239  else if (area_size(ac) != s) {
1240  /* I'm afraid this warning might be printed because area_size is given
1241  * a wrong value by CurrentOffsetOfArea().
1242  */
1243  user_warning("update_common_sizes",
1244  "inconsistent size (%d and %d) for common /%s/ in %s\n"
1245  "Best results are obtained if all instances of a "
1246  "COMMON are declared the same way.\n",
1247  area_size(ac), s, module_local_name(c),
1248  CurrentPackage);
1249  if(area_size(ac) < s)
1250  area_size(ac) = s;
1251  }
1252  else {
1253  debug(1, "update_common_sizes",
1254  "reset size %d for common %s\n", s, entity_name(c));
1255  }
1256  }
1257  // Postpone the resetting because DynamicArea is updated till EndOfProcedure()
1258  /* reset_common_size_map(); */
1259 
1260  gen_free_list(commons);
1261 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
static int tc
Internal variables
Definition: reindexing.c:107
void sort_list_of_entities(list l)
sorted in place.
Definition: entity.c:1358
#define intptr_t
Definition: stdint.in.h:294

References area_size, arguments_add_entity(), common_size_map, common_to_size(), CurrentPackage, debug(), ENTITY, entity_name, entity_type, FOREACH, gen_free_list(), HASH_MAP, HASH_UNDEFINED_VALUE, intptr_t, module_local_name(), NIL, pips_assert, pips_debug, sort_list_of_entities(), tc, type_area, and user_warning.

Referenced by EndOfProcedure().

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

◆ update_common_to_size()

void update_common_to_size ( entity  a,
size_t  new_size 
)
Parameters
new_sizeew_size

Definition at line 1010 of file declaration.c.

1011 {
1012  (void) hash_update(common_size_map, (char *) a, (char *) (new_size));
1013 }
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491

References common_size_map, and hash_update().

Referenced by ComputeAddresses(), CurrentOffsetOfArea(), and update_common_layout().

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

◆ update_functional_type_result()

void update_functional_type_result ( entity  f,
type  nt 
)

Update of the type returned by function f.

nt must be a freshly allocated object. It is included in f's data structure

The function is probably a formal parameter, its type is wrong. The return type is either void if it is called by CALL or its current implicit type.

Parameters
ntt

Definition at line 932 of file statement.c.

933 {
934  type ft = entity_type(f);
935  type rt = type_undefined;
936 
937  //pips_assert("function type is functional", type_functional_p(ft));
938  if(!type_functional_p(ft)) {
939  /* The function is probably a formal parameter, its type is
940  wrong. The return type is either void if it is called by CALL
941  or its current implicit type. */
943  pips_user_warning("Variable \"%s\" is a formal functional parameter\n",
945  ParserError(__FUNCTION__,
946  "Formal functional parameters are not yet supported\n");
947  }
948  else {
949  pips_internal_error("Unexpected case");
950  }
951  }
952  else {
954  }
955 
956  pips_assert("result type is variable or unkown or void or undefined",
957  type_undefined_p(rt)
958  || type_unknown_p(rt)
959  || type_void_p(rt)
960  || type_variable_p(rt));
961 
962  pips_assert("new result type is variable or void",
963  type_void_p(nt)
964  ||type_variable_p(nt));
965 
966  free_type(rt);
968 }
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487

References entity_storage, entity_type, entity_user_name(), f(), free_type(), functional_result, ParserError(), pips_assert, pips_internal_error, pips_user_warning, storage_formal_p, type_functional, type_functional_p, type_undefined, type_undefined_p, type_unknown_p, type_variable_p, and type_void_p.

Referenced by MakeCallInst().

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

◆ update_functional_type_with_actual_arguments()

void update_functional_type_with_actual_arguments ( entity  e,
list  l 
)

OK, it is not safe: may be it's a 0-ary function

The pre-existing typing of e should match the new one

parameter p = parameter_undefined;

OK

the actual parameter list must be exhausted

as well as the type parameter list

unless the last type in the parameter list is a varargs

Definition at line 971 of file statement.c.

972 {
973  list pc = list_undefined;
974  list pc2 = list_undefined;
975  type t = type_undefined;
977 
978  pips_assert("update_functional_type_with_actual_arguments", !type_undefined_p(entity_type(e)));
979  t = entity_type(e);
980  pips_assert("update_functional_type_with_actual_arguments", type_functional_p(t));
981  ft = type_functional(t);
982 
983 
984  if( ENDP(functional_parameters(ft))) {
985  /* OK, it is not safe: may be it's a 0-ary function */
986  for (pc = l; pc != NULL; pc = CDR(pc)) {
987  expression ae = EXPRESSION(CAR(pc));
988  type t = type_undefined;
990 
991  if(expression_reference_p(ae)) {
994 
995  if(type_functional_p(tv)) {
996  pips_user_warning("Functional actual argument %s found.\n"
997  "Functional arguments are not yet suported by PIPS\n",
999  }
1000 
1001  t = copy_type(tv);
1002  }
1003  else {
1004  basic b = basic_of_expression(ae);
1005  variable v = make_variable(b, NIL,NIL);
1006  t = make_type(is_type_variable, v);
1007  }
1008 
1009  p = make_parameter(t,
1011  make_dummy_unknown());
1012  functional_parameters(ft) =
1014  CONS(PARAMETER, p, NIL));
1015  }
1016  }
1017  else if(get_bool_property("PARSER_TYPE_CHECK_CALL_SITES")) {
1018  /* The pre-existing typing of e should match the new one */
1019  int i = 0;
1020  bool warning_p = false;
1021 
1022  for (pc = l, pc2 = functional_parameters(ft), i = 1;
1023  !ENDP(pc) && !ENDP(pc2);
1024  POP(pc), i++) {
1025  expression ae = EXPRESSION(CAR(pc));
1026  type at = type_undefined;
1027  type ft = parameter_type(PARAMETER(CAR(pc2)));
1028  type eft = type_varargs_p(ft)? type_varargs(ft) : ft;
1029  /* parameter p = parameter_undefined; */
1030 
1031  if(expression_reference_p(ae)) {
1034 
1035  if(type_functional_p(tv)) {
1036  pips_user_warning("Functional actual argument %s found.\n"
1037  "Functional arguments are not yet suported by PIPS\n",
1039  }
1040 
1041  at = copy_type(tv);
1042  }
1043  else {
1044  basic b = basic_of_expression(ae);
1045  variable v = make_variable(b, NIL,NIL);
1046 
1047  at = make_type(is_type_variable, v);
1048  }
1049 
1050  if((type_variable_p(eft)
1052  || type_equal_p(at, eft)) {
1053  /* OK */
1054  if(!type_varargs_p(ft))
1055  POP(pc2);
1056  }
1057  else {
1058  user_warning("update_functional_type_with_actual_arguments",
1059  "incompatible %d%s actual argument and type in call to %s "
1060  "between lines %d and %d. Current type is not updated\n",
1061  i, nth_suffix(i),
1063  free_type(at);
1064  warning_p = true;
1065  break;
1066  }
1067  free_type(at);
1068  }
1069 
1070  if(!warning_p) {
1071  if(!(ENDP(pc) /* the actual parameter list must be exhausted */
1072  && (ENDP(pc2) /* as well as the type parameter list */
1073  || (ENDP(CDR(pc2)) /* unless the last type in the parameter list is a varargs */
1074  && type_varargs_p(parameter_type(PARAMETER(CAR(pc2)))))))) {
1075  user_warning("update_functional_type_with_actual_arguments",
1076  "inconsistent arg. list lengths for %s:\n"
1077  " %d args according to type and %d actual arguments\n"
1078  "between lines %d and %d. Current type is not updated\n",
1079  module_local_name(e),
1082  }
1083  }
1084  }
1085 }
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
dummy make_dummy_unknown(void)
Definition: ri.c:617
string nth_suffix(int)
Definition: string.c:250
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
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
mode MakeModeReference(void)
Definition: type.c:82
#define parameter_type(x)
Definition: ri.h:1819
#define parameter_undefined
Definition: ri.h:1794
#define basic_overloaded_p(x)
Definition: ri.h:623
#define type_varargs(x)
Definition: ri.h:2955
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define type_varargs_p(x)
Definition: ri.h:2953
#define functional_undefined
Definition: ri.h:1418

References basic_of_expression(), basic_overloaded_p, CAR, CDR, CONS, copy_type(), ENDP, entity_local_name(), entity_type, EXPRESSION, expression_reference(), expression_reference_p(), free_type(), functional_parameters, functional_undefined, gen_length(), gen_nconc(), get_bool_property(), is_type_variable, line_b_I, line_e_I, list_undefined, make_dummy_unknown(), make_parameter(), make_type(), make_variable(), MakeModeReference(), module_local_name(), NIL, nth_suffix(), PARAMETER, parameter_type, parameter_undefined, pips_assert, pips_user_warning, POP, reference_variable, type_equal_p(), type_functional, type_functional_p, type_undefined, type_undefined_p, type_varargs, type_varargs_p, type_variable, type_variable_p, user_warning, and variable_basic.

Referenced by MakeAtom(), and MakeCallInst().

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

◆ update_user_common_layouts()

void update_user_common_layouts ( entity  m)

Check...

and fix, if needed!

Only user COMMONs are checked. The two implicit areas, DynamicArea and StaticArea, have not been initialized yet (see ComputeAddress() and the calls in EndOfProcedure()).

List of implicitly and explicitly declared variables, functions and areas

Structure of each area/common

User declarations of commons imply the offset and cannot conflict with equivalences, whereas static and dynamic variables must first comply with equivalences. Hence the layouts of user commons must be updated before equivalences are satisfied whereas layouts of the static and dynamic areas must be satisfied after the equiavelences have been processed.

Definition at line 1670 of file declaration.c.

1672 {
1673  list decls = NIL;
1674  list sorted_decls = NIL;
1675 
1676  pips_assert("update_user_common_layouts", entity_module_p(m));
1677 
1679  sorted_decls = gen_append(decls, NIL);
1680  sort_list_of_entities(sorted_decls);
1681 
1682  ifdebug(1) {
1683  pips_debug(1, "\nDeclarations for module %s\n", module_local_name(m));
1684 
1685  /* List of implicitly and explicitly declared variables,
1686  functions and areas */
1687 
1688  pips_debug(1, "%s\n", ENDP(decls)?
1689  "* empty declaration list *\n\n": "Variable list:\n\n");
1690 
1691  MAP(ENTITY, e,
1692  fprintf(stderr, "Declared entity %s\n", entity_name(e)),
1693  sorted_decls);
1694 
1695  /* Structure of each area/common */
1696  if(!ENDP(decls)) {
1697  (void) fprintf(stderr, "\nLayouts for areas (commons):\n\n");
1698  }
1699  }
1700 
1701  MAP(ENTITY, e, {
1702  if(type_area_p(entity_type(e))) {
1703  ifdebug(1) {
1704  print_common_layout(stderr, e, true);
1705  }
1706  if(!entity_special_area_p(e)) {
1707  /* User declarations of commons imply the offset and
1708  cannot conflict with equivalences, whereas static and
1709  dynamic variables must first comply with
1710  equivalences. Hence the layouts of user commons must be
1711  updated before equivalences are satisfied whereas
1712  layouts of the static and dynamic areas must be
1713  satisfied after the equiavelences have been
1714  processed. */
1715  if(update_common_layout(m, e)) {
1716  ifdebug(1) {
1717  print_common_layout(stderr, e, true);
1718  }
1719  }
1720  }
1721  }
1722  }, sorted_decls);
1723 
1724  gen_free_list(sorted_decls);
1725 
1726  pips_debug(1, "End of declarations for module %s\n\n",
1727  module_local_name(m));
1728 }
bool update_common_layout(entity m, entity c)
(Re)compute offests of all variables allocated in common c from module m and update (if necessary) th...
Definition: declaration.c:1746
void print_common_layout(FILE *fd, entity c, bool debug_p)
Definition: area.c:207
bool entity_module_p(entity e)
Definition: entity.c:683

References code_declarations, ENDP, ENTITY, entity_initial, entity_module_p(), entity_name, entity_special_area_p(), entity_type, fprintf(), gen_append(), gen_free_list(), ifdebug, MAP, module_local_name(), NIL, pips_assert, pips_debug, print_common_layout(), sort_list_of_entities(), type_area_p, update_common_layout(), and value_code.

Referenced by EndOfProcedure().

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

◆ UpdateFormalStorages()

void UpdateFormalStorages ( entity  m,
list  lfp 
)

this function check and set if necessary the storage of formal parameters in lfp.

formal parameter chunk

formal parameter offset

Oupss... the associated area should be cleaned up... but it should ony occur in EndOfProcedure() when all implictly declared variables have been encountered...

Parameters
lfpfp

Definition at line 2522 of file procedure.c.

2525 {
2526  list fpc; /* formal parameter chunk */
2527  int fpo; /* formal parameter offset */
2528 
2529  for (fpc = lfp, fpo = 1; !ENDP(fpc); POP(fpc), fpo += 1) {
2530  entity fp = ENTITY(CAR(fpc));
2531  storage fps = entity_storage(fp);
2532 
2533  pips_assert("Formal parameter fp must be in scope of module m",
2535 
2536  if(storage_undefined_p(fps)) {
2538  make_formal(m, fpo));
2539  }
2540  else if(storage_ram_p(fps)){
2541  /* Oupss... the associated area should be cleaned up... but
2542  * it should ony occur in EndOfProcedure() when all implictly
2543  * declared variables have been encountered...
2544  */
2545  free_storage(fps);
2547  make_formal(m, fpo));
2548  }
2549  else if(storage_formal_p(fps)){
2550  pips_assert("Consistent Offset",
2551  fpo==formal_offset(storage_formal(fps)));
2552  }
2553  else {
2554  pips_internal_error("Unexpected storage for entity %s",
2555  entity_name(fp));
2556  }
2557  }
2558 }
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
#define formal_offset(x)
Definition: ri.h:1408
#define storage_formal(x)
Definition: ri.h:2524

References CAR, ENDP, ENTITY, entity_module_name(), entity_name, entity_storage, formal_offset, free_storage(), is_storage_formal, local_name_to_top_level_entity(), make_formal(), make_storage(), pips_assert, pips_internal_error, POP, storage_formal, storage_formal_p, storage_ram_p, and storage_undefined_p.

Referenced by MakeEntry().

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

◆ UpdateFunctionalType()

void UpdateFunctionalType ( entity  f,
list  l 
)

This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction functional type.

l is this list.

It is called by EndOfProcedure().

FI: I do not understand this assert... at least now that functions may be typed at call sites. I do not understand why this assert has not made more damage. Only OVL in APSI (Spec-cfp95) generates a core dump. To be studied more!

This assert is guaranteed by MakeCurrentFunction() but not by retype_formal_parameters() which is called in case an intrinsic statement is encountered. It is not guaranteed by MakeExternalFunction() which uses the actual parameter list to estimate a functional type

Definition at line 1131 of file procedure.c.

1134 {
1135  cons *pc;
1136  parameter p;
1137  functional ft;
1138  entity CurrentFunction = f;
1139  type t = entity_type(CurrentFunction);
1140 
1141  ifdebug(8) {
1142  pips_debug(8, "Begin for %s with type ",
1143  module_local_name(CurrentFunction));
1144  fprint_functional(stderr, type_functional(t));
1145  (void) fprintf(stderr, "\n");
1146  }
1147 
1148  pips_assert("A module type should be functional", type_functional_p(t));
1149 
1150  ft = type_functional(t);
1151 
1152  /* FI: I do not understand this assert... at least now that
1153  * functions may be typed at call sites. I do not understand why this
1154  * assert has not made more damage. Only OVL in APSI (Spec-cfp95)
1155  * generates a core dump. To be studied more!
1156  *
1157  * This assert is guaranteed by MakeCurrentFunction() but not by
1158  * retype_formal_parameters() which is called in case an intrinsic
1159  * statement is encountered. It is not guaranteed by MakeExternalFunction()
1160  * which uses the actual parameter list to estimate a functional type
1161  */
1162  pips_assert("Parameter type list should be empty",
1164 
1165  for (pc = l; pc != NULL; pc = CDR(pc)) {
1166  entity fp = ENTITY(CAR(pc));
1167  type fpt = entity_type(fp);
1168 
1169  if(type_undefined_p(fpt)) {
1170  entity_type(fp) = ImplicitType(fp);
1171  }
1172 
1173  p = make_parameter((entity_type(fp)),
1175  functional_parameters(ft) =
1177  CONS(PARAMETER, p, NIL));
1178  }
1179 
1180  ifdebug(8) {
1181  pips_debug(8, "End for %s with type ",
1182  module_local_name(CurrentFunction));
1183  fprint_functional(stderr, type_functional(t));
1184  (void) fprintf(stderr, "\n");
1185  }
1186 }
dummy make_dummy_identifier(entity _field_)
Definition: ri.c:620

References CAR, CDR, CONS, ENDP, ENTITY, entity_type, f(), fprint_functional(), fprintf(), functional_parameters, gen_nconc(), ifdebug, ImplicitType(), make_dummy_identifier(), make_parameter(), MakeModeReference(), module_local_name(), NIL, PARAMETER, pips_assert, pips_debug, type_functional, type_functional_p, and type_undefined_p.

Referenced by EndOfProcedure(), gfc2pips_namespace(), gfc2pips_parameters(), and MakeEntry().

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

◆ uses_alternate_return()

void uses_alternate_return ( bool  use)
Parameters
usese

Definition at line 171 of file return.c.

172 {
173  if(use && strcmp(get_string_property("PARSER_SUBSTITUTE_ALTERNATE_RETURNS"), "NO")==0) {
175  ("Lines %d-%d: Alternate return not processed with current option \"%s\". "
176  "Formal label * ignored.\n"
177  "See property PARSER_SUBSTITUTE_ALTERNATE_RETURNS for other options\n",
178  line_b_I, line_e_I, get_string_property("PARSER_SUBSTITUTE_ALTERNATE_RETURNS"));
179  ParserError("uses_alternate_return", "Alternate returns prohibited by user\n");
180  }
181 
183 
185 }
static bool current_module_uses_alternate_returns
Remember if the current module uses alternate returns.
Definition: return.c:161

References current_module_uses_alternate_returns, current_number_of_alternate_returns, get_string_property(), line_b_I, line_e_I, ParserError(), and pips_user_warning.

Referenced by EndOfProcedure(), and ParserError().

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

◆ uses_alternate_return_p()

bool uses_alternate_return_p ( void  )

Definition at line 166 of file return.c.

167 {
169 }

References current_module_uses_alternate_returns.

Referenced by add_formal_return_code(), GenerateReturn(), and MakeReturn().

+ Here is the caller graph for this function:

◆ ValueOfIthLowerBound()

int ValueOfIthLowerBound ( entity  e,
int  i 
)

this function returns the size of the ith lower bound of a variable e.

Definition at line 1591 of file declaration.c.

1594 {
1595  cons * pc;
1596 
1597  pips_assert("ValueOfIthLowerBound", type_variable_p(entity_type(e)));
1598 
1599  pips_assert("ValueOfIthLowerBound", i >= 1 && i <= 7);
1600 
1602 
1603  while (pc != NULL && --i > 0)
1604  pc = CDR(pc);
1605 
1606  if (pc == NULL)
1607  ParserError("SizeOfIthLowerBound", "not enough dimensions\n");
1608 
1609  return(ExpressionToInt((dimension_lower(DIMENSION(CAR(pc))))));
1610 }
#define dimension_lower(x)
Definition: ri.h:980

References CAR, CDR, DIMENSION, dimension_lower, entity_type, ExpressionToInt(), ParserError(), pips_assert, type_variable, type_variable_p, and variable_dimensions.

Referenced by OffsetOfReference().

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

◆ Comm

char* Comm
extern

reader.c

Definition at line 152 of file reader.c.

Referenced by init_comment_buffers(), ReadLine(), and resize_comment_buffers().

◆ CurrComm

char* CurrComm
extern

Definition at line 152 of file reader.c.

Referenced by init_comment_buffers(), ReadLine(), and resize_comment_buffers().

◆ CurrentFN

char* CurrentFN
extern

parser.c

parser.c

name of the current file

Definition at line 49 of file parser.c.

Referenced by check_first_statement(), dump_current_statement(), ParserError(), and the_actual_parser().

◆ CurrentPackage

◆ CurrentType

type CurrentType
extern

to count control specifications in IO statements

Definition at line 101 of file syn_yacc.c.

◆ CurrentTypeSize

intptr_t CurrentTypeSize
extern

the type in a type or dimension or common statement

Definition at line 103 of file syn_yacc.c.

◆ DynamicArea

entity DynamicArea
extern

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

area.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.

◆ FormalParameters

cons* FormalParameters
extern

the current function

entity CurrentFunction; list of formal parameters of the current function

Definition at line 55 of file parser.c.

Referenced by EndOfProcedure(), and ScanFormalParameters().

◆ FormatValue

char FormatValue[(4096)]
extern

a string that will contain the value of the format in case of format statement

Definition at line 95 of file parser.c.

◆ HeapArea

entity HeapArea
extern

Definition at line 59 of file area.c.

Referenced by print_common_layout().

◆ ici

int ici
extern

syn_yacc.c

syn_yacc.c

Definition at line 100 of file syn_yacc.c.

◆ iComm

int iComm
extern

Definition at line 153 of file reader.c.

Referenced by parser_reset_all_reader_buffers(), and ReadLine().

◆ iCurrComm

int iCurrComm
extern

Definition at line 153 of file reader.c.

Referenced by parser_reset_all_reader_buffers(), and ReadLine().

◆ InParserError

bool InParserError
extern

Parser error handling.

Definition at line 113 of file parser.c.

Referenced by ParserError().

◆ iPrevComm

◆ lab_I

◆ line_b_C

int line_b_C
extern

Definition at line 68 of file parser.c.

Referenced by check_first_statement(), ReadStmt(), and set_first_format_statement().

◆ line_b_I

int line_b_I
extern

Indicates where the current instruction (in fact statement) starts and ends in the input file and gives its label.

Temporary versions of these variables are used because of the pipeline existing between the reader and the actual parser. The names of the temporary variables are prefixed with "tmp_". The default and reset values of these variables and their temporary versions (declared in reader.c) must be consistent.

Definition at line 68 of file parser.c.

Referenced by add_alternate_return(), AddVariableToCommon(), check_first_statement(), DeclarePointer(), DeclareVariable(), fix_if_condition(), implied_do_reference_number(), MakeReturn(), MakeWhileDoInst(), ParserError(), set_first_format_statement(), update_functional_type_with_actual_arguments(), and uses_alternate_return().

◆ line_e_C

int line_e_C
extern

Definition at line 68 of file parser.c.

Referenced by ReadStmt().

◆ line_e_I

◆ PrevComm

char* PrevComm
extern

◆ StackArea

entity StackArea
extern

Definition at line 60 of file area.c.

Referenced by print_common_layout().

◆ StaticArea

entity StaticArea
extern

Definition at line 58 of file area.c.

◆ syn__flex_debug

int syn__flex_debug
extern

◆ syn_char

int syn_char
extern

◆ syn_in

FILE* syn_in
extern

lex yacc interface

Definition at line 325 of file syntax.h.

◆ syn_leng

int syn_leng
extern

◆ syn_lineno

int syn_lineno
extern

◆ syn_nerrs

int syn_nerrs
extern

◆ syn_out

FILE* syn_out
extern

◆ syn_text

char* syn_text
extern

◆ vcid_syntax_equivalence

char vcid_syntax_equivalence[]
extern

equivalence.c

equivalence.c

Allocate addresses in commons and in the static area and in the dynamic area. The heap area is left aside.

Definition at line 33 of file equivalence.c.

◆ vcid_syntax_expression

char vcid_syntax_expression[]
extern

expression.c

Definition at line 29 of file expression.c.