compiler: remove duplication of Named_object traversal

Adding type parameters was about to add a partial third version.
Remove the duplication to avoid that.

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/375234
This commit is contained in:
Ian Lance Taylor 2022-01-03 12:47:50 -08:00
parent 7d11b64b18
commit a0239f8525
3 changed files with 100 additions and 151 deletions

View File

@ -1,4 +1,4 @@
d3be41f0a1fca20e241e1db62b4b0f5262caac55
9732b0766667b9235d0f35d0fb0abfe406b94d49
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -6890,80 +6890,12 @@ Block::traverse(Traverse* traverse)
| Traverse::traverse_expressions
| Traverse::traverse_types)) != 0)
{
const unsigned int e_or_t = (Traverse::traverse_expressions
| Traverse::traverse_types);
const unsigned int e_or_t_or_s = (e_or_t
| Traverse::traverse_statements);
for (Bindings::const_definitions_iterator pb =
this->bindings_->begin_definitions();
pb != this->bindings_->end_definitions();
++pb)
{
int t = TRAVERSE_CONTINUE;
switch ((*pb)->classification())
{
case Named_object::NAMED_OBJECT_CONST:
if ((traverse_mask & Traverse::traverse_constants) != 0)
t = traverse->constant(*pb, false);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t) != 0)
{
Type* tc = (*pb)->const_value()->type();
if (tc != NULL
&& Type::traverse(tc, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
t = (*pb)->const_value()->traverse_expression(traverse);
}
break;
case Named_object::NAMED_OBJECT_VAR:
case Named_object::NAMED_OBJECT_RESULT_VAR:
if ((traverse_mask & Traverse::traverse_variables) != 0)
t = traverse->variable(*pb);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t) != 0)
{
if ((*pb)->is_result_variable()
|| (*pb)->var_value()->has_type())
{
Type* tv = ((*pb)->is_variable()
? (*pb)->var_value()->type()
: (*pb)->result_var_value()->type());
if (tv != NULL
&& Type::traverse(tv, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
}
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t_or_s) != 0
&& (*pb)->is_variable())
t = (*pb)->var_value()->traverse_expression(traverse,
traverse_mask);
break;
case Named_object::NAMED_OBJECT_FUNC:
case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
go_unreachable();
case Named_object::NAMED_OBJECT_TYPE:
if ((traverse_mask & e_or_t) != 0)
t = Type::traverse((*pb)->type_value(), traverse);
break;
case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
case Named_object::NAMED_OBJECT_UNKNOWN:
case Named_object::NAMED_OBJECT_ERRONEOUS:
break;
case Named_object::NAMED_OBJECT_PACKAGE:
case Named_object::NAMED_OBJECT_SINK:
go_unreachable();
default:
go_unreachable();
}
if (t == TRAVERSE_EXIT)
if ((*pb)->traverse(traverse, false) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
}
@ -8673,6 +8605,99 @@ Named_object::location() const
}
}
// Traverse a Named_object.
int
Named_object::traverse(Traverse* traverse, bool is_global)
{
const unsigned int traverse_mask = traverse->traverse_mask();
const unsigned int e_or_t = (Traverse::traverse_expressions
| Traverse::traverse_types);
const unsigned int e_or_t_or_s = (e_or_t
| Traverse::traverse_statements);
int t = TRAVERSE_CONTINUE;
switch (this->classification_)
{
case Named_object::NAMED_OBJECT_CONST:
if ((traverse_mask & Traverse::traverse_constants) != 0)
t = traverse->constant(this, is_global);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t) != 0)
{
Type* tc = this->const_value()->type();
if (tc != NULL)
{
if (Type::traverse(tc, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
t = this->const_value()->traverse_expression(traverse);
}
break;
case Named_object::NAMED_OBJECT_VAR:
case Named_object::NAMED_OBJECT_RESULT_VAR:
if ((traverse_mask & Traverse::traverse_variables) != 0)
t = traverse->variable(this);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t) != 0)
{
if (this->is_result_variable() || this->var_value()->has_type())
{
Type* tv = (this->is_variable()
? this->var_value()->type()
: this->result_var_value()->type());
if (tv != NULL)
{
if (Type::traverse(tv, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
}
}
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t_or_s) != 0
&& this->is_variable())
t = this->var_value()->traverse_expression(traverse,
traverse_mask);
break;
case Named_object::NAMED_OBJECT_FUNC:
if ((traverse_mask & Traverse::traverse_functions) != 0)
t = traverse->function(this);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask
& (Traverse::traverse_variables
| Traverse::traverse_constants
| Traverse::traverse_functions
| Traverse::traverse_blocks
| Traverse::traverse_statements
| Traverse::traverse_expressions
| Traverse::traverse_types)) != 0)
t = this->func_value()->traverse(traverse);
break;
case Named_object::NAMED_OBJECT_TYPE:
if ((traverse_mask & e_or_t) != 0)
t = Type::traverse(this->type_value(), traverse);
break;
case Named_object::NAMED_OBJECT_PACKAGE:
case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
case Named_object::NAMED_OBJECT_UNKNOWN:
case Named_object::NAMED_OBJECT_ERRONEOUS:
break;
case Named_object::NAMED_OBJECT_SINK:
go_unreachable();
default:
go_unreachable();
}
return t;
}
// Export a named object.
void
@ -9198,90 +9223,10 @@ Bindings::traverse(Traverse* traverse, bool is_global)
// new global objects.
const unsigned int e_or_t = (Traverse::traverse_expressions
| Traverse::traverse_types);
const unsigned int e_or_t_or_s = (e_or_t
| Traverse::traverse_statements);
for (size_t i = 0; i < this->named_objects_.size(); ++i)
{
Named_object* p = this->named_objects_[i];
int t = TRAVERSE_CONTINUE;
switch (p->classification())
{
case Named_object::NAMED_OBJECT_CONST:
if ((traverse_mask & Traverse::traverse_constants) != 0)
t = traverse->constant(p, is_global);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t) != 0)
{
Type* tc = p->const_value()->type();
if (tc != NULL
&& Type::traverse(tc, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
t = p->const_value()->traverse_expression(traverse);
}
break;
case Named_object::NAMED_OBJECT_VAR:
case Named_object::NAMED_OBJECT_RESULT_VAR:
if ((traverse_mask & Traverse::traverse_variables) != 0)
t = traverse->variable(p);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t) != 0)
{
if (p->is_result_variable()
|| p->var_value()->has_type())
{
Type* tv = (p->is_variable()
? p->var_value()->type()
: p->result_var_value()->type());
if (tv != NULL
&& Type::traverse(tv, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
}
if (t == TRAVERSE_CONTINUE
&& (traverse_mask & e_or_t_or_s) != 0
&& p->is_variable())
t = p->var_value()->traverse_expression(traverse, traverse_mask);
break;
case Named_object::NAMED_OBJECT_FUNC:
if ((traverse_mask & Traverse::traverse_functions) != 0)
t = traverse->function(p);
if (t == TRAVERSE_CONTINUE
&& (traverse_mask
& (Traverse::traverse_variables
| Traverse::traverse_constants
| Traverse::traverse_functions
| Traverse::traverse_blocks
| Traverse::traverse_statements
| Traverse::traverse_expressions
| Traverse::traverse_types)) != 0)
t = p->func_value()->traverse(traverse);
break;
case Named_object::NAMED_OBJECT_PACKAGE:
// These are traversed in Gogo::traverse.
go_assert(is_global);
break;
case Named_object::NAMED_OBJECT_TYPE:
if ((traverse_mask & e_or_t) != 0)
t = Type::traverse(p->type_value(), traverse);
break;
case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
case Named_object::NAMED_OBJECT_UNKNOWN:
case Named_object::NAMED_OBJECT_ERRONEOUS:
break;
case Named_object::NAMED_OBJECT_SINK:
default:
go_unreachable();
}
if (t == TRAVERSE_EXIT)
if (p->traverse(traverse, is_global) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}

View File

@ -3047,6 +3047,10 @@ class Named_object
Location
location() const;
// Traverse a Named_object.
int
traverse(Traverse*, bool is_global);
// Convert a variable to the backend representation.
Bvariable*
get_backend_variable(Gogo*, Named_object* function);