diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-03-11 02:02:47 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-03-11 02:02:47 +0000 |
commit | 723928c7dcc79f7b19eb602fe52baae480b85a54 (patch) | |
tree | 509f01c8d5a8a45ef4b38a50814b32e8df88a4aa | |
parent | 0211714ecb22d6e6f13a0c6681fb88b9365004dc (diff) | |
download | bcm5719-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.td | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 84 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/include-relative/a.h | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/include-relative/module.map | 1 | ||||
-rw-r--r-- | clang/test/Modules/include-relative.c | 11 |
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; } |