Use duplicate symtable instead of symtable for enum constant value table (this will later allow us to detect semantic errors in IEC 61131-3 source code)
authorMario de Sousa <msousa@fe.up.pt>
Thu, 08 Nov 2012 17:31:29 +0000 (2012-11-08)
changeset 720 f637ac331a68
parent 719 19595fce59f0
child 721 5dc33058e041
Use duplicate symtable instead of symtable for enum constant value table (this will later allow us to detect semantic errors in IEC 61131-3 source code)
stage3/fill_candidate_datatypes.cc
--- a/stage3/fill_candidate_datatypes.cc	Thu Nov 08 12:49:03 2012 +0000
+++ b/stage3/fill_candidate_datatypes.cc	Thu Nov 08 17:31:29 2012 +0000
@@ -88,7 +88,7 @@
  */
 
  symbol_c null_globalenumvalue_symbol; /* cannot be static, so it may be used in the template!! */
- static symtable_c<symbol_c *, &null_globalenumvalue_symbol> global_enumerated_value_symtable;
+ static dsymtable_c<symbol_c *, &null_globalenumvalue_symbol> global_enumerated_value_symtable;
  
  
 class populate_globalenumvalue_symtable_c: public iterator_visitor_c {
@@ -139,17 +139,7 @@
      */
     /* if (value_type == current_enumerated_type) ERROR; */
 
-    if (value_type == global_enumerated_value_symtable.end_value())
-	/* This identifier has not yet been used in any previous declaration of an enumeration data type.
-	 * so we add it to the symbol table.
-	 */
-      global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
-    else if (value_type != NULL)
-	/* This identifier has already been used in a previous declaration of an enumeration data type.
-	 * so we set the symbol in symbol table pointing to NULL.
-	 */
-      global_enumerated_value_symtable.set(symbol->value, NULL);
-    
+    global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
     return NULL;
   }
 
@@ -187,10 +177,10 @@
  *
  * This class will add the enum values in (B) to the local_enumerated_value_symtable.
  *
- * If a locally defined enum value is identical to another locally defined enum_value, the
- *  corresponding entry in local_enumerated_value_symtable is set to NULL.
+ * If a locally defined enum value is identical to another locally defined enum_value, a 
+ *  duplicate entry is created.
  *  However, if a locally defined enum value is identical to another globally defined enum_value, the
- *  corresponding entry in local_enumerated_value_symtable is set to the local datatype (and not NULL).
+ *  corresponding entry in local_enumerated_value_symtable is also set to the local datatype.
  *  This is because anonynous locally feined enum datatypes are anonymous, and its enum values cannot therefore
  *  be disambiguated using EnumType#enum_value (since the enum type does not have a name, it is anonymous!).
  *  For this reason we implement the semantics where locally defined enum values, when in scope, will 'cover'
@@ -211,7 +201,7 @@
  */
  
  symbol_c null_localenumvalue_symbol; /* cannot be static, so it may be used in the template!! */
- static symtable_c<symbol_c *, &null_localenumvalue_symbol> local_enumerated_value_symtable;
+ static dsymtable_c<symbol_c *, &null_localenumvalue_symbol> local_enumerated_value_symtable;
 
 
 class populate_enumvalue_symtable_c: public iterator_visitor_c {
@@ -251,14 +241,10 @@
     /* this is really an ERROR! The initial value may use the syntax NUM_TYPE#enum_value, but in that case we should have return'd in the above statement !! */
     if (symbol->type != NULL) ERROR;  
 
-    // symbol_c *global_value_type = global_enumerated_value_symtable.find_value(symbol->value);
     symbol_c *local_value_type  = local_enumerated_value_symtable.find_value(symbol->value);
-    if (local_value_type == local_enumerated_value_symtable.end_value())
-      /* This identifier has not yet been used in any previous local declaration of an enumeration data type, so we add it to the local symbol table. */
-      local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
-    else 
-      /* This identifier has already been used in a previous declaration of an enumeration data type. so we set the symbol in symbol table pointing to NULL. */
-      local_enumerated_value_symtable.set(symbol->value, NULL);
+    
+    /* add it to the local symbol table. */
+    local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
     return NULL;
   }
 }; // class populate_enumvalue_symtable_c
@@ -528,7 +514,7 @@
 	 * expressions inside the function call will themselves have erros and will  guarantee that 
 	 * compilation is aborted in stage3 (in print_datatypes_error_c).
 	 */
-	if (function_symtable.multiplicity(fcall_data.function_name) == 1) {
+	if (function_symtable.count(fcall_data.function_name) == 1) {
 		f_decl = function_symtable.get_value(lower);
 		returned_parameter_type = base_type(f_decl->type_name);
 		if (add_datatype_to_candidate_list(fcall, returned_parameter_type))
@@ -920,17 +906,20 @@
 	if (NULL != symbol->type)
 		enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */
 	else {
-		global_enumerated_type = global_enumerated_value_symtable.find_value(symbol->value);
-		local_enumerated_type  =  local_enumerated_value_symtable.find_value(symbol->value);
-		if      (( local_enumerated_type ==  local_enumerated_value_symtable.end_value()) && (global_enumerated_type == global_enumerated_value_symtable.end_value()))
+		symbol_c *global_enumerated_type = global_enumerated_value_symtable.find_value  (symbol->value);
+		symbol_c * local_enumerated_type =  local_enumerated_value_symtable.find_value  (symbol->value);
+		int       global_multiplicity    = global_enumerated_value_symtable.count(symbol->value);
+		int        local_multiplicity    =  local_enumerated_value_symtable.count(symbol->value);
+
+		if      (( local_multiplicity == 0) && (global_multiplicity == 0))
 		  enumerated_type = NULL; // not found!
-		else if (( local_enumerated_type !=  local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL))
-			enumerated_type = NULL; // Duplicate, so it is ambiguous!
-		else if (( local_enumerated_type !=  local_enumerated_value_symtable.end_value()))
+		else if (  local_multiplicity  > 1)
+			enumerated_type = NULL; // Local duplicate, so it is ambiguous!
+		else if (  local_multiplicity == 1)
 			enumerated_type = local_enumerated_type;
-		else if ((global_enumerated_type != global_enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL))
-			enumerated_type = NULL; // Duplicate, so it is ambiguous!
-		else if ((global_enumerated_type != global_enumerated_value_symtable.end_value()))
+		else if ( global_multiplicity  > 1)
+			enumerated_type = NULL; // Global duplicate, so it is ambiguous!
+		else if ( global_multiplicity == 1)
 			enumerated_type = global_enumerated_type;
 		else ERROR;
 	}