r203005 - If a #include finds a file relative to the current file, don't forget to check

Richard Smith richard-llvm at metafoo.co.uk
Wed Mar 5 12:51:45 PST 2014


Author: rsmith
Date: Wed Mar  5 14:51:45 2014
New Revision: 203005

URL: http://llvm.org/viewvc/llvm-project?rev=203005&view=rev
Log:
If a #include finds a file relative to the current file, don't forget to check
whether it's part of a module.

Added:
    cfe/trunk/test/Modules/Inputs/recursive1.h
    cfe/trunk/test/Modules/Inputs/recursive2.h
    cfe/trunk/test/Modules/recursive.c
Modified:
    cfe/trunk/lib/Lex/HeaderSearch.cpp
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/Modules/submodules.cpp

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=203005&r1=203004&r2=203005&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Wed Mar  5 14:51:45 2014
@@ -219,6 +219,32 @@ const char *DirectoryLookup::getName() c
   return getHeaderMap()->getFileName();
 }
 
+static const FileEntry *
+getFileAndSuggestModule(HeaderSearch &HS, StringRef FileName,
+                        const DirectoryEntry *Dir, bool IsSystemHeaderDir,
+                        ModuleMap::KnownHeader *SuggestedModule) {
+  // If we have a module map that might map this header, load it and
+  // check whether we'll have a suggestion for a module.
+  HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir);
+  if (SuggestedModule) {
+    const FileEntry *File = HS.getFileMgr().getFile(FileName,
+                                                    /*OpenFile=*/false);
+    if (File) {
+      // If there is a module that corresponds to this header, suggest it.
+      *SuggestedModule = HS.findModuleForHeader(File);
+
+      // FIXME: This appears to be a no-op. We loaded the module map for this
+      // directory at the start of this function.
+      if (!SuggestedModule->getModule() &&
+          HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir))
+        *SuggestedModule = HS.findModuleForHeader(File);
+    }
+
+    return File;
+  }
+
+  return HS.getFileMgr().getFile(FileName, /*openFile=*/true);
+}
 
 /// LookupFile - Lookup the specified file in this search path, returning it
 /// if it exists or returning null if not.
@@ -246,25 +272,10 @@ const FileEntry *DirectoryLookup::Lookup
       RelativePath->clear();
       RelativePath->append(Filename.begin(), Filename.end());
     }
-    
-    // If we have a module map that might map this header, load it and
-    // check whether we'll have a suggestion for a module.
-    HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory());
-    if (SuggestedModule) {
-      const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(),
-                                                      /*openFile=*/false);
-      if (!File)
-        return File;
-      
-      // If there is a module that corresponds to this header, suggest it.
-      *SuggestedModule = HS.findModuleForHeader(File);
-      if (!SuggestedModule->getModule() &&
-          HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory()))
-        *SuggestedModule = HS.findModuleForHeader(File);
-      return File;
-    }
-    
-    return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true);
+
+    return getFileAndSuggestModule(HS, TmpDir.str(), getDir(),
+                                   isSystemHeaderDirectory(),
+                                   SuggestedModule);
   }
 
   if (isFramework())
@@ -573,6 +584,7 @@ const FileEntry *HeaderSearch::LookupFil
 
   // This is the header that MSVC's header search would have found.
   const FileEntry *MSFE = 0;
+  ModuleMap::KnownHeader MSSuggestedModule;
 
   // Unless disabled, check to see if the file is in the #includer's
   // directory.  This cannot be based on CurDir, because each includer could be
@@ -590,15 +602,18 @@ const FileEntry *HeaderSearch::LookupFil
       TmpDir = Includer->getDir()->getName();
       TmpDir.push_back('/');
       TmpDir.append(Filename.begin(), Filename.end());
+
+      HeaderFileInfo &FromHFI = getFileInfo(Includer);
       if (const FileEntry *FE =
-              FileMgr.getFile(TmpDir.str(), /*openFile=*/true)) {
+              getFileAndSuggestModule(*this, TmpDir.str(), Includer->getDir(),
+                                      FromHFI.DirInfo != SrcMgr::C_User,
+                                      SuggestedModule)) {
         // Leave CurDir unset.
         // This file is a system header or C++ unfriendly if the old file is.
         //
         // Note that we only use one of FromHFI/ToHFI at once, due to potential
         // reallocation of the underlying vector potentially making the first
         // reference binding dangling.
-        HeaderFileInfo &FromHFI = getFileInfo(Includer);
         unsigned DirInfo = FromHFI.DirInfo;
         bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
         StringRef Framework = FromHFI.Framework;
@@ -629,6 +644,10 @@ const FileEntry *HeaderSearch::LookupFil
           return FE;
         } else {
           MSFE = FE;
+          if (SuggestedModule) {
+            MSSuggestedModule = *SuggestedModule;
+            *SuggestedModule = ModuleMap::KnownHeader();
+          }
           break;
         }
       }
