-7e94bac5676afc8188677c98ecb263c78c1a7f8d
+89105404f94005ffa8e2b08df78015dc9ac91362
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
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("(");
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() == '(')
{
// 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*
// 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.
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_; }
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
// 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
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)
if (this->add_to_globals_)
this->gogo_->add_dot_import_object(no);
}
+
+ if (nointerface)
+ no->func_declaration_value()->set_nointerface();
+
return no;
}
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.