refactor an better comment framework lookup code. This moves it from

HeaderSearch into DirectoryLookup, as a particular framework lookup is 
specific to the directory we are currently querying.

llvm-svn: 45093
This commit is contained in:
Chris Lattner 2007-12-17 08:13:48 +00:00
parent f62f75895f
commit 712e3873a0
3 changed files with 70 additions and 48 deletions

View File

@ -86,40 +86,49 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE,
/// if it exists or returning null if not. /// if it exists or returning null if not.
const FileEntry *DirectoryLookup::LookupFile(const char *FilenameStart, const FileEntry *DirectoryLookup::LookupFile(const char *FilenameStart,
const char *FilenameEnd, const char *FilenameEnd,
FileManager &FileMgr) const { HeaderSearch &HS) const {
llvm::SmallString<1024> TmpDir; llvm::SmallString<1024> TmpDir;
if (isNormalDir()) {
// Concatenate the requested file onto the directory.
// FIXME: Portability. Filename concatenation should be in sys::Path.
TmpDir += getDir()->getName();
TmpDir.push_back('/');
TmpDir.append(FilenameStart, FilenameEnd);
return HS.getFileMgr().getFile(TmpDir.begin(), TmpDir.end());
}
// Concatenate the requested file onto the directory. if (isFramework())
// FIXME: Portability. Filename concatenation should be in sys::Path. return DoFrameworkLookup(FilenameStart, FilenameEnd, HS);
TmpDir += getDir()->getName();
TmpDir.push_back('/'); assert(0 && "headermap unimp");
TmpDir.append(FilenameStart, FilenameEnd);
return FileMgr.getFile(TmpDir.begin(), TmpDir.end());
} }
/// DoFrameworkLookup - Do a lookup of the specified file in the current
//===----------------------------------------------------------------------===// /// DirectoryLookup, which is a framework directory.
// Header File Location. const FileEntry *DirectoryLookup::DoFrameworkLookup(const char *FilenameStart,
//===----------------------------------------------------------------------===// const char *FilenameEnd,
HeaderSearch &HS) const {
const FileEntry *HeaderSearch::DoFrameworkLookup(const DirectoryEntry *Dir, FileManager &FileMgr = HS.getFileMgr();
const char *FilenameStart,
const char *FilenameEnd) {
// Framework names must have a '/' in the filename. // Framework names must have a '/' in the filename.
const char *SlashPos = std::find(FilenameStart, FilenameEnd, '/'); const char *SlashPos = std::find(FilenameStart, FilenameEnd, '/');
if (SlashPos == FilenameEnd) return 0; if (SlashPos == FilenameEnd) return 0;
llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup = // Find out if this is the home for the specified framework, by checking
FrameworkMap.GetOrCreateValue(FilenameStart, SlashPos); // HeaderSearch. Possible answer are yes/no and unknown.
const DirectoryEntry *&FrameworkDirCache =
HS.LookupFrameworkCache(FilenameStart, SlashPos);
// If it is some other directory, fail. // If it is known and in some other directory, fail.
if (CacheLookup.getValue() && CacheLookup.getValue() != Dir) if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir())
return 0; return 0;
// Otherwise, construct the path to this framework dir.
// FrameworkName = "/System/Library/Frameworks/" // FrameworkName = "/System/Library/Frameworks/"
llvm::SmallString<1024> FrameworkName; llvm::SmallString<1024> FrameworkName;
FrameworkName += Dir->getName(); FrameworkName += getFrameworkDir()->getName();
if (FrameworkName.empty() || FrameworkName.back() != '/') if (FrameworkName.empty() || FrameworkName.back() != '/')
FrameworkName.push_back('/'); FrameworkName.push_back('/');
@ -128,18 +137,21 @@ const FileEntry *HeaderSearch::DoFrameworkLookup(const DirectoryEntry *Dir,
// FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
FrameworkName += ".framework/"; FrameworkName += ".framework/";
if (CacheLookup.getValue() == 0) { // If the cache entry is still unresolved, query to see if the cache entry is
++NumFrameworkLookups; // still unresolved. If so, check its existence now.
if (FrameworkDirCache == 0) {
HS.IncrementFrameworkLookupCount();
// If the framework dir doesn't exist, we fail. // If the framework dir doesn't exist, we fail.
// FIXME: It's probably more efficient to query this with FileMgr.getDir.
if (!llvm::sys::Path(std::string(FrameworkName.begin(), if (!llvm::sys::Path(std::string(FrameworkName.begin(),
FrameworkName.end())).exists()) FrameworkName.end())).exists())
return 0; return 0;
// Otherwise, if it does, remember that this is the right direntry for this // Otherwise, if it does, remember that this is the right direntry for this
// framework. // framework.
CacheLookup.setValue(Dir); FrameworkDirCache = getFrameworkDir();
} }
// Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
@ -160,6 +172,11 @@ const FileEntry *HeaderSearch::DoFrameworkLookup(const DirectoryEntry *Dir,
} }
//===----------------------------------------------------------------------===//
// Header File Location.
//===----------------------------------------------------------------------===//
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
/// return null on failure. isAngled indicates whether the file reference is /// return null on failure. isAngled indicates whether the file reference is
/// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if /// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if
@ -236,24 +253,18 @@ const FileEntry *HeaderSearch::LookupFile(const char *FilenameStart,
// Check each directory in sequence to see if it contains this file. // Check each directory in sequence to see if it contains this file.
for (; i != SearchDirs.size(); ++i) { for (; i != SearchDirs.size(); ++i) {
const FileEntry *FE = 0; const FileEntry *FE =
if (!SearchDirs[i].isFramework()) { SearchDirs[i].LookupFile(FilenameStart, FilenameEnd, *this);
FE = SearchDirs[i].LookupFile(FilenameStart, FilenameEnd, FileMgr); if (!FE) continue;
} else {
FE = DoFrameworkLookup(SearchDirs[i].getFrameworkDir(),
FilenameStart, FilenameEnd);
}
if (FE) { CurDir = &SearchDirs[i];
CurDir = &SearchDirs[i];
// This file is a system header or C++ unfriendly if the dir is.
// This file is a system header or C++ unfriendly if the dir is. getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
// Remember this location for the next lookup we do.
// Remember this location for the next lookup we do. CacheLookup.second = i;
CacheLookup.second = i; return FE;
return FE;
}
} }
// Otherwise, didn't find it. Remember we didn't find this. // Otherwise, didn't find it. Remember we didn't find this.

View File

@ -18,7 +18,7 @@ namespace clang {
class HeaderMap; class HeaderMap;
class DirectoryEntry; class DirectoryEntry;
class FileEntry; class FileEntry;
class FileManager; class HeaderSearch;
/// DirectoryLookup - This class represents one entry in the search list that /// DirectoryLookup - This class represents one entry in the search list that
/// specifies the search order for directories in #include directives. It /// specifies the search order for directories in #include directives. It
@ -79,8 +79,7 @@ public:
/// LookupFile - Lookup the specified file in this search path, returning it /// LookupFile - Lookup the specified file in this search path, returning it
/// if it exists or returning null if not. /// if it exists or returning null if not.
const FileEntry *LookupFile(const char *FilenameStart, const FileEntry *LookupFile(const char *FilenameStart,
const char *FilenameEnd, const char *FilenameEnd, HeaderSearch &HS) const;
FileManager &FileMgr) const;
/// getDir - Return the directory that this entry refers to. /// getDir - Return the directory that this entry refers to.
/// ///
@ -116,6 +115,11 @@ public:
/// ///
bool isUserSupplied() const { return UserSupplied; } bool isUserSupplied() const { return UserSupplied; }
private:
const FileEntry *DoFrameworkLookup(const char *FilenameStart,
const char *FilenameEnd,
HeaderSearch &HS) const;
}; };
} // end namespace clang } // end namespace clang

