Commit 4e1866fe by Ian Lance Taylor Committed by Ian Lance Taylor

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.

From-SVN: r193008
parent a46837fe
2012-10-30 Ian Lance Taylor <iant@google.com>
* 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-17 Ian Lance Taylor <iant@google.com> 2012-09-17 Ian Lance Taylor <iant@google.com>
* config-lang.in (target_libs): Add target-libbacktrace. * config-lang.in (target_libs): Add target-libbacktrace.
......
...@@ -184,6 +184,12 @@ Using either @option{-fgo-pkgpath} or @option{-fgo-prefix} disables ...@@ -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 the special treatment of the @code{main} package and permits that
package to be imported like any other. 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 @item -frequire-return-statement
@itemx -fno-require-return-statement @itemx -fno-require-return-statement
@cindex @option{-frequire-return-statement} @cindex @option{-frequire-return-statement}
......
...@@ -33,7 +33,8 @@ extern int go_enable_optimize (const char*); ...@@ -33,7 +33,8 @@ extern int go_enable_optimize (const char*);
extern void go_add_search_path (const char*); extern void go_add_search_path (const char*);
extern void go_create_gogo (int int_type_size, int pointer_size, 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, extern void go_parse_input_files (const char**, unsigned int,
bool only_check_syntax, bool only_check_syntax,
......
...@@ -85,6 +85,7 @@ struct GTY(()) language_function ...@@ -85,6 +85,7 @@ struct GTY(()) language_function
static const char *go_pkgpath = NULL; static const char *go_pkgpath = NULL;
static const char *go_prefix = NULL; static const char *go_prefix = NULL;
static const char *go_relative_import_path = NULL;
/* Language hooks. */ /* Language hooks. */
...@@ -101,7 +102,8 @@ go_langhook_init (void) ...@@ -101,7 +102,8 @@ go_langhook_init (void)
to, e.g., unsigned_char_type_node) but before calling to, e.g., unsigned_char_type_node) but before calling
build_common_builtin_nodes (because it calls, indirectly, build_common_builtin_nodes (because it calls, indirectly,
go_type_for_size). */ 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 (); build_common_builtin_nodes ();
...@@ -240,6 +242,10 @@ go_langhook_handle_option ( ...@@ -240,6 +242,10 @@ go_langhook_handle_option (
go_prefix = arg; go_prefix = arg;
break; break;
case OPT_fgo_relative_import_path_:
go_relative_import_path = arg;
break;
default: default:
/* Just return 1 to indicate that the option is valid. */ /* Just return 1 to indicate that the option is valid. */
break; break;
......
...@@ -21,7 +21,7 @@ static Gogo* gogo; ...@@ -21,7 +21,7 @@ static Gogo* gogo;
GO_EXTERN_C GO_EXTERN_C
void void
go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath, 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); go_assert(::gogo == NULL);
Linemap* linemap = go_get_linemap(); Linemap* linemap = go_get_linemap();
...@@ -32,6 +32,9 @@ go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath, ...@@ -32,6 +32,9 @@ go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath,
else if (prefix != NULL) else if (prefix != NULL)
::gogo->set_prefix(prefix); ::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. // FIXME: This should be in the gcc dependent code.
::gogo->define_builtin_function_trees(); ::gogo->define_builtin_function_trees();
} }
......
...@@ -44,6 +44,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size, ...@@ -44,6 +44,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size,
pkgpath_set_(false), pkgpath_set_(false),
pkgpath_from_option_(false), pkgpath_from_option_(false),
prefix_from_option_(false), prefix_from_option_(false),
relative_import_path_(),
verify_types_(), verify_types_(),
interface_types_(), interface_types_(),
specific_type_functions_(), specific_type_functions_(),
...@@ -477,7 +478,8 @@ Gogo::import_package(const std::string& filename, ...@@ -477,7 +478,8 @@ Gogo::import_package(const std::string& filename,
return; return;
} }
Import::Stream* stream = Import::open_package(filename, location); Import::Stream* stream = Import::open_package(filename, location,
this->relative_import_path_);
if (stream == NULL) if (stream == NULL)
{ {
error_at(location, "import file %qs not found", filename.c_str()); error_at(location, "import file %qs not found", filename.c_str());
......
...@@ -206,6 +206,17 @@ class Gogo ...@@ -206,6 +206,17 @@ class Gogo
pkgpath_from_option() const pkgpath_from_option() const
{ return this->pkgpath_from_option_; } { 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. // Return the priority to use for the package we are compiling.
// This is two more than the largest priority of any package we // This is two more than the largest priority of any package we
// import. // import.
...@@ -732,6 +743,9 @@ class Gogo ...@@ -732,6 +743,9 @@ class Gogo
bool pkgpath_from_option_; bool pkgpath_from_option_;
// Whether an explicit prefix was set by -fgo-prefix. // Whether an explicit prefix was set by -fgo-prefix.
bool prefix_from_option_; 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. // A list of types to verify.
std::vector<Type*> verify_types_; std::vector<Type*> verify_types_;
// A list of interface types defined while parsing. // A list of interface types defined while parsing.
......
...@@ -41,6 +41,9 @@ go_add_search_path(const char* path) ...@@ -41,6 +41,9 @@ go_add_search_path(const char* path)
// When FILENAME is not an absolute path and does not start with ./ or // When FILENAME is not an absolute path and does not start with ./ or
// ../, we use the search path provided by -I and -L options. // ../, 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 // When FILENAME does not exist, we try modifying FILENAME to find the
// file. We use the first of these which exists: // file. We use the first of these which exists:
// * We append ".gox". // * We append ".gox".
...@@ -55,19 +58,35 @@ go_add_search_path(const char* path) ...@@ -55,19 +58,35 @@ go_add_search_path(const char* path)
// later in the search path. // later in the search path.
Import::Stream* 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; bool is_local;
if (IS_ABSOLUTE_PATH(filename)) if (IS_ABSOLUTE_PATH(filename))
is_local = true; 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; is_local = true;
else if (filename[0] == '.' else if (filename[0] == '.'
&& filename[1] == '.' && filename[1] == '.'
&& IS_DIR_SEPARATOR(filename[2])) && (filename[2] == '\0' || IS_DIR_SEPARATOR(filename[2])))
is_local = true; is_local = true;
else else
is_local = false; 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) if (!is_local)
{ {
for (std::vector<std::string>::const_iterator p = search_path.begin(); for (std::vector<std::string>::const_iterator p = search_path.begin();
...@@ -77,14 +96,14 @@ Import::open_package(const std::string& filename, Location location) ...@@ -77,14 +96,14 @@ Import::open_package(const std::string& filename, Location location)
std::string indir = *p; std::string indir = *p;
if (!indir.empty() && indir[indir.size() - 1] != '/') if (!indir.empty() && indir[indir.size() - 1] != '/')
indir += '/'; indir += '/';
indir += filename; indir += fn;
Stream* s = Import::try_package_in_directory(indir, location); Stream* s = Import::try_package_in_directory(indir, location);
if (s != NULL) if (s != NULL)
return s; return s;
} }
} }
Stream* s = Import::try_package_in_directory(filename, location); Stream* s = Import::try_package_in_directory(fn, location);
if (s != NULL) if (s != NULL)
return s; return s;
......
...@@ -124,8 +124,10 @@ class Import ...@@ -124,8 +124,10 @@ class Import
// Find import data. This searches the file system for FILENAME and // Find import data. This searches the file system for FILENAME and
// returns a pointer to a Stream object to read the data that it // returns a pointer to a Stream object to read the data that it
// exports. LOCATION is the location of the import statement. // exports. LOCATION is the location of the import statement.
// RELATIVE_IMPORT_PATH is used as a prefix for a relative import.
static Stream* 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. // Constructor.
Import(Stream*, Location); Import(Stream*, Location);
......
...@@ -61,6 +61,10 @@ fgo-prefix= ...@@ -61,6 +61,10 @@ fgo-prefix=
Go Joined RejectNegative Go Joined RejectNegative
-fgo-prefix=<string> Set package-specific prefix for exported Go names -fgo-prefix=<string> Set package-specific prefix for exported Go names
fgo-relative-import-path=
Go Joined RejectNegative
-fgo-relative-import-path=<path> Treat a relative import as relative to path
frequire-return-statement frequire-return-statement
Go Var(go_require_return_statement) Init(1) Warning Go Var(go_require_return_statement) Init(1) Warning
Functions which return values must end with return statements Functions which return values must end with return statements
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment