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.
const FileEntry *DirectoryLookup::LookupFile(const char *FilenameStart,
const char *FilenameEnd,
FileManager &FileMgr) const {
HeaderSearch &HS) const {
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.
// FIXME: Portability. Filename concatenation should be in sys::Path.
TmpDir += getDir()->getName();
TmpDir.push_back('/');
TmpDir.append(FilenameStart, FilenameEnd);
return FileMgr.getFile(TmpDir.begin(), TmpDir.end());
if (isFramework())
return DoFrameworkLookup(FilenameStart, FilenameEnd, HS);
assert(0 && "headermap unimp");
}
//===----------------------------------------------------------------------===//
// Header File Location.
//===----------------------------------------------------------------------===//
const FileEntry *HeaderSearch::DoFrameworkLookup(const DirectoryEntry *Dir,
const char *FilenameStart,
const char *FilenameEnd) {
/// DoFrameworkLookup - Do a lookup of the specified file in the current
/// DirectoryLookup, which is a framework directory.
const FileEntry *DirectoryLookup::DoFrameworkLookup(const char *FilenameStart,
const char *FilenameEnd,
HeaderSearch &HS) const {
FileManager &FileMgr = HS.getFileMgr();
// Framework names must have a '/' in the filename.
const char *SlashPos = std::find(FilenameStart, FilenameEnd, '/');
if (SlashPos == FilenameEnd) return 0;
llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup =
FrameworkMap.GetOrCreateValue(FilenameStart, SlashPos);
// Find out if this is the home for the specified framework, by checking
// HeaderSearch. Possible answer are yes/no and unknown.
const DirectoryEntry *&FrameworkDirCache =
HS.LookupFrameworkCache(FilenameStart, SlashPos);
// If it is some other directory, fail.
if (CacheLookup.getValue() && CacheLookup.getValue() != Dir)
// If it is known and in some other directory, fail.
if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir())
return 0;
// Otherwise, construct the path to this framework dir.
// FrameworkName = "/System/Library/Frameworks/"
llvm::SmallString<1024> FrameworkName;
FrameworkName += Dir->getName();
FrameworkName += getFrameworkDir()->getName();
if (FrameworkName.empty() || FrameworkName.back() != '/')
FrameworkName.push_back('/');
@ -128,18 +137,21 @@ const FileEntry *HeaderSearch::DoFrameworkLookup(const DirectoryEntry *Dir,
// FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
FrameworkName += ".framework/";
if (CacheLookup.getValue() == 0) {
++NumFrameworkLookups;
// If the cache entry is still unresolved, query to see if the cache entry is
// still unresolved. If so, check its existence now.
if (FrameworkDirCache == 0) {
HS.IncrementFrameworkLookupCount();
// 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(),
FrameworkName.end())).exists())
return 0;
// Otherwise, if it does, remember that this is the right direntry for this
// framework.
CacheLookup.setValue(Dir);
FrameworkDirCache = getFrameworkDir();
}
// 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,
/// return null on failure. isAngled indicates whether the file reference is
/// 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.
for (; i != SearchDirs.size(); ++i) {
const FileEntry *FE = 0;
if (!SearchDirs[i].isFramework()) {
FE = SearchDirs[i].LookupFile(FilenameStart, FilenameEnd, FileMgr);
} else {
FE = DoFrameworkLookup(SearchDirs[i].getFrameworkDir(),
FilenameStart, FilenameEnd);
}
const FileEntry *FE =
SearchDirs[i].LookupFile(FilenameStart, FilenameEnd, *this);
if (!FE) continue;
if (FE) {
CurDir = &SearchDirs[i];
// This file is a system header or C++ unfriendly if the dir is.
getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
// Remember this location for the next lookup we do.
CacheLookup.second = i;
return FE;
}
CurDir = &SearchDirs[i];
// This file is a system header or C++ unfriendly if the dir is.
getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
// Remember this location for the next lookup we do.
CacheLookup.second = i;
return FE;
}
// Otherwise, didn't find it. Remember we didn't find this.

View File

@ -18,7 +18,7 @@ namespace clang {
class HeaderMap;
class DirectoryEntry;
class FileEntry;
class FileManager;
class HeaderSearch;
/// DirectoryLookup - This class represents one entry in the search list that
/// 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
/// if it exists or returning null if not.
const FileEntry *LookupFile(const char *FilenameStart,
const char *FilenameEnd,
FileManager &FileMgr) const;
const char *FilenameEnd, HeaderSearch &HS) const;
/// getDir - Return the directory that this entry refers to.
///
@ -116,6 +115,11 @@ public:
///
bool isUserSupplied() const { return UserSupplied; }
private:
const FileEntry *DoFrameworkLookup(const char *FilenameStart,
const char *FilenameEnd,
HeaderSearch &HS) const;
};
} // end namespace clang

View File

@ -133,6 +133,14 @@ public:
const char *FilenameEnd,
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
/// #include, #include_next, or #import directive. Return false if #including
/// 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.
const HeaderMap *CreateHeaderMap(const FileEntry *FE, std::string &ErrorInfo);
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
void PrintStats();
private:
const FileEntry *DoFrameworkLookup(const DirectoryEntry *Dir,
const char *FilenameStart,
const char *FilenameEnd);
/// getFileInfo - Return the PerFileInfo structure for the specified
/// FileEntry.