Commit 34ea9597 by Ian Lance Taylor

compiler: finalize types parsed for inline functions

    
    When we inline functions, we may parse types that we have not seen
    before inlining.  Inlining runs after the finalize_methods pass, so
    those types will not be finalized, meaning that we don't have an
    accurate list of which methods they support.  Explicitly finalize them
    when we parse them.
    
    Reviewed-on: https://go-review.googlesource.com/c/150068

From-SVN: r266530
parent 80d7d30d
ce81aad0e3d53215e2c0f1f060c7fd6219e6fb23 c11d9528a0846293e4d615c86fc773c97252fdce
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -3243,6 +3243,17 @@ Gogo::finalize_methods() ...@@ -3243,6 +3243,17 @@ Gogo::finalize_methods()
this->traverse(&finalize); this->traverse(&finalize);
} }
// Finalize the method list for a type. This is called when a type is
// parsed for an inlined function body, which happens after the
// finalize_methods pass.
void
Gogo::finalize_methods_for_type(Type* type)
{
Finalize_methods finalize(this);
Type::traverse(type, &finalize);
}
// Set types for unspecified variables and constants. // Set types for unspecified variables and constants.
void void
......
...@@ -637,6 +637,10 @@ class Gogo ...@@ -637,6 +637,10 @@ class Gogo
void void
finalize_methods(); finalize_methods();
// Finalize the method list for one type.
void
finalize_methods_for_type(Type*);
// Work out the types to use for unspecified variables and // Work out the types to use for unspecified variables and
// constants. // constants.
void void
......
...@@ -886,7 +886,9 @@ Import::read_type() ...@@ -886,7 +886,9 @@ Import::read_type()
if (c == '>') if (c == '>')
{ {
// A reference to a type defined earlier. // A reference to a type defined earlier.
return this->type_for_index(index, "import data", stream->pos()); bool parsed;
return this->type_for_index(index, "import data", stream->pos(),
&parsed);
} }
if (this->version_ >= EXPORT_FORMAT_V3) if (this->version_ >= EXPORT_FORMAT_V3)
...@@ -1092,12 +1094,13 @@ Import::read_named_type(int index) ...@@ -1092,12 +1094,13 @@ Import::read_named_type(int index)
return type; return type;
} }
// Return the type given an index. // Return the type given an index. Set *PARSED if we parsed it here.
Type* Type*
Import::type_for_index(int index, const std::string& input_name, Import::type_for_index(int index, const std::string& input_name,
size_t input_offset) size_t input_offset, bool* parsed)
{ {
*parsed = false;
if (index >= 0 && !this->type_data_.empty()) if (index >= 0 && !this->type_data_.empty())
{ {
if (static_cast<size_t>(index) >= this->type_offsets_.size()) if (static_cast<size_t>(index) >= this->type_offsets_.size())
...@@ -1114,6 +1117,7 @@ Import::type_for_index(int index, const std::string& input_name, ...@@ -1114,6 +1117,7 @@ Import::type_for_index(int index, const std::string& input_name,
{ {
if (!this->parse_type(index)) if (!this->parse_type(index))
return Type::make_error_type(); return Type::make_error_type();
*parsed = true;
} }
} }
...@@ -1497,6 +1501,15 @@ Import_function_body::read_type() ...@@ -1497,6 +1501,15 @@ Import_function_body::read_type()
return Type::make_error_type(); return Type::make_error_type();
} }
return this->imp_->type_for_index(static_cast<int>(val), this->name(), bool parsed;
static_cast<unsigned long>(start)); Type* type = this->imp_->type_for_index(static_cast<int>(val), this->name(),
static_cast<unsigned long>(start),
&parsed);
// If we just read this type's information, its methods will not
// have been finalized. Do that now.
if (parsed)
this->gogo_->finalize_methods_for_type(type);
return type;
} }
...@@ -284,10 +284,11 @@ class Import : public Import_expression ...@@ -284,10 +284,11 @@ class Import : public Import_expression
read_type(); read_type();
// Return the type for a type index. INPUT_NAME and INPUT_OFFSET // Return the type for a type index. INPUT_NAME and INPUT_OFFSET
// are only for error reporting. // are only for error reporting. PARSED is set to whether we parsed
// the type information for a new type.
Type* Type*
type_for_index(int index, const std::string& input_name, type_for_index(int index, const std::string& input_name,
size_t input_offset); size_t input_offset, bool* parsed);
// Read an escape note. // Read an escape note.
std::string std::string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment