[clang] 3063a54 - [clang-cl] Implement /external:I, /external:env, and EXTERNAL_INCLUDE support (PR36003)

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 21 06:42:16 PDT 2021


Author: Hans Wennborg
Date: 2021-06-21T15:36:14+02:00
New Revision: 3063a5472266f05add4e5b85f34141ba2e66fa2e

URL: https://github.com/llvm/llvm-project/commit/3063a5472266f05add4e5b85f34141ba2e66fa2e
DIFF: https://github.com/llvm/llvm-project/commit/3063a5472266f05add4e5b85f34141ba2e66fa2e.diff

LOG: [clang-cl] Implement /external:I, /external:env, and EXTERNAL_INCLUDE support (PR36003)

This patch does three things:

- Map the /external:I flag to -isystem

- Add support for the /external:env:<var> flag which reads system
  include paths from the <var> environment variable

- Pick up system include dirs EXTERNAL_INCLUDE in addition to the old
  INCLUDE environment variable.

Differential revision: https://reviews.llvm.org/D104387

Added: 
    

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/MSVC.cpp
    clang/test/Driver/cl-include.c
    clang/test/Driver/cl-options.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0ccf5ef891990..ede7405964ff3 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5868,6 +5868,9 @@ def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">,
 def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
   MetaVarName<"<macro[=value]>">, Alias<D>;
 def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
+def _SLASH_external_COLON_I : CLJoinedOrSeparate<"external:I">, Alias<isystem>,
+  HelpText<"Add directory to include search path with warnings suppressed">,
+  MetaVarName<"<dir>">;
 def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ftrapping_math>;
 def _SLASH_fp_except_ : CLFlag<"fp:except-">,
   HelpText<"">, Alias<fno_trapping_math>;
@@ -6076,6 +6079,9 @@ def _SLASH_volatile_Group : OptionGroup<"</volatile group>">,
 def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">;
 def _SLASH_EP : CLFlag<"EP">,
   HelpText<"Disable linemarker output and preprocess to stdout">;
+def _SLASH_external_env : CLJoined<"external:env:">,
+  HelpText<"Add dirs in env var <var> to include search path with warnings suppressed">,
+  MetaVarName<"<var>">;
 def _SLASH_FA : CLFlag<"FA">,
   HelpText<"Output assembly code file during compilation">;
 def _SLASH_Fa : CLJoined<"Fa">,
@@ -6239,7 +6245,6 @@ def _SLASH_doc : CLJoined<"doc">;
 def _SLASH_experimental : CLJoined<"experimental:">;
 def _SLASH_exportHeader : CLFlag<"exportHeader">;
 def _SLASH_external : CLJoined<"external:">;
-def _SLASH_external_COLON_I : CLJoinedOrSeparate<"external:I">;
 def _SLASH_FA_joined : CLJoined<"FA">;
 def _SLASH_favor : CLJoined<"favor">;
 def _SLASH_fsanitize_address_use_after_return : CLJoined<"fsanitize-address-use-after-return">;

diff  --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index cf08c42965c8f..18543f313b2f6 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -1243,23 +1243,34 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
   for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
     addSystemInclude(DriverArgs, CC1Args, Path);
 
+  auto AddSystemIncludesFromEnv = [&](StringRef Var) -> bool {
+    SmallVector<StringRef, 8> Dirs;
+    if (auto Val = llvm::sys::Process::GetEnv(Var)) {
+      StringRef(*Val).split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+      if (!Dirs.empty()) {
+        addSystemIncludes(DriverArgs, CC1Args, Dirs);
+        return true;
+      }
+    }
+    return false;
+  };
+
+  // Add %INCLUDE%-like dirs via /external:env: flags.
+  for (const auto &Var :
+       DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
+    AddSystemIncludesFromEnv(Var);
+  }
+
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
-  // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
-  // Skip if the user expressly set a vctoolsdir
+  // Honor %INCLUDE% and %EXTERNAL_INCLUDE%. It should have essential search
+  // paths set by vcvarsall.bat. Skip if the user expressly set a vctoolsdir.
   if (!DriverArgs.getLastArg(options::OPT__SLASH_vctoolsdir,
                              options::OPT__SLASH_winsysroot)) {
-    if (llvm::Optional<std::string> cl_include_dir =
-            llvm::sys::Process::GetEnv("INCLUDE")) {
-      SmallVector<StringRef, 8> Dirs;
-      StringRef(*cl_include_dir)
-          .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
-      for (StringRef Dir : Dirs)
-        addSystemInclude(DriverArgs, CC1Args, Dir);
-      if (!Dirs.empty())
-        return;
-    }
+    if (AddSystemIncludesFromEnv("INCLUDE") |
+        AddSystemIncludesFromEnv("EXTERNAL_INCLUDE"))
+      return;
   }
 
   // When built with access to the proper Windows APIs, try to actually find

diff  --git a/clang/test/Driver/cl-include.c b/clang/test/Driver/cl-include.c
index a69265deed02c..ca9e7db1e6f07 100644
--- a/clang/test/Driver/cl-include.c
+++ b/clang/test/Driver/cl-include.c
@@ -7,19 +7,37 @@
 // RUN: %clang_cl -nobuiltininc -### -- %s 2>&1 | FileCheck %s --check-prefix=NOBUILTIN
 // NOBUILTIN-NOT: "-internal-isystem" "{{.*lib.*clang.*include}}"
 
