[modules] When diagnosing errors in module map files found by 'extern module' declara...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 Jul 2015 02:06:01 +0000 (02:06 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 Jul 2015 02:06:01 +0000 (02:06 +0000)
llvm-svn: 242105

clang/include/clang/Lex/ModuleMap.h
clang/lib/Lex/ModuleMap.cpp
clang/test/Modules/Inputs/diagnostics-aux.modulemap
clang/test/Modules/diagnostics.modulemap

index 2b18a7d..0b03c4a 100644 (file)
@@ -452,9 +452,13 @@ public:
   /// \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();
index 6faae81..96d3e4b 100644 (file)
@@ -1528,7 +1528,7 @@ void ModuleMapParser::parseModuleDecl() {
 ///     '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 @@ void ModuleMapParser::parseExternModuleDecl() {
         File, /*IsSystem=*/false,
         Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
             ? Directory
-            : File->getDir());
+            : File->getDir(), ExternLoc);
 }
 
 /// \brief Parse a requires declaration.
@@ -2319,7 +2319,8 @@ bool ModuleMapParser::parseModuleMapFile() {
 }
 
 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 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
 
   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;
index aef094d..3b5b6a5 100644 (file)
@@ -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'