summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp47
1 files changed, 44 insertions, 3 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
index bb3a673..67000b68 100644
--- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
+++ b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/Lexer.h"
#include "clang/Basic/Diagnostic.h"
@@ -38,10 +39,11 @@ HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) {
ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
-HeaderSearch::HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags,
+HeaderSearch::HeaderSearch(llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+ FileManager &FM, DiagnosticsEngine &Diags,
const LangOptions &LangOpts,
const TargetInfo *Target)
- : FileMgr(FM), Diags(Diags), FrameworkMap(64),
+ : HSOpts(HSOpts), FileMgr(FM), FrameworkMap(64),
ModMap(FileMgr, *Diags.getClient(), LangOpts, Target)
{
AngledDirIdx = 0;
@@ -905,7 +907,20 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name,
SubmodulePath.push_back(Name);
// Walk the directory structure to find any enclosing frameworks.
+#ifdef LLVM_ON_UNIX
+ // Note: as an egregious but useful hack we use the real path here, because
+ // frameworks moving from top-level frameworks to embedded frameworks tend
+ // to be symlinked from the top-level location to the embedded location,
+ // and we need to resolve lookups as if we had found the embedded location.
+ char RealDirName[PATH_MAX];
+ StringRef DirName;
+ if (realpath(Dir->getName(), RealDirName))
+ DirName = RealDirName;
+ else
+ DirName = Dir->getName();
+#else
StringRef DirName = Dir->getName();
+#endif
do {
// Get the parent directory name.
DirName = llvm::sys::path::parent_path(DirName);
@@ -924,7 +939,33 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name,
TopFrameworkDir = Dir;
}
} while (true);
-
+
+ // Determine whether we're allowed to infer a module map.
+ bool canInfer = false;
+ if (llvm::sys::path::has_parent_path(TopFrameworkDir->getName())) {
+ // Figure out the parent path.
+ StringRef Parent = llvm::sys::path::parent_path(TopFrameworkDir->getName());
+ if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
+ // If there's a module map file in the parent directory, it can
+ // explicitly allow us to infer framework modules.
+ switch (loadModuleMapFile(ParentDir)) {
+ case LMM_AlreadyLoaded:
+ case LMM_NewlyLoaded: {
+ StringRef Name = llvm::sys::path::stem(TopFrameworkDir->getName());
+ canInfer = ModMap.canInferFrameworkModule(ParentDir, Name, IsSystem);
+ break;
+ }
+ case LMM_InvalidModuleMap:
+ case LMM_NoDirectory:
+ break;
+ }
+ }
+ }
+
+ // If we're not allowed to infer a module map, we're done.
+ if (!canInfer)
+ return 0;
+
// Try to infer a module map from the top-level framework directory.
Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(),
TopFrameworkDir,
OpenPOWER on IntegriCloud