-// RUN: env INCLUDE=/my/system/inc %clang_cl -### -- %s 2>&1 | FileCheck %s --check-prefix=STDINC
+// RUN: env INCLUDE=/my/system/inc env EXTERNAL_INCLUDE=/my/system/inc2 %clang_cl -### -- %s 2>&1 | FileCheck %s --check-prefix=STDINC
 // STDINC: "-internal-isystem" "/my/system/inc"
+// STDINC: "-internal-isystem" "/my/system/inc2"
 
 // -nostdinc suppresses all of %INCLUDE%, clang resource dirs, and -imsvc dirs.
-// RUN: env INCLUDE=/my/system/inc %clang_cl -nostdinc -imsvc /my/other/inc -### -- %s 2>&1 | FileCheck %s --check-prefix=NOSTDINC
+// RUN: env INCLUDE=/my/system/inc env EXTERNAL_INCLUDE=/my/system/inc2 %clang_cl -nostdinc -imsvc /my/other/inc -### -- %s 2>&1 | FileCheck %s --check-prefix=NOSTDINC
 // NOSTDINC: argument unused{{.*}}-imsvc
 // NOSTDINC-NOT: "-internal-isystem" "/my/system/inc"
+// NOSTDINC-NOT: "-internal-isystem" "/my/system/inc2"
 // NOSTDINC-NOT: "-internal-isystem" "{{.*lib.*clang.*include}}"
 // NOSTDINC-NOT: "-internal-isystem" "/my/other/inc"
 
-// /X suppresses %INCLUDE% but not clang resource dirs or -imsvc dirs.
-// RUN: env INCLUDE=/my/system/inc %clang_cl /X -imsvc /my/other/inc -### -- %s 2>&1 | FileCheck %s --check-prefix=SLASHX
+// /X suppresses %INCLUDE% and %EXTERNAL_INCLUDE% but not clang resource dirs, -imsvc dirs, or /external: flags.
+// RUN: env INCLUDE=/my/system/inc env EXTERNAL_INCLUDE=/my/system/inc2 env FOO=/my/other/inc2 %clang_cl /X -imsvc /my/other/inc /external:env:FOO -### -- %s 2>&1 | FileCheck %s --check-prefix=SLASHX
 // SLASHX-NOT: "argument unused{{.*}}-imsvc"
 // SLASHX-NOT: "-internal-isystem" "/my/system/inc"
+// SLASHX-NOT: "-internal-isystem" "/my/system/inc2"
 // SLASHX: "-internal-isystem" "{{.*lib.*clang.*include}}"
 // SLASHX: "-internal-isystem" "/my/other/inc"
+// SLASHX: "-internal-isystem" "/my/other/inc2"
+
+// /winsysroot suppresses %EXTERNAL_INCLUDE% but not -imsvc dirs or /external: flags.
+// RUN: env env EXTERNAL_INCLUDE=/my/system/inc env FOO=/my/other/inc2 %clang_cl /winsysroot /foo -imsvc /my/other/inc /external:env:FOO -### -- %s 2>&1 | FileCheck %s --check-prefix=SYSROOT
+// SYSROOT-NOT: "argument unused{{.*}}-imsvc"
+// SYSROOT-NOT: "argument unused{{.*}}/external:"
+// SYSROOT-NOT: "/my/system/inc"
+// SYSROOT: "-internal-isystem" "/my/other/inc"
+// SYSROOT: "-internal-isystem" "/my/other/inc2"
+// SYSROOT: "-internal-isystem" "/foo{{.*}}"
+
+// RUN: env "FOO=/dir1;/dir2" env "BAR=/dir3" %clang_cl /external:env:FOO /external:env:BAR -### -- %s 2>&1 | FileCheck %s --check-prefix=EXTERNAL_ENV
+// EXTERNAL_ENV: "-internal-isystem" "/dir1"
+// EXTERNAL_ENV: "-internal-isystem" "/dir2"
+// EXTERNAL_ENV: "-internal-isystem" "/dir3"

diff  --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c
index 258ac451fee08..a483cc260612b 100644
--- a/clang/test/Driver/cl-options.c
+++ b/clang/test/Driver/cl-options.c
@@ -38,6 +38,10 @@
 // EP: "-P"
 // EP: "-o" "-"
 
+// RUN: %clang_cl /external:Ipath  -### -- %s 2>&1 | FileCheck -check-prefix=EXTERNAL_I %s
+// RUN: %clang_cl /external:I path -### -- %s 2>&1 | FileCheck -check-prefix=EXTERNAL_I %s
+// EXTERNAL_I: "-isystem" "path"
+
 // RUN: %clang_cl /fp:fast /fp:except -### -- %s 2>&1 | FileCheck -check-prefix=fpexcept %s
 // fpexcept-NOT: -menable-unsafe-fp-math
 
@@ -434,8 +438,6 @@
 // RUN:     /experimental:preprocessor \
 // RUN:     /exportHeader /headerName:foo \
 // RUN:     /external:anglebrackets \
-// RUN:     /external:Ipath \
-// RUN:     /external:I path \
 // RUN:     /external:env:var \
 // RUN:     /external:W0 \
 // RUN:     /external:W1 \


        


More information about the cfe-commits mailing list