aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-01-26 00:55:12 +0000
committerDouglas Gregor <dgregor@apple.com>2013-01-26 00:55:12 +0000
commit713b7c011869f177dc76e6df4f7f44b1bd073bb0 (patch)
tree2a5a5a69b2900acb1fdf5c3a3a6e9b7743baacc1 /lib/Lex
parent25cf8abf30189323199b1424848b105940267c1b (diff)
Since we're stuck with realpath for the header <-> module mapping,
factor the realpath calls into FileManager::getCanonicalName() so we can cache the results of this epically slow operation. 5% speedup on my modules test, and realpath drops out of the profile. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173542 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/HeaderSearch.cpp11
-rw-r--r--lib/Lex/ModuleMap.cpp59
2 files changed, 26 insertions, 44 deletions
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 14d44cc3da..6432925518 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -268,6 +268,10 @@ const FileEntry *DirectoryLookup::LookupFile(
return Result;
}
+/// FIXME: HACK HACK HACK!
+static llvm::DenseMap<const DirectoryEntry *, const DirectoryEntry *>
+ TopFrameworkDirs;
+
/// \brief Given a framework directory, find the top-most framework directory.
///
/// \param FileMgr The file manager to use for directory lookups.
@@ -280,7 +284,6 @@ getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
assert(llvm::sys::path::extension(DirName) == ".framework" &&
"Not a framework directory");
-#ifdef LLVM_ON_UNIX
// Note: as an egregious but useful hack we use the real path here, because
// frameworks moving between top-level frameworks to embedded frameworks tend
// to be symlinked, and we base the logical structure of modules on the
@@ -295,12 +298,8 @@ getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
//
// Similar issues occur when a top-level framework has moved into an
// embedded framework.
- char RealDirName[PATH_MAX];
- if (realpath(DirName.str().c_str(), RealDirName))
- DirName = RealDirName;
-#endif
-
const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName);
+ DirName = FileMgr.getCanonicalName(TopFrameworkDir);
do {
// Get the parent directory name.
DirName = llvm::sys::path::parent_path(DirName);
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 25e5bee9ce..7ad42bef15 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -163,20 +163,12 @@ Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
const DirectoryEntry *Dir = File->getDir();
SmallVector<const DirectoryEntry *, 2> SkippedDirs;
-#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
+ StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
// Keep walking up the directory hierarchy, looking for a directory with
// an umbrella header.
@@ -420,16 +412,13 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
// a framework module, do so.
if (!Parent) {
// Determine whether we're allowed to infer a module map.
- StringRef FrameworkDirName = FrameworkDir->getName();
-#ifdef LLVM_ON_UNIX
+
// Note: as an egregious but useful hack we use the real path here, because
// we might be looking at an embedded framework that symlinks out to a
// top-level framework, and we need to infer as if we were naming the
// top-level framework.
- char RealFrameworkDirName[PATH_MAX];
- if (realpath(FrameworkDir->getName(), RealFrameworkDirName))
- FrameworkDirName = RealFrameworkDirName;
-#endif
+ StringRef FrameworkDirName
+ = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
bool canInfer = false;
if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
@@ -527,29 +516,23 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
// 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);
+ StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
+ 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
+ if (!FoundParent)
+ continue;
// FIXME: Do we want to warn about subframeworks without umbrella headers?
SmallString<32> NameBuf;