From 23073792629256339bb75446c7f4e3ff88184ee5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 31 Oct 2012 00:38:29 +0000 Subject: compiler: Add -fgo-relative-import-path. * lang.opt (-fgo-relative-import-path): New option. * go-lang.c (go_relative_import_path): New static variable. (go_langhook_init): Pass go_relative_import_path to go_create_gogo. (go_langhook_handle_option): Handle -fgo-relative-import-path. * go-c.h (go_create_gogo): Update declaration. * gccgo.texi (Invoking gccgo): Document -fgo-relative-import-path. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@193007 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/ChangeLog | 11 +++++++++++ gcc/go/gccgo.texi | 6 ++++++ gcc/go/go-c.h | 3 ++- gcc/go/go-lang.c | 8 +++++++- gcc/go/gofrontend/go.cc | 5 ++++- gcc/go/gofrontend/gogo.cc | 4 +++- gcc/go/gofrontend/gogo.h | 14 ++++++++++++++ gcc/go/gofrontend/import.cc | 29 ++++++++++++++++++++++++----- gcc/go/gofrontend/import.h | 4 +++- gcc/go/lang.opt | 4 ++++ 10 files changed, 78 insertions(+), 10 deletions(-) diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 2165911fa72..d78924ba60c 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,14 @@ +2012-10-30 Ian Lance Taylor + + * lang.opt (-fgo-relative-import-path): New option. + * go-lang.c (go_relative_import_path): New static variable. + (go_langhook_init): Pass go_relative_import_path to + go_create_gogo. + (go_langhook_handle_option): Handle -fgo-relative-import-path. + * go-c.h (go_create_gogo): Update declaration. + * gccgo.texi (Invoking gccgo): Document + -fgo-relative-import-path. + 2012-09-20 Ian Lance Taylor * Make-lang.in (go/gogo.o): Depend on filenames.h. diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi index a5e37e76e80..91930c812f6 100644 --- a/gcc/go/gccgo.texi +++ b/gcc/go/gccgo.texi @@ -184,6 +184,12 @@ Using either @option{-fgo-pkgpath} or @option{-fgo-prefix} disables the special treatment of the @code{main} package and permits that package to be imported like any other. +@item -fgo-relative-import-path=@var{dir} +@cindex @option{-fgo-relative-import-path} +A relative import is an import that starts with @file{./} or +@file{../}. If this option is used, @command{gccgo} will use +@var{dir} as a prefix for the relative import when searching for it. + @item -frequire-return-statement @itemx -fno-require-return-statement @cindex @option{-frequire-return-statement} diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h index d46a08796e3..ea59fb6b39a 100644 --- a/gcc/go/go-c.h +++ b/gcc/go/go-c.h @@ -42,7 +42,8 @@ extern int go_enable_optimize (const char*); extern void go_add_search_path (const char*); extern void go_create_gogo (int int_type_size, int pointer_size, - const char* pkgpath, const char *prefix); + const char* pkgpath, const char *prefix, + const char *relative_import_path); extern void go_parse_input_files (const char**, unsigned int, bool only_check_syntax, diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index f02f769252b..61ca1478be6 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -85,6 +85,7 @@ struct GTY(()) language_function static const char *go_pkgpath = NULL; static const char *go_prefix = NULL; +static const char *go_relative_import_path = NULL; /* Language hooks. */ @@ -101,7 +102,8 @@ go_langhook_init (void) to, e.g., unsigned_char_type_node) but before calling build_common_builtin_nodes (because it calls, indirectly, go_type_for_size). */ - go_create_gogo (INT_TYPE_SIZE, POINTER_SIZE, go_pkgpath, go_prefix); + go_create_gogo (INT_TYPE_SIZE, POINTER_SIZE, go_pkgpath, go_prefix, + go_relative_import_path); build_common_builtin_nodes (); @@ -240,6 +242,10 @@ go_langhook_handle_option ( go_prefix = arg; break; + case OPT_fgo_relative_import_path_: + go_relative_import_path = arg; + break; + default: /* Just return 1 to indicate that the option is valid. */ break; diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc index 1f2ce8adcde..11692af8095 100644 --- a/gcc/go/gofrontend/go.cc +++ b/gcc/go/gofrontend/go.cc @@ -21,7 +21,7 @@ static Gogo* gogo; GO_EXTERN_C void go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath, - const char *prefix) + const char *prefix, const char *relative_import_path) { go_assert(::gogo == NULL); Linemap* linemap = go_get_linemap(); @@ -32,6 +32,9 @@ go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath, else if (prefix != NULL) ::gogo->set_prefix(prefix); + if (relative_import_path != NULL) + ::gogo->set_relative_import_path(relative_import_path); + // FIXME: This should be in the gcc dependent code. ::gogo->define_builtin_function_trees(); } diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index fa61808ec3c..c0aa496acc3 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -44,6 +44,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size, pkgpath_set_(false), pkgpath_from_option_(false), prefix_from_option_(false), + relative_import_path_(), verify_types_(), interface_types_(), specific_type_functions_(), @@ -477,7 +478,8 @@ Gogo::import_package(const std::string& filename, return; } - Import::Stream* stream = Import::open_package(filename, location); + Import::Stream* stream = Import::open_package(filename, location, + this->relative_import_path_); if (stream == NULL) { error_at(location, "import file %qs not found", filename.c_str()); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 36709f5b45b..cc707ad2dde 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -206,6 +206,17 @@ class Gogo pkgpath_from_option() const { return this->pkgpath_from_option_; } + // Return the relative import path as set from the command line. + // Returns an empty string if it was not set. + const std::string& + relative_import_path() const + { return this->relative_import_path_; } + + // Set the relative import path from a command line option. + void + set_relative_import_path(const std::string& s) + {this->relative_import_path_ = s; } + // Return the priority to use for the package we are compiling. // This is two more than the largest priority of any package we // import. @@ -732,6 +743,9 @@ class Gogo bool pkgpath_from_option_; // Whether an explicit prefix was set by -fgo-prefix. bool prefix_from_option_; + // The relative import path, from the -fgo-relative-import-path + // option. + std::string relative_import_path_; // A list of types to verify. std::vector verify_types_; // A list of interface types defined while parsing. diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 9febf231897..4913100b5fd 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -41,6 +41,9 @@ go_add_search_path(const char* path) // When FILENAME is not an absolute path and does not start with ./ or // ../, we use the search path provided by -I and -L options. +// When FILENAME does start with ./ or ../, we use +// RELATIVE_IMPORT_PATH as a prefix. + // When FILENAME does not exist, we try modifying FILENAME to find the // file. We use the first of these which exists: // * We append ".gox". @@ -55,19 +58,35 @@ go_add_search_path(const char* path) // later in the search path. Import::Stream* -Import::open_package(const std::string& filename, Location location) +Import::open_package(const std::string& filename, Location location, + const std::string& relative_import_path) { bool is_local; if (IS_ABSOLUTE_PATH(filename)) is_local = true; - else if (filename[0] == '.' && IS_DIR_SEPARATOR(filename[1])) + else if (filename[0] == '.' + && (filename[1] == '\0' || IS_DIR_SEPARATOR(filename[1]))) is_local = true; else if (filename[0] == '.' && filename[1] == '.' - && IS_DIR_SEPARATOR(filename[2])) + && (filename[2] == '\0' || IS_DIR_SEPARATOR(filename[2]))) is_local = true; else is_local = false; + + std::string fn = filename; + if (is_local && !IS_ABSOLUTE_PATH(filename) && !relative_import_path.empty()) + { + if (fn == ".") + { + // A special case. + fn = relative_import_path; + } + else + fn = relative_import_path + '/' + fn; + is_local = false; + } + if (!is_local) { for (std::vector::const_iterator p = search_path.begin(); @@ -77,14 +96,14 @@ Import::open_package(const std::string& filename, Location location) std::string indir = *p; if (!indir.empty() && indir[indir.size() - 1] != '/') indir += '/'; - indir += filename; + indir += fn; Stream* s = Import::try_package_in_directory(indir, location); if (s != NULL) return s; } } - Stream* s = Import::try_package_in_directory(filename, location); + Stream* s = Import::try_package_in_directory(fn, location); if (s != NULL) return s; diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h index 67bdcb02d57..c6844cda8a5 100644 --- a/gcc/go/gofrontend/import.h +++ b/gcc/go/gofrontend/import.h @@ -124,8 +124,10 @@ class Import // 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. LOCATION is the location of the import statement. + // RELATIVE_IMPORT_PATH is used as a prefix for a relative import. static Stream* - open_package(const std::string& filename, Location location); + open_package(const std::string& filename, Location location, + const std::string& relative_import_path); // Constructor. Import(Stream*, Location); diff --git a/gcc/go/lang.opt b/gcc/go/lang.opt index eb9ed9a63a0..22197a71e3d 100644 --- a/gcc/go/lang.opt +++ b/gcc/go/lang.opt @@ -61,6 +61,10 @@ fgo-prefix= Go Joined RejectNegative -fgo-prefix= Set package-specific prefix for exported Go names +fgo-relative-import-path= +Go Joined RejectNegative +-fgo-relative-import-path= Treat a relative import as relative to path + frequire-return-statement Go Var(go_require_return_statement) Init(1) Warning Functions which return values must end with return statements -- cgit v1.2.3