diff options
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 50 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 24 | ||||
-rw-r--r-- | gcc/go/gofrontend/import.cc | 7 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 7 |
5 files changed, 81 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index edffc11..3d73330 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index ab0c27b..11ac338 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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* diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index dfff5c1..139df17 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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 diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 2a3ea83..7e06a3c 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -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; } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index eb04fe1..40eccfc 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -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. |