diff options
author | Evan Wilde <etceterawilde@gmail.com> | 2024-03-19 13:17:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-19 13:17:11 -0700 |
commit | 12a6546395c6225112731f33608afed452c4f8d1 (patch) | |
tree | e4f625d30e9383750980b23bbe7823fc497dfcf3 /clang/lib/Frontend/CompilerInvocation.cpp | |
parent | 4242d15e68580d1d1f7c4d782a59e6dffb698ca8 (diff) | |
download | llvm-12a6546395c6225112731f33608afed452c4f8d1.zip llvm-12a6546395c6225112731f33608afed452c4f8d1.tar.gz llvm-12a6546395c6225112731f33608afed452c4f8d1.tar.bz2 |
Add support for sysroot-relative system header search paths (#82084)
Clang supported header searchpaths of the form `-I =/path`, relative to
the sysroot if one is passed, but did not implement that behavior for
`-iquote`, `-isystem`, or `-idirafter`.
This implements the `=` portion of the behavior implemented by GCC for
these flags described in
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html.
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2a21a9d..0df6a82 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3191,6 +3191,22 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, bool IsIndexHeaderMap = false; bool IsSysrootSpecified = Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); + + // Expand a leading `=` to the sysroot if one was passed (and it's not a + // framework flag). + auto PrefixHeaderPath = [IsSysrootSpecified, + &Opts](const llvm::opt::Arg *A, + bool IsFramework = false) -> std::string { + assert(A->getNumValues() && "Unexpected empty search path flag!"); + if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { + SmallString<32> Buffer; + llvm::sys::path::append(Buffer, Opts.Sysroot, + llvm::StringRef(A->getValue()).substr(1)); + return std::string(Buffer); + } + return A->getValue(); + }; + for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) { if (A->getOption().matches(OPT_index_header_map)) { // -index-header-map applies to the next -I or -F. @@ -3202,16 +3218,7 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled; bool IsFramework = A->getOption().matches(OPT_F); - std::string Path = A->getValue(); - - if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { - SmallString<32> Buffer; - llvm::sys::path::append(Buffer, Opts.Sysroot, - llvm::StringRef(A->getValue()).substr(1)); - Path = std::string(Buffer); - } - - Opts.AddPath(Path, Group, IsFramework, + Opts.AddPath(PrefixHeaderPath(A, IsFramework), Group, IsFramework, /*IgnoreSysroot*/ true); IsIndexHeaderMap = false; } @@ -3229,12 +3236,18 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, } for (const auto *A : Args.filtered(OPT_idirafter)) - Opts.AddPath(A->getValue(), frontend::After, false, true); + Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true); for (const auto *A : Args.filtered(OPT_iquote)) - Opts.AddPath(A->getValue(), frontend::Quoted, false, true); - for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) - Opts.AddPath(A->getValue(), frontend::System, false, - !A->getOption().matches(OPT_iwithsysroot)); + Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true); + + for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) { + if (A->getOption().matches(OPT_iwithsysroot)) { + Opts.AddPath(A->getValue(), frontend::System, false, + /*IgnoreSysRoot=*/false); + continue; + } + Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true); + } for (const auto *A : Args.filtered(OPT_iframework)) Opts.AddPath(A->getValue(), frontend::System, true, true); for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot)) |