Expressions_seen* expressions_seen_;
};
+// This class looks for interface types to finalize methods of inherited
+// interfaces.
+
+class Finalize_methods : public Traverse
+{
+ public:
+ Finalize_methods(Gogo* gogo)
+ : Traverse(traverse_types),
+ gogo_(gogo)
+ { }
+
+ int
+ type(Type*);
+
+ private:
+ Gogo* gogo_;
+};
+
// A class which makes it easier to insert new statements before the
// current statement during a traversal.
: gogo_(NULL), stream_(stream), location_(location), package_(NULL),
add_to_globals_(false), packages_(), type_data_(), type_pos_(0),
type_offsets_(), builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
- types_(), version_(EXPORT_FORMAT_UNKNOWN)
+ types_(), finalizer_(NULL), version_(EXPORT_FORMAT_UNKNOWN)
{
}
+Import::~Import()
+{
+ if (this->finalizer_ != NULL)
+ delete this->finalizer_;
+}
+
// Import the data in the associated stream.
Package*
this->gogo_->add_named_type(nt);
}
+ // Finalize methods for any imported types. This is done after most of
+ // read_types() is complete so as to avoid method finalization of a type
+ // whose methods refer to types that are only partially read in.
+ // See issue #33013 for more on why this is needed.
+ this->finalize_methods();
+
return true;
}
+void
+Import::finalize_methods()
+{
+ if (this->finalizer_ == NULL)
+ this->finalizer_ = new Finalize_methods(gogo_);
+ Unordered_set(Type*) real_for_named;
+ for (size_t i = 1; i < this->types_.size(); i++)
+ {
+ Type* type = this->types_[i];
+ if (type != NULL && type->named_type() != NULL)
+ {
+ this->finalizer_->type(type);
+ real_for_named.insert(type->named_type()->real_type());
+ }
+ }
+ for (size_t i = 1; i < this->types_.size(); i++)
+ {
+ Type* type = this->types_[i];
+ if (type != NULL
+ && type->named_type() == NULL
+ && real_for_named.find(type) == real_for_named.end())
+ this->finalizer_->type(type);
+ }
+}
+
// Import a constant.
void
class Import_function_body;
class Temporary_statement;
class Unnamed_label;
+class Finalize_methods;
// Expressions can be imported either directly from import data (for
// simple constant expressions that can appear in a const declaration
// Constructor.
Import(Stream*, Location);
- virtual ~Import()
- {}
+ virtual ~Import();
// Register the builtin types.
void
return true;
}
+ // Finalize methods for newly imported types.
+ void
+ finalize_methods();
+
// The general IR.
Gogo* gogo_;
// The stream from which to read import data.
std::vector<Named_type*> builtin_types_;
// Mapping from exported type codes to Type structures.
std::vector<Type*> types_;
+ // Helper for finalizing methods.
+ Finalize_methods* finalizer_;
// Version of export data we're reading.
Export_data_version version_;
};