@@ -709,8 +728,11 @@ const FileEntry *HeaderSearch::LookupFil
       }
     }
 
-    if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc))
+    if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
+      if (SuggestedModule)
+        *SuggestedModule = MSSuggestedModule;
       return MSFE;
+    }
 
     // Remember this location for the next lookup we do.
     CacheLookup.second = i;
@@ -734,19 +756,26 @@ const FileEntry *HeaderSearch::LookupFil
           ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir,
           Includers.front(), SearchPath, RelativePath, SuggestedModule);
 
-      if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc))
+      if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
+        if (SuggestedModule)
+          *SuggestedModule = MSSuggestedModule;
         return MSFE;
+      }
 
       std::pair<unsigned, unsigned> &CacheLookup 
         = LookupFileCache.GetOrCreateValue(Filename).getValue();
       CacheLookup.second
         = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second;
+      // FIXME: SuggestedModule.
       return FE;
     }
   }
 
-  if (checkMSVCHeaderSearch(Diags, MSFE, 0, IncludeLoc))
+  if (checkMSVCHeaderSearch(Diags, MSFE, 0, IncludeLoc)) {
+    if (SuggestedModule)
+      *SuggestedModule = MSSuggestedModule;
     return MSFE;
+  }
 
   // Otherwise, didn't find it. Remember we didn't find this.
   CacheLookup.second = SearchDirs.size();

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=203005&r1=203004&r2=203005&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Wed Mar  5 14:51:45 2014
@@ -297,6 +297,8 @@ ModuleMap::findModuleForHeader(const Fil
       Result = *I;
       // If 'File' is a public header of this module, this is as good as we
       // are going to get.
+      // FIXME: If we have a RequestingModule, we should prefer the header from
+      // that module.
       if (I->getRole() == ModuleMap::NormalHeader)
         break;
     }

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=203005&r1=203004&r2=203005&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Wed Mar  5 14:51:45 2014
@@ -290,3 +290,9 @@ module recursive_visibility_b {
 module recursive_visibility_c {
   header "recursive_visibility_c.h"
 }
+module recursive1 {
+  header "recursive1.h"
+}
+module recursive2 {
+  header "recursive2.h"
+}

Added: cfe/trunk/test/Modules/Inputs/recursive1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/recursive1.h?rev=203005&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/recursive1.h (added)
+++ cfe/trunk/test/Modules/Inputs/recursive1.h Wed Mar  5 14:51:45 2014
@@ -0,0 +1 @@
+#include "recursive2.h"

Added: cfe/trunk/test/Modules/Inputs/recursive2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/recursive2.h?rev=203005&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/recursive2.h (added)
+++ cfe/trunk/test/Modules/Inputs/recursive2.h Wed Mar  5 14:51:45 2014
@@ -0,0 +1 @@
+#include "recursive1.h"

Added: cfe/trunk/test/Modules/recursive.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/recursive.c?rev=203005&view=auto
==============================================================================
--- cfe/trunk/test/Modules/recursive.c (added)
+++ cfe/trunk/test/Modules/recursive.c Wed Mar  5 14:51:45 2014
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s 2>&1 | FileCheck %s
+#include "recursive1.h"
+
+// FIXME: rm -rf %t
+// FIXME: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=recursive1 %S/Inputs/module.map 2>&1 | FileCheck %s
+
+// CHECK:      While building module 'recursive1'{{( imported from .*/recursive.c:3)?}}:
+// CHECK-NEXT: While building module 'recursive2' imported from {{.*}}Inputs/recursive1.h:1:
+// CHECK-NEXT: In file included from <module-includes>:1:
+// CHECK-NEXT: recursive2.h:1:10: fatal error: cyclic dependency in module 'recursive1': recursive1 -> recursive2 -> recursive1

Modified: cfe/trunk/test/Modules/submodules.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/submodules.cpp?rev=203005&r1=203004&r2=203005&view=diff
==============================================================================
--- cfe/trunk/test/Modules/submodules.cpp (original)
+++ cfe/trunk/test/Modules/submodules.cpp Wed Mar  5 14:51:45 2014
@@ -31,9 +31,7 @@ hash_map<int, float> ints_to_floats2;
 extern MyTypeA import_self_test_a; // expected-error {{must be imported from module 'import_self.a'}}
 // expected-note at import-self-a.h:1 {{here}}
 extern MyTypeC import_self_test_c;
-// FIXME: This should be valid; import_self.b re-exports import_self.d.
-extern MyTypeD import_self_test_d; // expected-error {{must be imported from module 'import_self.d'}}
-// expected-note at import-self-d.h:1 {{here}}
+extern MyTypeD import_self_test_d;
 
 // expected-error at Inputs/submodules/module.map:15{{header 'missing.h' not found}}
 @import missing_headers.missing;





More information about the cfe-commits mailing list