diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 2d04f4b01c0..a18f3a37349 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 290d294e83b..e2fd509f58a 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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; } diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 9ffd120290d..2ee0fda00ae 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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);