PIPS
|
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "genC.h"
#include "parser_private.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "misc.h"
#include "properties.h"
#include "syntax.h"
#include "syn_yacc.h"
Go to the source code of this file.
Data Structures | |
struct | stmt |
struct | block |
Macros | |
#define | INITIAL_STMTHEAP_BUFFER_SIZE 10 |
the purpose of the following data structure is to associate labels to instructions. More... | |
#define | MAXBLOCK 200 |
The purpose of the following data structure is to build the control structure of the procedure being analyzed. More... | |
#define | UNDEF (-2) |
Well, some constant defined in reader.c and not deserving a promotion in syntax-local.h. More... | |
Typedefs | |
typedef struct block | block |
Functions | |
static void | init_StmtHeap_buffer (void) |
static void | resize_StmtHeap_buffer (void) |
void | parser_reset_StmtHeap_buffer (void) |
statement.c More... | |
statement | LabelToStmt (string l) |
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 e, statement s) |
this function stores a new association in table StmtHeap: the label of statement s is e. More... | |
void | ResetBlockStack () |
bool | IsBlockStackEmpty () |
bool | IsBlockStackFull () |
void | PushBlock (instruction i, string l) |
instruction | PopBlock () |
entity | MakeLabel (char *s) const |
This functions creates a label. More... | |
statement | MakeNewLabelledStatement (entity l, instruction i) |
statement | ReuseLabelledStatement (statement s, instruction i) |
statement | MakeStatement (entity l, instruction i) |
This function makes a statement. More... | |
void | LinkInstToCurrentBlock (instruction i, bool number_it) |
this function links the instruction i to the current block of statements. More... | |
instruction | MakeEmptyInstructionBlock () |
this function creates an empty block More... | |
instruction | MakeZeroOrOneArgCallInst (char *s, expression e) |
this function creates a simple Fortran statement such as RETURN, CONTINUE, ... More... | |
instruction | MakeGotoInst (string n) |
this function creates a goto instruction. More... | |
instruction | make_goto_instruction (entity l) |
In a "go to" instruction, the label does not appear explictly. More... | |
instruction | MakeComputedGotoInst (list ll, expression e) |
instruction | MakeAssignedGotoInst (list ll, entity i) |
instruction | MakeAssignedOrComputedGotoInst (list ll, expression ce, bool assigned) |
instruction | MakeAssignInst (syntax l, expression e) |
this function creates an affectation statement. More... | |
void | update_functional_type_result (entity f, type nt) |
Update of the type returned by function f. More... | |
void | update_functional_type_with_actual_arguments (entity e, list l) |
instruction | MakeCallInst (entity e, cons *l) |
this function creates a call statement. More... | |
void | MakeDoInst (syntax s, range r, string l) |
this function creates a do loop statement. More... | |
void | MakeWhileDoInst (expression c, string l) |
This function creates a while do loop statement. More... | |
expression | fix_if_condition (expression e) |
instruction | MakeLogicalIfInst (expression e, instruction i) |
this function creates a logical if statement. More... | |
instruction | MakeArithmIfInst (expression e, string l1, string l2, string l3) |
this function transforms an arithmetic if statement into a set of regular tests. More... | |
void | MakeBlockIfInst (expression e, int elsif) |
this function and the two next ones create a block if statement. More... | |
int | MakeElseInst (bool is_else_p) |
This function is used to handle either an ELSE or an ELSEIF construct. More... | |
void | MakeEndifInst () |
void | MakeEnddoInst () |
string | NameOfToken (int token) |
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=. More... | |
instruction | MakeIoInstA (int keyword, list lci, list lio) |
this function creates an IO statement. More... | |
instruction | MakeIoInstB (int keyword, expression e1, expression e2, expression e3, expression e4) |
this function creates a BUFFER IN or BUFFER OUT io statement. More... | |
instruction | MakeSimpleIoInst1 (int keyword, expression unit) |
instruction | MakeSimpleIoInst2 (int keyword, expression f, list io_list) |
void | reset_first_statement () |
void | set_first_format_statement () |
bool | first_executable_statement_seen () |
bool | first_format_statement_seen () |
void | check_in_declarations () |
void | check_first_statement () |
This function is called each time an executable statement is encountered but is effective the first time only. More... | |
Variables | |
static stmt * | StmtHeap_buffer |
static int | StmtHeap_buffer_size |
static int | CurrentStmt = 0 |
LOCAL block | BlockStack [MAXBLOCK] |
statement.c More... | |
LOCAL int | CurrentBlock = 0 |
static int | seen = false |
Are we in the declaration or in the executable part? Have we seen a FORMAT statement before an executable statement? For more explanation, see check_first_statement() below. More... | |
static int | format_seen = false |
static int | declaration_lines = -1 |
#define INITIAL_STMTHEAP_BUFFER_SIZE 10 |
the purpose of the following data structure is to associate labels to instructions.
The data structure contains a string (the label's name) and a statement (the statement which the label is attached to).
Definition at line 52 of file statement.c.
#define MAXBLOCK 200 |
The purpose of the following data structure is to build the control structure of the procedure being analyzed.
each time a control statement (do loop, block if, ...) is analyzed, a new block is created and pushed on the block stack. regular statement (assign, goto, return, ...) are linked to the block that is on the top of the stack. blocks are removed from the stack when the corresponding end statement is encountered (endif, end of loop, ...).
The block ending statements are ELSE, ENDIF,...
There does not seem to be any limit on the nesting level in Fortran standard. MAXBLOCK is set to "large" value for our users. The IF/THEN/ELSEIF construct is replaced by nested IF/ELSE statements which increases the nesting level observed by the source reader.
Fabien Coelho suggests to refactor this part of the code with a Newgen stack automatically reallocated on overflow:
stack s = stack_make(statement_domain, 0, 0); stack_push(e, s); e = stack_pop(s); while (!stack_empty_p(s)) { ... } stack_free(s);
Definition at line 189 of file statement.c.
#define UNDEF (-2) |
Well, some constant defined in reader.c and not deserving a promotion in syntax-local.h.
Definition at line 1941 of file statement.c.
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
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.
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.
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.
References format_seen, get_bool_property(), ParserError(), pips_user_warning, and seen.
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.
References CurrentStmt, instruction_undefined, label_local_name(), ParserError(), stmt::s, statement_instruction, statement_label, StmtHeap_buffer, and user_warning.
Referenced by EndOfProcedure().
bool first_executable_statement_seen | ( | void | ) |
bool first_format_statement_seen | ( | void | ) |
Definition at line 1970 of file statement.c.
References format_seen.
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.
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().
|
static |
if needed
Definition at line 64 of file statement.c.
References INITIAL_STMTHEAP_BUFFER_SIZE, malloc(), pips_assert, pips_debug, StmtHeap_buffer, and StmtHeap_buffer_size.
Referenced by NewStmt().
bool IsBlockStackEmpty | ( | void | ) |
Definition at line 209 of file statement.c.
References CurrentBlock.
Referenced by EndOfProcedure(), LinkInstToCurrentBlock(), and PopBlock().
bool IsBlockStackFull | ( | void | ) |
Definition at line 215 of file statement.c.
References CurrentBlock, and MAXBLOCK.
Referenced by PushBlock().
this functions looks up in table StmtHeap for the statement s whose label is l.
Definition at line 94 of file statement.c.
References CurrentStmt, statement_undefined, and StmtHeap_buffer.
Referenced by make_goto_instruction(), MakeStatement(), and NewStmt().
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 ...
number_it | umber_it |
Definition at line 529 of file statement.c.
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().
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.
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().
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.
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().
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
l1 | 1 |
l2 | 2 |
l3 | 3 |
Definition at line 1399 of file statement.c.
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.
instruction MakeAssignedGotoInst | ( | list | ll, |
entity | i | ||
) |
ll | l |
Definition at line 734 of file statement.c.
References DeclareVariable(), entity_to_expression(), MakeAssignedOrComputedGotoInst(), NIL, storage_undefined, type_undefined, and value_undefined.
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");
ll | l |
ce | e |
assigned | ssigned |
Definition at line 747 of file statement.c.
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().
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.
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.
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.
elsif | lsif |
Definition at line 1498 of file statement.c.
References BlockStack, CurrentBlock, fix_if_condition(), is_instruction_test, LinkInstToCurrentBlock(), make_instruction(), make_test(), MakeEmptyInstructionBlock(), MakeLabel(), MakeStatement(), and PushBlock().
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);
l | callee list of actual parameters |
Definition at line 1091 of file statement.c.
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.
instruction MakeComputedGotoInst | ( | list | ll, |
expression | e | ||
) |
ll | l |
Definition at line 727 of file statement.c.
References MakeAssignedOrComputedGotoInst().
Referenced by generate_return_code_checks().
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.
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.
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
is_else_p | s_else_p |
Definition at line 1522 of file statement.c.
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().
instruction MakeEmptyInstructionBlock | ( | void | ) |
this function creates an empty block
Definition at line 654 of file statement.c.
References make_instruction_block(), and NIL.
Referenced by MakeBlockIfInst(), MakeCurrentFunction(), MakeDoInst(), and MakeWhileDoInst().
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.
References BlockStack, CurrentBlock, lab_I, LinkInstToCurrentBlock(), make_continue_instruction(), ParserError(), and PopBlock().
void MakeEndifInst | ( | void | ) |
generate a CONTINUE to carry the comments
Definition at line 1578 of file statement.c.
References BlockStack, CurrentBlock, iPrevComm, LinkInstToCurrentBlock(), make_continue_instruction(), MakeElseInst(), ParserError(), pips_assert, and PopBlock().
instruction MakeGotoInst | ( | string | n | ) |
this function creates a goto instruction.
n is the target label.
Definition at line 686 of file statement.c.
References entity_undefined, instruction_undefined, make_goto_instruction(), and MakeLabel().
Referenced by MakeArithmIfInst(), MakeAssignedOrComputedGotoInst(), and MakeReturn().
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.
keyword | eyword |
lci | ci |
lio | io |
Definition at line 1715 of file statement.c.
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().
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.
keyword | eyword |
e1 | 1 |
e2 | 2 |
e3 | 3 |
e4 | 4 |
Definition at line 1837 of file statement.c.
References CONS, CreateIntrinsic(), EXPRESSION, is_instruction_call, make_call(), make_instruction(), and NameOfToken().
entity MakeLabel | ( | char* | s | ) | const |
This functions creates a label.
LABEL_PREFIX is added to its name, for integer constants and labels not to have the same name space.
If an empty string is passed, the empty label seems to be returned since EMPTY_LABEL_NAME is defined as LABEL_PREFIX in ri-util-local.h (FI, 5 March 1998)
Definition at line 257 of file statement.c.
References CurrentPackage, debug(), entity_initial, entity_storage, entity_type, FindOrCreateEntity(), is_value_constant, LABEL_PREFIX, LABEL_SIZE, make_constant_litteral(), make_storage_rom(), make_value(), MakeTypeStatement(), malloc(), TOP_LEVEL_MODULE_NAME, and type_undefined.
Referenced by add_alternate_return(), GenerateReturn(), LinkInstToCurrentBlock(), MakeBlockIfInst(), MakeDoInst(), MakeGotoInst(), MakeIoInstA(), MakeReturn(), and MakeWhileDoInst().
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:
It is not easy to number bt because Yacc reduction order does not help...
Instruction i should not be a block, unless:
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.
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.
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.
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().
instruction MakeSimpleIoInst1 | ( | int | keyword, |
expression | unit | ||
) |
Functionally PRINT is a special case of WRITE
keyword | eyword |
Definition at line 1854 of file statement.c.
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.
instruction MakeSimpleIoInst2 | ( | int | keyword, |
expression | f, | ||
list | io_list | ||
) |
keyword | eyword |
io_list | o_list |
Definition at line 1899 of file statement.c.
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().
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.
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().
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.
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().
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.
References CONS, CreateIntrinsic(), EXPRESSION, expression_undefined, is_instruction_call, make_call(), make_instruction(), and NIL.
Referenced by GenerateReturn(), gfc2pips_code2instruction__TOP(), MakeAssignedOrComputedGotoInst(), and MakeReturn().
just to avoid a gcc warning
token | oken |
Definition at line 1636 of file statement.c.
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().
this function stores a new association in table StmtHeap: the label of statement s is e.
Definition at line 141 of file statement.c.
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().
void parser_reset_StmtHeap_buffer | ( | void | ) |
statement.c
Definition at line 85 of file statement.c.
References CurrentStmt.
Referenced by ParserError().
instruction PopBlock | ( | void | ) |
Definition at line 238 of file statement.c.
References BlockStack, CurrentBlock, IsBlockStackEmpty(), and ParserError().
Referenced by EndOfProcedure(), LinkInstToCurrentBlock(), MakeElseInst(), MakeEnddoInst(), and MakeEndifInst().
void PushBlock | ( | instruction | i, |
string | l | ||
) |
Definition at line 221 of file statement.c.
References BlockStack, CurrentBlock, instruction_block_p, IsBlockStackFull(), ParserError(), and pips_assert.
Referenced by MakeBlockIfInst(), MakeCurrentFunction(), MakeDoInst(), MakeElseInst(), and MakeWhileDoInst().
void reset_first_statement | ( | void | ) |
Definition at line 1944 of file statement.c.
References declaration_lines, format_seen, and seen.
void ResetBlockStack | ( | void | ) |
Definition at line 203 of file statement.c.
References CurrentBlock.
Referenced by AbortOfProcedure(), and ParserError().
|
static |
Definition at line 74 of file statement.c.
References pips_assert, pips_debug, StmtHeap_buffer, and StmtHeap_buffer_size.
Referenced by NewStmt().
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.
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().
void set_first_format_statement | ( | void | ) |
declaration_lines = line_b_I-1;
Definition at line 1952 of file statement.c.
References debug(), declaration_lines, format_seen, line_b_C, line_b_I, seen, and UNDEF.
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.
nt | t |
Definition at line 932 of file statement.c.
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().
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.
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().
Definition at line 200 of file statement.c.
Referenced by IsBlockStackEmpty(), IsBlockStackFull(), LinkInstToCurrentBlock(), MakeBlockIfInst(), MakeElseInst(), MakeEnddoInst(), MakeEndifInst(), PopBlock(), PushBlock(), and ResetBlockStack().
|
static |
Definition at line 61 of file statement.c.
Referenced by CheckAndInitializeStmt(), LabelToStmt(), NewStmt(), and parser_reset_StmtHeap_buffer().
|
static |
Definition at line 1936 of file statement.c.
Referenced by check_first_statement(), reset_first_statement(), and set_first_format_statement().
Definition at line 1935 of file statement.c.
Referenced by check_first_statement(), check_in_declarations(), first_format_statement_seen(), reset_first_statement(), and set_first_format_statement().
Are we in the declaration or in the executable part? Have we seen a FORMAT statement before an executable statement? For more explanation, see check_first_statement() below.
Definition at line 1934 of file statement.c.
Referenced by check_first_statement(), check_in_declarations(), first_executable_statement_seen(), reset_first_statement(), and set_first_format_statement().
|
static |
Definition at line 59 of file statement.c.
Referenced by CheckAndInitializeStmt(), init_StmtHeap_buffer(), LabelToStmt(), NewStmt(), and resize_StmtHeap_buffer().
|
static |
Definition at line 60 of file statement.c.
Referenced by init_StmtHeap_buffer(), NewStmt(), and resize_StmtHeap_buffer().