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/gofrontend | |
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/gofrontend')
-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 |
8 files changed, 207 insertions, 12 deletions
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. |