Fix error messages of il function calls - it now prints out location info of first parameter.
authorMario de Sousa <msousa@fe.up.pt>
Wed, 14 Mar 2012 19:31:17 +0000
changeset 486 e22150ad75fd
parent 485 835697564c6d
child 487 1619b2fe03e1
Fix error messages of il function calls - it now prints out location info of first parameter.
stage3/flow_control_analysis.cc
stage3/print_datatypes_error.cc
--- a/stage3/flow_control_analysis.cc	Wed Mar 14 11:31:07 2012 +0000
+++ b/stage3/flow_control_analysis.cc	Wed Mar 14 19:31:17 2012 +0000
@@ -38,11 +38,19 @@
  *  prev_il_instruction variable in the il_instruction_c, so it points to
  *  the previous il_instruction_c object in the instruction list instruction_list_c.
  *
- *  The result will essentially be a linked list of il_instruction_c objects, each 
+ *  Since IL code can contain jumps (JMP), the same il_instruction may effectively have
+ *  several previous il_instructions. In order to accommodate this, each il_instruction
+ *  will maintain a vector (i..e an array) of pointers to all the previous il_instructions.
+ *  We do however attempt to guarantee that the first element in the vector (array) will preferentially
+ *  point to the il instruction that is right before / imediately preceding the current il instructions, 
+ *  i.e. the first element in the array will tend to point to the previous il_instruction
+ *  that is not a jump JMP IL instruction!
+ *
+ *  The result will essentially be a graph of il_instruction_c objects, each 
  *  pointing to the previous il_instruction_c object.
  *
  *  The reality is we will get several independent and isolated linked lists
- *  (actually, once we process labels correctly, this will become a graph):
+ *  (actually, since we now process labels correctly, this is really a graph):
  *  one for each block of IL code (e.g. inside a Function, FB or Program).
  *  Additionally, when the IL code has an expression (expression_c object), we will actually
  *  have one more isolated linked list for the IL code inside that expression.
@@ -196,7 +204,10 @@
 // void *visit(instruction_list_c *symbol);
 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
 	if ((NULL != prev_il_instruction) && (!prev_il_instruction_is_JMP_or_RET))
-		symbol->prev_il_instruction.push_back(prev_il_instruction);
+		/* We try to guarantee that the previous il instruction that is in the previous line, will occupy the first element of the vector.
+		 * In order to do that, we use insert() instead of push_back()
+		 */
+		symbol->prev_il_instruction.insert(symbol->prev_il_instruction.begin() , prev_il_instruction);
 
 	/* check if it is an il_expression_c, a JMP[C[N]], or a RET, and if so, handle it correctly */
 	prev_il_instruction_is_JMP_or_RET = false;
@@ -281,7 +292,10 @@
 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
 void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) {
 	if (NULL != prev_il_instruction)
-		symbol->prev_il_instruction.push_back(prev_il_instruction);
+		/* We try to guarantee that the previous il instruction that is in the previous line, will occupy the first element of the vector.
+		 * In order to do that, we use insert() instead of push_back()
+		 */
+		symbol->prev_il_instruction.insert(symbol->prev_il_instruction.begin() , prev_il_instruction);
 	return NULL;
 }
 
--- a/stage3/print_datatypes_error.cc	Wed Mar 14 11:31:07 2012 +0000
+++ b/stage3/print_datatypes_error.cc	Wed Mar 14 19:31:17 2012 +0000
@@ -2,8 +2,8 @@
  *  matiec - a compiler for the programming languages defined in IEC 61131-3
  *
  *  Copyright (C) 2009-2011  Mario de Sousa (msousa@fe.up.pt)
- *  Copyright (C) 20011-2012 Manuele Conti (manuele.conti@sirius-es.it)
- *  Copyright (C) 20011-2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it)
+ *  Copyright (C) 2011-2012 Manuele Conti (manuele.conti@sirius-es.it)
+ *  Copyright (C) 2011-2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it)
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -629,8 +629,27 @@
 // SYM_REF2(il_instruction_c, label, il_instruction)
 void *print_datatypes_error_c::visit(il_instruction_c *symbol) {
 	if (NULL != symbol->il_instruction) {
-// #if 0
 		il_instruction_c tmp_prev_il_instruction(NULL, NULL);
+		/* When handling a il function call, this fake_prev_il_instruction may be used as a standard function call parameter, so it is important that 
+		 * it contain some valid location info so error messages make sense.
+		 */
+		if (symbol->prev_il_instruction.size() > 0) {
+			/* since we don't want to copy all that data one variable at a time, we copy it all at once */
+			/* This has the advantage that, if we ever add some more data to the base symbol_c later on, we will not need to
+			 * change the following line to guarantee that the data is copied correctly!
+			 * However, it does have the drawback of copying more data than what we want!
+			 * In order to only copy the data in the base class symbol_c, we use the tmp_symbol pointer!
+			 * I (mario) have checked with a debugger, and it is working as intended!
+			 */
+			symbol_c *tmp_symbol1 = symbol->prev_il_instruction[0];
+			symbol_c *tmp_symbol2 = &tmp_prev_il_instruction;
+			*tmp_symbol2 = *tmp_symbol1;
+			/* we do not want to copy the datatype variable, so we reset it to NULL */
+			tmp_prev_il_instruction.datatype = NULL;
+			/* We don't need to worry about the candidate_datatype list (which we don't want to copy just yet), since that will 
+			 * be reset to the correct value when we call intersect_prev_candidate_datatype_lists() later on...
+			 */
+		}
 		/* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the 
 		 * list of the prev_il_instructions.
 		 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
@@ -641,17 +660,11 @@
 		if (are_all_datatypes_of_prev_il_instructions_datatypes_equal(symbol))
 			if (symbol->prev_il_instruction.size() > 0)
 				tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype;
+		
 		/* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */
 		fake_prev_il_instruction = &tmp_prev_il_instruction;
 		symbol->il_instruction->accept(*this);
 		fake_prev_il_instruction = NULL;
-// #endif
-// 		if (symbol->prev_il_instruction.size() > 1) ERROR; /* only valid for now! */
-// 		if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
-// 		else                                          prev_il_instruction = symbol->prev_il_instruction[0];
-
-// 		symbol->il_instruction->accept(*this);
-// 		prev_il_instruction = NULL;
 	}
 
 	return NULL;