summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-17 11:11:25 +0000
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-17 11:11:25 +0000
commit99227731b0f74729e239b2bd3c3450c1f98d7700 (patch)
tree2eedcb4f55a3cf78d29fa8c589d673751e940362 /gcc/fortran
parentf0903548b3287506d5f909fccde02f55b9c582c1 (diff)
downloadgcc-99227731b0f74729e239b2bd3c3450c1f98d7700.tar.gz
* gfortran.h (gfc_add_intrinsic_modules_path,
gfc_open_intrinsic_module): New prototypes. (gfc_add_include_path, gfc_open_included_file): Update prototypes. * lang.opt: Add -fintrinsic-modules-path option. * module.c (gfc_match_use): Match the Fortran 2003 form of USE statement. (gfc_use_module): Also handle intrinsic modules. * scanner.c (gfc_directorylist): Add use_for_modules for field. (intrinsic_modules_dirs): New static variable. (add_path_to_list, gfc_add_intrinsic_modules_path): New functions. (gfc_add_include_path): Use the new add_path_to_list helper function. (gfc_release_include_path): Free memory for intrinsic_modules_dirs. (open_included_file, gfc_open_intrinsic_module): New functions. (gfc_open_included_file): Use the new open_included_file helper function. * lang-specs.h: Use the new -fintrinsic-modules-path option. * parse.c (decode_statement): Do not match the required space after USE here. * options.c (gfc_handle_option): Handle the new option. Use new prototype for gfc_add_include_path. (gfc_post_options): Use new prototype for gfc_add_include_path. * gfortran.dg/use_1.f90: New test. * gfortran.dg/use_1.f90: New test. * gfortran.dg/use_1.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118930 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog25
-rw-r--r--gcc/fortran/gfortran.h6
-rw-r--r--gcc/fortran/lang-specs.h8
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/module.c86
-rw-r--r--gcc/fortran/options.c11
-rw-r--r--gcc/fortran/parse.c2
-rw-r--r--gcc/fortran/scanner.c85
8 files changed, 194 insertions, 33 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c26bf0b9cc4..281539573bb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,28 @@
+2006-11-17 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ * gfortran.h (gfc_add_intrinsic_modules_path,
+ gfc_open_intrinsic_module): New prototypes.
+ (gfc_add_include_path, gfc_open_included_file): Update prototypes.
+ * lang.opt: Add -fintrinsic-modules-path option.
+ * module.c (gfc_match_use): Match the Fortran 2003 form of
+ USE statement.
+ (gfc_use_module): Also handle intrinsic modules.
+ * scanner.c (gfc_directorylist): Add use_for_modules for field.
+ (intrinsic_modules_dirs): New static variable.
+ (add_path_to_list, gfc_add_intrinsic_modules_path): New functions.
+ (gfc_add_include_path): Use the new add_path_to_list helper
+ function.
+ (gfc_release_include_path): Free memory for intrinsic_modules_dirs.
+ (open_included_file, gfc_open_intrinsic_module): New functions.
+ (gfc_open_included_file): Use the new open_included_file
+ helper function.
+ * lang-specs.h: Use the new -fintrinsic-modules-path option.
+ * parse.c (decode_statement): Do not match the required space
+ after USE here.
+ * options.c (gfc_handle_option): Handle the new option. Use new
+ prototype for gfc_add_include_path.
+ (gfc_post_options): Use new prototype for gfc_add_include_path.
+
2006-11-16 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/29391
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index e5d32f6a6ee..f33d2ee50b5 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1709,9 +1709,11 @@ void gfc_advance_section (mpz_t *, gfc_array_ref *, mpz_t *);
void gfc_scanner_done_1 (void);
void gfc_scanner_init_1 (void);
-void gfc_add_include_path (const char *);
+void gfc_add_include_path (const char *, bool);
+void gfc_add_intrinsic_modules_path (const char *);
void gfc_release_include_path (void);
-FILE *gfc_open_included_file (const char *, bool);
+FILE *gfc_open_included_file (const char *, bool, bool);
+FILE *gfc_open_intrinsic_module (const char *);
int gfc_at_end (void);
int gfc_at_eof (void);
diff --git a/gcc/fortran/lang-specs.h b/gcc/fortran/lang-specs.h
index caf4b1b2114..56e55a1517f 100644
--- a/gcc/fortran/lang-specs.h
+++ b/gcc/fortran/lang-specs.h
@@ -15,7 +15,7 @@ This file is licensed under the GPL. */
%{E|M|MM:%(cpp_debug_options)}\
%{!M:%{!MM:%{!E: -o %|.f |\n\
f951 %|.f %{!ffree-form:-ffixed-form} %(cc1_options) %{J*} %{I*}\
- -fpreprocessed %{!nostdinc:-I finclude%s} %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+ -fpreprocessed %{!nostdinc:-fintrinsic-modules-path finclude%s} %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
{".F90", "@f95-cpp-input", 0, 0, 0},
{".F95", "@f95-cpp-input", 0, 0, 0},
{"@f95-cpp-input",
@@ -23,13 +23,13 @@ This file is licensed under the GPL. */
%{E|M|MM:%(cpp_debug_options)}\
%{!M:%{!MM:%{!E: -o %|.f95 |\n\
f951 %|.f95 %{!ffixed-form:-ffree-form} %(cc1_options) %{J*} %{I*}\
- -fpreprocessed %{!nostdinc:-I finclude%s} %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+ -fpreprocessed %{!nostdinc:-fintrinsic-modules-path finclude%s} %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
{".f90", "@f95", 0, 0, 0},
{".f95", "@f95", 0, 0, 0},
{"@f95", "%{!E:f951 %i %(cc1_options) %{J*} %{I*}\
- %{!nostdinc:-I finclude%s} %{!fsyntax-only:%(invoke_as)}}", 0, 0, 0},
+ %{!nostdinc:-fintrinsic-modules-path finclude%s} %{!fsyntax-only:%(invoke_as)}}", 0, 0, 0},
{".f", "@f77", 0, 0, 0},
{".for", "@f77", 0, 0, 0},
{".FOR", "@f77", 0, 0, 0},
{"@f77", "%{!E:f951 %i %{!ffree-form:-ffixed-form} %(cc1_options) %{J*} %{I*}\
- %{!nostdinc:-I finclude%s} %{!fsyntax-only:%(invoke_as)}}", 0, 0, 0},
+ %{!nostdinc:-fintrinsic-modules-path finclude%s} %{!fsyntax-only:%(invoke_as)}}", 0, 0, 0},
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index e8b8640213e..053f63b0019 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -149,6 +149,10 @@ ffixed-form
Fortran RejectNegative
Assume that the source file is fixed form
+fintrinsic-modules-path
+Fortran RejectNegative Joined Separate
+Specify where to find the compiled intrinsic modules
+
ffixed-line-length-none
Fortran RejectNegative
Allow arbitrary character line width in fixed mode
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index f7b45f331c0..dd103b896f4 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -173,6 +173,9 @@ static FILE *module_fp;
/* The name of the module we're reading (USE'ing) or writing. */
static char module_name[GFC_MAX_SYMBOL_LEN + 1];
+/* The way the module we're reading was specified. */
+static bool specified_nonint, specified_int;
+
static int module_line, module_column, only_flag;
static enum
{ IO_INPUT, IO_OUTPUT }
@@ -483,12 +486,65 @@ free_rename (void)
match
gfc_match_use (void)
{
- char name[GFC_MAX_SYMBOL_LEN + 1];
+ char name[GFC_MAX_SYMBOL_LEN + 1], module_nature[GFC_MAX_SYMBOL_LEN + 1];
gfc_use_rename *tail = NULL, *new;
interface_type type;
gfc_intrinsic_op operator;
match m;
+ specified_int = false;
+ specified_nonint = false;
+
+ if (gfc_match (" , ") == MATCH_YES)
+ {
+ if ((m = gfc_match (" %n ::", module_nature)) == MATCH_YES)
+ {
+ if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: module "
+ "nature in USE statement at %C") == FAILURE)
+ return MATCH_ERROR;
+
+ if (strcmp (module_nature, "intrinsic") == 0)
+ specified_int = true;
+ else
+ {
+ if (strcmp (module_nature, "non_intrinsic") == 0)
+ specified_nonint = true;
+ else
+ {
+ gfc_error ("Module nature in USE statement at %C shall "
+ "be either INTRINSIC or NON_INTRINSIC");
+ return MATCH_ERROR;
+ }
+ }
+ }
+ else
+ {
+ /* Help output a better error message than "Unclassifiable
+ statement". */
+ gfc_match (" %n", module_nature);
+ if (strcmp (module_nature, "intrinsic") == 0
+ || strcmp (module_nature, "non_intrinsic") == 0)
+ gfc_error ("\"::\" was expected after module nature at %C "
+ "but was not found");
+ return m;
+ }
+ }
+ else
+ {
+ m = gfc_match (" ::");
+ if (m == MATCH_YES &&
+ gfc_notify_std (GFC_STD_F2003, "Fortran 2003: "
+ "\"USE :: module\" at %C") == FAILURE)
+ return MATCH_ERROR;
+
+ if (m != MATCH_YES)
+ {
+ m = gfc_match ("% ");
+ if (m != MATCH_YES)
+ return m;
+ }
+ }
+
m = gfc_match_name (module_name);
if (m != MATCH_YES)
return m;
@@ -3801,7 +3857,33 @@ gfc_use_module (void)
strcpy (filename, module_name);
strcat (filename, MODULE_EXTENSION);
- module_fp = gfc_open_included_file (filename, true);
+ /* First, try to find an non-intrinsic module, unless the USE statement
+ specified that the module is intrinsic. */
+ module_fp = NULL;
+ if (!specified_int)
+ module_fp = gfc_open_included_file (filename, true, true);
+
+ /* Then, see if it's an intrinsic one, unless the USE statement
+ specified that the module is non-intrinsic. */
+ if (module_fp == NULL && !specified_nonint)
+ {
+#if 0
+ if (strcmp (module_name, "iso_fortran_env") == 0
+ && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: "
+ "ISO_FORTRAN_ENV intrinsic module at %C") != FAILURE)
+ {
+ use_iso_fortran_env_module ();
+ return;
+ }
+#endif
+
+ module_fp = gfc_open_intrinsic_module (filename);
+
+ if (module_fp == NULL && specified_int)
+ gfc_fatal_error ("Can't find an intrinsic module named '%s' at %C",
+ module_name);
+ }
+
if (module_fp == NULL)
gfc_fatal_error ("Can't open module file '%s' for reading at %C: %s",
filename, strerror (errno));
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index a81491072ee..f03319bbcea 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -217,10 +217,10 @@ gfc_post_options (const char **pfilename)
source_path = alloca (i + 1);
memcpy (source_path, canon_source_file, i);
source_path[i] = 0;
- gfc_add_include_path (source_path);
+ gfc_add_include_path (source_path, true);
}
else
- gfc_add_include_path (".");
+ gfc_add_include_path (".", true);
if (canon_source_file != gfc_source_file)
gfc_free ((void *) canon_source_file);
@@ -511,6 +511,11 @@ gfc_handle_option (size_t scode, const char *arg, int value)
gfc_option.flag_implicit_none = value;
break;
+ case OPT_fintrinsic_modules_path:
+ gfc_add_include_path (arg, false);
+ gfc_add_intrinsic_modules_path (arg);
+ break;
+
case OPT_fmax_errors_:
gfc_option.max_errors = value;
break;
@@ -555,7 +560,7 @@ gfc_handle_option (size_t scode, const char *arg, int value)
break;
case OPT_I:
- gfc_add_include_path (arg);
+ gfc_add_include_path (arg, true);
break;
case OPT_J:
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 4cd49f5a727..1d02c2083e0 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -280,7 +280,7 @@ decode_statement (void)
break;
case 'u':
- match ("use% ", gfc_match_use, ST_USE);
+ match ("use", gfc_match_use, ST_USE);
break;
case 'v':
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 92ee3661480..30d9b6f3b2c 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -51,12 +51,13 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
typedef struct gfc_directorylist
{
char *path;
+ bool use_for_modules;
struct gfc_directorylist *next;
}
gfc_directorylist;
/* List of include file search directories. */
-static gfc_directorylist *include_dirs;
+static gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
static gfc_file *file_head, *current_file;
@@ -118,22 +119,21 @@ gfc_scanner_done_1 (void)
/* Adds path to the list pointed to by list. */
-void
-gfc_add_include_path (const char *path)
+static void
+add_path_to_list (gfc_directorylist **list, const char *path,
+ bool use_for_modules)
{
gfc_directorylist *dir;
const char *p;
p = path;
- while (*p == ' ' || *p == '\t') /* someone might do 'gfortran "-I include"' */
+ while (*p == ' ' || *p == '\t') /* someone might do "-I include" */
if (*p++ == '\0')
return;
- dir = include_dirs;
+ dir = *list;
if (!dir)
- {
- dir = include_dirs = gfc_getmem (sizeof (gfc_directorylist));
- }
+ dir = *list = gfc_getmem (sizeof (gfc_directorylist));
else
{
while (dir->next)
@@ -144,12 +144,27 @@ gfc_add_include_path (const char *path)
}
dir->next = NULL;
+ dir->use_for_modules = use_for_modules;
dir->path = gfc_getmem (strlen (p) + 2);
strcpy (dir->path, p);
strcat (dir->path, "/"); /* make '/' last character */
}
+void
+gfc_add_include_path (const char *path, bool use_for_modules)
+{
+ add_path_to_list (&include_dirs, path, use_for_modules);
+}
+
+
+void
+gfc_add_intrinsic_modules_path (const char *path)
+{
+ add_path_to_list (&intrinsic_modules_dirs, path, true);
+}
+
+
/* Release resources allocated for options. */
void
@@ -165,28 +180,30 @@ gfc_release_include_path (void)
gfc_free (p->path);
gfc_free (p);
}
+
+ gfc_free (gfc_option.module_dir);
+ while (intrinsic_modules_dirs != NULL)
+ {
+ p = intrinsic_modules_dirs;
+ intrinsic_modules_dirs = intrinsic_modules_dirs->next;
+ gfc_free (p->path);
+ gfc_free (p);
+ }
}
-/* Opens file for reading, searching through the include directories
- given if necessary. If the include_cwd argument is true, we try
- to open the file in the current directory first. */
-FILE *
-gfc_open_included_file (const char *name, const bool include_cwd)
+static FILE *
+open_included_file (const char *name, gfc_directorylist *list, bool module)
{
char *fullname;
gfc_directorylist *p;
FILE *f;
- if (include_cwd)
+ for (p = list; p; p = p->next)
{
- f = gfc_open_file (name);
- if (f != NULL)
- return f;
- }
+ if (module && !p->use_for_modules)
+ continue;
- for (p = include_dirs; p; p = p->next)
- {
fullname = (char *) alloca(strlen (p->path) + strlen (name) + 1);
strcpy (fullname, p->path);
strcat (fullname, name);
@@ -199,6 +216,32 @@ gfc_open_included_file (const char *name, const bool include_cwd)
return NULL;
}
+
+/* Opens file for reading, searching through the include directories
+ given if necessary. If the include_cwd argument is true, we try
+ to open the file in the current directory first. */
+
+FILE *
+gfc_open_included_file (const char *name, bool include_cwd, bool module)
+{
+ FILE *f;
+
+ if (include_cwd)
+ {
+ f = gfc_open_file (name);
+ if (f != NULL)
+ return f;
+ }
+
+ return open_included_file (name, include_dirs, module);
+}
+
+FILE *
+gfc_open_intrinsic_module (const char *name)
+{
+ return open_included_file (name, intrinsic_modules_dirs, true);
+}
+
/* Test to see if we're at the end of the main source file. */
int
@@ -1393,7 +1436,7 @@ load_file (const char *filename, bool initial)
}
else
{
- input = gfc_open_included_file (filename, false);
+ input = gfc_open_included_file (filename, false, false);
if (input == NULL)
{
gfc_error_now ("Can't open included file '%s'", filename);