mirror of git://gcc.gnu.org/git/gcc.git
re PR fortran/52846 ([F2008] Support submodules)
2015-07-17 Paul Thomas <pault@gcc.gnu.org> PR fortran/52846 * decl.c (gfc_match_end): Pick out declared submodule name from the composite identifier. * gfortran.h : Add 'submodule_name' to gfc_use_list structure. * module.c (gfc_match_submodule): Define submodule_name and add static 'submodule_name'. (gfc_match_submodule): Build up submodule filenames, using '@' as a delimiter. Store the output filename in 'submodule_name'. Similarly, the submodule identifier is built using '.' as an identifier. (gfc_dump_module): If current state is COMP_SUBMODULE, write to file 'submodule_name', using SUBMODULE_EXTENSION. (gfc_use_module): Similarly, use the 'submodule_name' field in the gfc_use_list structure and SUBMODULE_EXTENSION to read the implicitly used submodule files. 2015-07-17 Paul Thomas <pault@gcc.gnu.org> PR fortran/52846 * lib/fortran-modules.exp (proc cleanup-submodules): New procedure. * gfortran.dg/submodule_1.f08: Change extension and clean up the submodule files. * gfortran.dg/submodule_2.f08: ditto * gfortran.dg/submodule_6.f08: ditto * gfortran.dg/submodule_7.f08: ditto * gfortran.dg/submodule_8.f08: New test * gfortran.dg/submodule_9.f08: New test From-SVN: r225945
This commit is contained in:
parent
896c28a7fa
commit
3d5dc929f4
|
|
@ -1,3 +1,21 @@
|
||||||
|
2015-07-17 Paul Thomas <pault@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR fortran/52846
|
||||||
|
* decl.c (gfc_match_end): Pick out declared submodule name from
|
||||||
|
the composite identifier.
|
||||||
|
* gfortran.h : Add 'submodule_name' to gfc_use_list structure.
|
||||||
|
* module.c (gfc_match_submodule): Define submodule_name and add
|
||||||
|
static 'submodule_name'.
|
||||||
|
(gfc_match_submodule): Build up submodule filenames, using '@'
|
||||||
|
as a delimiter. Store the output filename in 'submodule_name'.
|
||||||
|
Similarly, the submodule identifier is built using '.' as an
|
||||||
|
identifier.
|
||||||
|
(gfc_dump_module): If current state is COMP_SUBMODULE, write
|
||||||
|
to file 'submodule_name', using SUBMODULE_EXTENSION.
|
||||||
|
(gfc_use_module): Similarly, use the 'submodule_name' field in
|
||||||
|
the gfc_use_list structure and SUBMODULE_EXTENSION to read the
|
||||||
|
implicitly used submodule files.
|
||||||
|
|
||||||
2015-07-17 Alessandro Fanfarillo <fanfarillo.gcc@gmail.com>
|
2015-07-17 Alessandro Fanfarillo <fanfarillo.gcc@gmail.com>
|
||||||
|
|
||||||
* trans-intrinsic.c (conv_co_collective): Remove redundant address
|
* trans-intrinsic.c (conv_co_collective): Remove redundant address
|
||||||
|
|
|
||||||
|
|
@ -6450,6 +6450,11 @@ gfc_match_end (gfc_statement *st)
|
||||||
if (block_name == NULL)
|
if (block_name == NULL)
|
||||||
goto syntax;
|
goto syntax;
|
||||||
|
|
||||||
|
/* We have to pick out the declared submodule name from the composite
|
||||||
|
required by F2008:11.2.3 para 2, which ends in the declared name. */
|
||||||
|
if (state == COMP_SUBMODULE)
|
||||||
|
block_name = strchr (block_name, '.') + 1;
|
||||||
|
|
||||||
if (strcmp (name, block_name) != 0 && strcmp (block_name, "ppr@") != 0)
|
if (strcmp (name, block_name) != 0 && strcmp (block_name, "ppr@") != 0)
|
||||||
{
|
{
|
||||||
gfc_error ("Expected label %qs for %s statement at %C", block_name,
|
gfc_error ("Expected label %qs for %s statement at %C", block_name,
|
||||||
|
|
|
||||||
|
|
@ -1556,6 +1556,7 @@ gfc_use_rename;
|
||||||
typedef struct gfc_use_list
|
typedef struct gfc_use_list
|
||||||
{
|
{
|
||||||
const char *module_name;
|
const char *module_name;
|
||||||
|
const char *submodule_name;
|
||||||
bool intrinsic;
|
bool intrinsic;
|
||||||
bool non_intrinsic;
|
bool non_intrinsic;
|
||||||
bool only_flag;
|
bool only_flag;
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#define MODULE_EXTENSION ".mod"
|
#define MODULE_EXTENSION ".mod"
|
||||||
|
#define SUBMODULE_EXTENSION ".smod"
|
||||||
|
|
||||||
/* Don't put any single quote (') in MOD_VERSION, if you want it to be
|
/* Don't put any single quote (') in MOD_VERSION, if you want it to be
|
||||||
recognized. */
|
recognized. */
|
||||||
|
|
@ -190,6 +191,8 @@ static gzFile module_fp;
|
||||||
|
|
||||||
/* The name of the module we're reading (USE'ing) or writing. */
|
/* The name of the module we're reading (USE'ing) or writing. */
|
||||||
static const char *module_name;
|
static const char *module_name;
|
||||||
|
/* The name of the .smod file that the submodule will write to. */
|
||||||
|
static const char *submodule_name;
|
||||||
static gfc_use_list *module_list;
|
static gfc_use_list *module_list;
|
||||||
|
|
||||||
/* If we're reading an intrinsic module, this is its ID. */
|
/* If we're reading an intrinsic module, this is its ID. */
|
||||||
|
|
@ -715,7 +718,17 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Match a SUBMODULE statement. */
|
/* Match a SUBMODULE statement.
|
||||||
|
|
||||||
|
According to F2008:11.2.3.2, "The submodule identifier is the
|
||||||
|
ordered pair whose first element is the ancestor module name and
|
||||||
|
whose second element is the submodule name. 'Submodule_name' is
|
||||||
|
used for the submodule filename and uses '@' as a separator, whilst
|
||||||
|
the name of the symbol for the module uses '.' as a a separator.
|
||||||
|
The reasons for these choices are:
|
||||||
|
(i) To follow another leading brand in the submodule filenames;
|
||||||
|
(ii) Since '.' is not particularly visible in the filenames; and
|
||||||
|
(iii) The linker does not permit '@' in mnemonics. */
|
||||||
|
|
||||||
match
|
match
|
||||||
gfc_match_submodule (void)
|
gfc_match_submodule (void)
|
||||||
|
|
@ -740,7 +753,6 @@ gfc_match_submodule (void)
|
||||||
goto syntax;
|
goto syntax;
|
||||||
|
|
||||||
use_list = gfc_get_use_list ();
|
use_list = gfc_get_use_list ();
|
||||||
use_list->module_name = gfc_get_string (name);
|
|
||||||
use_list->where = gfc_current_locus;
|
use_list->where = gfc_current_locus;
|
||||||
|
|
||||||
if (module_list)
|
if (module_list)
|
||||||
|
|
@ -749,9 +761,17 @@ gfc_match_submodule (void)
|
||||||
while (last->next)
|
while (last->next)
|
||||||
last = last->next;
|
last = last->next;
|
||||||
last->next = use_list;
|
last->next = use_list;
|
||||||
|
use_list->module_name
|
||||||
|
= gfc_get_string ("%s.%s", module_list->module_name, name);
|
||||||
|
use_list->submodule_name
|
||||||
|
= gfc_get_string ("%s@%s", module_list->module_name, name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
module_list = use_list;
|
module_list = use_list;
|
||||||
|
use_list->module_name = gfc_get_string (name);
|
||||||
|
use_list->submodule_name = use_list->module_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (gfc_match_char (')') == MATCH_YES)
|
if (gfc_match_char (')') == MATCH_YES)
|
||||||
break;
|
break;
|
||||||
|
|
@ -764,10 +784,26 @@ gfc_match_submodule (void)
|
||||||
if (m != MATCH_YES)
|
if (m != MATCH_YES)
|
||||||
goto syntax;
|
goto syntax;
|
||||||
|
|
||||||
|
submodule_name = gfc_get_string ("%s@%s", module_list->module_name,
|
||||||
|
gfc_new_block->name);
|
||||||
|
|
||||||
|
gfc_new_block->name = gfc_get_string ("%s.%s",
|
||||||
|
module_list->module_name,
|
||||||
|
gfc_new_block->name);
|
||||||
|
|
||||||
if (!gfc_add_flavor (&gfc_new_block->attr, FL_MODULE,
|
if (!gfc_add_flavor (&gfc_new_block->attr, FL_MODULE,
|
||||||
gfc_new_block->name, NULL))
|
gfc_new_block->name, NULL))
|
||||||
return MATCH_ERROR;
|
return MATCH_ERROR;
|
||||||
|
|
||||||
|
/* Just retain the ultimate .(s)mod file for reading, since it
|
||||||
|
contains all the information in its ancestors. */
|
||||||
|
use_list = module_list;
|
||||||
|
for (; module_list->next; use_list = use_list->next)
|
||||||
|
{
|
||||||
|
module_list = use_list->next;
|
||||||
|
free (use_list);
|
||||||
|
}
|
||||||
|
|
||||||
return MATCH_YES;
|
return MATCH_YES;
|
||||||
|
|
||||||
syntax:
|
syntax:
|
||||||
|
|
@ -5932,7 +5968,16 @@ gfc_dump_module (const char *name, int dump_flag)
|
||||||
char *filename, *filename_tmp;
|
char *filename, *filename_tmp;
|
||||||
uLong crc, crc_old;
|
uLong crc, crc_old;
|
||||||
|
|
||||||
|
module_name = gfc_get_string (name);
|
||||||
|
|
||||||
|
if (gfc_state_stack->state == COMP_SUBMODULE)
|
||||||
|
{
|
||||||
|
name = submodule_name;
|
||||||
|
n = strlen (name) + strlen (SUBMODULE_EXTENSION) + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
n = strlen (name) + strlen (MODULE_EXTENSION) + 1;
|
n = strlen (name) + strlen (MODULE_EXTENSION) + 1;
|
||||||
|
|
||||||
if (gfc_option.module_dir != NULL)
|
if (gfc_option.module_dir != NULL)
|
||||||
{
|
{
|
||||||
n += strlen (gfc_option.module_dir);
|
n += strlen (gfc_option.module_dir);
|
||||||
|
|
@ -5945,6 +5990,10 @@ gfc_dump_module (const char *name, int dump_flag)
|
||||||
filename = (char *) alloca (n);
|
filename = (char *) alloca (n);
|
||||||
strcpy (filename, name);
|
strcpy (filename, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gfc_state_stack->state == COMP_SUBMODULE)
|
||||||
|
strcat (filename, SUBMODULE_EXTENSION);
|
||||||
|
else
|
||||||
strcat (filename, MODULE_EXTENSION);
|
strcat (filename, MODULE_EXTENSION);
|
||||||
|
|
||||||
/* Name of the temporary file used to write the module. */
|
/* Name of the temporary file used to write the module. */
|
||||||
|
|
@ -5974,7 +6023,6 @@ gfc_dump_module (const char *name, int dump_flag)
|
||||||
|
|
||||||
/* Write the module itself. */
|
/* Write the module itself. */
|
||||||
iomode = IO_OUTPUT;
|
iomode = IO_OUTPUT;
|
||||||
module_name = gfc_get_string (name);
|
|
||||||
|
|
||||||
init_pi_tree ();
|
init_pi_tree ();
|
||||||
|
|
||||||
|
|
@ -6705,10 +6753,22 @@ gfc_use_module (gfc_use_list *module)
|
||||||
gfc_warning_now (OPT_Wuse_without_only,
|
gfc_warning_now (OPT_Wuse_without_only,
|
||||||
"USE statement at %C has no ONLY qualifier");
|
"USE statement at %C has no ONLY qualifier");
|
||||||
|
|
||||||
filename = XALLOCAVEC (char, strlen (module_name) + strlen (MODULE_EXTENSION)
|
if (gfc_state_stack->state == COMP_MODULE
|
||||||
+ 1);
|
|| module->submodule_name == NULL
|
||||||
|
|| strcmp (module_name, module->submodule_name) == 0)
|
||||||
|
{
|
||||||
|
filename = XALLOCAVEC (char, strlen (module_name)
|
||||||
|
+ strlen (MODULE_EXTENSION) + 1);
|
||||||
strcpy (filename, module_name);
|
strcpy (filename, module_name);
|
||||||
strcat (filename, MODULE_EXTENSION);
|
strcat (filename, MODULE_EXTENSION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename = XALLOCAVEC (char, strlen (module->submodule_name)
|
||||||
|
+ strlen (SUBMODULE_EXTENSION) + 1);
|
||||||
|
strcpy (filename, module->submodule_name);
|
||||||
|
strcat (filename, SUBMODULE_EXTENSION);
|
||||||
|
}
|
||||||
|
|
||||||
/* First, try to find an non-intrinsic module, unless the USE statement
|
/* First, try to find an non-intrinsic module, unless the USE statement
|
||||||
specified that the module is intrinsic. */
|
specified that the module is intrinsic. */
|
||||||
|
|
|
||||||
|
|
@ -170,3 +170,6 @@
|
||||||
message2 = ""
|
message2 = ""
|
||||||
end subroutine
|
end subroutine
|
||||||
end program
|
end program
|
||||||
|
! { dg-final { cleanup-submodules "foo_interface_son" } }
|
||||||
|
! { dg-final { cleanup-submodules "foo_interface_grandson" } }
|
||||||
|
! { dg-final { cleanup-submodules "foo_interface_daughter" } }
|
||||||
|
|
@ -29,6 +29,19 @@ proc cleanup-modules { modlist } {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Remove files for specified Fortran submodules.
|
||||||
|
proc cleanup-submodules { modlist } {
|
||||||
|
global clean
|
||||||
|
foreach mod [concat $modlist $clean] {
|
||||||
|
set m [string tolower $mod].smod
|
||||||
|
verbose "cleanup-submodule `$m'" 2
|
||||||
|
if [is_remote host] {
|
||||||
|
remote_file host delete $m
|
||||||
|
}
|
||||||
|
remote_file build delete $m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proc keep-modules { modlist } {
|
proc keep-modules { modlist } {
|
||||||
global clean
|
global clean
|
||||||
# if the modlist is empty, keep everything
|
# if the modlist is empty, keep everything
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue