[cfe-commits] r45089 - in /cfe/trunk: Driver/clang.cpp Lex/HeaderSearch.cpp clang.xcodeproj/project.pbxproj include/clang/Lex/DirectoryLookup.h include/clang/Lex/HeaderMap.h include/clang/Lex/HeaderSearch.h
Chris Lattner
sabre at nondot.org
Sun Dec 16 22:36:45 PST 2007
Author: lattner
Date: Mon Dec 17 00:36:45 2007
New Revision: 45089
URL: http://llvm.org/viewvc/llvm-project?rev=45089&view=rev
Log:
Step #1 in adding headermap support to clang.
Added:
cfe/trunk/include/clang/Lex/HeaderMap.h
Modified:
cfe/trunk/Driver/clang.cpp
cfe/trunk/Lex/HeaderSearch.cpp
cfe/trunk/clang.xcodeproj/project.pbxproj
cfe/trunk/include/clang/Lex/DirectoryLookup.h
cfe/trunk/include/clang/Lex/HeaderSearch.h
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=45089&r1=45088&r2=45089&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Mon Dec 17 00:36:45 2007
@@ -613,8 +613,9 @@
///
static void AddPath(const std::string &Path, IncludeDirGroup Group,
bool isCXXAware, bool isUserSupplied,
- bool isFramework, FileManager &FM) {
+ bool isFramework, HeaderSearch &HS) {
assert(!Path.empty() && "can't handle empty path here");
+ FileManager &FM = HS.getFileMgr();
// Compute the actual path, taking into consideration -isysroot.
llvm::SmallString<256> MappedPath;
@@ -648,6 +649,25 @@
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;
+ }
+ }
+
if (Verbose)
fprintf(stderr, "ignoring nonexistent directory \"%s\"\n", Path.c_str());
}
@@ -674,23 +694,23 @@
const LangOptions &Lang) {
// Handle -F... options.
for (unsigned i = 0, e = F_dirs.size(); i != e; ++i)
- AddPath(F_dirs[i], Angled, false, true, true, FM);
+ AddPath(F_dirs[i], Angled, false, true, true, Headers);
// Handle -I... options.
for (unsigned i = 0, e = I_dirs.size(); i != e; ++i)
- AddPath(I_dirs[i], Angled, false, true, false, FM);
+ AddPath(I_dirs[i], Angled, false, true, false, Headers);
// Handle -idirafter... options.
for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
- AddPath(idirafter_dirs[i], After, false, true, false, FM);
+ AddPath(idirafter_dirs[i], After, false, true, false, Headers);
// Handle -iquote... options.
for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
- AddPath(iquote_dirs[i], Quoted, false, true, false, FM);
+ AddPath(iquote_dirs[i], Quoted, false, true, false, Headers);
// Handle -isystem... options.
for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
- AddPath(isystem_dirs[i], System, false, true, false, FM);
+ AddPath(isystem_dirs[i], System, false, true, false, Headers);
// Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
// parallel, processing the values in order of occurance to get the right
@@ -719,12 +739,12 @@
iwithprefix_vals.getPosition(iwithprefix_idx) <
iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
- System, false, false, false, FM);
+ System, false, false, false, Headers);
++iwithprefix_idx;
iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
} else {
AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
- Angled, false, false, false, FM);
+ Angled, false, false, false, Headers);
++iwithprefixbefore_idx;
iwithprefixbefore_done =
iwithprefixbefore_idx == iwithprefixbefore_vals.size();
@@ -739,34 +759,35 @@
// FIXME: get these from the target?
if (!nostdinc) {
if (Lang.CPlusPlus) {
- AddPath("/usr/include/c++/4.0.0", System, true, false, false, FM);
+ AddPath("/usr/include/c++/4.0.0", System, true, false, false, Headers);
AddPath("/usr/include/c++/4.0.0/i686-apple-darwin8", System, true, false,
- false, FM);
- AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false,FM);
+ false, Headers);
+ AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false,
+ Headers);
}
- AddPath("/usr/local/include", System, false, false, false, FM);
+ AddPath("/usr/local/include", System, false, false, false, Headers);
// leopard
AddPath("/usr/lib/gcc/i686-apple-darwin9/4.0.1/include", System,
- false, false, false, FM);
+ false, false, false, Headers);
AddPath("/usr/lib/gcc/powerpc-apple-darwin9/4.0.1/include",
- System, false, false, false, FM);
+ System, false, false, false, Headers);
AddPath("/usr/lib/gcc/powerpc-apple-darwin9/"
"4.0.1/../../../../powerpc-apple-darwin0/include",
- System, false, false, false, FM);
+ System, false, false, false, Headers);
// tiger
AddPath("/usr/lib/gcc/i686-apple-darwin8/4.0.1/include", System,
- false, false, false, FM);
+ false, false, false, Headers);
AddPath("/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include",
- System, false, false, false, FM);
+ System, false, false, false, Headers);
AddPath("/usr/lib/gcc/powerpc-apple-darwin8/"
"4.0.1/../../../../powerpc-apple-darwin8/include",
- System, false, false, false, FM);
+ System, false, false, false, Headers);
- AddPath("/usr/include", System, false, false, false, FM);
- AddPath("/System/Library/Frameworks", System, true, false, true, FM);
- AddPath("/Library/Frameworks", System, true, false, true, FM);
+ AddPath("/usr/include", System, false, false, false, Headers);
+ AddPath("/System/Library/Frameworks", System, true, false, true, Headers);
+ AddPath("/Library/Frameworks", System, true, false, true, Headers);
}
// Now that we have collected all of the include paths, merge them all
Modified: cfe/trunk/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/HeaderSearch.cpp?rev=45089&r1=45088&r2=45089&view=diff
==============================================================================
--- cfe/trunk/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/Lex/HeaderSearch.cpp Mon Dec 17 00:36:45 2007
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderMap.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/System/Path.h"
@@ -27,6 +28,12 @@
NumFrameworkLookups = NumSubFrameworkLookups = 0;
}
+HeaderSearch::~HeaderSearch() {
+ // Delete headermaps.
+ for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
+ delete HeaderMaps[i].second;
+}
+
void HeaderSearch::PrintStats() {
fprintf(stderr, "\n*** HeaderSearch Stats:\n");
fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
@@ -49,6 +56,27 @@
fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
}
+/// CreateHeaderMap - This method returns a HeaderMap for the specified
+/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
+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 (!HeaderMaps.empty()) {
+ for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
+ if (HeaderMaps[i].first == FE)
+ return HeaderMaps[i].second;
+ }
+
+ if (const HeaderMap *HM = HeaderMap::Create(FE, ErrorInfo)) {
+ HeaderMaps.push_back(std::make_pair(FE, HM));
+ return HM;
+ }
+
+ return 0;
+}
+
+
//===----------------------------------------------------------------------===//
// Header File Location.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=45089&r1=45088&r2=45089&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Mon Dec 17 00:36:45 2007
@@ -314,6 +314,7 @@
DE6951C60C4D1F5D00A5826B /* RecordLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = RecordLayout.h; path = clang/AST/RecordLayout.h; sourceTree = "<group>"; };
DE6954630C5121BD00A5826B /* Token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; };
DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclObjC.cpp; path = Sema/SemaDeclObjC.cpp; sourceTree = "<group>"; };
+ DE704BD10D1647E7009C7762 /* HeaderMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeaderMap.h; sourceTree = "<group>"; };
DE75ED280B044DC90020CF81 /* ASTContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTContext.h; path = clang/AST/ASTContext.h; sourceTree = "<group>"; };
DE75EDF00B06880E0020CF81 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Type.cpp; path = AST/Type.cpp; sourceTree = "<group>"; };
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleBuilder.cpp; path = CodeGen/ModuleBuilder.cpp; sourceTree = "<group>"; };
@@ -684,6 +685,7 @@
isa = PBXGroup;
children = (
DE3450D60AEB543100DBC861 /* DirectoryLookup.h */,
+ DE704BD10D1647E7009C7762 /* HeaderMap.h */,
DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */,
DED7D73B0A524295003AD0FB /* Lexer.h */,
1A869A6E0BA2164C008DA07A /* LiteralSupport.h */,
Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=45089&r1=45088&r2=45089&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Mon Dec 17 00:36:45 2007
@@ -16,9 +16,13 @@
namespace clang {
class DirectoryEntry;
+class HeaderMap;
-/// DirectoryLookup - This class is used to specify the search order for
-/// directories in #include directives.
+/// 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.
class DirectoryLookup {
public:
enum DirType {
@@ -26,10 +30,16 @@
SystemHeaderDir,
ExternCSystemHeaderDir
};
-private:
- /// Dir - This is the actual directory that we're referring to.
- ///
- const DirectoryEntry *Dir;
+private:
+ union { // This union is discriminated by isHeaderMap.
+ /// Dir - This is the actual directory that we're referring to.
+ ///
+ const DirectoryEntry *Dir;
+
+ /// Map - This is the HeaderMap corresponding if the isHeaderMap field is
+ /// true.
+ const HeaderMap *Map;
+ } u;
/// DirCharacteristic - The type of directory this is, one of the DirType enum
/// values.
@@ -42,15 +52,35 @@
/// 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;
public:
+ /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+ /// 'dir'.
DirectoryLookup(const DirectoryEntry *dir, DirType DT, bool isUser,
bool isFramework)
- : Dir(dir), DirCharacteristic(DT), UserSupplied(isUser),
- Framework(isFramework) {}
+ : DirCharacteristic(DT), UserSupplied(isUser),
+ Framework(isFramework), isHeaderMap(false) {
+ 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) {
+ u.Map = map;
+ }
/// getDir - Return the directory that this entry refers to.
///
- const DirectoryEntry *getDir() const { return Dir; }
+ const DirectoryEntry *getDir() const { return !isHeaderMap ? u.Dir : 0; }
+
+ /// getHeaderMap - Return the directory that this entry refers to.
+ ///
+ const HeaderMap *getHeaderMap() const { return isHeaderMap ? u.Map : 0; }
/// DirCharacteristic - The type of directory this is, one of the DirType enum
/// values.
Added: cfe/trunk/include/clang/Lex/HeaderMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderMap.h?rev=45089&view=auto
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderMap.h (added)
+++ cfe/trunk/include/clang/Lex/HeaderMap.h Mon Dec 17 00:36:45 2007
@@ -0,0 +1,37 @@
+//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the HeaderMap interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERMAP_H
+#define LLVM_CLANG_LEX_HEADERMAP_H
+
+namespace clang {
+
+/// This class represents an Apple concept known as a 'header map'. To the
+/// #include file resolution process, it basically acts like a directory of
+/// symlinks to files. Its advantages are that it is dense and more efficient
+/// to create and process than a directory of symlinks.
+class HeaderMap {
+public:
+ /// HeaderMap::Create - This attempts to load the specified file as a header
+ /// map. If it doesn't look like a HeaderMap, it gives up and returns null.
+ /// If it looks like a HeaderMap but is obviously corrupted, it puts a reason
+ /// into the string error argument and returns null.
+ static const HeaderMap *Create(const FileEntry *FE, std::string &ErrorInfo) {
+ // FIXME: woot!
+ return 0;
+ }
+};
+
+} // end namespace clang.
+
+#endif
\ No newline at end of file
Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=45089&r1=45088&r2=45089&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Mon Dec 17 00:36:45 2007
@@ -81,12 +81,17 @@
/// name like "Carbon" to the Carbon.framework directory.
llvm::StringMap<const DirectoryEntry *> FrameworkMap;
+ /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
+ /// headermaps. This vector owns the headermap.
+ std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
+
// Various statistics we track for performance analysis.
unsigned NumIncluded;
unsigned NumMultiIncludeFileOptzn;
unsigned NumFrameworkLookups, NumSubFrameworkLookups;
public:
HeaderSearch(FileManager &FM);
+ ~HeaderSearch();
FileManager &getFileMgr() const { return FileMgr; }
@@ -166,6 +171,10 @@
getFileInfo(File).ControllingMacro = ControllingMacro;
}
+ /// CreateHeaderMap - This method returns a HeaderMap for the specified
+ /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
+ const HeaderMap *CreateHeaderMap(const FileEntry *FE, std::string &ErrorInfo);
+
void PrintStats();
private:
const FileEntry *DoFrameworkLookup(const DirectoryEntry *Dir,
More information about the cfe-commits
mailing list