diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 5304311ef619..5c9a9b4fefbb 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -26,6 +26,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include using namespace clang; Module::ExportDecl @@ -343,9 +344,37 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, Dir != DirEnd && !EC; Dir.increment(EC)) { if (!StringRef(Dir->path()).endswith(".framework")) continue; - + if (const DirectoryEntry *SubframeworkDir = FileMgr.getDirectory(Dir->path())) { + // Note: as an egregious but useful hack, we use the real path here and + // check whether it is actually a subdirectory of the parent directory. + // This will not be the case if the 'subframework' is actually a symlink + // out to a top-level framework. +#ifdef LLVM_ON_UNIX + char RealSubframeworkDirName[PATH_MAX]; + if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) { + StringRef SubframeworkDirName = RealSubframeworkDirName; + + bool FoundParent = false; + do { + // Get the parent directory name. + SubframeworkDirName + = llvm::sys::path::parent_path(SubframeworkDirName); + if (SubframeworkDirName.empty()) + break; + + if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { + FoundParent = true; + break; + } + } while (true); + + if (!FoundParent) + continue; + } +#endif + // FIXME: Do we want to warn about subframeworks without umbrella headers? inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, IsSystem, Result);