diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -695,6 +695,9 @@ "no module named '%0' visible from '%1'">; def err_mmap_missing_module_qualified : Error< "no module named '%0' in '%1'">; +def err_mmap_missing_parent_module: Error< + "no module named '%0' %select{found|in '%2'}1, " + "parent module must be defined before the submodule">; def err_mmap_top_level_inferred_submodule : Error< "only submodules and framework modules may be inferred with wildcard syntax">; def err_mmap_inferred_no_umbrella : Error< diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -1903,18 +1903,16 @@ continue; } - if (ActiveModule) { - Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) - << Id[I].first - << ActiveModule->getTopLevelModule()->getFullModuleName(); - } else { - Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); - } + Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module) + << Id[I].first << (ActiveModule != nullptr) + << (ActiveModule + ? ActiveModule->getTopLevelModule()->getFullModuleName() + : ""); HadError = true; - return; } - if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { + if (TopLevelModule && + ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && "submodule defined in same file as 'module *' that allowed its " "top-level module"); diff --git a/clang/test/Modules/diagnostics.modulemap b/clang/test/Modules/diagnostics.modulemap --- a/clang/test/Modules/diagnostics.modulemap +++ b/clang/test/Modules/diagnostics.modulemap @@ -28,3 +28,9 @@ header "quux.h" { size 1 mtime 2 } header "no_attrs.h" {} } + +// CHECK: diagnostics.modulemap:[[@LINE+1]]:8: error: no module named 'unknown' found, parent module must be defined before the submodule +module unknown.submodule {} +module known_top_level {} +// CHECK: diagnostics.modulemap:[[@LINE+1]]:24: error: no module named 'unknown' in 'known_top_level', parent module must be defined before the submodule +module known_top_level.unknown.submodule {}