parent
899ff4a26d
commit
c4ba38ed1e
|
@ -613,8 +613,9 @@ static std::vector<DirectoryLookup> IncludeGroup[4];
|
|||
///
|
||||
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 @@ static void AddPath(const std::string &Path, IncludeDirGroup Group,
|
|||
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 @@ static void InitializeIncludePaths(HeaderSearch &Headers, FileManager &FM,
|
|||
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 @@ static void InitializeIncludePaths(HeaderSearch &Headers, FileManager &FM,
|
|||
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 @@ static void InitializeIncludePaths(HeaderSearch &Headers, FileManager &FM,
|
|||
// 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
|
||||
|
|
|
@ -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 @@ HeaderSearch::HeaderSearch(FileManager &FM) : FileMgr(FM), FrameworkMap(64) {
|
|||
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 @@ void HeaderSearch::PrintStats() {
|
|||
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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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 */,
|
||||
|
|
|
@ -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 {
|
||||
|
@ -27,10 +31,16 @@ public:
|
|||
ExternCSystemHeaderDir
|
||||
};
|
||||
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.
|
||||
DirType DirCharacteristic : 2;
|
||||
|
@ -42,15 +52,35 @@ private:
|
|||
/// 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.
|
||||
|
|
|
@ -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
|
|
@ -81,12 +81,17 @@ class HeaderSearch {
|
|||
/// 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 @@ public:
|
|||
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,
|
||||
|
|
Loading…
Reference in New Issue