absyntax_utils/search_base_type.cc
changeset 726 9b61eb4f00dc
parent 718 a9f8cc778444
child 793 268bf4ca5fa1
--- a/absyntax_utils/search_base_type.cc	Tue Nov 13 18:02:15 2012 +0000
+++ b/absyntax_utils/search_base_type.cc	Tue Nov 13 18:03:17 2012 +0000
@@ -54,7 +54,7 @@
 
 
 
-search_base_type_c::search_base_type_c(void) {current_type_name = NULL;}
+search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = NULL;}
 
 /* static method! */
 void search_base_type_c::create_singleton(void) {
@@ -66,15 +66,17 @@
 symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) {
   create_singleton();
   if (NULL == symbol)    return NULL; 
+  search_base_type_singleton->current_type_name = NULL;
+  search_base_type_singleton->current_basetype  = NULL; 
   return (symbol_c *)symbol->accept(*search_base_type_singleton);
 }
 
 /* static method! */
 symbol_c *search_base_type_c::get_basetype_id  (symbol_c *symbol) {
   create_singleton();
-  if (NULL == symbol)    return NULL;
-  
+  if (NULL == symbol)    return NULL; 
   search_base_type_singleton->current_type_name = NULL;
+  search_base_type_singleton->current_basetype  = NULL; 
   symbol->accept(*search_base_type_singleton);
   return (symbol_c *)search_base_type_singleton->current_type_name;
 }
@@ -112,6 +114,10 @@
   symbol_c *type_decl;
 
   this->current_type_name = type_name;
+  /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for,
+   * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!)
+   */
+  this->current_basetype  = NULL; 
   
   /* look up the type declaration... */
   type_decl = type_symtable.find_value(type_name);
@@ -244,20 +250,37 @@
 /*  enumerated_type_name ':' enumerated_spec_init */
 void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) {
   this->current_type_name = symbol->enumerated_type_name;
+  /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible
+   *       (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an
+   *        anonymous datatype declared in a VAR ... AND_VAR declaration).
+   *       However, we cannot return this symbol just yet, as it may not be the final base datatype.
+   *       So we store it in a temporary current_basetype variable!
+   */
+  this->current_basetype  = symbol; 
   return symbol->enumerated_spec_init->accept(*this);
 }
 
 /* enumerated_specification ASSIGN enumerated_value */
 void *search_base_type_c::visit(enumerated_spec_init_c *symbol) {
   this->is_enumerated = true;
-  return symbol->enumerated_specification->accept(*this);
+  // current_basetype may have been set in the previous enumerated_type_declaration_c visitor, in which case we do not want to overwrite the value!
+  if (NULL == this->current_basetype)
+    this->current_basetype  = symbol; 
+  /* NOTE: the following line may call either the visitor to 
+   *         - identifier_c, in which case this is not yet the base datatype we are looking for (it will set current_basetype to NULL!)
+   *         - enumerated_value_list_c, in which case we have found the base datatype.
+   */
+  return symbol->enumerated_specification->accept(*this); 
 }
 
 /* helper symbol for enumerated_specification->enumerated_spec_init */
 /* enumerated_value_list ',' enumerated_value */
 void *search_base_type_c::visit(enumerated_value_list_c *symbol) {
   this->is_enumerated = true;
-  return (void *)symbol;
+  // current_basetype may have been set in the previous enumerated_type_declaration_c or enumerated_spec_init_c visitors, in which case we do not want to overwrite the value!
+  if (NULL == this->current_basetype) 
+    this->current_basetype  = symbol; 
+  return (void *)current_basetype;
 }
 
 /* enumerated_type_name '#' identifier */