summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/FrontendActions.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-12-02 00:08:08 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-12-02 00:08:08 +0000
commit3c1a41ad9969ae4e3353f5984d66af85ce56cf9a (patch)
treef19e3452dbc34c152accbcee5057286a353da704 /clang/lib/Frontend/FrontendActions.cpp
parent4cdf4eba74df1c2a679931716fc630fd484bdb3c (diff)
downloadbcm5719-llvm-3c1a41ad9969ae4e3353f5984d66af85ce56cf9a.tar.gz
bcm5719-llvm-3c1a41ad9969ae4e3353f5984d66af85ce56cf9a.zip
[modules] Track how 'header' directives were written in module map files,
rather than trying to extract this information from the FileEntry after the fact. This has a number of beneficial effects. For instance, diagnostic messages for failed module builds give a path relative to the "module root" rather than an absolute file path, and the contents of the module includes file is no longer dependent on what files the including TU happened to inspect prior to triggering the module build. llvm-svn: 223095
Diffstat (limited to 'clang/lib/Frontend/FrontendActions.cpp')
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp71
1 files changed, 43 insertions, 28 deletions
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 6a2ac60570d..701ef026d49 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -142,17 +142,9 @@ static std::error_code addHeaderInclude(StringRef HeaderName,
Includes += "#import \"";
else
Includes += "#include \"";
- // 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 (std::error_code Err = llvm::sys::fs::make_absolute(Header))
- return Err;
- Includes += Header;
- }
+
+ Includes += HeaderName;
+
Includes += "\"\n";
if (IsExternC && LangOpts.CPlusPlus)
Includes += "}\n";
@@ -163,7 +155,16 @@ static std::error_code addHeaderInclude(const FileEntry *Header,
SmallVectorImpl<char> &Includes,
const LangOptions &LangOpts,
bool IsExternC) {
- return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
+ // Use an absolute path if we don't have a filename as written in the module
+ // map file; this ensures that we will identify the right file independent of
+ // header search paths.
+ if (llvm::sys::path::is_absolute(Header->getName()))
+ return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
+
+ SmallString<256> AbsName(Header->getName());
+ if (std::error_code Err = llvm::sys::fs::make_absolute(AbsName))
+ return Err;
+ return addHeaderInclude(AbsName, Includes, LangOpts, IsExternC);
}
/// \brief Collect the set of header includes needed to construct the given
@@ -182,16 +183,20 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
return std::error_code();
// 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);
- if (std::error_code Err =
- addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC))
+ for (Module::Header &H : Module->Headers[Module::HK_Normal]) {
+ Module->addTopHeader(H.Entry);
+ // Use the path as specified in the module map file. We'll look for this
+ // file relative to the module build directory (the directory containing
+ // the module map file) so this will find the same file that we found
+ // while parsing the module map.
+ if (std::error_code Err = addHeaderInclude(H.NameAsWritten, Includes,
+ LangOpts, Module->IsExternC))
return Err;
}
// Note that Module->PrivateHeaders will not be a TopHeader.
if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
+ // FIXME: Track the name as written here.
Module->addTopHeader(UmbrellaHeader);
if (Module->Parent) {
// Include the umbrella header for submodules.
@@ -213,25 +218,30 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
.Cases(".h", ".H", ".hh", ".hpp", true)
.Default(false))
continue;
-
+
+ const FileEntry *Header = FileMgr.getFile(Dir->path());
+ // FIXME: This shouldn't happen unless there is a file system race. Is
+ // that worth diagnosing?
+ if (!Header)
+ continue;
+
// If this header is marked 'unavailable' in this module, don't include
// it.
- if (const FileEntry *Header = FileMgr.getFile(Dir->path())) {
- if (ModMap.isHeaderUnavailableInModule(Header, Module))
- continue;
- Module->addTopHeader(Header);
- }
-
+ if (ModMap.isHeaderUnavailableInModule(Header, Module))
+ continue;
+
// Include this header as part of the umbrella directory.
- if (std::error_code Err = addHeaderInclude(Dir->path(), Includes,
- LangOpts, Module->IsExternC))
+ // FIXME: Track the name as written through to here.
+ Module->addTopHeader(Header);
+ if (std::error_code Err =
+ addHeaderInclude(Header, 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();
@@ -288,7 +298,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
// Check whether we can build this module at all.
clang::Module::Requirement Requirement;
- clang::Module::HeaderDirective MissingHeader;
+ clang::Module::UnresolvedHeaderDirective MissingHeader;
if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
MissingHeader)) {
if (MissingHeader.FileNameLoc.isValid()) {
@@ -317,6 +327,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
SmallString<256> HeaderContents;
std::error_code Err = std::error_code();
if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader())
+ // FIXME: Track the file name as written.
Err = addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
Module->IsExternC);
if (!Err)
@@ -331,6 +342,10 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
return false;
}
+ // Inform the preprocessor that includes from within the input buffer should
+ // be resolved relative to the build directory of the module map file.
+ CI.getPreprocessor().setMainFileDir(Module->Directory);
+
std::unique_ptr<llvm::MemoryBuffer> InputBuffer =
llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
Module::getModuleInputBufferName());
OpenPOWER on IntegriCloud