View File

@ -133,6 +133,14 @@ public:
const char *FilenameEnd, const char *FilenameEnd,
const FileEntry *RelativeFileEnt); const FileEntry *RelativeFileEnt);
/// LookupFrameworkCache - Look up the specified framework name in our
/// framework cache, returning the DirectoryEntry it is in if we know,
/// otherwise, return null.
const DirectoryEntry *&LookupFrameworkCache(const char *FWNameStart,
const char *FWNameEnd) {
return FrameworkMap.GetOrCreateValue(FWNameStart, FWNameEnd).getValue();
}
/// ShouldEnterIncludeFile - Mark the specified file as a target of of a /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
/// #include, #include_next, or #import directive. Return false if #including /// #include, #include_next, or #import directive. Return false if #including
/// the file will have no effect or true if we should include it. /// the file will have no effect or true if we should include it.
@ -175,11 +183,10 @@ public:
/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE, std::string &ErrorInfo); const HeaderMap *CreateHeaderMap(const FileEntry *FE, std::string &ErrorInfo);
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
void PrintStats(); void PrintStats();
private: private:
const FileEntry *DoFrameworkLookup(const DirectoryEntry *Dir,
const char *FilenameStart,
const char *FilenameEnd);
/// getFileInfo - Return the PerFileInfo structure for the specified /// getFileInfo - Return the PerFileInfo structure for the specified
/// FileEntry. /// FileEntry.