compiler: remove duplication of Named_object traversal
Adding type parameters was about to add a partial third version.
Remove the duplication to avoid that.
Change-Id: I0f9ca818c9ff030520690c085d9651681b2dae32
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/375234
Trust: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/go/gogo.cc b/go/gogo.cc
index 290d294..e2fd509 100644
--- a/go/gogo.cc
+++ b/go/gogo.cc
@@ -6890,80 +6890,12 @@
| 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 @@
}
}
+// 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 @@
// 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;
}
diff --git a/go/gogo.h b/go/gogo.h
index 9ffd120..2ee0fda 100644
--- a/go/gogo.h
+++ b/go/gogo.h
@@ -3047,6 +3047,10 @@
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);