1//===- unittests/Driver/DXCModeTest.cpp --- DXC Mode tests ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Unit tests for driver DXCMode.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/Basic/DiagnosticIDs.h"
14#include "clang/Basic/DiagnosticOptions.h"
15#include "clang/Basic/LLVM.h"
16#include "clang/Basic/TargetOptions.h"
17#include "clang/Driver/Compilation.h"
18#include "clang/Driver/Driver.h"
19#include "clang/Driver/ToolChain.h"
20#include "clang/Frontend/CompilerInstance.h"
21#include "llvm/Support/VirtualFileSystem.h"
22#include "llvm/Support/raw_ostream.h"
23#include "gtest/gtest.h"
24#include <memory>
25
26#include "SimpleDiagnosticConsumer.h"
27
28using namespace clang;
29using namespace clang::driver;
30
31static void validateTargetProfile(
32 StringRef TargetProfile, StringRef ExpectTriple,
33 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> &InMemoryFileSystem,
34 DiagnosticsEngine &Diags) {
35 Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
36 std::unique_ptr<Compilation> C{TheDriver.BuildCompilation(
37 Args: {"clang", "--driver-mode=dxc", TargetProfile.data(), "foo.hlsl", "-Vd"})};
38 EXPECT_TRUE(C);
39 EXPECT_STREQ(TheDriver.getTargetTriple().c_str(), ExpectTriple.data());
40 EXPECT_EQ(Diags.getNumErrors(), 0u);
41}
42
43static void validateTargetProfile(
44 StringRef TargetProfile, StringRef ExpectError,
45 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> &InMemoryFileSystem,
46 DiagnosticsEngine &Diags, SimpleDiagnosticConsumer *DiagConsumer,
47 unsigned NumOfErrors) {
48 Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
49 std::unique_ptr<Compilation> C{TheDriver.BuildCompilation(
50 Args: {"clang", "--driver-mode=dxc", TargetProfile.data(), "foo.hlsl", "-Vd"})};
51 EXPECT_TRUE(C);
52 EXPECT_EQ(Diags.getNumErrors(), NumOfErrors);
53 EXPECT_STREQ(DiagConsumer->Errors.back().c_str(), ExpectError.data());
54 DiagConsumer->clear();
55}
56
57TEST(DxcModeTest, TargetProfileValidation) {
58 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
59
60 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
61 new llvm::vfs::InMemoryFileSystem);
62
63 InMemoryFileSystem->addFile(Path: "foo.hlsl", ModificationTime: 0,
64 Buffer: llvm::MemoryBuffer::getMemBuffer(InputData: "\n"));
65
66 auto *DiagConsumer = new SimpleDiagnosticConsumer;
67 DiagnosticOptions DiagOpts;
68 DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer);
69
70 validateTargetProfile(TargetProfile: "-Tvs_6_0", ExpectTriple: "dxilv1.0--shadermodel6.0-vertex",
71 InMemoryFileSystem, Diags);
72 validateTargetProfile(TargetProfile: "-Ths_6_1", ExpectTriple: "dxilv1.1--shadermodel6.1-hull",
73 InMemoryFileSystem, Diags);
74 validateTargetProfile(TargetProfile: "-Tds_6_2", ExpectTriple: "dxilv1.2--shadermodel6.2-domain",
75 InMemoryFileSystem, Diags);
76 validateTargetProfile(TargetProfile: "-Tds_6_2", ExpectTriple: "dxilv1.2--shadermodel6.2-domain",
77 InMemoryFileSystem, Diags);
78 validateTargetProfile(TargetProfile: "-Tgs_6_3", ExpectTriple: "dxilv1.3--shadermodel6.3-geometry",
79 InMemoryFileSystem, Diags);
80 validateTargetProfile(TargetProfile: "-Tps_6_4", ExpectTriple: "dxilv1.4--shadermodel6.4-pixel",
81 InMemoryFileSystem, Diags);
82 validateTargetProfile(TargetProfile: "-Tcs_6_5", ExpectTriple: "dxilv1.5--shadermodel6.5-compute",
83 InMemoryFileSystem, Diags);
84 validateTargetProfile(TargetProfile: "-Tms_6_6", ExpectTriple: "dxilv1.6--shadermodel6.6-mesh",
85 InMemoryFileSystem, Diags);
86 validateTargetProfile(TargetProfile: "-Tas_6_7", ExpectTriple: "dxilv1.7--shadermodel6.7-amplification",
87 InMemoryFileSystem, Diags);
88 validateTargetProfile(TargetProfile: "-Tcs_6_8", ExpectTriple: "dxilv1.8--shadermodel6.8-compute",
89 InMemoryFileSystem, Diags);
90 validateTargetProfile(TargetProfile: "-Tlib_6_x", ExpectTriple: "dxilv1.8--shadermodel6.15-library",
91 InMemoryFileSystem, Diags);
92
93 // Invalid tests.
94 validateTargetProfile(TargetProfile: "-Tpss_6_1", ExpectError: "invalid profile : pss_6_1",
95 InMemoryFileSystem, Diags, DiagConsumer, NumOfErrors: 1);
96
97 validateTargetProfile(TargetProfile: "-Tps_6_x", ExpectError: "invalid profile : ps_6_x",
98 InMemoryFileSystem, Diags, DiagConsumer, NumOfErrors: 2);
99 validateTargetProfile(TargetProfile: "-Tlib_6_1", ExpectError: "invalid profile : lib_6_1",
100 InMemoryFileSystem, Diags, DiagConsumer, NumOfErrors: 3);
101 validateTargetProfile(TargetProfile: "-Tfoo", ExpectError: "invalid profile : foo", InMemoryFileSystem,
102 Diags, DiagConsumer, NumOfErrors: 4);
103 validateTargetProfile(TargetProfile: "", ExpectError: "target profile option (-T) is missing",
104 InMemoryFileSystem, Diags, DiagConsumer, NumOfErrors: 5);
105}
106
107TEST(DxcModeTest, ValidatorVersionValidation) {
108 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
109
110 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
111 new llvm::vfs::InMemoryFileSystem);
112
113 InMemoryFileSystem->addFile(Path: "foo.hlsl", ModificationTime: 0,
114 Buffer: llvm::MemoryBuffer::getMemBuffer(InputData: "\n"));
115
116 auto *DiagConsumer = new SimpleDiagnosticConsumer;
117 DiagnosticOptions DiagOpts;
118 DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer);
119 Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
120 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
121 Args: {"clang", "--driver-mode=dxc", "-Tlib_6_7", "foo.hlsl"}));
122 EXPECT_TRUE(C);
123 EXPECT_TRUE(!C->containsError());
124
125 auto &TC = C->getDefaultToolChain();
126 bool ContainsError = false;
127 auto Args = TheDriver.ParseArgStrings(Args: {"-validator-version", "1.1"}, UseDriverMode: false,
128 ContainsError);
129 EXPECT_FALSE(ContainsError);
130 auto DAL = std::make_unique<llvm::opt::DerivedArgList>(args&: Args);
131 for (auto *A : Args)
132 DAL->append(A);
133
134 std::unique_ptr<llvm::opt::DerivedArgList> TranslatedArgs{
135 TC.TranslateArgs(Args: *DAL, BoundArch: "0", DeviceOffloadKind: Action::OffloadKind::OFK_None)};
136 EXPECT_NE(TranslatedArgs, nullptr);
137 if (TranslatedArgs) {
138 auto *A = TranslatedArgs->getLastArg(
139 clang::driver::options::OPT_dxil_validator_version);
140 EXPECT_NE(A, nullptr);
141 if (A) {
142 EXPECT_STREQ(A->getValue(), "1.1");
143 }
144 }
145 EXPECT_EQ(Diags.getNumErrors(), 0u);
146
147 // Invalid tests.
148 Args = TheDriver.ParseArgStrings(Args: {"-validator-version", "0.1"}, UseDriverMode: false,
149 ContainsError);
150 EXPECT_FALSE(ContainsError);
151 DAL = std::make_unique<llvm::opt::DerivedArgList>(args&: Args);
152 for (auto *A : Args)
153 DAL->append(A);
154
155 TranslatedArgs.reset(
156 p: TC.TranslateArgs(Args: *DAL, BoundArch: "0", DeviceOffloadKind: Action::OffloadKind::OFK_None));
157 EXPECT_EQ(Diags.getNumErrors(), 1u);
158 EXPECT_STREQ(
159 DiagConsumer->Errors.back().c_str(),
160 "invalid validator version : 0.1; if validator major version is 0, "
161 "minor version must also be 0");
162 DiagConsumer->clear();
163
164 Args = TheDriver.ParseArgStrings(Args: {"-validator-version", "1"}, UseDriverMode: false,
165 ContainsError);
166 EXPECT_FALSE(ContainsError);
167 DAL = std::make_unique<llvm::opt::DerivedArgList>(args&: Args);
168 for (auto *A : Args)
169 DAL->append(A);
170
171 TranslatedArgs.reset(
172 p: TC.TranslateArgs(Args: *DAL, BoundArch: "0", DeviceOffloadKind: Action::OffloadKind::OFK_None));
173 EXPECT_EQ(Diags.getNumErrors(), 2u);
174 EXPECT_STREQ(DiagConsumer->Errors.back().c_str(),
175 "invalid validator version : 1; format of validator version is "
176 "\"<major>.<minor>\" (ex:\"1.4\")");
177 DiagConsumer->clear();
178
179 Args = TheDriver.ParseArgStrings(Args: {"-validator-version", "-Tlib_6_7"}, UseDriverMode: false,
180 ContainsError);
181 EXPECT_FALSE(ContainsError);
182 DAL = std::make_unique<llvm::opt::DerivedArgList>(args&: Args);
183 for (auto *A : Args)
184 DAL->append(A);
185
186 TranslatedArgs.reset(
187 p: TC.TranslateArgs(Args: *DAL, BoundArch: "0", DeviceOffloadKind: Action::OffloadKind::OFK_None));
188 EXPECT_EQ(Diags.getNumErrors(), 3u);
189 EXPECT_STREQ(
190 DiagConsumer->Errors.back().c_str(),
191 "invalid validator version : -Tlib_6_7; format of validator version is "
192 "\"<major>.<minor>\" (ex:\"1.4\")");
193 DiagConsumer->clear();
194
195 Args = TheDriver.ParseArgStrings(Args: {"-validator-version", "foo"}, UseDriverMode: false,
196 ContainsError);
197 EXPECT_FALSE(ContainsError);
198 DAL = std::make_unique<llvm::opt::DerivedArgList>(args&: Args);
199 for (auto *A : Args)
200 DAL->append(A);
201
202 TranslatedArgs.reset(
203 p: TC.TranslateArgs(Args: *DAL, BoundArch: "0", DeviceOffloadKind: Action::OffloadKind::OFK_None));
204 EXPECT_EQ(Diags.getNumErrors(), 4u);
205 EXPECT_STREQ(
206 DiagConsumer->Errors.back().c_str(),
207 "invalid validator version : foo; format of validator version is "
208 "\"<major>.<minor>\" (ex:\"1.4\")");
209 DiagConsumer->clear();
210}
211
212TEST(DxcModeTest, DefaultEntry) {
213 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
214 new llvm::vfs::InMemoryFileSystem);
215
216 InMemoryFileSystem->addFile(Path: "foo.hlsl", ModificationTime: 0,
217 Buffer: llvm::MemoryBuffer::getMemBuffer(InputData: "\n"));
218
219 const char *Args[] = {"clang", "--driver-mode=dxc", "-Tcs_6_7", "foo.hlsl"};
220
221 DiagnosticOptions DiagOpts;
222 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
223 CompilerInstance::createDiagnostics(VFS&: *InMemoryFileSystem, Opts&: DiagOpts);
224
225 CreateInvocationOptions CIOpts;
226 CIOpts.Diags = Diags;
227 std::unique_ptr<CompilerInvocation> CInvok =
228 createInvocation(Args, Opts: std::move(CIOpts));
229 EXPECT_TRUE(CInvok);
230 // Make sure default entry is "main".
231 EXPECT_STREQ(CInvok->getTargetOpts().HLSLEntry.c_str(), "main");
232
233 const char *EntryArgs[] = {"clang", "--driver-mode=dxc", "-Ebar", "-Tcs_6_7",
234 "foo.hlsl"};
235 CInvok = createInvocation(Args: EntryArgs, Opts: std::move(CIOpts));
236 EXPECT_TRUE(CInvok);
237 // Make sure "-E" will set entry.
238 EXPECT_STREQ(CInvok->getTargetOpts().HLSLEntry.c_str(), "bar");
239}
240

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/unittests/Driver/DXCModeTest.cpp