diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -683,6 +683,8 @@ "target profile option (-T) is missing">; def err_drv_hlsl_unsupported_target : Error< "HLSL code generation is unsupported for target '%0'">; +def warn_drv_dxc_missing_dxv : Warning<"dxv not found." + " Resulting DXIL will not be signed for use in release environments.">; def err_drv_invalid_range_dxil_validator_version : Error< "invalid validator version : %0\n" diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7102,3 +7102,5 @@ Group, Flags<[DXCOption, NoXarchOption]>, HelpText<"Entry point name">; +def dxc_validator_path_EQ : Joined<["--"], "dxv-path=">, Group, + HelpText<"DXIL validator installation path">; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4211,7 +4211,12 @@ for (auto &I : Inputs) I.second->claim(); } - + // Call validator for dxc. + if (IsDXCMode()) { + Action *LastAction = Actions.back(); + Actions.push_back( + C.MakeAction(LastAction, types::TY_Nothing)); + } // Claim ignored clang-cl options. Args.ClaimAllArgs(options::OPT_cl_ignored_Group); } diff --git a/clang/lib/Driver/ToolChains/HLSL.h b/clang/lib/Driver/ToolChains/HLSL.h --- a/clang/lib/Driver/ToolChains/HLSL.h +++ b/clang/lib/Driver/ToolChains/HLSL.h @@ -9,17 +9,37 @@ #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H +#include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" namespace clang { namespace driver { +namespace tools { + +namespace hlsl { +class LLVM_LIBRARY_VISIBILITY VerifyDebug : public Tool { +public: + VerifyDebug(const ToolChain &TC) : Tool("hlsl::VerifyDebug", "dxv", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +} // namespace hlsl +} // namespace tools + namespace toolchains { class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain { public: HLSLToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); + Tool *getTool(Action::ActionClass AC) const override; + bool isPICDefault() const override { return false; } bool isPIEDefault(const llvm::opt::ArgList &Args) const override { return false; @@ -30,6 +50,9 @@ TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override; static std::optional parseTargetProfile(StringRef TargetProfile); + +private: + mutable std::unique_ptr VerifyDebug; }; } // end namespace toolchains diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -8,7 +8,9 @@ #include "HLSL.h" #include "CommonArgs.h" +#include "clang/Driver/Compilation.h" #include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Job.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" @@ -133,10 +135,53 @@ } // namespace +void tools::hlsl::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + std::string DxvPath = getToolChain().GetProgramPath("dxv"); + if (DxvPath == "dxv") { + // Not find dxv. + C.getDriver().Diag(diag::warn_drv_dxc_missing_dxv); + return; + } + + ArgStringList CmdArgs; + assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); + const InputInfo &Input = Inputs[0]; + assert(Input.isFilename() && "Unexpected verify input"); + // Grabbing the output of the earlier cc1 run. + CmdArgs.push_back(Input.getFilename()); + // Use the same name as output. + CmdArgs.push_back("-o"); + CmdArgs.push_back(Input.getFilename()); + + const char *Exec = Args.MakeArgString(DxvPath); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs, Output)); +} + /// DirectX Toolchain HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : ToolChain(D, Triple, Args) {} + : ToolChain(D, Triple, Args) { + if (Args.hasArg(options::OPT_dxc_validator_path_EQ)) + getProgramPaths().push_back( + Args.getLastArgValue(options::OPT_dxc_validator_path_EQ).str()); +} + +Tool *clang::driver::toolchains::HLSLToolChain::getTool( + Action::ActionClass AC) const { + switch (AC) { + case Action::VerifyDebugInfoJobClass: + if (!VerifyDebug) + VerifyDebug.reset(new tools::hlsl::VerifyDebug(*this)); + return VerifyDebug.get(); + default: + return ToolChain::getTool(AC); + } +} std::optional clang::driver::toolchains::HLSLToolChain::parseTargetProfile( diff --git a/clang/test/Driver/dxc_D.hlsl b/clang/test/Driver/dxc_D.hlsl --- a/clang/test/Driver/dxc_D.hlsl +++ b/clang/test/Driver/dxc_D.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_dxc -DTEST=2 -### %s 2>&1 | FileCheck %s +// RUN: %clang_dxc -DTEST=2 -Tlib_6_7 -### %s 2>&1 | FileCheck %s // RUN: %clang_dxc -DTEST=2 -Tlib_6_7 %s -fcgl -Fo - | FileCheck %s --check-prefix=ERROR // Make sure -D send to cc1. diff --git a/clang/test/Driver/dxc_I.hlsl b/clang/test/Driver/dxc_I.hlsl --- a/clang/test/Driver/dxc_I.hlsl +++ b/clang/test/Driver/dxc_I.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_dxc -I test -### %s 2>&1 | FileCheck %s +// RUN: %clang_dxc -I test -Tlib_6_3 -### %s 2>&1 | FileCheck %s // Make sure -I send to cc1. // CHECK:"-I" "test" diff --git a/clang/test/Driver/dxc_dxv_path.hlsl b/clang/test/Driver/dxc_dxv_path.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/Driver/dxc_dxv_path.hlsl @@ -0,0 +1,7 @@ +// RUN: %clang_dxc -I test -Tlib_6_3 -### %s 2>&1 | FileCheck %s + +// Make sure report warning. +// CHECK:dxv not found. + +// RUN: echo "dxv" > %T/dxv && chmod 754 %T/dxv && %clang_dxc --dxv-path=%T %s -Tlib_6_3 -### 2>&1 | FileCheck %s --check-prefix=DXV_PATH +// DXV_PATH:dxv" "-" "-o" "-"