]> granicus.if.org Git - clang/commitdiff
Frontend: support -I=path for sysroot expansion
authorSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 6 May 2016 19:13:55 +0000 (19:13 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 6 May 2016 19:13:55 +0000 (19:13 +0000)
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
test/Preprocessor/sysroot-prefix.c [new file with mode: 0644]

index 0b154b6743c8c923f4aa6b41df05b7028af77992..a97dc92adfa81f0913fd53f39ffd6d9e82b6df1e 100644 (file)
@@ -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 (file)
index 0000000..feea502
--- /dev/null
@@ -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"
+