Implement subframework lookup

llvm-svn: 39015
This commit is contained in:
Chris Lattner 2006-10-20 04:42:40 +00:00
parent 25e0d54a0e
commit 63dd32b656
4 changed files with 95 additions and 9 deletions

View File

@ -35,7 +35,7 @@ void HeaderSearch::PrintStats() {
std::cerr << " " << NumIncluded << " #include/#include_next/#import.\n";
std::cerr << " " << NumMultiIncludeFileOptzn << " #includes skipped due to"
<< " the multi-include optimization.\n";
<< " the multi-include optimization.\n";
}
@ -68,12 +68,14 @@ static std::string DoFrameworkLookup(const DirectoryEntry *Dir,
// Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
std::string HeadersFilename = FrameworkName + "Headers/" +
std::string(Filename.begin()+SlashPos+1, Filename.end());
if (sys::Path(HeadersFilename).exists()) return HeadersFilename;
if (sys::Path(HeadersFilename).exists())
return HeadersFilename;
// Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
std::string PrivateHeadersFilename = FrameworkName + "PrivateHeaders/" +
std::string(Filename.begin()+SlashPos+1, Filename.end());
if (sys::Path(PrivateHeadersFilename).exists()) return HeadersFilename;
if (sys::Path(PrivateHeadersFilename).exists())
return PrivateHeadersFilename;
return "";
}
@ -103,7 +105,7 @@ const FileEntry *HeaderSearch::LookupFile(const std::string &Filename,
// Step #0, unless disabled, check to see if the file is in the #includer's
// directory. This search is not done for <> headers.
if (CurFileEnt && !NoCurDirSearch) {
if (CurFileEnt && !isAngled && !NoCurDirSearch) {
// Concatenate the requested file onto the directory.
// FIXME: Portability. Filename concatenation should be in sys::Path.
if (const FileEntry *FE =
@ -111,7 +113,7 @@ const FileEntry *HeaderSearch::LookupFile(const std::string &Filename,
// Leave CurDir unset.
// This file is a system header or C++ unfriendly if the old file is.
getFileInfo(CurFileEnt).DirInfo = getFileInfo(CurFileEnt).DirInfo;
getFileInfo(FE).DirInfo = getFileInfo(CurFileEnt).DirInfo;
return FE;
}
}
@ -152,6 +154,58 @@ const FileEntry *HeaderSearch::LookupFile(const std::string &Filename,
return 0;
}
/// LookupSubframeworkHeader - Look up a subframework for the specified
/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
/// is a subframework within Carbon.framework. If so, return the FileEntry
/// for the designated file, otherwise return null.
const FileEntry *HeaderSearch::
LookupSubframeworkHeader(const std::string &Filename,
const FileEntry *ContextFileEnt) {
// Framework names must have a '/' in the filename. Find it.
std::string::size_type SlashPos = Filename.find('/');
if (SlashPos == std::string::npos) return 0;
// TODO: Cache subframework.
// Look up the base framework name of the ContextFileEnt.
const std::string &ContextName = ContextFileEnt->getName();
std::string::size_type FrameworkPos = ContextName.find(".framework/");
// If the context info wasn't a framework, couldn't be a subframework.
if (FrameworkPos == std::string::npos)
return 0;
std::string FrameworkName(ContextName.begin(),
ContextName.begin()+FrameworkPos+strlen(".framework/"));
// Append Frameworks/HIToolbox.framework/
FrameworkName += "Frameworks/";
FrameworkName += std::string(Filename.begin(), Filename.begin()+SlashPos);
FrameworkName += ".framework/";
// Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
std::string HeadersFilename = FrameworkName + "Headers/" +
std::string(Filename.begin()+SlashPos+1, Filename.end());
if (!sys::Path(HeadersFilename).exists()) {
// Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
std::string PrivateHeadersFilename = FrameworkName + "PrivateHeaders/" +
std::string(Filename.begin()+SlashPos+1, Filename.end());
if (!sys::Path(PrivateHeadersFilename).exists())
return 0;
HeadersFilename = PrivateHeadersFilename;
}
// Concatenate the requested file onto the directory.
if (const FileEntry *FE = FileMgr.getFile(HeadersFilename)) {
// This file is a system header or C++ unfriendly if the old file is.
getFileInfo(FE).DirInfo = getFileInfo(ContextFileEnt).DirInfo;
return FE;
}
return 0;
}
//===----------------------------------------------------------------------===//
// File Info Management.
//===----------------------------------------------------------------------===//

View File

@ -247,7 +247,6 @@ CreateString(const char *Buf, unsigned Len, SourceLocation SLoc) {
// Source File Location Methods.
//===----------------------------------------------------------------------===//
/// 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 "").
@ -258,13 +257,38 @@ const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
// If the header lookup mechanism may be relative to the current file, pass in
// info about where the current file is.
const FileEntry *CurFileEnt = 0;
if (!isAngled && !FromDir) {
if (!FromDir) {
unsigned TheFileID = getCurrentFileLexer()->getCurFileID();
CurFileEnt = SourceMgr.getFileEntryForFileID(TheFileID);
}
// Do a standard file entry lookup.
CurDir = CurDirLookup;
return HeaderInfo.LookupFile(Filename, isAngled, FromDir, CurDir, CurFileEnt);
const FileEntry *FE =
HeaderInfo.LookupFile(Filename, isAngled, FromDir, CurDir, CurFileEnt);
if (FE) return FE;
// Otherwise, see if this is a subframework header. If so, this is relative
// to one of the headers on the #include stack. Walk the list of the current
// headers on the #include stack and pass them to HeaderInfo.
if (CurLexer) {
CurFileEnt = SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID());
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
return FE;
}
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
if (ISEntry.TheLexer) {
CurFileEnt =
SourceMgr.getFileEntryForFileID(ISEntry.TheLexer->getCurFileID());
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
return FE;
}
}
// Otherwise, we really couldn't find the file.
return 0;
}
/// isInPrimaryFile - Return true if we're in the top-level file, not in a

View File

@ -115,7 +115,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
DE06BEC80A854E390050E87E /* Scope.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Scope.cpp; path = Parse/Scope.cpp; sourceTree = "<group>"; };
DE06BECA0A854E4B0050E87E /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Parse/Scope.h; sourceTree = "<group>"; };

View File

@ -151,6 +151,14 @@ public:
const DirectoryLookup *&CurDir,
const FileEntry *CurFileEnt);
/// LookupSubframeworkHeader - Look up a subframework for the specified
/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
/// is a subframework within Carbon.framework. If so, return the FileEntry
/// for the designated file, otherwise return null.
const FileEntry *LookupSubframeworkHeader(const std::string &Filename,
const FileEntry *RelativeFileEnt);
/// 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.