[cfe-commits] r136331 - in /cfe/trunk: include/clang/Driver/CC1Options.td include/clang/Driver/Options.td include/clang/Frontend/HeaderSearchOptions.h include/clang/Lex/DirectoryLookup.h include/clang/Lex/HeaderSearch.h lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp lib/Frontend/InitHeaderSearch.cpp lib/Lex/HeaderSearch.cpp test/Driver/index-header-map.c
Douglas Gregor
dgregor at apple.com
Wed Jul 27 21:45:53 PDT 2011
Author: dgregor
Date: Wed Jul 27 23:45:53 2011
New Revision: 136331
URL: http://llvm.org/viewvc/llvm-project?rev=136331&view=rev
Log:
Introduce the "-index-header-map" option, to give special semantics
for quoted header lookup when dealing with not-yet-installed
frameworks. Fixes <rdar://problem/9824020>.
Added:
cfe/trunk/test/Driver/index-header-map.c (with props)
Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h
cfe/trunk/include/clang/Lex/DirectoryLookup.h
cfe/trunk/include/clang/Lex/HeaderSearch.h
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/Frontend/InitHeaderSearch.cpp
cfe/trunk/lib/Lex/HeaderSearch.cpp
Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Jul 27 23:45:53 2011
@@ -609,6 +609,8 @@
HelpText<"Add directory to include search path">;
def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"<directory>">,
HelpText<"Add directory to AFTER include search path">;
+def index_header_map : Flag<"-index-header-map">,
+ HelpText<"Make the next included directory (-I or -F) an indexer header map">;
def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">,
HelpText<"Add directory to QUOTE include search path">;
def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, MetaVarName<"<directory>">,
Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Wed Jul 27 23:45:53 2011
@@ -500,6 +500,7 @@
def g_Flag : Flag<"-g">, Group<g_Group>;
def g_Joined : Joined<"-g">, Group<g_Group>;
def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
+def index_header_map : Flag<"-index-header-map">;
def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>;
def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>;
Modified: cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h Wed Jul 27 23:45:53 2011
@@ -23,6 +23,8 @@
enum IncludeDirGroup {
Quoted = 0, ///< '#include ""' paths, added by'gcc -iquote'.
Angled, ///< Paths for '#include <>' added by '-I'.
+ IndexHeaderMap, ///< Like Angled, but marks header maps used when
+ /// building frameworks.
System, ///< Like Angled, but marks system directories.
CXXSystem, ///< Like System, but only used for C++.
After ///< Like System, but searched after the system directories.
Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Wed Jul 27 23:45:53 2011
@@ -56,21 +56,27 @@
/// LookupType - This indicates whether this DirectoryLookup object is a
/// normal directory, a framework, or a headermap.
unsigned LookupType : 2;
+
+ /// \brief Whether this is a header map used when building a framework.
+ unsigned IsIndexHeaderMap : 1;
+
public:
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'dir'.
DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
bool isUser, bool isFramework)
- : DirCharacteristic(DT), UserSupplied(isUser),
- LookupType(isFramework ? LT_Framework : LT_NormalDir) {
+ : DirCharacteristic(DT), UserSupplied(isUser),
+ LookupType(isFramework ? LT_Framework : LT_NormalDir),
+ IsIndexHeaderMap(false) {
u.Dir = dir;
}
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'map'.
DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
- bool isUser)
- : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) {
+ bool isUser, bool isIndexHeaderMap)
+ : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap),
+ IsIndexHeaderMap(isIndexHeaderMap) {
u.Map = map;
}
@@ -116,7 +122,11 @@
///
bool isUserSupplied() const { return UserSupplied; }
-
+ /// \brief Whether this header map is building a framework or not.
+ bool isIndexHeaderMap() const {
+ return isHeaderMap() && IsIndexHeaderMap;
+ }
+
/// LookupFile - Lookup the specified file in this search path, returning it
/// if it exists or returning null if not.
///
Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Wed Jul 27 23:45:53 2011
@@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Allocator.h"
#include <vector>
@@ -48,6 +49,15 @@
/// "resolved", meaning that it was loaded from the external source.
unsigned Resolved : 1;
+ /// \brief Whether this is a header inside a framework that is currently
+ /// being built.
+ ///
+ /// When a framework is being built, the headers have not yet been placed
+ /// into the appropriate framework subdirectories, and therefore are
+ /// provided via a header map. This bit indicates when this is one of
+ /// those framework headers.
+ unsigned IndexHeaderMapHeader : 1;
+
/// NumIncludes - This is the number of times the file has been included
/// already.
unsigned short NumIncludes;
@@ -69,10 +79,14 @@
/// external storage.
const IdentifierInfo *ControllingMacro;
+ /// \brief If this header came from a framework include, this is the name
+ /// of the framework.
+ StringRef Framework;
+
HeaderFileInfo()
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
- External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0),
- ControllingMacro(0) {}
+ External(false), Resolved(false), IndexHeaderMapHeader(false),
+ NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {}
/// \brief Retrieve the controlling macro for this header file, if
/// any.
@@ -139,6 +153,10 @@
/// headermaps. This vector owns the headermap.
std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
+ /// \brief Uniqued set of framework names, which is used to track which
+ /// headers were included as framework headers.
+ llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
+
/// \brief Entity used to resolve the identifier IDs of controlling
/// macros into IdentifierInfo pointers, as needed.
ExternalIdentifierLookup *ExternalLookup;
@@ -325,6 +343,9 @@
}
search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
+ /// \brief Retrieve a uniqued framework name.
+ StringRef getUniqueFrameworkName(StringRef Framework);
+
void PrintStats();
size_t getTotalMemory() const;
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Jul 27 23:45:53 2011
@@ -341,7 +341,8 @@
}
Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
- Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
+ Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
+ options::OPT_index_header_map);
// Add C++ include arguments, if needed.
types::ID InputType = Inputs[0].getType();
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Jul 27 23:45:53 2011
@@ -520,17 +520,31 @@
if (E.IsFramework && (E.Group != frontend::Angled || !E.IsUserSupplied))
llvm::report_fatal_error("Invalid option set!");
if (E.IsUserSupplied) {
- if (E.Group == frontend::After) {
+ switch (E.Group) {
+ case frontend::After:
Res.push_back("-idirafter");
- } else if (E.Group == frontend::Quoted) {
+ break;
+
+ case frontend::Quoted:
Res.push_back("-iquote");
- } else if (E.Group == frontend::System) {
+ break;
+
+ case frontend::System:
Res.push_back("-isystem");
- } else if (E.Group == frontend::CXXSystem) {
+ break;
+
+ case frontend::IndexHeaderMap:
+ Res.push_back("-index-header-map");
+ Res.push_back(E.IsFramework? "-F" : "-I");
+ break;
+
+ case frontend::CXXSystem:
Res.push_back("-cxx-isystem");
- } else {
- assert(E.Group == frontend::Angled && "Invalid group!");
+ break;
+
+ case frontend::Angled:
Res.push_back(E.IsFramework ? "-F" : "-I");
+ break;
}
} else {
if (E.Group != frontend::Angled && E.Group != frontend::System)
@@ -1364,11 +1378,24 @@
Opts.UseLibcxx = (strcmp(A->getValue(Args), "libc++") == 0);
Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
- // Add -I... and -F... options in order.
- for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F),
- ie = Args.filtered_end(); it != ie; ++it)
- Opts.AddPath((*it)->getValue(Args), frontend::Angled, true,
+ // Add -I..., -F..., and -index-header-map options in order.
+ bool IsIndexHeaderMap = false;
+ for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F,
+ OPT_index_header_map),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ if ((*it)->getOption().matches(OPT_index_header_map)) {
+ // -index-header-map applies to the next -I or -F.
+ IsIndexHeaderMap = true;
+ continue;
+ }
+
+ frontend::IncludeDirGroup Group
+ = IsIndexHeaderMap? frontend::IndexHeaderMap : frontend::Angled;
+
+ Opts.AddPath((*it)->getValue(Args), Group, true,
/*IsFramework=*/ (*it)->getOption().matches(OPT_F), false);
+ IsIndexHeaderMap = false;
+ }
// Add -iprefix/-iwith-prefix/-iwithprefixbefore options.
StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
Modified: cfe/trunk/lib/Frontend/InitHeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitHeaderSearch.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitHeaderSearch.cpp (original)
+++ cfe/trunk/lib/Frontend/InitHeaderSearch.cpp Wed Jul 27 23:45:53 2011
@@ -134,7 +134,7 @@
// Compute the DirectoryLookup type.
SrcMgr::CharacteristicKind Type;
- if (Group == Quoted || Group == Angled)
+ if (Group == Quoted || Group == Angled || Group == IndexHeaderMap)
Type = SrcMgr::C_User;
else if (isCXXAware)
Type = SrcMgr::C_System;
@@ -156,7 +156,7 @@
if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
// It is a headermap, add it to the search path.
IncludePath.push_back(std::make_pair(Group, DirectoryLookup(HM, Type,
- isUserSupplied)));
+ isUserSupplied, Group == IndexHeaderMap)));
return;
}
}
@@ -1054,7 +1054,7 @@
for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
it != ie; ++it) {
- if (it->first == Angled)
+ if (it->first == Angled || it->first == IndexHeaderMap)
SearchList.push_back(it->second);
}
Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Wed Jul 27 23:45:53 2011
@@ -280,7 +280,23 @@
return FileMgr.getFile(Filename, /*openFile=*/true);
}
- // Step #0, unless disabled, check to see if the file is in the #includer's
+ // If we are including a file with a quoted include "foo.h" from inside
+ // a header in a framework that is currently being built, change the include
+ // to <Foo/foo.h>, where "Foo" is the name of the framework in which the
+ // including header was found.
+ llvm::SmallString<128> ScratchFilename;
+ if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) {
+ HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt);
+ if (IncludingHFI.IndexHeaderMapHeader) {
+ isAngled = true;
+ ScratchFilename += IncludingHFI.Framework;
+ ScratchFilename += '/';
+ ScratchFilename += Filename;
+ Filename = ScratchFilename;
+ }
+ }
+
+ // Unless disabled, check to see if the file is in the #includer's
// 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".
@@ -353,8 +369,20 @@
CurDir = &SearchDirs[i];
// This file is a system header or C++ unfriendly if the dir is.
- getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
+ HeaderFileInfo &HFI = getFileInfo(FE);
+ HFI.DirInfo = CurDir->getDirCharacteristic();
+ // If this file is found in a header map and uses the framework style of
+ // includes, then this header is part of a framework we're building.
+ if (CurDir->isIndexHeaderMap()) {
+ size_t SlashPos = Filename.find('/');
+ if (SlashPos != StringRef::npos) {
+ HFI.IndexHeaderMapHeader = 1;
+ HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
+ SlashPos));
+ }
+ }
+
// Remember this location for the next lookup we do.
CacheLookup.second = i;
return FE;
@@ -550,3 +578,7 @@
+ LookupFileCache.getAllocator().getTotalMemory()
+ FrameworkMap.getAllocator().getTotalMemory();
}
+
+StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
+ return FrameworkNames.GetOrCreateValue(Framework).getKey();
+}
Added: cfe/trunk/test/Driver/index-header-map.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/index-header-map.c?rev=136331&view=auto
==============================================================================
--- cfe/trunk/test/Driver/index-header-map.c (added)
+++ cfe/trunk/test/Driver/index-header-map.c Wed Jul 27 23:45:53 2011
@@ -0,0 +1,4 @@
+// RUN: %clang -I%S/Before -index-header-map -I%S/Index -I%S/After %s -### 2>> %t.log
+// RUN: FileCheck %s < %t.log
+
+// CHECK: {{-I.*Before.*-index-header-map.*-I.*Index.*-I.*After}}
Propchange: cfe/trunk/test/Driver/index-header-map.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Driver/index-header-map.c
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Driver/index-header-map.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list