summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-03-11 02:02:47 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-03-11 02:02:47 +0000
commit723928c7dcc79f7b19eb602fe52baae480b85a54 (patch)
tree509f01c8d5a8a45ef4b38a50814b32e8df88a4aa
parent0211714ecb22d6e6f13a0c6681fb88b9365004dc (diff)
downloadbcm5719-llvm-723928c7dcc79f7b19eb602fe52baae480b85a54.tar.gz
bcm5719-llvm-723928c7dcc79f7b19eb602fe52baae480b85a54.zip
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. llvm-svn: 203528
-rw-r--r--clang/include/clang/Basic/DiagnosticFrontendKinds.td2
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp84
-rw-r--r--clang/test/Modules/Inputs/include-relative/a.h1
-rw-r--r--clang/test/Modules/Inputs/include-relative/module.map1
-rw-r--r--clang/test/Modules/include-relative.c11
5 files changed, 73 insertions, 26 deletions
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 41a83a0b8ed..32c824a9302 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -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 "
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index b41da6da5c7..786fadb2fe6 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -128,27 +128,38 @@ operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
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 FileEntry *Header,
///
/// \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(const LangOptions &LangOpts,
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(const LangOptions &LangOpts,
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::BeginSourceFileAction(CompilerInstance &CI,
// 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,
diff --git a/clang/test/Modules/Inputs/include-relative/a.h b/clang/test/Modules/Inputs/include-relative/a.h
new file mode 100644
index 00000000000..b95284b323b
--- /dev/null
+++ b/clang/test/Modules/Inputs/include-relative/a.h
@@ -0,0 +1 @@
+extern int n;
diff --git a/clang/test/Modules/Inputs/include-relative/module.map b/clang/test/Modules/Inputs/include-relative/module.map
new file mode 100644
index 00000000000..bb00c840ce3
--- /dev/null
+++ b/clang/test/Modules/Inputs/include-relative/module.map
@@ -0,0 +1 @@
+module a { header "a.h" }
diff --git a/clang/test/Modules/include-relative.c b/clang/test/Modules/include-relative.c
new file mode 100644
index 00000000000..264df5f3189
--- /dev/null
+++ b/clang/test/Modules/include-relative.c
@@ -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; }
OpenPOWER on IntegriCloud