[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