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
This commit is contained in:
parent
0444aa9c0a
commit
8221fb01d6
@ -1,4 +1,4 @@
|
||||
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,
|
||||
¶meters, &results, &is_varargs);
|
||||
¶meters, &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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user