aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorEvan Wilde <etceterawilde@gmail.com>2024-03-19 13:17:11 -0700
committerGitHub <noreply@github.com>2024-03-19 13:17:11 -0700
commit12a6546395c6225112731f33608afed452c4f8d1 (patch)
treee4f625d30e9383750980b23bbe7823fc497dfcf3 /clang/lib/Frontend/CompilerInvocation.cpp
parent4242d15e68580d1d1f7c4d782a59e6dffb698ca8 (diff)
downloadllvm-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.cpp43
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))