[clang] 721651b - [HLSL][clang][Driver] Support target profile command line option.
Chris Bieneman via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 15 12:18:26 PDT 2022
Author: Xiang Li
Date: 2022-04-15T14:18:18-05:00
New Revision: 721651be246e26efd767c3ec55c8f06c7b5a9a3d
URL: https://github.com/llvm/llvm-project/commit/721651be246e26efd767c3ec55c8f06c7b5a9a3d
DIFF: https://github.com/llvm/llvm-project/commit/721651be246e26efd767c3ec55c8f06c7b5a9a3d.diff
LOG: [HLSL][clang][Driver] Support target profile command line option.
The target profile option(/T) decide the shader model when compile hlsl.
The format is shaderKind_major_minor like ps_6_1.
The shader model is saved as llvm::Triple is clang/llvm like
dxil-unknown-shadermodel6.1-hull.
The main job to support the option is translating ps_6_1 into
shadermodel6.1-pixel.
That is done inside tryParseProfile at HLSL.cpp.
To integrate the option into clang Driver, a new DriverMode DxcMode is
created. When DxcMode is enabled, OSType for TargetTriple will be
forced into Triple::ShaderModel. And new ToolChain HLSLToolChain will
be created when OSType is Triple::ShaderModel.
In HLSLToolChain, ComputeEffectiveClangTriple is overridden to call
tryParseProfile when targetProfile option is set.
To make test work, Fo option is added and .hlsl is added for active
-xhlsl.
Reviewed By: beanz
Differential Revision: https://reviews.llvm.org/D122865
Patch by: Xiang Li <python3kgae at outlook.com>
Added:
clang/lib/Driver/ToolChains/HLSL.cpp
clang/lib/Driver/ToolChains/HLSL.h
Modified:
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Driver/Driver.h
clang/include/clang/Driver/Options.h
clang/include/clang/Driver/Options.td
clang/lib/Driver/CMakeLists.txt
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChain.cpp
clang/lib/Driver/Types.cpp
clang/test/lit.cfg.py
clang/unittests/Driver/ToolChainTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 64af4c84672fe..cb53804d9e4f8 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -657,4 +657,7 @@ def warn_drv_fjmc_for_elf_only : Warning<
def err_drv_target_variant_invalid : Error<
"unsupported '%0' value '%1'; use 'ios-macabi' instead">;
+def err_drv_invalid_directx_shader_module : Error<
+ "invalid profile : %0">;
+
}
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 6f24f649ea544..b33b64cd9e6a2 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -68,7 +68,8 @@ class Driver {
GXXMode,
CPPMode,
CLMode,
- FlangMode
+ FlangMode,
+ DXCMode
} Mode;
enum SaveTempsMode {
@@ -195,6 +196,9 @@ class Driver {
/// Other modes fall back to calling gcc which in turn calls gfortran.
bool IsFlangMode() const { return Mode == FlangMode; }
+ /// Whether the driver should follow dxc.exe like behavior.
+ bool IsDXCMode() const { return Mode == DXCMode; }
+
/// Only print tool bindings, don't build any jobs.
unsigned CCCPrintBindings : 1;
diff --git a/clang/include/clang/Driver/Options.h b/clang/include/clang/Driver/Options.h
index 056660192ac5f..f9b9632ee7cbe 100644
--- a/clang/include/clang/Driver/Options.h
+++ b/clang/include/clang/Driver/Options.h
@@ -35,7 +35,8 @@ enum ClangFlags {
FlangOption = (1 << 14),
FC1Option = (1 << 15),
FlangOnlyOption = (1 << 16),
- Ignored = (1 << 17),
+ DXCOption = (1 << 17),
+ Ignored = (1 << 18),
};
enum ID {
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 104c8ea8483d1..f454bd038ecf8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -49,6 +49,10 @@ def CC1Option : OptionFlag;
// CC1AsOption - This option should be accepted by clang -cc1as.
def CC1AsOption : OptionFlag;
+// DXCOption - This is a dxc.exe compatibility option. Options with this flag
+// are made available when the driver is running in DXC compatibility mode.
+def DXCOption : OptionFlag;
+
// NoDriverOption - This option should not be accepted by the driver.
def NoDriverOption : OptionFlag;
@@ -6686,3 +6690,33 @@ def _SLASH_Ze : CLFlag<"Ze">;
def _SLASH_Zg : CLFlag<"Zg">;
def _SLASH_ZI : CLFlag<"ZI">;
def _SLASH_ZW : CLJoined<"ZW">;
+
+//===----------------------------------------------------------------------===//
+// clang-dxc Options
+//===----------------------------------------------------------------------===//
+
+def dxc_Group : OptionGroup<"<clang-dxc options>">, Flags<[DXCOption]>,
+ HelpText<"dxc compatibility options">;
+
+class DXCJoinedOrSeparate<string name> : Option<["/", "-"], name,
+ KIND_JOINED_OR_SEPARATE>, Group<dxc_Group>, Flags<[DXCOption, NoXarchOption]>;
+
+def dxc_help : Option<["/", "-", "--"], "help", KIND_JOINED>,
+ Group<dxc_Group>, Flags<[DXCOption, NoXarchOption]>, Alias<help>,
+ HelpText<"Display available options">;
+
+
+def Fo : DXCJoinedOrSeparate<"Fo">, Alias<o>,
+ HelpText<"Output object file.">;
+
+def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
+ HelpText<"Set target profile.">,
+ Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"
+ "vs_6_0, vs_6_1, vs_6_2, vs_6_3, vs_6_4, vs_6_5, vs_6_6, vs_6_7,"
+ "gs_6_0, gs_6_1, gs_6_2, gs_6_3, gs_6_4, gs_6_5, gs_6_6, gs_6_7,"
+ "hs_6_0, hs_6_1, hs_6_2, hs_6_3, hs_6_4, hs_6_5, hs_6_6, hs_6_7,"
+ "ds_6_0, ds_6_1, ds_6_2, ds_6_3, ds_6_4, ds_6_5, ds_6_6, ds_6_7,"
+ "cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, cs_6_6, cs_6_7,"
+ "lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x,"
+ "ms_6_5, ms_6_6, ms_6_7,"
+ "as_6_5, as_6_6, as_6_7">;
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index dc6d370810abb..18c9b2d042f6c 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -60,6 +60,7 @@ add_clang_library(clangDriver
ToolChains/HIPAMD.cpp
ToolChains/HIPSPV.cpp
ToolChains/Hexagon.cpp
+ ToolChains/HLSL.cpp
ToolChains/Hurd.cpp
ToolChains/Linux.cpp
ToolChains/MipsLinux.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8de1a364092dc..0095e87b6ba00 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -26,6 +26,7 @@
#include "ToolChains/Gnu.h"
#include "ToolChains/HIPAMD.h"
#include "ToolChains/HIPSPV.h"
+#include "ToolChains/HLSL.h"
#include "ToolChains/Haiku.h"
#include "ToolChains/Hexagon.h"
#include "ToolChains/Hurd.h"
@@ -232,6 +233,7 @@ void Driver::setDriverMode(StringRef Value) {
.Case("cpp", CPPMode)
.Case("cl", CLMode)
.Case("flang", FlangMode)
+ .Case("dxc", DXCMode)
.Default(None))
Mode = *M;
else
@@ -1190,7 +1192,14 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
T.setEnvironment(llvm::Triple::MSVC);
T.setObjectFormat(llvm::Triple::COFF);
TargetTriple = T.str();
+ } else if (IsDXCMode()) {
+ // clang-dxc target is build from target_profile option.
+ // Just set OS to shader model to select HLSLToolChain.
+ llvm::Triple T(TargetTriple);
+ T.setOS(llvm::Triple::ShaderModel);
+ TargetTriple = T.str();
}
+
if (const Arg *A = Args.getLastArg(options::OPT_target))
TargetTriple = A->getValue();
if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
@@ -5684,6 +5693,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
case llvm::Triple::ZOS:
TC = std::make_unique<toolchains::ZOS>(*this, Target, Args);
break;
+ case llvm::Triple::ShaderModel:
+ TC = std::make_unique<toolchains::HLSLToolChain>(*this, Target, Args);
+ break;
default:
// Of these targets, Hexagon is the only one that might have
// an OS of Linux, in which case it got handled above already.
@@ -5902,7 +5914,13 @@ Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
} else {
ExcludedFlagsBitmask |= options::CLOption;
}
-
+ if (IsDXCMode()) {
+ // Include DXC and Core options.
+ IncludedFlagsBitmask |= options::DXCOption;
+ IncludedFlagsBitmask |= options::CoreOption;
+ } else {
+ ExcludedFlagsBitmask |= options::DXCOption;
+ }
return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
}
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index f4415a30eb9d4..d45a90048dcbe 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -153,6 +153,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
{"cl", "--driver-mode=cl"},
{"++", "--driver-mode=g++"},
{"flang", "--driver-mode=flang"},
+ {"clang-dxc", "--driver-mode=dxc"},
};
for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) {
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
new file mode 100644
index 0000000000000..a2a2a3a7bf552
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -0,0 +1,133 @@
+//===--- HLSL.cpp - HLSL ToolChain Implementations --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "HLSL.h"
+#include "CommonArgs.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+using namespace llvm;
+
+namespace {
+
+const unsigned OfflineLibMinor = 0xF;
+
+bool isLegalShaderModel(Triple &T) {
+ if (T.getOS() != Triple::OSType::ShaderModel)
+ return false;
+
+ auto Version = T.getOSVersion();
+ if (Version.getBuild())
+ return false;
+ if (Version.getSubminor())
+ return false;
+
+ auto Kind = T.getEnvironment();
+
+ switch (Kind) {
+ default:
+ return false;
+ case Triple::EnvironmentType::Vertex:
+ case Triple::EnvironmentType::Hull:
+ case Triple::EnvironmentType::Domain:
+ case Triple::EnvironmentType::Geometry:
+ case Triple::EnvironmentType::Pixel:
+ case Triple::EnvironmentType::Compute: {
+ VersionTuple MinVer(4, 0);
+ return MinVer <= Version;
+ } break;
+ case Triple::EnvironmentType::Library: {
+ VersionTuple SM6x(6, OfflineLibMinor);
+ if (Version == SM6x)
+ return true;
+
+ VersionTuple MinVer(6, 3);
+ return MinVer <= Version;
+ } break;
+ case Triple::EnvironmentType::Amplification:
+ case Triple::EnvironmentType::Mesh: {
+ VersionTuple MinVer(6, 5);
+ return MinVer <= Version;
+ } break;
+ }
+ return false;
+}
+
+std::string tryParseProfile(StringRef Profile) {
+ // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
+ SmallVector<StringRef, 3> Parts;
+ Profile.split(Parts, "_");
+ if (Parts.size() != 3)
+ return "";
+
+ Triple::EnvironmentType Kind =
+ StringSwitch<Triple::EnvironmentType>(Parts[0])
+ .Case("ps", Triple::EnvironmentType::Pixel)
+ .Case("vs", Triple::EnvironmentType::Vertex)
+ .Case("gs", Triple::EnvironmentType::Geometry)
+ .Case("hs", Triple::EnvironmentType::Hull)
+ .Case("ds", Triple::EnvironmentType::Domain)
+ .Case("cs", Triple::EnvironmentType::Compute)
+ .Case("lib", Triple::EnvironmentType::Library)
+ .Case("ms", Triple::EnvironmentType::Mesh)
+ .Case("as", Triple::EnvironmentType::Amplification)
+ .Default(Triple::EnvironmentType::UnknownEnvironment);
+ if (Kind == Triple::EnvironmentType::UnknownEnvironment)
+ return "";
+
+ unsigned long long Major = 0;
+ if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
+ return "";
+
+ unsigned long long Minor = 0;
+ if (Parts[2] == "x" && Kind == Triple::EnvironmentType::Library)
+ Minor = OfflineLibMinor;
+ else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
+ return "";
+
+ // dxil-unknown-shadermodel-hull
+ llvm::Triple T;
+ T.setArch(Triple::ArchType::dxil);
+ T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() +
+ VersionTuple(Major, Minor).getAsString());
+ T.setEnvironment(Kind);
+ if (isLegalShaderModel(T))
+ return T.getTriple();
+ else
+ return "";
+}
+
+} // namespace
+
+/// DirectX Toolchain
+HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : ToolChain(D, Triple, Args) {}
+
+std::string
+HLSLToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
+ types::ID InputType) const {
+ if (Arg *A = Args.getLastArg(options::OPT_target_profile)) {
+ StringRef Profile = A->getValue();
+ std::string Triple = tryParseProfile(Profile);
+ if (Triple == "") {
+ getDriver().Diag(diag::err_drv_invalid_directx_shader_module) << Profile;
+ Triple = ToolChain::ComputeEffectiveClangTriple(Args, InputType);
+ }
+ A->claim();
+ return Triple;
+ } else {
+ return ToolChain::ComputeEffectiveClangTriple(Args, InputType);
+ }
+}
diff --git a/clang/lib/Driver/ToolChains/HLSL.h b/clang/lib/Driver/ToolChains/HLSL.h
new file mode 100644
index 0000000000000..052003f53ae05
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/HLSL.h
@@ -0,0 +1,37 @@
+//===--- HLSL.h - HLSL ToolChain Implementations ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H
+
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
+public:
+ HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
+ bool isPICDefault() const override { return false; }
+ bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
+ return false;
+ }
+ bool isPICDefaultForced() const override { return false; }
+
+ std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+ types::ID InputType) const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HLSL_H
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 8f6adc6c2ad1e..befdc50faa9c5 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -332,6 +332,7 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
.Case("c++m", TY_CXXModule)
.Case("cppm", TY_CXXModule)
.Case("cxxm", TY_CXXModule)
+ .Case("hlsl", TY_HLSL)
.Default(TY_INVALID);
}
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index 44b26e7822714..afc119cd4166d 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -67,6 +67,8 @@
'clang-tblgen', 'clang-scan-deps', 'opt', 'llvm-ifs', 'yaml2obj',
ToolSubst('%clang_extdef_map', command=FindTool(
'clang-extdef-mapping'), unresolved='ignore'),
+ ToolSubst('%clang_dxc', command=config.clang,
+ extra_args=['--driver-mode=dxc']),
]
if config.clang_examples:
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index 286ad84e92d67..3d9d266ef3161 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -300,6 +300,12 @@ TEST(ToolChainTest, GetTargetAndMode) {
EXPECT_TRUE(Res.ModeSuffix == "clang-cl");
EXPECT_STREQ(Res.DriverMode, "--driver-mode=cl");
EXPECT_FALSE(Res.TargetIsValid);
+
+ Res = ToolChain::getTargetAndModeFromProgramName("clang-dxc");
+ EXPECT_TRUE(Res.TargetPrefix.empty());
+ EXPECT_TRUE(Res.ModeSuffix == "clang-dxc");
+ EXPECT_STREQ(Res.DriverMode, "--driver-mode=dxc");
+ EXPECT_FALSE(Res.TargetIsValid);
}
TEST(ToolChainTest, CommandOutput) {
@@ -361,4 +367,141 @@ TEST(GetDriverMode, PrefersLastDriverMode) {
EXPECT_EQ(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)), "bar");
}
+TEST(DxcModeTest, TargetProfileValidation) {
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ struct SimpleDiagnosticConsumer : public DiagnosticConsumer {
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override {
+ if (DiagLevel == DiagnosticsEngine::Level::Error) {
+ Errors.emplace_back();
+ Info.FormatDiagnostic(Errors.back());
+ } else {
+ Msgs.emplace_back();
+ Info.FormatDiagnostic(Msgs.back());
+ }
+ }
+ void clear() override {
+ Msgs.clear();
+ Errors.clear();
+ DiagnosticConsumer::clear();
+ }
+ std::vector<SmallString<32>> Msgs;
+ std::vector<SmallString<32>> Errors;
+ };
+
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new llvm::vfs::InMemoryFileSystem);
+
+ InMemoryFileSystem->addFile("foo.hlsl", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+
+ auto *DiagConsumer = new SimpleDiagnosticConsumer;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+ DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
+ Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
+ std::unique_ptr<Compilation> C(
+ TheDriver.BuildCompilation({"clang", "--driver-mode=dxc", "foo.hlsl"}));
+ EXPECT_TRUE(C);
+ EXPECT_TRUE(!C->containsError());
+
+ auto &TC = C->getDefaultToolChain();
+ bool ContainsError = false;
+ auto Args = TheDriver.ParseArgStrings({"-Tvs_6_0"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ auto Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.0-vertex");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Ths_6_1"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.1-hull");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tgs_6_3"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.3-geometry");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tps_6_4"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.4-pixel");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tcs_6_5"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.5-compute");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tms_6_6"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.6-mesh");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tas_6_7"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.7-amplification");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ Args = TheDriver.ParseArgStrings({"-Tlib_6_x"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.15-library");
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+
+ // Invalid tests.
+ Args = TheDriver.ParseArgStrings({"-Tpss_6_1"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
+ EXPECT_EQ(Diags.getNumErrors(), 1u);
+ EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : pss_6_1");
+ Diags.Clear();
+ DiagConsumer->clear();
+
+ Args = TheDriver.ParseArgStrings({"-Tps_6_x"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
+ EXPECT_EQ(Diags.getNumErrors(), 2u);
+ EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : ps_6_x");
+ Diags.Clear();
+ DiagConsumer->clear();
+
+ Args = TheDriver.ParseArgStrings({"-Tlib_6_1"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
+ EXPECT_EQ(Diags.getNumErrors(), 3u);
+ EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : lib_6_1");
+ Diags.Clear();
+ DiagConsumer->clear();
+
+ Args = TheDriver.ParseArgStrings({"-Tfoo"}, false, ContainsError);
+ EXPECT_FALSE(ContainsError);
+ Triple = TC.ComputeEffectiveClangTriple(Args);
+ EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
+ EXPECT_EQ(Diags.getNumErrors(), 4u);
+ EXPECT_STREQ(DiagConsumer->Errors.back().data(), "invalid profile : foo");
+ Diags.Clear();
+ DiagConsumer->clear();
+}
+
} // end anonymous namespace.
More information about the cfe-commits
mailing list