summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-04-19 13:21:58 (GMT)
committerBrad King <brad.king@kitware.com>2018-04-20 14:57:31 (GMT)
commit402735314ec7fe48ec21e5f4c5b19b6f17682c54 (patch)
tree6ad7b1ccfa99d27779cabaa23095bded497a6cfd /Source
parent62538b2c4c70eeef52886092e24c97a9a7699a00 (diff)
downloadCMake-402735314ec7fe48ec21e5f4c5b19b6f17682c54.zip
CMake-402735314ec7fe48ec21e5f4c5b19b6f17682c54.tar.gz
CMake-402735314ec7fe48ec21e5f4c5b19b6f17682c54.tar.bz2
Fortran: Add support for submodule dependencies
Since commit v3.7.0-rc1~73^2~1 (Fortran: Add support for submodule syntax in dependency scanning, 2016-09-05) we support parsing Fortran sources that use submodule syntax, but it left addition of `.smod` dependencies to future work. Add it now. The syntax submodule (module_name) submodule_name means the current source requires `module_name.mod` and provides `module_name@submodule_name.smod`. The syntax submodule (module_name:submodule_name) nested_submodule_name means the current source requires `module_name@submodule_name.smod` provides `module_name@nested_submodule_name.smod`. Fixes: #17017
Diffstat (limited to 'Source')
-rw-r--r--Source/LexerParser/cmFortranParser.cxx4
-rw-r--r--Source/LexerParser/cmFortranParser.y4
-rw-r--r--Source/cmDependsFortran.cxx7
-rw-r--r--Source/cmFortranParser.h7
-rw-r--r--Source/cmFortranParserImpl.cxx44
5 files changed, 60 insertions, 6 deletions
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 2b3452f..00c8a8a 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -1563,7 +1563,7 @@ yyreduce:
#line 119 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleUse(parser, (yyvsp[-4].string));
+ cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
@@ -1574,7 +1574,7 @@ yyreduce:
#line 125 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleUse(parser, (yyvsp[-6].string));
+ cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
free((yyvsp[-6].string));
free((yyvsp[-4].string));
free((yyvsp[-2].string));
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index acfb40a..5e09248 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -118,13 +118,13 @@ stmt:
}
| SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleUse(parser, $3);
+ cmFortranParser_RuleSubmodule(parser, $3, $5);
free($3);
free($5);
}
| SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleUse(parser, $3);
+ cmFortranParser_RuleSubmoduleNested(parser, $3, $5, $7);
free($3);
free($5);
free($7);
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index da644dd..dbea15a 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -31,6 +31,8 @@ static void cmFortranModuleAppendUpperLower(std::string const& mod,
std::string::size_type ext_len = 0;
if (cmHasLiteralSuffix(mod, ".mod")) {
ext_len = 4;
+ } else if (cmHasLiteralSuffix(mod, ".smod")) {
+ ext_len = 5;
}
std::string const& name = mod.substr(0, mod.size() - ext_len);
std::string const& ext = mod.substr(mod.size() - ext_len);
@@ -283,7 +285,8 @@ void cmDependsFortran::MatchRemoteModules(std::istream& fin,
if (line[0] == ' ') {
if (doing_provides) {
std::string mod = line;
- if (!cmHasLiteralSuffix(mod, ".mod")) {
+ if (!cmHasLiteralSuffix(mod, ".mod") &&
+ !cmHasLiteralSuffix(mod, ".smod")) {
// Support fortran.internal files left by older versions of CMake.
// They do not include the ".mod" extension.
mod += ".mod";
@@ -486,7 +489,7 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
if (args.size() >= 5) {
compilerId = args[4];
}
- if (!cmHasLiteralSuffix(mod, ".mod")) {
+ if (!cmHasLiteralSuffix(mod, ".mod") && !cmHasLiteralSuffix(mod, ".smod")) {
// Support depend.make files left by older versions of CMake.
// They do not include the ".mod" extension.
mod += ".mod";
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index 5a0bb09..efcd100 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -45,6 +45,13 @@ void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
void cmFortranParser_RuleInclude(cmFortranParser* parser, const char* name);
void cmFortranParser_RuleModule(cmFortranParser* parser,
const char* module_name);
+void cmFortranParser_RuleSubmodule(cmFortranParser* parser,
+ const char* module_name,
+ const char* submodule_name);
+void cmFortranParser_RuleSubmoduleNested(cmFortranParser* parser,
+ const char* module_name,
+ const char* submodule_name,
+ const char* nested_submodule_name);
void cmFortranParser_RuleDefine(cmFortranParser* parser, const char* name);
void cmFortranParser_RuleUndef(cmFortranParser* parser, const char* name);
void cmFortranParser_RuleIfdef(cmFortranParser* parser, const char* name);
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index e4a6ac7..01cbb78 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -245,6 +245,50 @@ void cmFortranParser_RuleModule(cmFortranParser* parser,
}
}
+void cmFortranParser_RuleSubmodule(cmFortranParser* parser,
+ const char* module_name,
+ const char* submodule_name)
+{
+ if (parser->InPPFalseBranch) {
+ return;
+ }
+
+ // syntax: "submodule (module_name) submodule_name"
+ // requires: "module_name.mod"
+ // provides: "module_name@submodule_name.smod"
+ //
+ // FIXME: Some compilers split the submodule part of a module into a
+ // separate "module_name.smod" file. Whether it is generated or
+ // not depends on conditions more subtle than we currently detect.
+ // For now we depend directly on "module_name.mod".
+
+ std::string const& mod_name = cmSystemTools::LowerCase(module_name);
+ std::string const& sub_name = cmSystemTools::LowerCase(submodule_name);
+ parser->Info.Requires.insert(mod_name + ".mod");
+ parser->Info.Provides.insert(mod_name + "@" + sub_name + ".smod");
+}
+
+void cmFortranParser_RuleSubmoduleNested(cmFortranParser* parser,
+ const char* module_name,
+ const char* submodule_name,
+ const char* nested_submodule_name)
+{
+ if (parser->InPPFalseBranch) {
+ return;
+ }
+
+ // syntax: "submodule (module_name:submodule_name) nested_submodule_name"
+ // requires: "module_name@submodule_name.smod"
+ // provides: "module_name@nested_submodule_name.smod"
+
+ std::string const& mod_name = cmSystemTools::LowerCase(module_name);
+ std::string const& sub_name = cmSystemTools::LowerCase(submodule_name);
+ std::string const& nest_name =
+ cmSystemTools::LowerCase(nested_submodule_name);
+ parser->Info.Requires.insert(mod_name + "@" + sub_name + ".smod");
+ parser->Info.Provides.insert(mod_name + "@" + nest_name + ".smod");
+}
+
void cmFortranParser_RuleDefine(cmFortranParser* parser, const char* macro)
{
if (!parser->InPPFalseBranch) {