[PATCH] Modules fix for relative include paths

John Thompson john.thompson.jtsoftware at gmail.com
Mon Mar 10 14:17:46 PDT 2014


Hi rsmith,

This is a fix for an error that occurs when building a module when relative include paths (-I) are used.

I'm not sure if it's the best solution.

I considered instead saving the header path as given in the module map, such that the headers would be relative to the module map,and using those in the #include directives in the build-module file, but there's no guarantee that the the path to the module map will be among the -I options, so this seemed a better option.

Thanks.
 
-John


http://llvm-reviews.chandlerc.com/D3033

Files:
  include/clang/Lex/HeaderSearch.h
  lib/Frontend/FrontendActions.cpp

Index: include/clang/Lex/HeaderSearch.h
===================================================================
--- include/clang/Lex/HeaderSearch.h
+++ include/clang/Lex/HeaderSearch.h
@@ -253,6 +253,9 @@
   
   FileManager &getFileMgr() const { return FileMgr; }
 
+  /// \brief Get include search paths.
+  std::vector<DirectoryLookup> &getSearchDirs() { return SearchDirs; }
+
   /// \brief Interface for setting the file search paths.
   void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
                       unsigned angledDirIdx, unsigned systemDirIdx,
Index: lib/Frontend/FrontendActions.cpp
===================================================================
--- lib/Frontend/FrontendActions.cpp
+++ lib/Frontend/FrontendActions.cpp
@@ -129,26 +129,42 @@
 }
 
 static void addHeaderInclude(StringRef HeaderName,
+                             std::vector<DirectoryLookup> &IncludePaths,
                              SmallVectorImpl<char> &Includes,
                              const LangOptions &LangOpts,
                              bool IsExternC) {
+  StringRef FilePath(HeaderName);
+  for (std::vector<DirectoryLookup>::iterator I =
+    IncludePaths.begin(), E = IncludePaths.end(); I !=  E; ++I) {
+    StringRef IncludePath(I->getDir()->getName());
+    size_t Offset = IncludePath.size();
+    if (Offset) {
+      if (FilePath.startswith(IncludePath)
+          && ((FilePath[Offset] == '/') || (FilePath[Offset] == '\\'))) {
+        FilePath = FilePath.substr(Offset + 1);
+        break;
+      }
+    }
+  }
   if (IsExternC)
     Includes += "extern \"C\" {\n";
   if (LangOpts.ObjC1)
     Includes += "#import \"";
   else
     Includes += "#include \"";
-  Includes += HeaderName;
+  Includes += FilePath;
   Includes += "\"\n";
   if (IsExternC)
     Includes += "}\n";
 }
 
 static void addHeaderInclude(const FileEntry *Header,
+                             std::vector<DirectoryLookup> &IncludePaths,
                              SmallVectorImpl<char> &Includes,
                              const LangOptions &LangOpts,
                              bool IsExternC) {
-  addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
+  addHeaderInclude(Header->getName(), IncludePaths, Includes, LangOpts,
+    IsExternC);
 }
 
 /// \brief Collect the set of header includes needed to construct the given 
@@ -159,27 +175,30 @@
 /// \param Includes Will be augmented with the set of \#includes or \#imports
 /// needed to load all of the named headers.
 static void collectModuleHeaderIncludes(const LangOptions &LangOpts,
-                                        FileManager &FileMgr,
-                                        ModuleMap &ModMap,
-                                        clang::Module *Module,
-                                        SmallVectorImpl<char> &Includes) {
+    FileManager &FileMgr,
+    ModuleMap &ModMap,
+    std::vector<DirectoryLookup> &IncludePaths,
+    clang::Module *Module,
+    SmallVectorImpl<char> &Includes) {
   // Don't collect any headers for unavailable modules.
   if (!Module->isAvailable())
     return;
 
   // Add includes for each of these headers.
   for (unsigned I = 0, N = Module->NormalHeaders.size(); I != N; ++I) {
     const FileEntry *Header = Module->NormalHeaders[I];
     Module->addTopHeader(Header);
-    addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC);
+    addHeaderInclude(Header, IncludePaths, Includes, LangOpts,
+      Module->IsExternC);
   }
   // Note that Module->PrivateHeaders will not be a TopHeader.
 
   if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
     Module->addTopHeader(UmbrellaHeader);
     if (Module->Parent) {
       // Include the umbrella header for submodules.
-      addHeaderInclude(UmbrellaHeader, Includes, LangOpts, Module->IsExternC);
+      addHeaderInclude(UmbrellaHeader, IncludePaths, Includes, LangOpts,
+        Module->IsExternC);
     }
   } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
     // Add all of the headers we find in this subdirectory.
@@ -205,15 +224,17 @@
       }
       
       // Include this header umbrella header for submodules.
-      addHeaderInclude(Dir->path(), Includes, LangOpts, Module->IsExternC);
+      addHeaderInclude(Dir->path(), IncludePaths, Includes, LangOpts,
+        Module->IsExternC);
     }
   }
   
   // Recurse into submodules.
   for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
                                       SubEnd = Module->submodule_end();
        Sub != SubEnd; ++Sub)
-    collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, Includes);
+    collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, IncludePaths, *Sub,
+      Includes);
 }
 
 bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, 
@@ -281,10 +302,12 @@
   // Collect the set of #includes we need to build the module.
   SmallString<256> HeaderContents;
   if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader())
-    addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
-                     Module->IsExternC);
+    addHeaderInclude(UmbrellaHeader,
+      CI.getPreprocessor().getHeaderSearchInfo().getSearchDirs(),
+      HeaderContents, CI.getLangOpts(), Module->IsExternC);
   collectModuleHeaderIncludes(CI.getLangOpts(), FileMgr,
     CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),
+    CI.getPreprocessor().getHeaderSearchInfo().getSearchDirs(),
     Module, HeaderContents);
 
   llvm::MemoryBuffer *InputBuffer =
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3033.1.patch
Type: text/x-patch
Size: 5684 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140310/4d180a24/attachment.bin>


More information about the cfe-commits mailing list