r203528 - If a module map is found in a relative -I path, convert the filenames within it

Richard Smith richard-llvm at metafoo.co.uk
Mon Mar 10 19:02:47 PDT 2014


Author: rsmith
Date: Mon Mar 10 21:02:47 2014
New Revision: 203528

URL: http://llvm.org/viewvc/llvm-project?rev=203528&view=rev
Log:
If a module map is found in a relative -I path, convert the filenames within it
to absolute paths when building the includes file for the module. Without this,
the module build would fail, because the relative paths we were using are not
necessarily relative to a directory in our include path.

Added:
    cfe/trunk/test/Modules/Inputs/include-relative/
    cfe/trunk/test/Modules/Inputs/include-relative/a.h
    cfe/trunk/test/Modules/Inputs/include-relative/module.map
    cfe/trunk/test/Modules/include-relative.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
    cfe/trunk/lib/Frontend/FrontendActions.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=203528&r1=203527&r2=203528&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Mon Mar 10 21:02:47 2014
@@ -152,6 +152,8 @@ def err_module_unavailable : Error<
   "module '%0' %select{is incompatible with|requires}1 feature '%2'">;
 def err_module_header_missing : Error<
   "%select{|umbrella }0header '%1' not found">;
+def err_module_cannot_create_includes : Error<
+  "cannot create includes file for module %0: %1">;
 def warn_module_config_macro_undef : Warning<
   "%select{definition|#undef}0 of configuration macro '%1' has no effect on "
   "the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line "

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=203528&r1=203527&r2=203528&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Mon Mar 10 21:02:47 2014
@@ -128,27 +128,38 @@ operator+=(SmallVectorImpl<char> &Includ
   return Includes;
 }
 
-static void addHeaderInclude(StringRef HeaderName,
-                             SmallVectorImpl<char> &Includes,
-                             const LangOptions &LangOpts,
-                             bool IsExternC) {
+static llvm::error_code addHeaderInclude(StringRef HeaderName,
+                                         SmallVectorImpl<char> &Includes,
+                                         const LangOptions &LangOpts,
+                                         bool IsExternC) {
   if (IsExternC && LangOpts.CPlusPlus)
     Includes += "extern \"C\" {\n";
   if (LangOpts.ObjC1)
     Includes += "#import \"";
   else
     Includes += "#include \"";
-  Includes += HeaderName;
+  // Use an absolute path for the include; there's no reason to think that
+  // a relative path will work (. might not be on our include path) or that
+  // it will find the same file.
+  if (llvm::sys::path::is_absolute(HeaderName)) {
+    Includes += HeaderName;
+  } else {
+    SmallString<256> Header = HeaderName;
+    if (llvm::error_code Err = llvm::sys::fs::make_absolute(Header))
+      return Err;
+    Includes += Header;
+  }
   Includes += "\"\n";
   if (IsExternC && LangOpts.CPlusPlus)
     Includes += "}\n";
+  return llvm::error_code::success();
 }
 
-static void addHeaderInclude(const FileEntry *Header,
-                             SmallVectorImpl<char> &Includes,
-                             const LangOptions &LangOpts,
-                             bool IsExternC) {
-  addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
+static llvm::error_code addHeaderInclude(const FileEntry *Header,
+                                         SmallVectorImpl<char> &Includes,
+                                         const LangOptions &LangOpts,
+                                         bool IsExternC) {
+  return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
 }
 
 /// \brief Collect the set of header includes needed to construct the given 
@@ -158,20 +169,21 @@ static void addHeaderInclude(const FileE
 ///
 /// \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) {
+static llvm::error_code
+collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
+                            ModuleMap &ModMap, clang::Module *Module,
+                            SmallVectorImpl<char> &Includes) {
   // Don't collect any headers for unavailable modules.
   if (!Module->isAvailable())
-    return;
+    return llvm::error_code::success();
 
   // 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);
+    if (llvm::error_code Err =
+            addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC))
+      return Err;
   }
   // Note that Module->PrivateHeaders will not be a TopHeader.
 
@@ -179,7 +191,9 @@ static void collectModuleHeaderIncludes(
     Module->addTopHeader(UmbrellaHeader);
     if (Module->Parent) {
       // Include the umbrella header for submodules.
-      addHeaderInclude(UmbrellaHeader, Includes, LangOpts, Module->IsExternC);
+      if (llvm::error_code Err = addHeaderInclude(UmbrellaHeader, Includes,
+                                                  LangOpts, Module->IsExternC))
+        return Err;
     }
   } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
     // Add all of the headers we find in this subdirectory.
@@ -204,16 +218,25 @@ static void collectModuleHeaderIncludes(
         Module->addTopHeader(Header);
       }
       
-      // Include this header umbrella header for submodules.
-      addHeaderInclude(Dir->path(), Includes, LangOpts, Module->IsExternC);
+      // Include this header as part of the umbrella directory.
+      if (llvm::error_code Err = addHeaderInclude(Dir->path(), Includes,
+                                                  LangOpts, Module->IsExternC))
+        return Err;
     }
+
+    if (EC)
+      return EC;
   }
   
   // 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);
+    if (llvm::error_code Err = collectModuleHeaderIncludes(
+            LangOpts, FileMgr, ModMap, *Sub, Includes))
+      return Err;
+
+  return llvm::error_code::success();
 }
 
 bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, 
@@ -280,12 +303,21 @@ bool GenerateModuleAction::BeginSourceFi
 
   // Collect the set of #includes we need to build the module.
   SmallString<256> HeaderContents;
+  llvm::error_code Err = llvm::error_code::success();
   if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader())
-    addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
-                     Module->IsExternC);
-  collectModuleHeaderIncludes(CI.getLangOpts(), FileMgr,
-    CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),
-    Module, HeaderContents);
+    Err = addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
+                           Module->IsExternC);
+  if (!Err)
+    Err = collectModuleHeaderIncludes(
+        CI.getLangOpts(), FileMgr,
+        CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), Module,
+        HeaderContents);
+
+  if (Err) {
+    CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
+      << Module->getFullModuleName() << Err.message();
+    return false;
+  }
 
   llvm::MemoryBuffer *InputBuffer =
       llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,

Added: cfe/trunk/test/Modules/Inputs/include-relative/a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/include-relative/a.h?rev=203528&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/include-relative/a.h (added)
+++ cfe/trunk/test/Modules/Inputs/include-relative/a.h Mon Mar 10 21:02:47 2014
@@ -0,0 +1 @@
+extern int n;

Added: cfe/trunk/test/Modules/Inputs/include-relative/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/include-relative/module.map?rev=203528&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/include-relative/module.map (added)
+++ cfe/trunk/test/Modules/Inputs/include-relative/module.map Mon Mar 10 21:02:47 2014
@@ -0,0 +1 @@
+module a { header "a.h" }

Added: cfe/trunk/test/Modules/include-relative.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/include-relative.c?rev=203528&view=auto
==============================================================================
--- cfe/trunk/test/Modules/include-relative.c (added)
+++ cfe/trunk/test/Modules/include-relative.c Mon Mar 10 21:02:47 2014
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp -r %S/Inputs/include-relative %t/include-relative
+// RUN: cd %t
+// RUN: %clang_cc1 -fmodules -x c -verify -fmodules-cache-path=%t -I include-relative %s
+
+// expected-no-diagnostics
+
+#include "a.h"
+
+int f() { return n; }





More information about the cfe-commits mailing list