diff -r bd5998ee8876 -r ff4d26b7e51d stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Mon Feb 13 17:04:29 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Thu Feb 16 10:27:52 2012 +0000 @@ -76,6 +76,11 @@ return false; } +/* + * All parameters being passed to the called function MUST be in the parameter list to which f_call points to! + * This means that, for non formal function calls in IL, de current (default value) must be artificially added to the + * beginning of the parameter list BEFORE calling handle_function_call(). + */ void narrow_candidate_datatypes_c::narrow_nonformal_call(symbol_c *f_call, symbol_c *f_decl, int *ext_parm_count) { symbol_c *call_param_value, *param_type; identifier_c *param_name; @@ -110,6 +115,19 @@ if ((NULL != param_name) && (NULL == desired_datatype)) ERROR; if ((NULL == param_name) && (NULL != desired_datatype)) ERROR; + /* NOTE: When we are handling a nonformal function call made from IL, the first parameter is the 'default' or 'current' + * il value. However, a pointer to the prev_il_instruction is pre-pended into the operand list (done in fill_candidate_datatypes_c, + * and later undone in print_datatypes_error_c - this class is run after the first, and before the latter!), so + * the call + * call_param_value->accept(*this); + * may actually be calling an object of the il_instruction_c class. + * If that is the case, that same il_instruction_c object will be called again inside the for() loop + * of void *narrow_candidate_datatypes_c::visit(instruction_list_c *symbol); + * This is actually safe, as the narrow algorithm for all IL instructions is idem-potent. + * (It is easier to just let it be called twice than to hack the code to guarantee that it is + * only called once - this would also make this hacked code ugly an un-elegant, so we leave + * it as it is for now...) + */ set_datatype(desired_datatype, call_param_value); call_param_value->accept(*this); @@ -265,6 +283,17 @@ return NULL; } +/* simple_specification ASSIGN constant */ +// SYM_REF2(simple_spec_init_c, simple_specification, constant) +void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { + symbol_c *datatype = base_type(symbol->simple_specification); + if (NULL != symbol->constant) { + int typeoffset = search_in_datatype_list(datatype, symbol->constant->candidate_datatypes); + if (typeoffset >= 0) + symbol->constant->datatype = symbol->constant->candidate_datatypes[typeoffset]; + } + return NULL; +} /*********************/ /* B 1.4 - Variables */ @@ -309,10 +338,9 @@ /*********************/ void *narrow_candidate_datatypes_c::visit(function_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); + symbol->var_declarations_list->accept(*this); if (debug) printf("Narrowing candidate data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value); - prev_il_instruction = NULL; symbol->function_body->accept(*this); - prev_il_instruction = NULL; delete search_varfb_instance_type; search_varfb_instance_type = NULL; return NULL; @@ -323,10 +351,9 @@ /***************************/ void *narrow_candidate_datatypes_c::visit(function_block_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); + symbol->var_declarations->accept(*this); if (debug) printf("Narrowing candidate data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value); - prev_il_instruction = NULL; symbol->fblock_body->accept(*this); - prev_il_instruction = NULL; delete search_varfb_instance_type; search_varfb_instance_type = NULL; return NULL; @@ -337,10 +364,9 @@ /********************/ void *narrow_candidate_datatypes_c::visit(program_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); + symbol->var_declarations->accept(*this); if (debug) printf("Narrowing candidate data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value); - prev_il_instruction = NULL; symbol->function_block_body->accept(*this); - prev_il_instruction = NULL; delete search_varfb_instance_type; search_varfb_instance_type = NULL; return NULL; @@ -351,10 +377,8 @@ /* B 1.7 Configuration elements */ /********************************/ void *narrow_candidate_datatypes_c::visit(configuration_declaration_c *symbol) { -#if 0 // TODO !!! /* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */ -#endif return NULL; } @@ -365,13 +389,38 @@ /***********************************/ /* B 2.1 Instructions and Operands */ /***********************************/ + +/*| instruction_list il_instruction */ +// SYM_LIST(instruction_list_c) +void *narrow_candidate_datatypes_c::visit(instruction_list_c *symbol) { + /* We need to go through the instructions backwards, so we can not use the base class' visitor */ + for(int i = symbol->n-1; i >= 0; i--) { + symbol->elements[i]->accept(*this); + } + return NULL; +} + +/* | label ':' [il_incomplete_instruction] eol_list */ +// SYM_REF2(il_instruction_c, label, il_instruction) +// void *visit(instruction_list_c *symbol); +void *narrow_candidate_datatypes_c::visit(il_instruction_c *symbol) { + if (NULL == symbol->il_instruction) + return NULL; + + prev_il_instruction = symbol->prev_il_instruction; + /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (we iterate backwards!) */ + symbol->il_instruction->datatype = symbol->datatype; + symbol->il_instruction->accept(*this); + return NULL; +} + + // void *visit(instruction_list_c *symbol); void *narrow_candidate_datatypes_c::visit(il_simple_operation_c *symbol) { + /* Tell the il_simple_operator the datatype that it must generate - this was chosen by the next il_instruction (we iterate backwards!) */ + symbol->il_simple_operator->datatype = symbol->datatype; + /* recursive call to see whether data types are compatible */ il_operand = symbol->il_operand; - if (NULL != symbol->il_operand) { - symbol->il_operand->accept(*this); - } - /* recursive call to see whether data types are compatible */ symbol->il_simple_operator->accept(*this); il_operand = NULL; return NULL; @@ -399,6 +448,8 @@ * the following code is actually correct! */ narrow_function_invocation(symbol, fcall_param); + /* set the desired datatype of the previous il instruction */ + prev_il_instruction->datatype = symbol->datatype; return NULL; } @@ -464,6 +515,8 @@ }; narrow_function_invocation(symbol, fcall_param); + /* set the desired datatype of the previous il instruction */ + prev_il_instruction->datatype = symbol->datatype; return NULL; } @@ -479,28 +532,51 @@ /*******************/ /* B 2.2 Operators */ /*******************/ -void *narrow_candidate_datatypes_c::visit(LD_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(LDN_operator_c *symbol) { + +void *narrow_candidate_datatypes_c::handle_il_instruction(symbol_c *symbol) { + if (NULL == symbol->datatype) + /* next IL instructions were unable to determine the datatype this instruction should produce */ + return NULL; + /* set the datatype for the operand */ + il_operand->datatype = symbol->datatype; + il_operand->accept(*this); + /* set the desired datatype of the previous il instruction */ + prev_il_instruction->datatype = symbol->datatype; + return NULL; +} + +void *narrow_candidate_datatypes_c::visit(LD_operator_c *symbol) { + if (NULL == symbol->datatype) + /* next IL instructions were unable to determine the datatype this instruction should produce */ + return NULL; + /* set the datatype for the operand */ + il_operand->datatype = symbol->datatype; + il_operand->accept(*this); + return NULL; +} + + +void *narrow_candidate_datatypes_c::visit(LDN_operator_c *symbol) { + if (NULL == symbol->datatype) + /* next IL instructions were unable to determine the datatype this instruction should produce */ + return NULL; + /* set the datatype for the operand */ + il_operand->datatype = symbol->datatype; + il_operand->accept(*this); + return NULL; +} + +void *narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) { + if (debug) printf("narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) called.\n"); if (symbol->candidate_datatypes.size() != 1) return NULL; symbol->datatype = symbol->candidate_datatypes[0]; + /* set the datatype for the operand */ il_operand->datatype = symbol->datatype; il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; + /* set the desired datatype of the previous il instruction */ + prev_il_instruction->datatype = symbol->datatype; + if (debug) printf("narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) returning. previous_il_instruction->datatype = %p\n", prev_il_instruction->datatype); return NULL; } @@ -508,9 +584,11 @@ if (symbol->candidate_datatypes.size() != 1) return NULL; symbol->datatype = symbol->candidate_datatypes[0]; + /* set the datatype for the operand */ il_operand->datatype = symbol->datatype; il_operand->accept(*this); - prev_il_instruction = symbol; + /* set the desired datatype of the previous il instruction */ + prev_il_instruction->datatype = symbol->datatype; return NULL; } @@ -519,233 +597,86 @@ return NULL; } -void *narrow_candidate_datatypes_c::visit(S_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(R_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(S1_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(R1_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} +void *narrow_candidate_datatypes_c::visit(S_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(R_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(S1_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(R1_operator_c *symbol) {return handle_il_instruction(symbol);} void *narrow_candidate_datatypes_c::visit(CLK_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(CU_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(CD_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(PV_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(IN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(PT_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(AND_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(OR_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(XOR_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(ANDN_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(ORN_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(XORN_operator_c *symbol) { - if (symbol->candidate_datatypes.size() != 1) - return NULL; - symbol->datatype = symbol->candidate_datatypes[0]; - il_operand->datatype = symbol->datatype; - il_operand->accept(*this); - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(ADD_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(SUB_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(MUL_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(DIV_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(MOD_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(GT_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(GE_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(EQ_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(LT_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(LE_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} - -void *narrow_candidate_datatypes_c::visit(NE_operator_c *symbol) { - prev_il_instruction = symbol; - return NULL; -} + return NULL; +} + +void *narrow_candidate_datatypes_c::visit(AND_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(OR_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(XOR_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(ANDN_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(ORN_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(XORN_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(ADD_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(SUB_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(MUL_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(DIV_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(MOD_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(GT_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(GE_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(EQ_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(LT_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(LE_operator_c *symbol) {return handle_il_instruction(symbol);} +void *narrow_candidate_datatypes_c::visit(NE_operator_c *symbol) {return handle_il_instruction(symbol);} void *narrow_candidate_datatypes_c::visit(CAL_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(CALC_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(RET_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(RETC_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(JMP_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(JMPC_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; }