diff options
Diffstat (limited to 'clang/lib/Frontend/ModuleDependencyCollector.cpp')
-rw-r--r-- | clang/lib/Frontend/ModuleDependencyCollector.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/Frontend/ModuleDependencyCollector.cpp b/clang/lib/Frontend/ModuleDependencyCollector.cpp index b58e1bfac67..ca11f9b863b 100644 --- a/clang/lib/Frontend/ModuleDependencyCollector.cpp +++ b/clang/lib/Frontend/ModuleDependencyCollector.cpp @@ -48,6 +48,34 @@ struct ModuleDependencyMMCallbacks : public ModuleMapCallbacks { if (llvm::sys::path::is_absolute(HeaderPath)) Collector.addFile(HeaderPath); } + void moduleMapAddUmbrellaHeader(FileManager *FileMgr, + const FileEntry *Header) override { + StringRef HeaderFilename = Header->getName(); + moduleMapAddHeader(HeaderFilename); + // The FileManager can find and cache the symbolic link for a framework + // header before its real path, this means a module can have some of its + // headers to use other paths. Although this is usually not a problem, it's + // inconsistent, and not collecting the original path header leads to + // umbrella clashes while rebuilding modules in the crash reproducer. For + // example: + // ApplicationServices.framework/Frameworks/ImageIO.framework/ImageIO.h + // instead of: + // ImageIO.framework/ImageIO.h + // + // FIXME: this shouldn't be necessary once we have FileName instances + // around instead of FileEntry ones. For now, make sure we collect all + // that we need for the reproducer to work correctly. + StringRef UmbreallDirFromHeader = + llvm::sys::path::parent_path(HeaderFilename); + StringRef UmbrellaDir = Header->getDir()->getName(); + if (!UmbrellaDir.equals(UmbreallDirFromHeader)) { + SmallString<128> AltHeaderFilename; + llvm::sys::path::append(AltHeaderFilename, UmbrellaDir, + llvm::sys::path::filename(HeaderFilename)); + if (FileMgr->getFile(AltHeaderFilename)) + moduleMapAddHeader(AltHeaderFilename); + } + } }; } |