Commit 8221fb01 by Ian Lance Taylor

compiler: track //go:nointerface in export data

    
    The magic //go:nointerface comment, used for field tracking, was only
    implemented for conversions to interface types in the same package.
    Record it in the export data, so that it works as expected for types
    imported from a different package.
    
    Reviewed-on: https://go-review.googlesource.com/93075

From-SVN: r257540
parent 0444aa9c
7e94bac5676afc8188677c98ecb263c78c1a7f8d
89105404f94005ffa8e2b08df78015dc9ac91362
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
......@@ -5189,17 +5189,24 @@ Function::defer_stack(Location location)
void
Function::export_func(Export* exp, const std::string& name) const
{
Function::export_func_with_type(exp, name, this->type_);
Function::export_func_with_type(exp, name, this->type_,
this->is_method() && this->nointerface());
}
// Export a function with a type.
void
Function::export_func_with_type(Export* exp, const std::string& name,
const Function_type* fntype)
const Function_type* fntype, bool nointerface)
{
exp->write_c_string("func ");
if (nointerface)
{
go_assert(fntype->is_method());
exp->write_c_string("/*nointerface*/ ");
}
if (fntype->is_method())
{
exp->write_c_string("(");
......@@ -5280,10 +5287,21 @@ Function::import_func(Import* imp, std::string* pname,
Typed_identifier** preceiver,
Typed_identifier_list** pparameters,
Typed_identifier_list** presults,
bool* is_varargs)
bool* is_varargs,
bool* nointerface)
{
imp->require_c_string("func ");
*nointerface = false;
if (imp->match_c_string("/*"))
{
imp->require_c_string("/*nointerface*/ ");
*nointerface = true;
// Only a method can be nointerface.
go_assert(imp->peek_char() == '(');
}
*preceiver = NULL;
if (imp->peek_char() == '(')
{
......@@ -6213,6 +6231,32 @@ Bindings_snapshot::check_goto_defs(Location loc, const Block* block,
// Class Function_declaration.
// Whether this declares a method.
bool
Function_declaration::is_method() const
{
return this->fntype_->is_method();
}
// Whether this method should not be included in the type descriptor.
bool
Function_declaration::nointerface() const
{
go_assert(this->is_method());
return (this->pragmas_ & GOPRAGMA_NOINTERFACE) != 0;
}
// Record that this method should not be included in the type
// descriptor.
void
Function_declaration::set_nointerface()
{
this->pragmas_ |= GOPRAGMA_NOINTERFACE;
}
// Return the function descriptor.
Expression*
......
......@@ -1476,13 +1476,14 @@ class Function
// Export a function with a type.
static void
export_func_with_type(Export*, const std::string& name,
const Function_type*);
const Function_type*, bool nointerface);
// Import a function.
static void
import_func(Import*, std::string* pname, Typed_identifier** receiver,
Typed_identifier_list** pparameters,
Typed_identifier_list** presults, bool* is_varargs);
Typed_identifier_list** presults, bool* is_varargs,
bool* nointerface);
private:
// Type for mapping from label names to Label objects.
......@@ -1607,6 +1608,10 @@ class Function_declaration
location() const
{ return this->location_; }
// Return whether this function declaration is a method.
bool
is_method() const;
const std::string&
asm_name() const
{ return this->asm_name_; }
......@@ -1628,6 +1633,16 @@ class Function_declaration
this->pragmas_ = pragmas;
}
// Whether this method should not be included in the type
// descriptor.
bool
nointerface() const;
// Record that this method should not be included in the type
// descriptor.
void
set_nointerface();
// Return an expression for the function descriptor, given the named
// object for this function. This may only be called for functions
// without a closure. This will be an immutable struct with one
......@@ -1652,7 +1667,10 @@ class Function_declaration
// Export a function declaration.
void
export_func(Export* exp, const std::string& name) const
{ Function::export_func_with_type(exp, name, this->fntype_); }
{
Function::export_func_with_type(exp, name, this->fntype_,
this->is_method() && this->nointerface());
}
// Check that the types used in this declaration's signature are defined.
void
......
......@@ -607,8 +607,9 @@ Import::import_func(Package* package)
Typed_identifier_list* parameters;
Typed_identifier_list* results;
bool is_varargs;
bool nointerface;
Function::import_func(this, &name, &receiver,
&parameters, &results, &is_varargs);
&parameters, &results, &is_varargs, &nointerface);
Function_type *fntype = Type::make_function_type(receiver, parameters,
results, this->location_);
if (is_varargs)
......@@ -648,6 +649,10 @@ Import::import_func(Package* package)
if (this->add_to_globals_)
this->gogo_->add_dot_import_object(no);
}
if (nointerface)
no->func_declaration_value()->set_nointerface();
return no;
}
......
......@@ -9742,7 +9742,12 @@ bool
Named_method::do_nointerface() const
{
Named_object* no = this->named_object_;
return no->is_function() && no->func_value()->nointerface();
if (no->is_function())
return no->func_value()->nointerface();
else if (no->is_function_declaration())
return no->func_declaration_value()->nointerface();
else
go_unreachable();
}
// Class Interface_method.
......
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