From: Joerg Sonnenberger Date: Tue, 22 Feb 2011 00:40:56 +0000 (+0000) Subject: Bug#8945: Add -cxx-isystem option to specify C++ system directories. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2df6647847af283302834dadae5d9dcefa7e0ad4;p=clang Bug#8945: Add -cxx-isystem option to specify C++ system directories. It works like -isystem and the search path keeps -isystem and -cxx-isystem in order relative to each other. -cxx-isystem is only used for C++ sources though. Drop the existing -cxx-system-include option for cc1 as it is now redundant. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126167 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index a2c69f9954..17fd41a406 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -536,6 +536,8 @@ def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"">, HelpText<"Add directory to AFTER include search path">; def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"">, HelpText<"Add directory to QUOTE include search path">; +def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, MetaVarName<"">, + HelpText<"Add directory to the C++ SYSTEM include search path">; def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"">, HelpText<"Add directory to SYSTEM include search path">; def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">,MetaVarName<"">, @@ -550,8 +552,6 @@ def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, HelpText<"Set directory to include search path with prefix">; def isysroot : JoinedOrSeparate<"-isysroot">, MetaVarName<"">, HelpText<"Set the system root directory (usually /)">; -def cxx_system_include : Separate<"-cxx-system-include">, - HelpText<"Add a system #include directory for the C++ standard library">; def v : Flag<"-v">, HelpText<"Enable verbose output">; //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 7e3ddc616e..288c10f523 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -208,6 +208,7 @@ def compatibility__version : JoinedOrSeparate<"-compatibility_version">; def coverage : Flag<"-coverage">; def cpp_precomp : Flag<"-cpp-precomp">; def current__version : JoinedOrSeparate<"-current_version">; +def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, Group; def c : Flag<"-c">, Flags<[DriverOption]>, HelpText<"Only run preprocess, compile, and assemble steps">; def dA : Flag<"-dA">, Group; diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h index cbb4a57993..51e22d23d7 100644 --- a/include/clang/Frontend/HeaderSearchOptions.h +++ b/include/clang/Frontend/HeaderSearchOptions.h @@ -22,6 +22,7 @@ namespace frontend { Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`. Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`) System, ///< Like Angled, but marks system directories. + CXXSystem, ///< Like System, but only used for C++. After ///< Like System, but searched after the system directories. }; } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 103d251a88..915634b1dd 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -490,6 +490,8 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts, Res.push_back("-iquote"); } else if (E.Group == frontend::System) { Res.push_back("-isystem"); + } else if (E.Group == frontend::CXXSystem) { + Res.push_back("-cxx-isystem"); } else { assert(E.Group == frontend::Angled && "Invalid group!"); Res.push_back(E.IsFramework ? "-F" : "-I"); @@ -1236,7 +1238,6 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0, static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { using namespace cc1options; - Opts.CXXSystemIncludes = Args.getAllArgValues(OPT_cxx_system_include); Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/"); Opts.Verbose = Args.hasArg(OPT_v); Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc); @@ -1272,10 +1273,12 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { for (arg_iterator it = Args.filtered_begin(OPT_iquote), ie = Args.filtered_end(); it != ie; ++it) Opts.AddPath((*it)->getValue(Args), frontend::Quoted, true, false, true); - for (arg_iterator it = Args.filtered_begin(OPT_isystem, OPT_iwithsysroot), - ie = Args.filtered_end(); it != ie; ++it) - Opts.AddPath((*it)->getValue(Args), frontend::System, true, false, - (*it)->getOption().matches(OPT_iwithsysroot)); + for (arg_iterator it = Args.filtered_begin(OPT_cxx_isystem, OPT_isystem, + OPT_iwithsysroot), ie = Args.filtered_end(); it != ie; ++it) + Opts.AddPath((*it)->getValue(Args), + ((*it)->getOption().matches(OPT_cxx_isystem) ? + frontend::CXXSystem : frontend::System), + true, false, (*it)->getOption().matches(OPT_iwithsysroot)); // FIXME: Need options for the various environment variables! } diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 4855b62b74..855a9bed4c 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -42,7 +42,9 @@ namespace { /// a HeaderSearch object. InitHeaderSearch stores several search path lists /// internally, which can be sent to a HeaderSearch object in one swoop. class InitHeaderSearch { - std::vector IncludeGroup[4]; + std::vector > IncludePath; + typedef std::vector >::const_iterator path_iterator; HeaderSearch& Headers; bool Verbose; std::string IncludeSysroot; @@ -94,7 +96,7 @@ public: /// Realize - Merges all search path lists into one list and send it to /// HeaderSearch. - void Realize(); + void Realize(const LangOptions &Lang); }; } @@ -131,8 +133,8 @@ void InitHeaderSearch::AddPath(const llvm::Twine &Path, // If the directory exists, add it. if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) { - IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied, - isFramework)); + IncludePath.push_back(std::make_pair(Group, DirectoryLookup(DE, Type, + isUserSupplied, isFramework))); return; } @@ -142,7 +144,8 @@ void InitHeaderSearch::AddPath(const llvm::Twine &Path, if (const FileEntry *FE = FM.getFile(MappedPathStr)) { if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) { // It is a headermap, add it to the search path. - IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied)); + IncludePath.push_back(std::make_pair(Group, DirectoryLookup(HM, Type, + isUserSupplied))); return; } } @@ -179,29 +182,29 @@ void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(llvm::StringRef Base, llvm::StringRef Dir64, const llvm::Triple &triple) { // Add the base dir - AddPath(Base, System, true, false, false); + AddPath(Base, CXXSystem, true, false, false); // Add the multilib dirs llvm::Triple::ArchType arch = triple.getArch(); bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64; if (is64bit) - AddPath(Base + "/" + ArchDir + "/" + Dir64, System, true, false, false); + AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, true, false, false); else - AddPath(Base + "/" + ArchDir + "/" + Dir32, System, true, false, false); + AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, true, false, false); // Add the backward dir - AddPath(Base + "/backward", System, true, false, false); + AddPath(Base + "/backward", CXXSystem, true, false, false); } void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base, llvm::StringRef Arch, llvm::StringRef Version) { AddPath(Base + "/" + Arch + "/" + Version + "/include/c++", - System, true, false, false); + CXXSystem, true, false, false); AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch, - System, true, false, false); + CXXSystem, true, false, false); AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward", - System, true, false, false); + CXXSystem, true, false, false); } // FIXME: This probably should goto to some platform utils place. @@ -567,13 +570,17 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { break; case llvm::Triple::MinGW32: // mingw-w64-20110207 - AddPath("c:/MinGW/include/c++/4.5.3", System, true, false, false); - AddPath("c:/MinGW/include/c++/4.5.3/x86_64-w64-mingw32", System, true, false, false); - AddPath("c:/MinGW/include/c++/4.5.3/backward", System, true, false, false); + AddPath("c:/MinGW/include/c++/4.5.3", CXXSystem, true, false, false); + AddPath("c:/MinGW/include/c++/4.5.3/x86_64-w64-mingw32", CXXSystem, true, + false, false); + AddPath("c:/MinGW/include/c++/4.5.3/backward", CXXSystem, true, false, + false); // mingw-w64-20101129 - AddPath("c:/MinGW/include/c++/4.5.2", System, true, false, false); - AddPath("c:/MinGW/include/c++/4.5.2/x86_64-w64-mingw32", System, true, false, false); - AddPath("c:/MinGW/include/c++/4.5.2/backward", System, true, false, false); + AddPath("c:/MinGW/include/c++/4.5.2", CXXSystem, true, false, false); + AddPath("c:/MinGW/include/c++/4.5.2/x86_64-w64-mingw32", CXXSystem, true, + false, false); + AddPath("c:/MinGW/include/c++/4.5.2/backward", CXXSystem, true, false, + false); // Try gcc 4.5.0 AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0"); // Try gcc 4.4.0 @@ -613,7 +620,7 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { } break; case llvm::Triple::DragonFly: - AddPath("/usr/include/c++/4.1", System, true, false, false); + AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false); break; case llvm::Triple::Linux: //===------------------------------------------------------------------===// @@ -812,7 +819,7 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang, if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes) { if (!HSOpts.CXXSystemIncludes.empty()) { for (unsigned i = 0, e = HSOpts.CXXSystemIncludes.size(); i != e; ++i) - AddPath(HSOpts.CXXSystemIncludes[i], System, true, false, false); + AddPath(HSOpts.CXXSystemIncludes[i], CXXSystem, true, false, false); } else AddDefaultCPlusPlusIncludePaths(triple); } @@ -829,11 +836,11 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang, /// RemoveDuplicates - If there are duplicate directory entries in the specified /// search list, remove the later (dead) ones. static void RemoveDuplicates(std::vector &SearchList, - bool Verbose) { + unsigned First, bool Verbose) { llvm::SmallPtrSet SeenDirs; llvm::SmallPtrSet SeenFrameworkDirs; llvm::SmallPtrSet SeenHeaderMaps; - for (unsigned i = 0; i != SearchList.size(); ++i) { + for (unsigned i = First; i != SearchList.size(); ++i) { unsigned DirToRemove = i; const DirectoryLookup &CurEntry = SearchList[i]; @@ -908,32 +915,49 @@ static void RemoveDuplicates(std::vector &SearchList, } -void InitHeaderSearch::Realize() { +void InitHeaderSearch::Realize(const LangOptions &Lang) { // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList. std::vector SearchList; - SearchList = IncludeGroup[Angled]; - SearchList.insert(SearchList.end(), IncludeGroup[System].begin(), - IncludeGroup[System].end()); - SearchList.insert(SearchList.end(), IncludeGroup[After].begin(), - IncludeGroup[After].end()); - RemoveDuplicates(SearchList, Verbose); - RemoveDuplicates(IncludeGroup[Quoted], Verbose); + SearchList.reserve(IncludePath.size()); - // Prepend QUOTED list on the search list. - SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(), - IncludeGroup[Quoted].end()); + /* Quoted arguments go first. */ + for (path_iterator it = IncludePath.begin(), ie = IncludePath.end(); + it != ie; ++it) { + if (it->first == Quoted) + SearchList.push_back(it->second); + } + /* Deduplicate and remember index */ + RemoveDuplicates(SearchList, 0, Verbose); + unsigned quoted = SearchList.size(); + + for (path_iterator it = IncludePath.begin(), ie = IncludePath.end(); + it != ie; ++it) { + if (it->first == Angled) + SearchList.push_back(it->second); + } + + for (path_iterator it = IncludePath.begin(), ie = IncludePath.end(); + it != ie; ++it) { + if (it->first == System || (Lang.CPlusPlus && it->first == CXXSystem)) + SearchList.push_back(it->second); + } + + for (path_iterator it = IncludePath.begin(), ie = IncludePath.end(); + it != ie; ++it) { + if (it->first == After) + SearchList.push_back(it->second); + } + RemoveDuplicates(SearchList, quoted, Verbose); bool DontSearchCurDir = false; // TODO: set to true if -I- is set? - Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(), - DontSearchCurDir); + Headers.SetSearchPaths(SearchList, quoted, DontSearchCurDir); // If verbose, print the list of directories that will be searched. if (Verbose) { llvm::errs() << "#include \"...\" search starts here:\n"; - unsigned QuotedIdx = IncludeGroup[Quoted].size(); for (unsigned i = 0, e = SearchList.size(); i != e; ++i) { - if (i == QuotedIdx) + if (i == quoted) llvm::errs() << "#include <...> search starts here:\n"; const char *Name = SearchList[i].getName(); const char *Suffix; @@ -978,5 +1002,5 @@ void clang::ApplyHeaderSearchOptions(HeaderSearch &HS, if (HSOpts.UseStandardIncludes) Init.AddDefaultSystemIncludePaths(Lang, Triple, HSOpts); - Init.Realize(); + Init.Realize(Lang); }