diff options
author | Ian Lance Taylor <iant@golang.org> | 2023-06-26 09:57:21 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2023-06-26 09:57:21 -0700 |
commit | aa1e672b5d99102b03eb5fb9c51609c45f62bff7 (patch) | |
tree | 886212591b1c9d127eaaf234a4a2e22452ea384a /gcc/go | |
parent | 97e31a0a2a2d2273687fcdb4e5416aab1a2186e1 (diff) | |
parent | 3a39a31b8ae9c6465434aefa657f7fcc86f905c0 (diff) | |
download | gcc-aa1e672b5d99102b03eb5fb9c51609c45f62bff7.zip gcc-aa1e672b5d99102b03eb5fb9c51609c45f62bff7.tar.gz gcc-aa1e672b5d99102b03eb5fb9c51609c45f62bff7.tar.bz2 |
Merge from trunk revision 3a39a31b8ae9c6465434aefa657f7fcc86f905c0.devel/gccgo
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/gccgo.texi | 8 | ||||
-rw-r--r-- | gcc/go/go-backend.cc | 6 | ||||
-rw-r--r-- | gcc/go/go-c.h | 1 | ||||
-rw-r--r-- | gcc/go/go-lang.cc | 14 | ||||
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/embed.cc | 11 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 13 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 5 | ||||
-rw-r--r-- | gcc/go/gofrontend/go.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 50 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 12 | ||||
-rw-r--r-- | gcc/go/gofrontend/import.cc | 124 | ||||
-rw-r--r-- | gcc/go/lang.opt | 4 |
14 files changed, 238 insertions, 19 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 507e2d3..931c3be 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2023-06-22 Paul E. Murphy <murphyp@linux.ibm.com> + + * go-backend.cc [TARGET_AIX]: Rename and update usage to TARGET_AIX_OS. + * go-lang.cc: Likewise. + 2023-03-24 Jakub Jelinek <jakub@redhat.com> PR middle-end/109258 diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi index 4ab1a76..90651af 100644 --- a/gcc/go/gccgo.texi +++ b/gcc/go/gccgo.texi @@ -271,6 +271,14 @@ pattern to a list of file names, and @code{Files} maps each file name to a full path to the file. This option is intended for use by the @command{go} command to implement @code{//go:embed}. +@cindex @option{-fgo-importcfg} +@item -fgo-importcfg=@var{file} +Identify a file that provides mappings for import package paths found +in the Go source files. The file can contain two commands: +@code{importpath} to rename import paths for vendoring and +@code{packagefile} to map from package path to files containing export +data. This option is intended for use by the @command{go} command. + @cindex @option{-g for gccgo} @item -g This is the standard @command{gcc} option (@pxref{Debugging Options, , diff --git a/gcc/go/go-backend.cc b/gcc/go/go-backend.cc index c6a1a2b..6e2c919 100644 --- a/gcc/go/go-backend.cc +++ b/gcc/go/go-backend.cc @@ -45,8 +45,8 @@ along with GCC; see the file COPYING3. If not see #define GO_EXPORT_SECTION_NAME ".go_export" #endif -#ifndef TARGET_AIX -#define TARGET_AIX 0 +#ifndef TARGET_AIX_OS +#define TARGET_AIX_OS 0 #endif /* This file holds all the cases where the Go frontend needs @@ -107,7 +107,7 @@ go_write_export_data (const char *bytes, unsigned int size) { gcc_assert (targetm_common.have_named_sections); sec = get_section (GO_EXPORT_SECTION_NAME, - TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG, + TARGET_AIX_OS ? SECTION_EXCLUDE : SECTION_DEBUG, NULL); } diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h index c605038..6a2b57b 100644 --- a/gcc/go/go-c.h +++ b/gcc/go/go-c.h @@ -41,6 +41,7 @@ struct go_create_gogo_args const char* prefix; const char* relative_import_path; const char* c_header; + const char* importcfg; const char* embedcfg; Backend* backend; Linemap* linemap; diff --git a/gcc/go/go-lang.cc b/gcc/go/go-lang.cc index b6e8c37..e85a4bf 100644 --- a/gcc/go/go-lang.cc +++ b/gcc/go/go-lang.cc @@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see #include "go-c.h" #include "go-gcc.h" -#ifndef TARGET_AIX -#define TARGET_AIX 0 +#ifndef TARGET_AIX_OS +#define TARGET_AIX_OS 0 #endif /* Language-dependent contents of a type. */ @@ -90,6 +90,7 @@ static const char *go_prefix = NULL; static const char *go_relative_import_path = NULL; static const char *go_c_header = NULL; static const char *go_embedcfg = NULL; +static const char *go_importcfg = NULL; /* Language hooks. */ @@ -111,14 +112,15 @@ go_langhook_init (void) args.relative_import_path = go_relative_import_path; args.c_header = go_c_header; args.embedcfg = go_embedcfg; + args.importcfg = go_importcfg; args.check_divide_by_zero = go_check_divide_zero; args.check_divide_overflow = go_check_divide_overflow; args.compiling_runtime = go_compiling_runtime; args.debug_escape_level = go_debug_escape_level; args.debug_escape_hash = go_debug_escape_hash; - args.nil_check_size_threshold = TARGET_AIX ? -1 : 4096; + args.nil_check_size_threshold = TARGET_AIX_OS ? -1 : 4096; args.debug_optimization = go_debug_optimization; - args.need_eqtype = TARGET_AIX ? true : false; + args.need_eqtype = TARGET_AIX_OS ? true : false; args.linemap = go_get_linemap(); args.backend = go_get_backend(); go_create_gogo (&args); @@ -286,6 +288,10 @@ go_langhook_handle_option ( go_embedcfg = arg; break; + case OPT_fgo_importcfg_: + go_importcfg = arg; + break; + default: /* Just return 1 to indicate that the option is valid. */ break; diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index dbb2d68..c44cdc2 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6a1d165c2218cd127ee937a1f45599075762f716 +92152c88ea8e2dd9e8c67e91bf4ae5e3edf1b506 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/embed.cc b/gcc/go/gofrontend/embed.cc index 0584f70..6dada5e 100644 --- a/gcc/go/gofrontend/embed.cc +++ b/gcc/go/gofrontend/embed.cc @@ -19,8 +19,8 @@ // Read a file into *DATA. Returns false on error. -static bool -read_file(const char* filename, Location loc, std::string* data) +bool +Gogo::read_file(const char* filename, Location loc, std::string* data) { int fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) @@ -346,7 +346,8 @@ Gogo::read_embedcfg(const char *filename) bool Embedcfg_reader::initialize_from_file() { - if (!read_file(this->filename_, Linemap::unknown_location(), &this->data_)) + if (!Gogo::read_file(this->filename_, Linemap::unknown_location(), + &this->data_)) return false; if (this->data_.empty()) { @@ -849,7 +850,7 @@ Gogo::initializer_for_embeds(Type* type, } std::string data; - if (!read_file(this->embed_files_[paths[0]].c_str(), loc, &data)) + if (!Gogo::read_file(this->embed_files_[paths[0]].c_str(), loc, &data)) return Expression::make_error(loc); Expression* e = Expression::make_string(data, loc); @@ -909,7 +910,7 @@ Gogo::initializer_for_embeds(Type* type, std::string data; if ((*pp)[pp->size() - 1] != '/') { - if (!read_file(this->embed_files_[*pp].c_str(), loc, &data)) + if (!Gogo::read_file(this->embed_files_[*pp].c_str(), loc, &data)) return Expression::make_error(loc); } diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 4ac55af..d276bd8 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -12272,7 +12272,8 @@ Call_expression::intrinsify(Gogo* gogo, return Runtime::make_call(code, loc, 3, a1, a2, a3); } } - else if (package == "internal/abi") + else if (package == "internal/abi" + || package == "bootstrap/internal/abi") // for bootstrapping gc { if (is_method) return NULL; @@ -18307,6 +18308,16 @@ Slice_value_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +// Determine type of a slice value. + +void +Slice_value_expression::do_determine_type(const Type_context*) +{ + this->valmem_->determine_type_no_context(); + this->len_->determine_type_no_context(); + this->cap_->determine_type_no_context(); +} + Expression* Slice_value_expression::do_copy() { diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 3d7e787..bdb7ccd 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -4364,8 +4364,7 @@ class Slice_value_expression : public Expression { return this->type_; } void - do_determine_type(const Type_context*) - { } + do_determine_type(const Type_context*); Expression* do_copy(); @@ -4419,7 +4418,7 @@ class Slice_info_expression : public Expression void do_determine_type(const Type_context*) - { } + { this->slice_->determine_type_no_context(); } Expression* do_copy() diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc index 1512770..66d4816 100644 --- a/gcc/go/gofrontend/go.cc +++ b/gcc/go/gofrontend/go.cc @@ -40,6 +40,8 @@ go_create_gogo(const struct go_create_gogo_args* args) ::gogo->set_compiling_runtime(args->compiling_runtime); if (args->c_header != NULL) ::gogo->set_c_header(args->c_header); + if (args->importcfg != NULL) + ::gogo->read_importcfg(args->importcfg); if (args->embedcfg != NULL) ::gogo->read_embedcfg(args->embedcfg); ::gogo->set_debug_escape_level(args->debug_escape_level); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 9197eef..fa3cd6e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -52,6 +52,10 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size) prefix_from_option_(false), relative_import_path_(), c_header_(), + import_map_(), + package_file_(), + embed_patterns_(), + embed_files_(), check_divide_by_zero_(true), check_divide_overflow_(true), compiling_runtime_(false), @@ -517,7 +521,20 @@ Gogo::import_package(const std::string& filename, return; } - Import::Stream* stream = Import::open_package(filename, location, + // If we are using an importcfg file we have to check two mappings. + // IMPORT_MAP_ is a mapping from package path to real package path, + // for vendoring. PACKAGE_FILE_ is a mapping from package path to + // file name, to find the file in the build cache. + std::string path = filename; + Unordered_map(std::string, std::string)::const_iterator pi; + pi = this->import_map_.find(filename); + if (pi != this->import_map_.end()) + path = pi->second; + pi = this->package_file_.find(path); + if (pi != this->package_file_.end()) + path = pi->second; + + Import::Stream* stream = Import::open_package(path, location, this->relative_import_path_); if (stream == NULL) { @@ -3296,6 +3313,9 @@ class Create_function_descriptors : public Traverse int expression(Expression**); + static bool + skip_descriptor(Gogo* gogo, const Named_object*); + private: Gogo* gogo_; }; @@ -3306,6 +3326,9 @@ class Create_function_descriptors : public Traverse int Create_function_descriptors::function(Named_object* no) { + if (Create_function_descriptors::skip_descriptor(this->gogo_, no)) + return TRAVERSE_CONTINUE; + if (no->is_function() && no->func_value()->enclosing() == NULL && !no->func_value()->is_method() @@ -3393,6 +3416,28 @@ Create_function_descriptors::expression(Expression** pexpr) return TRAVERSE_CONTINUE; } +// The gc compiler has some special cases that it always compiles as +// intrinsics. For those we don't want to generate a function +// descriptor, as there will be no code for it to refer to. + +bool +Create_function_descriptors::skip_descriptor(Gogo* gogo, + const Named_object* no) +{ + const std::string& pkgpath(no->package() == NULL + ? gogo->pkgpath() + : no->package()->pkgpath()); + + // internal/abi is the standard library package, + // bootstrap/internal/abi is the name used when bootstrapping the gc + // compiler. + + return ((pkgpath == "internal/abi" + || pkgpath == "bootstrap/internal/abi") + && (no->name() == "FuncPCABI0" + || no->name() == "FuncPCABIInternal")); +} + // Create function descriptors as needed. We need a function // descriptor for all exported functions and for all functions that // are referenced without being called. @@ -3414,7 +3459,8 @@ Gogo::create_function_descriptors() if (no->is_function_declaration() && !no->func_declaration_value()->type()->is_method() && !Linemap::is_predeclared_location(no->location()) - && !Gogo::is_hidden_name(no->name())) + && !Gogo::is_hidden_name(no->name()) + && !Create_function_descriptors::skip_descriptor(this, no)) fndecls.push_back(no); } for (std::vector<Named_object*>::const_iterator p = fndecls.begin(); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index c08a16b..4fd45bf 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -393,6 +393,10 @@ class Gogo set_c_header(const std::string& s) { this->c_header_ = s; } + // Read an importcfg file. + void + read_importcfg(const char* filename); + // Read an embedcfg file. void read_embedcfg(const char* filename); @@ -1126,6 +1130,10 @@ class Gogo static size_t special_name_pos(const std::string& name); + // Read a file into memory. + static bool + read_file(const char* filename, Location loc, std::string* data); + private: // During parsing, we keep a stack of functions. Each function on // the stack is one that we are currently parsing. For each @@ -1295,6 +1303,10 @@ class Gogo std::string relative_import_path_; // The C header file to write, from the -fgo-c-header option. std::string c_header_; + // Mapping from imports in the source file to the real import paths. + Unordered_map(std::string, std::string) import_map_; + // Mapping from import paths to files to read. + Unordered_map(std::string, std::string) package_file_; // Patterns from an embedcfg file. Embed_patterns embed_patterns_; // Mapping from file to full path from an embedcfg file. diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 6a5491b..21691fa 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -34,6 +34,130 @@ go_add_search_path(const char* path) search_path.push_back(std::string(path)); } +// Read an importcfg file. + +void +Gogo::read_importcfg(const char* filename) +{ + std::string data; + if (!Gogo::read_file(filename, Linemap::unknown_location(), &data)) + return; + const char* p = data.data(); + const char* pend = p + data.length(); + int lineno = 0; + const char *pnext = NULL; + for (; p < pend; p = pnext) + { + // Line numbers start at 1. + lineno++; + + // Find end of line. + const char* pnl = static_cast<const char*>(memchr(p, '\n', pend - p)); + if (pnl != NULL) + pnext = pnl + 1; + else + { + pnl = pend; + pnext = pnl; + } + + // Trim leading spaces. + while (p < pnl) + { + unsigned int rune; + int rune_len = Lex::fetch_char(p, &rune); + if (rune_len == 0) + { + go_error_at(Linemap::unknown_location(), + "%s:%d: invalid character in importcfg file", + filename, lineno); + return; + } + if (!Lex::is_unicode_space(rune)) + break; + p += rune_len; + } + + // Trim trailing spaces. + while (pnl > p) + { + size_t start = pnl - p - 1; + unsigned int rune = (unsigned char)p[start]; + int rune_len = 1; + if (rune > 0x7f) + { + for (start--; start > 0; start--) + { + unsigned char c = p[start]; + if ((c & 0xc0) != 0x80) + break; + } + rune_len = Lex::fetch_char(p + start, &rune); + if (static_cast<size_t>(rune_len) != (pnl - p) - start) + { + go_error_at(Linemap::unknown_location(), + "%s:%d: invalid character in importcfg file", + filename, lineno); + return; + } + } + if (!Lex::is_unicode_space(rune)) + break; + pnl -= rune_len; + } + + // Skip empty lines and comment lines. + if (p == pnl || *p == '#') + continue; + + size_t verb_len; + const char* psp = static_cast<const char*>(memchr(p, ' ', pnl - p)); + if (psp == NULL) + verb_len = pnl - p; + else + verb_len = psp - p; + + bool importmap = false; + bool packagefile = false; + if (strncmp(p, "importmap", verb_len) == 0) + importmap = true; + else if (strncmp(p, "packagefile", verb_len) == 0) + packagefile = true; + else + { + go_error_at(Linemap::unknown_location(), + "%s:%d: unknown directive in importcfg file", + filename, lineno); + return; + } + + const char* peq; + if (psp == NULL) + peq = NULL; + else + { + psp++; + peq = static_cast<const char*>(memchr(psp, '=', pnl - psp)); + } + if (peq == NULL || peq + 1 == pnl) + { + go_error_at(Linemap::unknown_location(), + "%s:%d: invalid syntax in importcfg file", + filename, lineno); + return; + } + + std::string first(psp, peq - psp); + std::string second(peq + 1, pnl - (peq + 1)); + if (importmap) + this->import_map_[first] = second; + else if (packagefile) + this->package_file_[first] = second; + else + go_unreachable(); + } +} + // Find import data. This searches the file system for FILENAME and // returns a pointer to a Stream object to read the data that it // exports. If the file is not found, it returns NULL. diff --git a/gcc/go/lang.opt b/gcc/go/lang.opt index 4ca989c..0d658fc 100644 --- a/gcc/go/lang.opt +++ b/gcc/go/lang.opt @@ -61,6 +61,10 @@ fgo-embedcfg= Go Joined RejectNegative -fgo-embedcfg=<file> List embedded files via go:embed. +fgo-importcfg= +Go Joined RejectNegative +-fgo-importcfg=<file> Provide file that tells where to find imports. + fgo-optimize- Go Joined -fgo-optimize-<type> Turn on optimization passes in the frontend. |