diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Driver/Tools.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 47 | ||||
-rw-r--r-- | lib/Frontend/InitHeaderSearch.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/HeaderSearch.cpp | 38 |
4 files changed, 77 insertions, 17 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 31413c7cf9..5fd2b9b486 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -341,7 +341,8 @@ void Clang::AddPreprocessingOptions(const Driver &D, } 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(); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8967d5280b..47e9590f47 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -520,17 +520,31 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts, 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 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { 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. diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index ed763e27c7..f596b992f5 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -134,7 +134,7 @@ void InitHeaderSearch::AddPath(const Twine &Path, // 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 @@ void InitHeaderSearch::AddPath(const Twine &Path, 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 @@ void InitHeaderSearch::Realize(const LangOptions &Lang) { 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); } diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 11cb1ecd8c..2592ada676 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -280,7 +280,23 @@ const FileEntry *HeaderSearch::LookupFile( 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 @@ const FileEntry *HeaderSearch::LookupFile( 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 @@ size_t HeaderSearch::getTotalMemory() const { + LookupFileCache.getAllocator().getTotalMemory() + FrameworkMap.getAllocator().getTotalMemory(); } + +StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { + return FrameworkNames.GetOrCreateValue(Framework).getKey(); +} |