forked from OSchip/llvm-project
[flang] Be more persistent in search for non-intrinsic module file
When a particular module name has been brought into a compilation as an intrinsic module via USE,INTRINSIC, perhaps indirectly via an enclosing USE statement, f18 will resolve later USE statements to it unless they are USE,NON_INTRINSIC. This is not entirely correct -- a bare USE statement for a module name that happens to match that of an intrinsic module should still search the search paths for a non-intrinsic module file of the same name. Differential Revision: https://reviews.llvm.org/D132163
This commit is contained in:
parent
c1a77839cc
commit
dcbfabbeb5
|
@ -928,49 +928,64 @@ Scope *ModFileReader::Read(const SourceName &name,
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
ancestorName = ancestor->GetName().value().ToString();
|
ancestorName = ancestor->GetName().value().ToString();
|
||||||
} else {
|
}
|
||||||
if (!isIntrinsic.value_or(false)) {
|
if (!isIntrinsic.value_or(false) && !ancestor) {
|
||||||
auto it{context_.globalScope().find(name)};
|
// Already present in the symbol table as a usable non-intrinsic module?
|
||||||
if (it != context_.globalScope().end()) {
|
auto it{context_.globalScope().find(name)};
|
||||||
Scope *scope{it->second->scope()};
|
if (it != context_.globalScope().end()) {
|
||||||
if (scope->kind() == Scope::Kind::Module) {
|
Scope *scope{it->second->scope()};
|
||||||
return scope;
|
if (scope->kind() == Scope::Kind::Module) {
|
||||||
} else {
|
return scope;
|
||||||
notAModule = scope->symbol();
|
} else {
|
||||||
// USE, NON_INTRINSIC global name isn't a module?
|
notAModule = scope->symbol();
|
||||||
fatalError = isIntrinsic.has_value();
|
// USE, NON_INTRINSIC global name isn't a module?
|
||||||
}
|
fatalError = isIntrinsic.has_value();
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isIntrinsic.value_or(true)) {
|
|
||||||
auto it{context_.intrinsicModulesScope().find(name)};
|
|
||||||
if (it != context_.intrinsicModulesScope().end()) {
|
|
||||||
return it->second->scope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto path{ModFileName(name, ancestorName, context_.moduleFileSuffix())};
|
||||||
parser::Parsing parsing{context_.allCookedSources()};
|
parser::Parsing parsing{context_.allCookedSources()};
|
||||||
parser::Options options;
|
parser::Options options;
|
||||||
options.isModuleFile = true;
|
options.isModuleFile = true;
|
||||||
options.features.Enable(common::LanguageFeature::BackslashEscapes);
|
options.features.Enable(common::LanguageFeature::BackslashEscapes);
|
||||||
options.features.Enable(common::LanguageFeature::OpenMP);
|
options.features.Enable(common::LanguageFeature::OpenMP);
|
||||||
if (!isIntrinsic.value_or(false) && !notAModule) {
|
if (!isIntrinsic.value_or(false) && !notAModule) {
|
||||||
// Scan non-intrinsic module directories
|
// The search for this module file will scan non-intrinsic module
|
||||||
|
// directories. If a directory is in both the intrinsic and non-intrinsic
|
||||||
|
// directory lists, the intrinsic module directory takes precedence.
|
||||||
options.searchDirectories = context_.searchDirectories();
|
options.searchDirectories = context_.searchDirectories();
|
||||||
// If a directory is in both lists, the intrinsic module directory
|
|
||||||
// takes precedence.
|
|
||||||
for (const auto &dir : context_.intrinsicModuleDirectories()) {
|
for (const auto &dir : context_.intrinsicModuleDirectories()) {
|
||||||
std::remove(options.searchDirectories.begin(),
|
std::remove(options.searchDirectories.begin(),
|
||||||
options.searchDirectories.end(), dir);
|
options.searchDirectories.end(), dir);
|
||||||
}
|
}
|
||||||
options.searchDirectories.insert(options.searchDirectories.begin(), "."s);
|
options.searchDirectories.insert(options.searchDirectories.begin(), "."s);
|
||||||
}
|
}
|
||||||
|
bool foundNonIntrinsicModuleFile{false};
|
||||||
|
if (!isIntrinsic) {
|
||||||
|
std::list<std::string> searchDirs;
|
||||||
|
for (const auto &d : options.searchDirectories) {
|
||||||
|
searchDirs.push_back(d);
|
||||||
|
}
|
||||||
|
foundNonIntrinsicModuleFile =
|
||||||
|
parser::LocateSourceFile(path, searchDirs).has_value();
|
||||||
|
}
|
||||||
|
if (isIntrinsic.value_or(!foundNonIntrinsicModuleFile)) {
|
||||||
|
// Explicitly intrinsic, or not specified and not found in the search
|
||||||
|
// path; see whether it's already in the symbol table as an intrinsic
|
||||||
|
// module.
|
||||||
|
auto it{context_.intrinsicModulesScope().find(name)};
|
||||||
|
if (it != context_.intrinsicModulesScope().end()) {
|
||||||
|
return it->second->scope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We don't have this module in the symbol table yet.
|
||||||
|
// Find its module file and parse it. Define or extend the search
|
||||||
|
// path with intrinsic module directories, if appropriate.
|
||||||
if (isIntrinsic.value_or(true)) {
|
if (isIntrinsic.value_or(true)) {
|
||||||
for (const auto &dir : context_.intrinsicModuleDirectories()) {
|
for (const auto &dir : context_.intrinsicModuleDirectories()) {
|
||||||
options.searchDirectories.push_back(dir);
|
options.searchDirectories.push_back(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto path{ModFileName(name, ancestorName, context_.moduleFileSuffix())};
|
|
||||||
const auto *sourceFile{fatalError ? nullptr : parsing.Prescan(path, options)};
|
const auto *sourceFile{fatalError ? nullptr : parsing.Prescan(path, options)};
|
||||||
if (fatalError || parsing.messages().AnyFatalError()) {
|
if (fatalError || parsing.messages().AnyFatalError()) {
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
|
|
Loading…
Reference in New Issue