[cfe-commits] r45092 - in /cfe/trunk: Driver/clang.cpp Lex/HeaderSearch.cpp include/clang/Lex/DirectoryLookup.h
Chris Lattner
sabre at nondot.org
Sun Dec 16 23:52:41 PST 2007
Author: lattner
Date: Mon Dec 17 01:52:39 2007
New Revision: 45092
URL: http://llvm.org/viewvc/llvm-project?rev=45092&view=rev
Log:
as it turns out, frameworks and headermaps are orthogonal. Make this so in
the internal representation. This also fixes a bug where -I foo -F foo would
not search foo as both a normal and framework include dir.
Modified:
cfe/trunk/Driver/clang.cpp
cfe/trunk/Lex/HeaderSearch.cpp
cfe/trunk/include/clang/Lex/DirectoryLookup.h
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=45092&r1=45091&r2=45092&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Mon Dec 17 01:52:39 2007
@@ -651,22 +651,24 @@
return;
}
- // Check to see if this is an apple-style headermap.
- if (const FileEntry *FE = FM.getFile(&MappedPath[0],
- &MappedPath[0]+MappedPath.size())) {
- std::string ErrorInfo;
- const HeaderMap *HM = HS.CreateHeaderMap(FE, ErrorInfo);
- if (HM) {
- IncludeGroup[Group].push_back(DirectoryLookup(HM, Type, isUserSupplied,
- isFramework));
- return;
- }
-
- // If this looked like a headermap but was corrupted, emit that error,
- // otherwise treat it as a missing directory.
- if (!ErrorInfo.empty()) {
- fprintf(stderr, "%s\n", ErrorInfo.c_str());
- return;
+ // Check to see if this is an apple-style headermap (which are not allowed to
+ // be frameworks).
+ if (!isFramework) {
+ if (const FileEntry *FE = FM.getFile(&MappedPath[0],
+ &MappedPath[0]+MappedPath.size())) {
+ std::string ErrorInfo;
+ const HeaderMap *HM = HS.CreateHeaderMap(FE, ErrorInfo);
+ if (HM) {
+ IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
+ return;
+ }
+
+ // If this looked like a headermap but was corrupted, emit that error,
+ // otherwise treat it as a missing directory.
+ if (!ErrorInfo.empty()) {
+ fprintf(stderr, "%s\n", ErrorInfo.c_str());
+ return;
+ }
}
}
@@ -678,6 +680,7 @@
/// search list, remove the later (dead) ones.
static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList) {
llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
+ llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
for (unsigned i = 0; i != SearchList.size(); ++i) {
if (SearchList[i].isNormalDir()) {
@@ -688,6 +691,15 @@
if (Verbose)
fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
SearchList[i].getDir()->getName());
+ } else if (SearchList[i].isFramework()) {
+ // If this isn't the first time we've seen this framework dir, remove it.
+ if (SeenFrameworkDirs.insert(SearchList[i].getFrameworkDir()))
+ continue;
+
+ if (Verbose)
+ fprintf(stderr, "ignoring duplicate framework \"%s\"\n",
+ SearchList[i].getFrameworkDir()->getName());
+
} else {
assert(SearchList[i].isHeaderMap() && "Not a headermap or normal dir?");
// If this isn't the first time we've seen this headermap, remove it.
Modified: cfe/trunk/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/HeaderSearch.cpp?rev=45092&r1=45091&r2=45092&view=diff
==============================================================================
--- cfe/trunk/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/Lex/HeaderSearch.cpp Mon Dec 17 01:52:39 2007
@@ -61,9 +61,11 @@
const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE,
std::string &ErrorInfo) {
// We expect the number of headermaps to be small, and almost always empty.
- // If it ever grows, use of a linear search should be reevaluated.
+ // If it ever grows, use of a linear search should be re-evaluated.
if (!HeaderMaps.empty()) {
for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
+ // Pointer equality comparison of FileEntries works because they are
+ // already uniqued by inode.
if (HeaderMaps[i].first == FE)
return HeaderMaps[i].second;
}
@@ -76,6 +78,26 @@
return 0;
}
+//===----------------------------------------------------------------------===//
+// File lookup within a DirectoryLookup scope
+//===----------------------------------------------------------------------===//
+
+/// LookupFile - Lookup the specified file in this search path, returning it
+/// if it exists or returning null if not.
+const FileEntry *DirectoryLookup::LookupFile(const char *FilenameStart,
+ const char *FilenameEnd,
+ FileManager &FileMgr) const {
+ llvm::SmallString<1024> TmpDir;
+
+ // 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());
+}
+
+
//===----------------------------------------------------------------------===//
// Header File Location.
@@ -137,6 +159,7 @@
return FileMgr.getFile(FrameworkName.begin(), FrameworkName.end());
}
+
/// 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
@@ -161,11 +184,13 @@
return FileMgr.getFile(FilenameStart, FilenameEnd);
}
- llvm::SmallString<1024> TmpDir;
-
// Step #0, unless disabled, check to see if the file is in the #includer's
- // directory. This search is not done for <> headers.
+ // directory. This has to be based on CurFileEnt, not CurDir, because
+ // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
+ // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
+ // This search is not done for <> headers.
if (CurFileEnt && !isAngled && !NoCurDirSearch) {
+ llvm::SmallString<1024> TmpDir;
// Concatenate the requested file onto the directory.
// FIXME: Portability. Filename concatenation should be in sys::Path.
TmpDir += CurFileEnt->getDir()->getName();
@@ -173,12 +198,10 @@
TmpDir.append(FilenameStart, FilenameEnd);
if (const FileEntry *FE = FileMgr.getFile(TmpDir.begin(), TmpDir.end())) {
// Leave CurDir unset.
-
// This file is a system header or C++ unfriendly if the old file is.
getFileInfo(FE).DirInfo = getFileInfo(CurFileEnt).DirInfo;
return FE;
}
- TmpDir.clear();
}
CurDir = 0;
@@ -210,20 +233,15 @@
// start point value.
CacheLookup.first = i+1;
}
-
+
// 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()) {
- // FIXME: Portability. Adding file to dir should be in sys::Path.
- // Concatenate the requested file onto the directory.
- TmpDir.clear();
- TmpDir += SearchDirs[i].getDir()->getName();
- TmpDir.push_back('/');
- TmpDir.append(FilenameStart, FilenameEnd);
- FE = FileMgr.getFile(TmpDir.begin(), TmpDir.end());
+ FE = SearchDirs[i].LookupFile(FilenameStart, FilenameEnd, FileMgr);
} else {
- FE = DoFrameworkLookup(SearchDirs[i].getDir(), FilenameStart,FilenameEnd);
+ FE = DoFrameworkLookup(SearchDirs[i].getFrameworkDir(),
+ FilenameStart, FilenameEnd);
}
if (FE) {
Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=45092&r1=45091&r2=45092&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Mon Dec 17 01:52:39 2007
@@ -15,14 +15,15 @@
#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
namespace clang {
-class DirectoryEntry;
class HeaderMap;
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
/// DirectoryLookup - This class represents one entry in the search list that
/// specifies the search order for directories in #include directives. It
-/// represents either a directory or a 'headermap'. A headermap is just like a
-/// directory, but it remaps its contents through an indirection table instead
-/// of indexing a directory.
+/// represents either a directory, a framework, or a headermap.
+///
class DirectoryLookup {
public:
enum DirType {
@@ -30,14 +31,20 @@
SystemHeaderDir,
ExternCSystemHeaderDir
};
+
+ enum LookupType_t {
+ LT_NormalDir,
+ LT_Framework,
+ LT_HeaderMap
+ };
private:
union { // This union is discriminated by isHeaderMap.
- /// Dir - This is the actual directory that we're referring to.
- ///
+ /// Dir - This is the actual directory that we're referring to for a normal
+ /// directory or a framework.
const DirectoryEntry *Dir;
- /// Map - This is the HeaderMap corresponding if the isHeaderMap field is
- /// true.
+ /// Map - This is the HeaderMap if this is a headermap lookup.
+ ///
const HeaderMap *Map;
} u;
@@ -49,44 +56,57 @@
///
bool UserSupplied : 1;
- /// Framework - True if this is a framework directory search-path.
- ///
- bool Framework : 1;
-
- /// IsHeaderMap - True if the HeaderMap field is valid, false if the Dir field
- /// is valid.
- bool IsHeaderMap : 1;
+ /// LookupType - This indicates whether this DirectoryLookup object is a
+ /// normal directory, a framework, or a headermap.
+ unsigned LookupType : 2;
public:
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'dir'.
DirectoryLookup(const DirectoryEntry *dir, DirType DT, bool isUser,
bool isFramework)
: DirCharacteristic(DT), UserSupplied(isUser),
- Framework(isFramework), IsHeaderMap(false) {
+ LookupType(isFramework ? LT_Framework : LT_NormalDir) {
u.Dir = dir;
}
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'map'.
- DirectoryLookup(const HeaderMap *map, DirType DT, bool isUser, bool isFWork)
- : DirCharacteristic(DT), UserSupplied(isUser), Framework(isFWork),
- IsHeaderMap(true) {
+ DirectoryLookup(const HeaderMap *map, DirType DT, bool isUser)
+ : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) {
u.Map = map;
}
+ /// 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;
+
/// getDir - Return the directory that this entry refers to.
///
- const DirectoryEntry *getDir() const { return !IsHeaderMap ? u.Dir : 0; }
+ const DirectoryEntry *getDir() const { return isNormalDir() ? u.Dir : 0; }
+
+ /// getFrameworkDir - Return the directory that this framework refers to.
+ ///
+ const DirectoryEntry *getFrameworkDir() const {
+ return isFramework() ? u.Dir : 0;
+ }
/// getHeaderMap - Return the directory that this entry refers to.
///
- const HeaderMap *getHeaderMap() const { return IsHeaderMap ? u.Map : 0; }
+ const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
+ LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
+
/// isNormalDir - Return true if this is a normal directory, not a header map.
- bool isNormalDir() const { return !IsHeaderMap; }
+ bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
+
+ /// isFramework - True if this is a framework directory.
+ ///
+ bool isFramework() const { return getLookupType() == LT_Framework; }
/// isHeaderMap - Return true if this is a header map, not a normal directory.
- bool isHeaderMap() const { return IsHeaderMap; }
+ bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
/// DirCharacteristic - The type of directory this is, one of the DirType enum
/// values.
@@ -96,9 +116,6 @@
///
bool isUserSupplied() const { return UserSupplied; }
- /// isFramework - True if this is a framework directory.
- ///
- bool isFramework() const { return Framework; }
};
} // end namespace clang
More information about the cfe-commits
mailing list