55 } |
55 } |
56 |
56 |
57 |
57 |
58 /* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */ |
58 /* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */ |
59 static void set_datatype(symbol_c *datatype, symbol_c *symbol) { |
59 static void set_datatype(symbol_c *datatype, symbol_c *symbol) { |
60 symbol->datatype = NULL; |
60 |
61 if (search_in_candidate_datatype_list(datatype, symbol->candidate_datatypes) >= 0) |
61 /* If we are trying to set to the undefined type, and the symbol's datatype has already been set to something else, |
62 symbol->datatype = datatype; |
62 * we abort the compoiler as I don't think this should ever occur. |
|
63 * However, I (Mario) am not too sure of this, so if the compiler ever aborts here, please analyse the situation |
|
64 * carefully as it might be perfectly legal and something I have missed! |
|
65 */ |
|
66 if ((NULL == datatype) && (NULL != symbol->datatype)) ERROR; |
|
67 |
|
68 if ((NULL == datatype) && (NULL == symbol->datatype)) return; |
|
69 |
|
70 if (search_in_candidate_datatype_list(datatype, symbol->candidate_datatypes) < 0) |
|
71 symbol->datatype = &(search_constant_type_c::invalid_type_name); |
|
72 else { |
|
73 if (NULL == symbol->datatype) |
|
74 /* not yet set to anything, so we set it to the requested data type */ |
|
75 symbol->datatype = datatype; |
|
76 else { |
|
77 /* had already been set previously to some data type. Let's check if they are the same! */ |
|
78 if (!is_type_equal(symbol->datatype, datatype)) |
|
79 symbol->datatype = &(search_constant_type_c::invalid_type_name); |
|
80 // else |
|
81 /* we leave it unchanged, as it is the same as the requested data type! */ |
|
82 } |
|
83 } |
63 } |
84 } |
64 |
85 |
65 |
86 |
66 |
87 |
67 /* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */ |
88 /* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */ |
68 static void set_datatype_in_prev_il_instruction(symbol_c *datatype, il_instruction_c *symbol) { |
89 // static void set_datatype_in_prev_il_instructions(symbol_c *datatype, std::vector <symbol_c *> prev_il_instructions) { |
|
90 static void set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol) { |
|
91 if (NULL == symbol) ERROR; |
69 for (unsigned int i = 0; i < symbol->prev_il_instruction.size(); i++) |
92 for (unsigned int i = 0; i < symbol->prev_il_instruction.size(); i++) |
70 set_datatype(datatype, symbol->prev_il_instruction[i]); |
93 set_datatype(datatype, symbol->prev_il_instruction[i]); |
71 } |
94 } |
72 |
95 |
73 |
96 |
274 set_datatype(called_fb_declaration, il_operand); |
297 set_datatype(called_fb_declaration, il_operand); |
275 il_operand->accept(*this); |
298 il_operand->accept(*this); |
276 } |
299 } |
277 symbol_c *fb_decl = il_operand->datatype; |
300 symbol_c *fb_decl = il_operand->datatype; |
278 |
301 |
279 if (NULL == prev_il_instruction) { |
302 if (0 == fake_prev_il_instruction->prev_il_instruction.size()) { |
280 /* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction |
303 /* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction |
281 * (or list of instructions) that will set the IL current/default value. |
304 * (or list of instructions) that will set the IL current/default value. |
282 * We cannot proceed verifying type compatibility of something that does not exist. |
305 * We cannot proceed verifying type compatibility of something that does not exist. |
283 */ |
306 */ |
284 return NULL; |
307 return NULL; |
285 } |
308 } |
286 |
309 |
287 if (NULL == fb_decl) { |
310 if (NULL == fb_decl) { |
288 /* the il_operand is a not FB instance */ |
311 /* the il_operand is a not FB instance */ |
289 /* so we simply pass on the required datatype to the prev_il_instruction */ |
312 /* so we simply pass on the required datatype to the prev_il_instructions */ |
290 /* The invalid FB invocation will be caught by the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */ |
313 /* The invalid FB invocation will be caught in the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */ |
291 prev_il_instruction->datatype = il_instruction->datatype; |
314 set_datatype_in_prev_il_instructions(il_instruction->datatype, fake_prev_il_instruction); |
292 return NULL; |
315 return NULL; |
293 } |
316 } |
294 |
317 |
295 |
318 |
296 /* The value being passed to the 'param_name' parameter is actually the prev_il_instruction. |
319 /* The value being passed to the 'param_name' parameter is actually the prev_il_instruction. |
300 * (called from the instruction_list_c for() loop that works backwards). We DO NOT want to visit it twice. |
323 * (called from the instruction_list_c for() loop that works backwards). We DO NOT want to visit it twice. |
301 * (Anyway, if we let the visit(il_fb_call_c *) recursively visit the current prev_il_instruction, this pointer |
324 * (Anyway, if we let the visit(il_fb_call_c *) recursively visit the current prev_il_instruction, this pointer |
302 * would be changed to the IL instruction coming before the current prev_il_instruction! => things would get all messed up!) |
325 * would be changed to the IL instruction coming before the current prev_il_instruction! => things would get all messed up!) |
303 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object! |
326 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object! |
304 */ |
327 */ |
305 symbol_c param_value = *prev_il_instruction; |
328 printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): fake_prev_il_instruction->candidate_datatypes.size() = %d\n",fake_prev_il_instruction->candidate_datatypes.size()); |
306 |
329 printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): fake_prev_il_instruction->candidate_datatypes[0] = %p\n",fake_prev_il_instruction->candidate_datatypes[0]); |
|
330 symbol_c param_value = *fake_prev_il_instruction; /* copy the candidate_datatypes list ! */ |
|
331 printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.candidate_datatypes.size() = %d\n",param_value.candidate_datatypes.size()); |
|
332 printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.candidate_datatypes[0] = %p\n",param_value.candidate_datatypes[0]); |
|
333 printf("00::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): search_constant_type::time_type_name = %p\n", &search_constant_type_c::time_type_name); |
|
334 printf("00::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): search_constant_type::invalid_type_name = %p\n", &search_constant_type_c::invalid_type_name); |
|
335 |
|
336 printf("11::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype); |
307 identifier_c variable_name(param_name); |
337 identifier_c variable_name(param_name); |
308 // SYM_REF1(il_assign_operator_c, variable_name) |
338 // SYM_REF1(il_assign_operator_c, variable_name) |
309 il_assign_operator_c il_assign_operator(&variable_name); |
339 il_assign_operator_c il_assign_operator(&variable_name); |
310 // SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
340 // SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
311 il_param_assignment_c il_param_assignment(&il_assign_operator, ¶m_value/*il_operand*/, NULL); |
341 il_param_assignment_c il_param_assignment(&il_assign_operator, ¶m_value/*il_operand*/, NULL); |
312 il_param_list_c il_param_list; |
342 il_param_list_c il_param_list; |
313 il_param_list.add_element(&il_param_assignment); |
343 il_param_list.add_element(&il_param_assignment); |
314 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
344 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
315 CAL_operator_c CAL_operator; |
345 CAL_operator_c CAL_operator; |
316 il_fb_call_c il_fb_call(&CAL_operator, il_operand, NULL, &il_param_list); |
346 il_fb_call_c il_fb_call(&CAL_operator, il_operand, NULL, &il_param_list); |
|
347 printf("22::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype); |
317 |
348 |
318 /* A FB call does not return any datatype, but the IL instructions that come after this |
349 /* A FB call does not return any datatype, but the IL instructions that come after this |
319 * FB call may require a specific datatype in the il current/default variable, |
350 * FB call may require a specific datatype in the il current/default variable, |
320 * so we must pass this information up to the IL instruction before the FB call, since it will |
351 * so we must pass this information up to the IL instruction before the FB call, since it will |
321 * be that IL instruction that will be required to produce the desired dtataype. |
352 * be that IL instruction that will be required to produce the desired dtataype. |
324 * correctly set up the il_fb_call.datatype variable! |
355 * correctly set up the il_fb_call.datatype variable! |
325 */ |
356 */ |
326 // copy_candidate_datatype_list(il_instruction/*from*/, &il_fb_call/*to*/); |
357 // copy_candidate_datatype_list(il_instruction/*from*/, &il_fb_call/*to*/); |
327 il_fb_call.called_fb_declaration = called_fb_declaration; |
358 il_fb_call.called_fb_declaration = called_fb_declaration; |
328 il_fb_call.accept(*this); |
359 il_fb_call.accept(*this); |
|
360 printf("33::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype); |
329 |
361 |
330 /* set the required datatype of the previous IL instruction! */ |
362 /* set the required datatype of the previous IL instruction! */ |
331 /* NOTE: |
363 /* NOTE: |
332 * When handling these implicit IL calls, the parameter_value being passed to the FB parameter |
364 * When handling these implicit IL calls, the parameter_value being passed to the FB parameter |
333 * is actually the prev_il_instruction. |
365 * is actually the prev_il_instruction. |
336 * must also be used ny the IL instruction coming after this FB call. |
368 * must also be used ny the IL instruction coming after this FB call. |
337 * |
369 * |
338 * This means that we have two consumers/users for the same value. |
370 * This means that we have two consumers/users for the same value. |
339 * We must therefore check whether the datatype required by the IL instructions following this FB call |
371 * We must therefore check whether the datatype required by the IL instructions following this FB call |
340 * is the same as that required for the first parameter. If not, then we have a semantic error, |
372 * is the same as that required for the first parameter. If not, then we have a semantic error, |
341 * and we set it to NULL. |
373 * and we set it to invalid_type_name. |
342 * |
374 * |
343 * However, we only do that if: |
375 * However, we only do that if: |
344 * - The IL instruction that comes after this IL FB call actually asked this FB call for a specific |
376 * - The IL instruction that comes after this IL FB call actually asked this FB call for a specific |
345 * datatype in the current/default vairable, once this IL FB call returns. |
377 * datatype in the current/default vairable, once this IL FB call returns. |
346 * However, sometimes, (for e.g., this FB call is the last in the IL list) the subsequent FB to not aks this |
378 * However, sometimes, (for e.g., this FB call is the last in the IL list) the subsequent FB to not aks this |
347 * FB call for any datatype. In that case, then the datatype required to pass to the first parameter of the |
379 * FB call for any datatype. In that case, then the datatype required to pass to the first parameter of the |
348 * FB call must be left unchanged! |
380 * FB call must be left unchanged! |
349 */ |
381 */ |
350 if ((NULL == il_instruction->datatype) || (is_type_equal(param_value.datatype, il_instruction->datatype))) { |
382 if ((NULL == il_instruction->datatype) || (is_type_equal(param_value.datatype, il_instruction->datatype))) { |
351 prev_il_instruction->datatype = param_value.datatype; |
383 printf("44::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype); |
|
384 set_datatype_in_prev_il_instructions(param_value.datatype, fake_prev_il_instruction); |
352 } else { |
385 } else { |
353 prev_il_instruction->datatype = NULL; |
386 printf("55::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype); |
|
387 set_datatype_in_prev_il_instructions(&search_constant_type_c::invalid_type_name, fake_prev_il_instruction); |
354 } |
388 } |
355 return NULL; |
389 return NULL; |
356 } |
390 } |
357 |
391 |
358 |
392 |
508 // SYM_REF2(il_instruction_c, label, il_instruction) |
542 // SYM_REF2(il_instruction_c, label, il_instruction) |
509 // void *visit(instruction_list_c *symbol); |
543 // void *visit(instruction_list_c *symbol); |
510 void *narrow_candidate_datatypes_c::visit(il_instruction_c *symbol) { |
544 void *narrow_candidate_datatypes_c::visit(il_instruction_c *symbol) { |
511 if (NULL == symbol->il_instruction) { |
545 if (NULL == symbol->il_instruction) { |
512 /* this empty/null il_instruction cannot generate the desired datatype. We pass on the request to the previous il instruction. */ |
546 /* this empty/null il_instruction cannot generate the desired datatype. We pass on the request to the previous il instruction. */ |
513 set_datatype_in_prev_il_instruction(symbol->datatype, symbol); |
547 set_datatype_in_prev_il_instructions(symbol->datatype, symbol); |
514 } else { |
548 } else { |
|
549 il_instruction_c tmp_prev_il_instruction(NULL, NULL); |
|
550 /* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
|
551 * list of the prev_il_instructions. |
|
552 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
|
553 * and shove that data into this single variable. |
|
554 */ |
|
555 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
|
556 intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction); |
515 /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */ |
557 /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */ |
516 if (symbol->prev_il_instruction.size() > 1) ERROR; /* This assertion is only valid for now. Remove it once flow_control_analysis_c is complete */ |
558 fake_prev_il_instruction = &tmp_prev_il_instruction; |
517 if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL; |
559 symbol->il_instruction->datatype = symbol->datatype; |
518 else prev_il_instruction = symbol->prev_il_instruction[0]; |
|
519 symbol->il_instruction->accept(*this); |
560 symbol->il_instruction->accept(*this); |
520 prev_il_instruction = NULL; |
561 fake_prev_il_instruction = NULL; |
521 } |
562 } |
522 return NULL; |
563 return NULL; |
523 } |
564 } |
524 |
565 |
525 |
566 |
550 * |
591 * |
551 * However, if no further paramters are given, then il_operand_list will be NULL, and we will |
592 * However, if no further paramters are given, then il_operand_list will be NULL, and we will |
552 * need to create a new object to hold the pointer to prev_il_instruction. |
593 * need to create a new object to hold the pointer to prev_il_instruction. |
553 * This change will also be undone later in print_datatypes_error_c. |
594 * This change will also be undone later in print_datatypes_error_c. |
554 */ |
595 */ |
555 symbol_c param_value; |
596 symbol_c param_value = *fake_prev_il_instruction; /* copy the candidate_datatypes list */ |
556 if (NULL == symbol->il_operand_list) symbol->il_operand_list = new il_operand_list_c; |
597 if (NULL == symbol->il_operand_list) symbol->il_operand_list = new il_operand_list_c; |
557 if (NULL == symbol->il_operand_list) ERROR; |
598 if (NULL == symbol->il_operand_list) ERROR; |
558 |
599 |
559 if (NULL != prev_il_instruction) |
|
560 param_value = *prev_il_instruction; |
|
561 ((list_c *)symbol->il_operand_list)->insert_element(¶m_value, 0); |
600 ((list_c *)symbol->il_operand_list)->insert_element(¶m_value, 0); |
562 |
601 |
563 generic_function_call_t fcall_param = { |
602 generic_function_call_t fcall_param = { |
564 /* fcall_param.function_name = */ symbol->function_name, |
603 /* fcall_param.function_name = */ symbol->function_name, |
565 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
604 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
569 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
608 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
570 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
609 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
571 }; |
610 }; |
572 |
611 |
573 narrow_function_invocation(symbol, fcall_param); |
612 narrow_function_invocation(symbol, fcall_param); |
574 if (NULL != prev_il_instruction) |
613 set_datatype_in_prev_il_instructions(param_value.datatype, fake_prev_il_instruction); |
575 prev_il_instruction->datatype = param_value.datatype; |
|
576 |
614 |
577 /* Undo the changes to the abstract syntax tree we made above... */ |
615 /* Undo the changes to the abstract syntax tree we made above... */ |
578 ((list_c *)symbol->il_operand_list)->remove_element(0); |
616 ((list_c *)symbol->il_operand_list)->remove_element(0); |
579 if (((list_c *)symbol->il_operand_list)->n == 0) { |
617 if (((list_c *)symbol->il_operand_list)->n == 0) { |
580 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
618 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
594 il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */ |
632 il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */ |
595 symbol->il_expr_operator->accept(*this); |
633 symbol->il_expr_operator->accept(*this); |
596 |
634 |
597 /* now give the parenthesised IL list a chance to narrow the datatypes */ |
635 /* now give the parenthesised IL list a chance to narrow the datatypes */ |
598 /* The datatype that is must return was set by the call symbol->il_expr_operator->accept(*this) */ |
636 /* The datatype that is must return was set by the call symbol->il_expr_operator->accept(*this) */ |
599 symbol_c *save_prev_il_instruction = prev_il_instruction; /*this is not really necessary, but lets play it safe */ |
637 il_instruction_c *save_fake_prev_il_instruction = fake_prev_il_instruction; /*this is not really necessary, but lets play it safe */ |
600 symbol->simple_instr_list->accept(*this); |
638 symbol->simple_instr_list->accept(*this); |
601 prev_il_instruction = save_prev_il_instruction; |
639 fake_prev_il_instruction = save_fake_prev_il_instruction; |
602 return NULL; |
640 return NULL; |
603 } |
641 } |
604 |
642 |
605 |
643 |
606 /* il_call_operator prev_declared_fb_name |
644 /* il_call_operator prev_declared_fb_name |
607 * | il_call_operator prev_declared_fb_name '(' ')' |
645 * | il_call_operator prev_declared_fb_name '(' ')' |
662 } |
700 } |
663 |
701 |
664 |
702 |
665 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
703 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
666 void *narrow_candidate_datatypes_c::visit(il_simple_instruction_c *symbol) { |
704 void *narrow_candidate_datatypes_c::visit(il_simple_instruction_c *symbol) { |
667 if (symbol->prev_il_instruction.size() > 1) ERROR; /* This assertion is only valid for now. Remove it once flow_control_analysis_c is complete */ |
705 if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */ |
668 if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL; |
706 |
669 else prev_il_instruction = symbol->prev_il_instruction[0]; |
707 il_instruction_c tmp_prev_il_instruction(NULL, NULL); |
|
708 /* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
|
709 * list of the prev_il_instructions. |
|
710 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
|
711 * and shove that data into this single variable. |
|
712 */ |
|
713 if (symbol->prev_il_instruction.size() > 0) |
|
714 tmp_prev_il_instruction.candidate_datatypes = symbol->prev_il_instruction[0]->candidate_datatypes; |
|
715 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
|
716 |
|
717 /* copy the candidate_datatypes list */ |
|
718 fake_prev_il_instruction = &tmp_prev_il_instruction; |
670 symbol->il_simple_instruction->datatype = symbol->datatype; |
719 symbol->il_simple_instruction->datatype = symbol->datatype; |
671 symbol->il_simple_instruction->accept(*this); |
720 symbol->il_simple_instruction->accept(*this); |
672 prev_il_instruction = NULL; |
721 fake_prev_il_instruction = NULL; |
673 return NULL; |
722 return NULL; |
674 } |
723 } |
675 |
724 |
676 // void *visit(il_param_list_c *symbol); |
725 // void *visit(il_param_list_c *symbol); |
677 // void *visit(il_param_assignment_c *symbol); |
726 // void *visit(il_param_assignment_c *symbol); |
700 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction |
749 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction |
701 * is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c |
750 * is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c |
702 * (or simple_instr_list_c), which iterates backwards. |
751 * (or simple_instr_list_c), which iterates backwards. |
703 */ |
752 */ |
704 /* set the desired datatype of the previous il instruction */ |
753 /* set the desired datatype of the previous il instruction */ |
705 prev_il_instruction->datatype = symbol->datatype; |
754 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
|
755 |
706 /* set the datatype for the operand */ |
756 /* set the datatype for the operand */ |
707 il_operand->datatype = symbol->datatype; |
757 il_operand->datatype = symbol->datatype; |
708 il_operand->accept(*this); |
758 il_operand->accept(*this); |
709 return NULL; |
759 return NULL; |
710 } |
760 } |
737 symbol->datatype = symbol->candidate_datatypes[0]; |
787 symbol->datatype = symbol->candidate_datatypes[0]; |
738 /* set the datatype for the operand */ |
788 /* set the datatype for the operand */ |
739 il_operand->datatype = symbol->datatype; |
789 il_operand->datatype = symbol->datatype; |
740 il_operand->accept(*this); |
790 il_operand->accept(*this); |
741 /* set the desired datatype of the previous il instruction */ |
791 /* set the desired datatype of the previous il instruction */ |
742 prev_il_instruction->datatype = symbol->datatype; |
792 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
743 if (debug) printf("narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) returning. previous_il_instruction->datatype = %p\n", prev_il_instruction->datatype); |
|
744 return NULL; |
793 return NULL; |
745 } |
794 } |
746 |
795 |
747 void *narrow_candidate_datatypes_c::visit(STN_operator_c *symbol) { |
796 void *narrow_candidate_datatypes_c::visit(STN_operator_c *symbol) { |
748 if (symbol->candidate_datatypes.size() != 1) |
797 if (symbol->candidate_datatypes.size() != 1) |
803 // SYM_REF0(CAL_operator_c) |
852 // SYM_REF0(CAL_operator_c) |
804 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */ |
853 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */ |
805 void *narrow_candidate_datatypes_c::visit(CAL_operator_c *symbol) { |
854 void *narrow_candidate_datatypes_c::visit(CAL_operator_c *symbol) { |
806 /* set the desired datatype of the previous il instruction */ |
855 /* set the desired datatype of the previous il instruction */ |
807 /* This FB call does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction */ |
856 /* This FB call does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction */ |
808 if (NULL != prev_il_instruction) |
857 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
809 prev_il_instruction->datatype = symbol->datatype; |
|
810 return NULL; |
858 return NULL; |
811 } |
859 } |
812 |
860 |
813 |
861 |
814 void *narrow_candidate_datatypes_c::narrow_conditional_flow_control_IL_instruction(symbol_c *symbol) { |
862 void *narrow_candidate_datatypes_c::narrow_conditional_flow_control_IL_instruction(symbol_c *symbol) { |
825 if (symbol->candidate_datatypes.size() == 0) symbol->datatype = NULL; |
873 if (symbol->candidate_datatypes.size() == 0) symbol->datatype = NULL; |
826 else symbol->datatype = symbol->candidate_datatypes[0]; /* i.e. a bool_type_name_c! */ |
874 else symbol->datatype = symbol->candidate_datatypes[0]; /* i.e. a bool_type_name_c! */ |
827 if ((NULL != symbol->datatype) && (!is_type(symbol->datatype, bool_type_name_c))) ERROR; |
875 if ((NULL != symbol->datatype) && (!is_type(symbol->datatype, bool_type_name_c))) ERROR; |
828 |
876 |
829 /* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */ |
877 /* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */ |
830 if (NULL != prev_il_instruction) prev_il_instruction->datatype = symbol->datatype; |
878 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
831 return NULL; |
879 return NULL; |
832 } |
880 } |
833 |
881 |
834 |
882 |
835 // SYM_REF0(CALC_operator_c) |
883 // SYM_REF0(CALC_operator_c) |
844 /* This RET instruction does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction. |
892 /* This RET instruction does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction. |
845 * Actually this should always be NULL, otherwise we have a bug in the flow_control_analysis_c |
893 * Actually this should always be NULL, otherwise we have a bug in the flow_control_analysis_c |
846 * However, since that class has not yet been completely finished, we do not yet check this assertion! |
894 * However, since that class has not yet been completely finished, we do not yet check this assertion! |
847 */ |
895 */ |
848 // if (NULL != symbol->datatype) ERROR; |
896 // if (NULL != symbol->datatype) ERROR; |
849 if (NULL != prev_il_instruction) |
897 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
850 prev_il_instruction->datatype = symbol->datatype; |
|
851 return NULL; |
898 return NULL; |
852 } |
899 } |
853 |
900 |
854 void *narrow_candidate_datatypes_c::visit( RETC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
901 void *narrow_candidate_datatypes_c::visit( RETC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
855 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
902 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
859 /* This JMP instruction does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction. |
906 /* This JMP instruction does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction. |
860 * Actually this should always be NULL, otherwise we have a bug in the flow_control_analysis_c |
907 * Actually this should always be NULL, otherwise we have a bug in the flow_control_analysis_c |
861 * However, since that class has not yet been completely finished, we do not yet check this assertion! |
908 * However, since that class has not yet been completely finished, we do not yet check this assertion! |
862 */ |
909 */ |
863 // if (NULL != symbol->datatype) ERROR; |
910 // if (NULL != symbol->datatype) ERROR; |
864 if (NULL != prev_il_instruction) |
911 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
865 prev_il_instruction->datatype = symbol->datatype; |
|
866 return NULL; |
912 return NULL; |
867 } |
913 } |
868 |
914 |
869 void *narrow_candidate_datatypes_c::visit( JMPC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
915 void *narrow_candidate_datatypes_c::visit( JMPC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
870 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
916 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |