From 0f9d5d9db32bcd4e8f1a5a11c71bba3ae86227f7 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 6 May 2016 19:13:55 +0000 Subject: [PATCH] Frontend: support -I=path for sysroot expansion From the GCC manpage: -I dir ... If dir begins with =, then the = will be replaced by the sysroot prefix; see --sysroot and -isysroot. Add support to expand the `=` as a prefix of the include path with the sysroot if specified. `-isysroot` takes precedence over `--sysroot` as the normal argument behaviour occurs. The ordering of the `-isysroot` is relevant to the path substituted. If no `--sysroot=` or `-isysroot` option is present, the = is not expanded. Resolves PR26965! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@268777 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Frontend/CompilerInvocation.cpp | 16 ++++++++++++++-- test/Preprocessor/sysroot-prefix.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 test/Preprocessor/sysroot-prefix.c diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 0b154b6743..a97dc92adf 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1278,6 +1278,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { // Add -I..., -F..., and -index-header-map options in order. bool IsIndexHeaderMap = false; + bool IsSysrootSpecified = + Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); for (const Arg *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. @@ -1288,8 +1290,18 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { frontend::IncludeDirGroup Group = IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled; - Opts.AddPath(A->getValue(), Group, - /*IsFramework=*/A->getOption().matches(OPT_F), true); + 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 = Buffer.str(); + } + + Opts.AddPath(Path.c_str(), Group, IsFramework, + /*IgnoreSysroot*/ true); IsIndexHeaderMap = false; } diff --git a/test/Preprocessor/sysroot-prefix.c b/test/Preprocessor/sysroot-prefix.c new file mode 100644 index 0000000000..feea5023e3 --- /dev/null +++ b/test/Preprocessor/sysroot-prefix.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -v -isysroot /var/empty -I /dev/null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_NO_SYSROOT %s +// RUN: %clang_cc1 -v -isysroot /var/empty -I =/dev/null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_SYSROOT_DEV_NULL %s +// RUN: %clang_cc1 -v -I =/dev/null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-NO_ISYSROOT_SYSROOT_DEV_NULL %s +// RUN: %clang_cc1 -v -isysroot /var/empty -I =null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_SYSROOT_NULL %s +// RUN: %clang_cc1 -v -isysroot /var/empty -isysroot /var/empty/root -I =null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_ISYSROOT_SYSROOT_NULL %s +// RUN: %clang_cc1 -v -isysroot /var/empty/root -isysroot /var/empty -I =null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_ISYSROOT_SWAPPED_SYSROOT_NULL %s + +// CHECK-ISYSROOT_NO_SYSROOT: ignoring nonexistent directory "/dev/null" +// CHECK-ISYSROOT_NO_SYSROOT-NOT: ignoring nonexistent directory "/var/empty/dev/null" + +// CHECK-NO_ISYSROOT_SYSROOT_DEV_NULL: ignoring nonexistent directory "=/dev/null" +// CHECK-NO_ISYSROOT_SYSROOT_DEV_NULL-NOT: ignoring nonexistent directory "/dev/null" + +// CHECK-ISYSROOT_SYSROOT_DEV_NULL: ignoring nonexistent directory "/var/empty/dev/null" +// CHECK-ISYSROOT_SYSROOT_DEV_NULL-NOT: ignoring nonexistent directory "/dev/null" + +// CHECK-NO_ISYSROOT_SYSROOT: ignoring nonexistent directory "=/dev/null" +// CHECK-NO_ISYSROOT_SYSROOT-NOT: ignoring nonexistent directory "/var/empty/dev/null" + +// CHECK-ISYSROOT_SYSROOT_NULL: ignoring nonexistent directory "/var/empty/null" +// CHECK-ISYSROOT_SYSROOT_NULL-NOT: ignoring nonexistent directory "=null" + +// CHECK-ISYSROOT_ISYSROOT_SYSROOT_NULL: ignoring nonexistent directory "/var/empty/root/null" +// CHECK-ISYSROOT_ISYSROOT_SYSROOT_NULL-NOT: ignoring nonexistent directory "=null" + +// CHECK-ISYSROOT_ISYSROOT_SWAPPED_SYSROOT_NULL: ignoring nonexistent directory "/var/empty/null" +// CHECK-ISYSROOT_ISYSROOT_SWAPPED_SYSROOT_NULL-NOT: ignoring nonexistent directory "=null" + -- 2.50.1