[modules] When diagnosing errors in module map files found by 'extern module' declarations, show how we got to that module map file.
llvm-svn: 242105
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 2b18a7d..0b03c4a 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -452,9 +452,13 @@
/// \param HomeDir The directory in which relative paths within this module
/// map file will be resolved.
///
+ /// \param ExternModuleLoc The location of the "extern module" declaration
+ /// that caused us to load this module map file, if any.
+ ///
/// \returns true if an error occurred, false otherwise.
bool parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *HomeDir);
+ const DirectoryEntry *HomeDir,
+ SourceLocation ExternModuleLoc = SourceLocation());
/// \brief Dump the contents of the module map, for debugging purposes.
void dump();
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 6faae81..96d3e4b 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -1528,7 +1528,7 @@
/// 'extern' 'module' module-id string-literal
void ModuleMapParser::parseExternModuleDecl() {
assert(Tok.is(MMToken::ExternKeyword));
- consumeToken(); // 'extern' keyword
+ SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
// Parse 'module' keyword.
if (!Tok.is(MMToken::ModuleKeyword)) {
@@ -1567,7 +1567,7 @@
File, /*IsSystem=*/false,
Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
? Directory
- : File->getDir());
+ : File->getDir(), ExternLoc);
}
/// \brief Parse a requires declaration.
@@ -2319,7 +2319,8 @@
}
bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *Dir) {
+ const DirectoryEntry *Dir,
+ SourceLocation ExternModuleLoc) {
llvm::DenseMap<const FileEntry *, bool>::iterator Known
= ParsedModuleMap.find(File);
if (Known != ParsedModuleMap.end())
@@ -2327,7 +2328,7 @@
assert(Target && "Missing target information");
auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
- FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
+ FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
if (!Buffer)
return ParsedModuleMap[File] = true;
diff --git a/clang/test/Modules/Inputs/diagnostics-aux.modulemap b/clang/test/Modules/Inputs/diagnostics-aux.modulemap
index d067d04..2c6ecb9 100644
--- a/clang/test/Modules/Inputs/diagnostics-aux.modulemap
+++ b/clang/test/Modules/Inputs/diagnostics-aux.modulemap
@@ -1 +1,3 @@
module foo {}
+
+extern module external "diagnostics-aux-2.modulemap"
diff --git a/clang/test/Modules/diagnostics.modulemap b/clang/test/Modules/diagnostics.modulemap
index aef094d..3b5b6a5 100644
--- a/clang/test/Modules/diagnostics.modulemap
+++ b/clang/test/Modules/diagnostics.modulemap
@@ -1,5 +1,8 @@
// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/diagnostics-aux.modulemap -fmodule-map-file=%s -fsyntax-only -x c++ /dev/null 2>&1 | FileCheck %s
+// CHECK: In file included from {{.*}}diagnostics-aux.modulemap:3:
+// CHECK: diagnostics-aux-2.modulemap:2:3: error: expected
+
// PR22299: Ensure we can produce diagnostics for duplicate modules from -fmodule-map-file=.
//
// CHECK: diagnostics.modulemap:[[@LINE+2]]:8: error: redefinition of module 'foo'