1//=== ParseHLSLRootSignatureTest.cpp - Parse Root Signature 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#include "clang/AST/ASTContext.h"
10#include "clang/AST/Expr.h"
11#include "clang/Basic/Diagnostic.h"
12#include "clang/Basic/DiagnosticOptions.h"
13#include "clang/Basic/FileManager.h"
14#include "clang/Basic/LangOptions.h"
15#include "clang/Basic/SourceLocation.h"
16#include "clang/Basic/SourceManager.h"
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Lex/HeaderSearch.h"
19#include "clang/Lex/HeaderSearchOptions.h"
20#include "clang/Lex/Lexer.h"
21#include "clang/Lex/ModuleLoader.h"
22#include "clang/Lex/Preprocessor.h"
23#include "clang/Lex/PreprocessorOptions.h"
24
25#include "clang/Lex/LexHLSLRootSignature.h"
26#include "clang/Parse/ParseHLSLRootSignature.h"
27#include "gtest/gtest.h"
28
29using namespace clang;
30using namespace clang::hlsl;
31using namespace llvm::hlsl::rootsig;
32
33namespace {
34
35using llvm::dxbc::RootSignatureVersion;
36
37// Diagnostic helper for helper tests
38class ExpectedDiagConsumer : public DiagnosticConsumer {
39 virtual void anchor() {}
40
41 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
42 const Diagnostic &Info) override {
43 if (!FirstDiag || !ExpectedDiagID.has_value()) {
44 Satisfied = false;
45 return;
46 }
47 FirstDiag = false;
48
49 Satisfied = ExpectedDiagID.value() == Info.getID();
50 }
51
52 bool FirstDiag = true;
53 bool Satisfied = false;
54 std::optional<unsigned> ExpectedDiagID;
55
56public:
57 void setNoDiag() {
58 Satisfied = true;
59 ExpectedDiagID = std::nullopt;
60 }
61
62 void setExpected(unsigned DiagID) {
63 Satisfied = false;
64 ExpectedDiagID = DiagID;
65 }
66
67 bool isSatisfied() { return Satisfied; }
68};
69
70// The test fixture.
71class ParseHLSLRootSignatureTest : public ::testing::Test {
72protected:
73 ParseHLSLRootSignatureTest()
74 : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
75 Consumer(new ExpectedDiagConsumer()), Diags(DiagID, DiagOpts, Consumer),
76 SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
77 // This is an arbitrarily chosen target triple to create the target info.
78 TargetOpts->Triple = "dxil";
79 Target = TargetInfo::CreateTargetInfo(Diags, Opts&: *TargetOpts);
80 }
81
82 std::unique_ptr<Preprocessor> createPP(StringRef Source,
83 TrivialModuleLoader &ModLoader) {
84 std::unique_ptr<llvm::MemoryBuffer> Buf =
85 llvm::MemoryBuffer::getMemBuffer(InputData: Source);
86 SourceMgr.setMainFileID(SourceMgr.createFileID(Buffer: std::move(Buf)));
87
88 HeaderSearchOptions SearchOpts;
89 HeaderSearch HeaderInfo(SearchOpts, SourceMgr, Diags, LangOpts,
90 Target.get());
91 auto PP = std::make_unique<Preprocessor>(
92 args&: PPOpts, args&: Diags, args&: LangOpts, args&: SourceMgr, args&: HeaderInfo, args&: ModLoader,
93 /*IILookup =*/args: nullptr, /*OwnsHeaderSearch =*/args: false);
94 PP->Initialize(Target: *Target);
95 PP->EnterMainSourceFile();
96 return PP;
97 }
98
99 std::unique_ptr<ASTContext> createMinimalASTContext() {
100 IdentifierTable Idents(LangOpts);
101 SelectorTable Selectors;
102 Builtin::Context Builtins;
103
104 return std::make_unique<ASTContext>(args&: LangOpts, args&: SourceMgr, args&: Idents, args&: Selectors,
105 args&: Builtins, args: TU_Complete);
106 }
107
108 StringLiteral *wrapSource(std::unique_ptr<ASTContext> &Ctx,
109 StringRef Source) {
110 SourceLocation Locs[1] = {SourceLocation()};
111 return StringLiteral::Create(Ctx: *Ctx, Str: Source, Kind: StringLiteralKind::Unevaluated,
112 Pascal: false, Ty: Ctx->VoidTy, Locs);
113 }
114
115 FileSystemOptions FileMgrOpts;
116 FileManager FileMgr;
117 IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
118 DiagnosticOptions DiagOpts;
119 ExpectedDiagConsumer *Consumer;
120 DiagnosticsEngine Diags;
121 SourceManager SourceMgr;
122 LangOptions LangOpts;
123 PreprocessorOptions PPOpts;
124 std::shared_ptr<TargetOptions> TargetOpts;
125 IntrusiveRefCntPtr<TargetInfo> Target;
126};
127
128// Valid Parser Tests
129
130TEST_F(ParseHLSLRootSignatureTest, ValidParseEmptyTest) {
131 const llvm::StringLiteral Source = R"cc()cc";
132
133 auto Ctx = createMinimalASTContext();
134 StringLiteral *Signature = wrapSource(Ctx, Source);
135
136 TrivialModuleLoader ModLoader;
137 auto PP = createPP(Source, ModLoader);
138
139 SmallVector<RootSignatureElement> Elements;
140 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
141 Signature, *PP);
142
143 // Test no diagnostics produced
144 Consumer->setNoDiag();
145
146 ASSERT_FALSE(Parser.parse());
147 ASSERT_EQ((int)Elements.size(), 0);
148
149 ASSERT_TRUE(Consumer->isSatisfied());
150}
151
152TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
153 using llvm::dxbc::DescriptorRangeFlags;
154 const llvm::StringLiteral Source = R"cc(
155 DescriptorTable(
156 CBV(b0),
157 SRV(space = 3, offset = 32, t42, flags = 0, numDescriptors = 4),
158 visibility = SHADER_VISIBILITY_PIXEL,
159 Sampler(s987, space = +2, offset = DESCRIPTOR_RANGE_OFFSET_APPEND),
160 UAV(u4294967294, numDescriptors = unbounded,
161 flags = Descriptors_Volatile | Data_Volatile
162 | Data_Static_While_Set_At_Execute | Data_Static
163 | Descriptors_Static_Keeping_Buffer_Bounds_Checks
164 )
165 ),
166 DescriptorTable()
167 )cc";
168
169 auto Ctx = createMinimalASTContext();
170 StringLiteral *Signature = wrapSource(Ctx, Source);
171
172 TrivialModuleLoader ModLoader;
173 auto PP = createPP(Source, ModLoader);
174
175 SmallVector<RootSignatureElement> Elements;
176 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
177 Signature, *PP);
178
179 // Test no diagnostics produced
180 Consumer->setNoDiag();
181
182 ASSERT_FALSE(Parser.parse());
183
184 // First Descriptor Table with 4 elements
185 RootElement Elem = Elements[0].getElement();
186 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
187 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::CBuffer);
188 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
189 RegisterType::BReg);
190 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 0u);
191 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors, 1u);
192 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 0u);
193 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset,
194 DescriptorTableOffsetAppend);
195 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
196 DescriptorRangeFlags::DataStaticWhileSetAtExecute);
197
198 Elem = Elements[1].getElement();
199 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
200 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::SRV);
201 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
202 RegisterType::TReg);
203 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 42u);
204 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors, 4u);
205 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 3u);
206 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset, 32u);
207 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
208 DescriptorRangeFlags::None);
209
210 Elem = Elements[2].getElement();
211 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
212 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::Sampler);
213 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
214 RegisterType::SReg);
215 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 987u);
216 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors, 1u);
217 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 2u);
218 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset,
219 DescriptorTableOffsetAppend);
220 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
221 DescriptorRangeFlags::None);
222
223 Elem = Elements[3].getElement();
224 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
225 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::UAV);
226 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
227 RegisterType::UReg);
228 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 4294967294u);
229 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors,
230 NumDescriptorsUnbounded);
231 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 0u);
232 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset,
233 DescriptorTableOffsetAppend);
234 auto ValidDescriptorRangeFlags =
235 DescriptorRangeFlags::DescriptorsVolatile |
236 DescriptorRangeFlags::DataVolatile |
237 DescriptorRangeFlags::DataStaticWhileSetAtExecute |
238 DescriptorRangeFlags::DataStatic |
239 DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks;
240 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
241 ValidDescriptorRangeFlags);
242
243 Elem = Elements[4].getElement();
244 ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
245 ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)4);
246 ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility,
247 llvm::dxbc::ShaderVisibility::Pixel);
248
249 // Empty Descriptor Table
250 Elem = Elements[5].getElement();
251 ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
252 ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, 0u);
253 ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility,
254 llvm::dxbc::ShaderVisibility::All);
255
256 ASSERT_TRUE(Consumer->isSatisfied());
257}
258
259TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
260 const llvm::StringLiteral Source = R"cc(
261 StaticSampler(s0),
262 StaticSampler(s0, maxAnisotropy = 3, space = 4,
263 visibility = SHADER_VISIBILITY_DOMAIN,
264 minLOD = 4.2f, mipLODBias = 0.23e+3,
265 addressW = TEXTURE_ADDRESS_CLAMP,
266 addressV = TEXTURE_ADDRESS_BORDER,
267 filter = FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT,
268 maxLOD = 9000, addressU = TEXTURE_ADDRESS_MIRROR,
269 comparisonFunc = COMPARISON_NOT_EQUAL,
270 borderColor = STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT
271 )
272 )cc";
273
274 auto Ctx = createMinimalASTContext();
275 StringLiteral *Signature = wrapSource(Ctx, Source);
276
277 TrivialModuleLoader ModLoader;
278 auto PP = createPP(Source, ModLoader);
279
280 SmallVector<RootSignatureElement> Elements;
281 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
282 Signature, *PP);
283
284 // Test no diagnostics produced
285 Consumer->setNoDiag();
286
287 ASSERT_FALSE(Parser.parse());
288
289 ASSERT_EQ(Elements.size(), 2u);
290
291 // Check default values are as expected
292 RootElement Elem = Elements[0].getElement();
293 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
294 ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
295 ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
296 ASSERT_EQ(std::get<StaticSampler>(Elem).Filter,
297 llvm::dxbc::SamplerFilter::Anisotropic);
298 ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU,
299 llvm::dxbc::TextureAddressMode::Wrap);
300 ASSERT_EQ(std::get<StaticSampler>(Elem).AddressV,
301 llvm::dxbc::TextureAddressMode::Wrap);
302 ASSERT_EQ(std::get<StaticSampler>(Elem).AddressW,
303 llvm::dxbc::TextureAddressMode::Wrap);
304 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
305 ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 16u);
306 ASSERT_EQ(std::get<StaticSampler>(Elem).CompFunc,
307 llvm::dxbc::ComparisonFunc::LessEqual);
308 ASSERT_EQ(std::get<StaticSampler>(Elem).BorderColor,
309 llvm::dxbc::StaticBorderColor::OpaqueWhite);
310 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MinLOD, 0.f);
311 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MaxLOD, 3.402823466e+38f);
312 ASSERT_EQ(std::get<StaticSampler>(Elem).Space, 0u);
313 ASSERT_EQ(std::get<StaticSampler>(Elem).Visibility,
314 llvm::dxbc::ShaderVisibility::All);
315
316 // Check values can be set as expected
317 Elem = Elements[1].getElement();
318 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
319 ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
320 ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
321 ASSERT_EQ(std::get<StaticSampler>(Elem).Filter,
322 llvm::dxbc::SamplerFilter::MaximumMinPointMagLinearMipPoint);
323 ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU,
324 llvm::dxbc::TextureAddressMode::Mirror);
325 ASSERT_EQ(std::get<StaticSampler>(Elem).AddressV,
326 llvm::dxbc::TextureAddressMode::Border);
327 ASSERT_EQ(std::get<StaticSampler>(Elem).AddressW,
328 llvm::dxbc::TextureAddressMode::Clamp);
329 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 230.f);
330 ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 3u);
331 ASSERT_EQ(std::get<StaticSampler>(Elem).CompFunc,
332 llvm::dxbc::ComparisonFunc::NotEqual);
333 ASSERT_EQ(std::get<StaticSampler>(Elem).BorderColor,
334 llvm::dxbc::StaticBorderColor::OpaqueBlackUint);
335 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MinLOD, 4.2f);
336 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MaxLOD, 9000.f);
337 ASSERT_EQ(std::get<StaticSampler>(Elem).Space, 4u);
338 ASSERT_EQ(std::get<StaticSampler>(Elem).Visibility,
339 llvm::dxbc::ShaderVisibility::Domain);
340
341 ASSERT_TRUE(Consumer->isSatisfied());
342}
343
344TEST_F(ParseHLSLRootSignatureTest, ValidParseFloatsTest) {
345 const llvm::StringLiteral Source = R"cc(
346 StaticSampler(s0, mipLODBias = 0),
347 StaticSampler(s0, mipLODBias = +1),
348 StaticSampler(s0, mipLODBias = -1),
349 StaticSampler(s0, mipLODBias = 42.),
350 StaticSampler(s0, mipLODBias = +4.2),
351 StaticSampler(s0, mipLODBias = -.42),
352 StaticSampler(s0, mipLODBias = .42e+3),
353 StaticSampler(s0, mipLODBias = 42E-12),
354 StaticSampler(s0, mipLODBias = 42.f),
355 StaticSampler(s0, mipLODBias = 4.2F),
356 StaticSampler(s0, mipLODBias = 42.e+10f),
357 StaticSampler(s0, mipLODBias = -2147483648),
358 StaticSampler(s0, mipLODBias = 2147483648),
359 )cc";
360
361 auto Ctx = createMinimalASTContext();
362 StringLiteral *Signature = wrapSource(Ctx, Source);
363
364 TrivialModuleLoader ModLoader;
365 auto PP = createPP(Source, ModLoader);
366
367 SmallVector<RootSignatureElement> Elements;
368 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
369 Signature, *PP);
370
371 // Test no diagnostics produced
372 Consumer->setNoDiag();
373
374 ASSERT_FALSE(Parser.parse());
375
376 RootElement Elem = Elements[0].getElement();
377 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
378 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
379
380 Elem = Elements[1].getElement();
381 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
382 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 1.f);
383
384 Elem = Elements[2].getElement();
385 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
386 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, -1.f);
387
388 Elem = Elements[3].getElement();
389 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
390 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 42.f);
391
392 Elem = Elements[4].getElement();
393 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
394 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 4.2f);
395
396 Elem = Elements[5].getElement();
397 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
398 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, -.42f);
399
400 Elem = Elements[6].getElement();
401 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
402 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 420.f);
403
404 Elem = Elements[7].getElement();
405 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
406 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.000000000042f);
407
408 Elem = Elements[8].getElement();
409 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
410 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 42.f);
411
412 Elem = Elements[9].getElement();
413 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
414 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 4.2f);
415
416 Elem = Elements[10].getElement();
417 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
418 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 420000000000.f);
419
420 Elem = Elements[11].getElement();
421 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
422 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, -2147483648.f);
423
424 Elem = Elements[12].getElement();
425 ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
426 ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 2147483648.f);
427
428 ASSERT_TRUE(Consumer->isSatisfied());
429}
430
431TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
432 // This test will checks we can set the valid enum for Sampler descriptor
433 // range flags
434 const llvm::StringLiteral Source = R"cc(
435 DescriptorTable(Sampler(s0, flags = DESCRIPTORS_VOLATILE))
436 )cc";
437
438 auto Ctx = createMinimalASTContext();
439 StringLiteral *Signature = wrapSource(Ctx, Source);
440
441 TrivialModuleLoader ModLoader;
442 auto PP = createPP(Source, ModLoader);
443
444 SmallVector<RootSignatureElement> Elements;
445 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
446 Signature, *PP);
447
448 // Test no diagnostics produced
449 Consumer->setNoDiag();
450
451 ASSERT_FALSE(Parser.parse());
452
453 RootElement Elem = Elements[0].getElement();
454 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
455 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::Sampler);
456 auto ValidSamplerFlags =
457 llvm::dxbc::DescriptorRangeFlags::DescriptorsVolatile;
458 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags, ValidSamplerFlags);
459
460 ASSERT_TRUE(Consumer->isSatisfied());
461}
462
463TEST_F(ParseHLSLRootSignatureTest, ValidParseRootConsantsTest) {
464 const llvm::StringLiteral Source = R"cc(
465 RootConstants(num32BitConstants = 1, b0),
466 RootConstants(b42, space = 3, num32BitConstants = 4294967295,
467 visibility = SHADER_VISIBILITY_HULL
468 )
469 )cc";
470
471 auto Ctx = createMinimalASTContext();
472 StringLiteral *Signature = wrapSource(Ctx, Source);
473
474 TrivialModuleLoader ModLoader;
475 auto PP = createPP(Source, ModLoader);
476
477 SmallVector<RootSignatureElement> Elements;
478 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
479 Signature, *PP);
480
481 // Test no diagnostics produced
482 Consumer->setNoDiag();
483
484 ASSERT_FALSE(Parser.parse());
485
486 ASSERT_EQ(Elements.size(), 2u);
487
488 RootElement Elem = Elements[0].getElement();
489 ASSERT_TRUE(std::holds_alternative<RootConstants>(Elem));
490 ASSERT_EQ(std::get<RootConstants>(Elem).Num32BitConstants, 1u);
491 ASSERT_EQ(std::get<RootConstants>(Elem).Reg.ViewType, RegisterType::BReg);
492 ASSERT_EQ(std::get<RootConstants>(Elem).Reg.Number, 0u);
493 ASSERT_EQ(std::get<RootConstants>(Elem).Space, 0u);
494 ASSERT_EQ(std::get<RootConstants>(Elem).Visibility,
495 llvm::dxbc::ShaderVisibility::All);
496
497 Elem = Elements[1].getElement();
498 ASSERT_TRUE(std::holds_alternative<RootConstants>(Elem));
499 ASSERT_EQ(std::get<RootConstants>(Elem).Num32BitConstants, 4294967295u);
500 ASSERT_EQ(std::get<RootConstants>(Elem).Reg.ViewType, RegisterType::BReg);
501 ASSERT_EQ(std::get<RootConstants>(Elem).Reg.Number, 42u);
502 ASSERT_EQ(std::get<RootConstants>(Elem).Space, 3u);
503 ASSERT_EQ(std::get<RootConstants>(Elem).Visibility,
504 llvm::dxbc::ShaderVisibility::Hull);
505
506 ASSERT_TRUE(Consumer->isSatisfied());
507}
508
509TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) {
510 using llvm::dxbc::RootFlags;
511 const llvm::StringLiteral Source = R"cc(
512 RootFlags(),
513 RootFlags(0),
514 RootFlags(
515 deny_domain_shader_root_access |
516 deny_pixel_shader_root_access |
517 local_root_signature |
518 cbv_srv_uav_heap_directly_indexed |
519 deny_amplification_shader_root_access |
520 deny_geometry_shader_root_access |
521 deny_hull_shader_root_access |
522 deny_mesh_shader_root_access |
523 allow_stream_output |
524 sampler_heap_directly_indexed |
525 allow_input_assembler_input_layout |
526 deny_vertex_shader_root_access
527 )
528 )cc";
529
530 auto Ctx = createMinimalASTContext();
531 StringLiteral *Signature = wrapSource(Ctx, Source);
532
533 TrivialModuleLoader ModLoader;
534 auto PP = createPP(Source, ModLoader);
535
536 SmallVector<RootSignatureElement> Elements;
537 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
538 Signature, *PP);
539
540 // Test no diagnostics produced
541 Consumer->setNoDiag();
542
543 ASSERT_FALSE(Parser.parse());
544
545 ASSERT_EQ(Elements.size(), 3u);
546
547 RootElement Elem = Elements[0].getElement();
548 ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
549 ASSERT_EQ(std::get<RootFlags>(Elem), RootFlags::None);
550
551 Elem = Elements[1].getElement();
552 ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
553 ASSERT_EQ(std::get<RootFlags>(Elem), RootFlags::None);
554
555 Elem = Elements[2].getElement();
556 ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
557 auto ValidRootFlags = RootFlags::AllowInputAssemblerInputLayout |
558 RootFlags::DenyVertexShaderRootAccess |
559 RootFlags::DenyHullShaderRootAccess |
560 RootFlags::DenyDomainShaderRootAccess |
561 RootFlags::DenyGeometryShaderRootAccess |
562 RootFlags::DenyPixelShaderRootAccess |
563 RootFlags::AllowStreamOutput |
564 RootFlags::LocalRootSignature |
565 RootFlags::DenyAmplificationShaderRootAccess |
566 RootFlags::DenyMeshShaderRootAccess |
567 RootFlags::CBVSRVUAVHeapDirectlyIndexed |
568 RootFlags::SamplerHeapDirectlyIndexed;
569 ASSERT_EQ(std::get<RootFlags>(Elem), ValidRootFlags);
570
571 ASSERT_TRUE(Consumer->isSatisfied());
572}
573
574TEST_F(ParseHLSLRootSignatureTest, ValidParseRootDescriptorsTest) {
575 using llvm::dxbc::RootDescriptorFlags;
576 const llvm::StringLiteral Source = R"cc(
577 CBV(b0),
578 SRV(space = 4, t42, visibility = SHADER_VISIBILITY_GEOMETRY,
579 flags = DATA_VOLATILE | DATA_STATIC | DATA_STATIC_WHILE_SET_AT_EXECUTE
580 ),
581 UAV(visibility = SHADER_VISIBILITY_HULL, u34893247),
582 CBV(b0, flags = 0),
583 )cc";
584
585 auto Ctx = createMinimalASTContext();
586 StringLiteral *Signature = wrapSource(Ctx, Source);
587
588 TrivialModuleLoader ModLoader;
589 auto PP = createPP(Source, ModLoader);
590
591 SmallVector<RootSignatureElement> Elements;
592 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
593 Signature, *PP);
594
595 // Test no diagnostics produced
596 Consumer->setNoDiag();
597
598 ASSERT_FALSE(Parser.parse());
599
600 ASSERT_EQ(Elements.size(), 4u);
601
602 RootElement Elem = Elements[0].getElement();
603 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
604 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::CBuffer);
605 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.ViewType, RegisterType::BReg);
606 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.Number, 0u);
607 ASSERT_EQ(std::get<RootDescriptor>(Elem).Space, 0u);
608 ASSERT_EQ(std::get<RootDescriptor>(Elem).Visibility,
609 llvm::dxbc::ShaderVisibility::All);
610 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags,
611 RootDescriptorFlags::DataStaticWhileSetAtExecute);
612
613 Elem = Elements[1].getElement();
614 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
615 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::SRV);
616 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.ViewType, RegisterType::TReg);
617 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.Number, 42u);
618 ASSERT_EQ(std::get<RootDescriptor>(Elem).Space, 4u);
619 ASSERT_EQ(std::get<RootDescriptor>(Elem).Visibility,
620 llvm::dxbc::ShaderVisibility::Geometry);
621 auto ValidRootDescriptorFlags =
622 RootDescriptorFlags::DataVolatile |
623 RootDescriptorFlags::DataStaticWhileSetAtExecute |
624 RootDescriptorFlags::DataStatic;
625 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags, ValidRootDescriptorFlags);
626
627 Elem = Elements[2].getElement();
628 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
629 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::UAV);
630 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.ViewType, RegisterType::UReg);
631 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.Number, 34893247u);
632 ASSERT_EQ(std::get<RootDescriptor>(Elem).Space, 0u);
633 ASSERT_EQ(std::get<RootDescriptor>(Elem).Visibility,
634 llvm::dxbc::ShaderVisibility::Hull);
635 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags,
636 RootDescriptorFlags::DataVolatile);
637 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags,
638 RootDescriptorFlags::DataVolatile);
639
640 Elem = Elements[3].getElement();
641 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::CBuffer);
642 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.ViewType, RegisterType::BReg);
643 ASSERT_EQ(std::get<RootDescriptor>(Elem).Reg.Number, 0u);
644 ASSERT_EQ(std::get<RootDescriptor>(Elem).Space, 0u);
645 ASSERT_EQ(std::get<RootDescriptor>(Elem).Visibility,
646 llvm::dxbc::ShaderVisibility::All);
647 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags, RootDescriptorFlags::None);
648
649 ASSERT_TRUE(Consumer->isSatisfied());
650}
651
652TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
653 // This test will checks we can handling trailing commas ','
654 const llvm::StringLiteral Source = R"cc(
655 DescriptorTable(
656 CBV(b0, ),
657 SRV(t42),
658 )
659 )cc";
660
661 auto Ctx = createMinimalASTContext();
662 StringLiteral *Signature = wrapSource(Ctx, Source);
663
664 TrivialModuleLoader ModLoader;
665 auto PP = createPP(Source, ModLoader);
666
667 SmallVector<RootSignatureElement> Elements;
668 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
669 Signature, *PP);
670
671 // Test no diagnostics produced
672 Consumer->setNoDiag();
673
674 ASSERT_FALSE(Parser.parse());
675
676 ASSERT_TRUE(Consumer->isSatisfied());
677}
678
679TEST_F(ParseHLSLRootSignatureTest, ValidVersion10Test) {
680 // This test checks that the default values are set correctly
681 // when parsing with root signature version 1.0
682 const llvm::StringLiteral Source = R"cc(
683 CBV(b0),
684 SRV(t0),
685 UAV(u0),
686 DescriptorTable(
687 CBV(b1),
688 SRV(t1),
689 UAV(u1),
690 Sampler(s1),
691 )
692 )cc";
693
694 auto Ctx = createMinimalASTContext();
695 StringLiteral *Signature = wrapSource(Ctx, Source);
696
697 TrivialModuleLoader ModLoader;
698 auto PP = createPP(Source, ModLoader);
699
700 SmallVector<RootSignatureElement> Elements;
701 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_0, Elements,
702 Signature, *PP);
703
704 // Test no diagnostics produced
705 Consumer->setNoDiag();
706
707 ASSERT_FALSE(Parser.parse());
708
709 auto DefRootDescriptorFlag = llvm::dxbc::RootDescriptorFlags::DataVolatile;
710 RootElement Elem = Elements[0].getElement();
711 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
712 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::CBuffer);
713 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags, DefRootDescriptorFlag);
714
715 Elem = Elements[1].getElement();
716 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
717 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::SRV);
718 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags, DefRootDescriptorFlag);
719
720 Elem = Elements[2].getElement();
721 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
722 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::UAV);
723 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags, DefRootDescriptorFlag);
724
725 auto ValidNonSamplerFlags =
726 llvm::dxbc::DescriptorRangeFlags::DescriptorsVolatile |
727 llvm::dxbc::DescriptorRangeFlags::DataVolatile;
728 Elem = Elements[3].getElement();
729 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
730 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::CBuffer);
731 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags, ValidNonSamplerFlags);
732
733 Elem = Elements[4].getElement();
734 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
735 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::SRV);
736 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags, ValidNonSamplerFlags);
737
738 Elem = Elements[5].getElement();
739 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
740 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::UAV);
741 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags, ValidNonSamplerFlags);
742
743 Elem = Elements[6].getElement();
744 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
745 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::Sampler);
746 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
747 llvm::dxbc::DescriptorRangeFlags::DescriptorsVolatile);
748
749 ASSERT_TRUE(Consumer->isSatisfied());
750}
751
752TEST_F(ParseHLSLRootSignatureTest, ValidVersion11Test) {
753 // This test checks that the default values are set correctly
754 // when parsing with root signature version 1.1
755 const llvm::StringLiteral Source = R"cc(
756 CBV(b0),
757 SRV(t0),
758 UAV(u0),
759 DescriptorTable(
760 CBV(b1),
761 SRV(t1),
762 UAV(u1),
763 Sampler(s1),
764 )
765 )cc";
766
767 auto Ctx = createMinimalASTContext();
768 StringLiteral *Signature = wrapSource(Ctx, Source);
769
770 TrivialModuleLoader ModLoader;
771 auto PP = createPP(Source, ModLoader);
772
773 SmallVector<RootSignatureElement> Elements;
774 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
775 Signature, *PP);
776
777 // Test no diagnostics produced
778 Consumer->setNoDiag();
779
780 ASSERT_FALSE(Parser.parse());
781
782 RootElement Elem = Elements[0].getElement();
783 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
784 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::CBuffer);
785 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags,
786 llvm::dxbc::RootDescriptorFlags::DataStaticWhileSetAtExecute);
787
788 Elem = Elements[1].getElement();
789 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
790 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::SRV);
791 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags,
792 llvm::dxbc::RootDescriptorFlags::DataStaticWhileSetAtExecute);
793
794 Elem = Elements[2].getElement();
795 ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
796 ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::UAV);
797 ASSERT_EQ(std::get<RootDescriptor>(Elem).Flags,
798 llvm::dxbc::RootDescriptorFlags::DataVolatile);
799
800 Elem = Elements[3].getElement();
801 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
802 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::CBuffer);
803 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
804 llvm::dxbc::DescriptorRangeFlags::DataStaticWhileSetAtExecute);
805
806 Elem = Elements[4].getElement();
807 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
808 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::SRV);
809 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
810 llvm::dxbc::DescriptorRangeFlags::DataStaticWhileSetAtExecute);
811
812 Elem = Elements[5].getElement();
813 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
814 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::UAV);
815 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
816 llvm::dxbc::DescriptorRangeFlags::DataVolatile);
817
818 Elem = Elements[6].getElement();
819 ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
820 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::Sampler);
821 ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
822 llvm::dxbc::DescriptorRangeFlags::None);
823
824 ASSERT_TRUE(Consumer->isSatisfied());
825}
826
827// Invalid Parser Tests
828
829TEST_F(ParseHLSLRootSignatureTest, InvalidParseUnexpectedTokenTest) {
830 const llvm::StringLiteral Source = R"cc(
831 DescriptorTable()
832 space
833 )cc";
834
835 auto Ctx = createMinimalASTContext();
836 StringLiteral *Signature = wrapSource(Ctx, Source);
837
838 TrivialModuleLoader ModLoader;
839 auto PP = createPP(Source, ModLoader);
840
841 SmallVector<RootSignatureElement> Elements;
842 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
843 Signature, *PP);
844
845 // Test correct diagnostic produced
846 Consumer->setExpected(diag::err_expected_either);
847 ASSERT_TRUE(Parser.parse());
848
849 ASSERT_TRUE(Consumer->isSatisfied());
850}
851
852TEST_F(ParseHLSLRootSignatureTest, InvalidParseInvalidTokenTest) {
853 const llvm::StringLiteral Source = R"cc(
854 notAnIdentifier
855 )cc";
856
857 auto Ctx = createMinimalASTContext();
858 StringLiteral *Signature = wrapSource(Ctx, Source);
859
860 TrivialModuleLoader ModLoader;
861 auto PP = createPP(Source, ModLoader);
862
863 SmallVector<RootSignatureElement> Elements;
864 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
865 Signature, *PP);
866
867 // Test correct diagnostic produced - invalid token
868 Consumer->setExpected(diag::err_hlsl_invalid_token);
869 ASSERT_TRUE(Parser.parse());
870
871 ASSERT_TRUE(Consumer->isSatisfied());
872}
873
874TEST_F(ParseHLSLRootSignatureTest, InvalidParseUnexpectedEndOfStreamTest) {
875 const llvm::StringLiteral Source = R"cc(
876 DescriptorTable
877 )cc";
878
879 auto Ctx = createMinimalASTContext();
880 StringLiteral *Signature = wrapSource(Ctx, Source);
881
882 TrivialModuleLoader ModLoader;
883 auto PP = createPP(Source, ModLoader);
884
885 SmallVector<RootSignatureElement> Elements;
886 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
887 Signature, *PP);
888
889 // Test correct diagnostic produced - expected '(' after DescriptorTable
890 Consumer->setExpected(diag::err_expected_after);
891
892 ASSERT_TRUE(Parser.parse());
893
894 ASSERT_TRUE(Consumer->isSatisfied());
895}
896
897TEST_F(ParseHLSLRootSignatureTest, InvalidMissingDTParameterTest) {
898 // This test will check that the parsing fails due a mandatory
899 // parameter (register) not being specified
900 const llvm::StringLiteral Source = R"cc(
901 DescriptorTable(
902 CBV()
903 )
904 )cc";
905
906 auto Ctx = createMinimalASTContext();
907 StringLiteral *Signature = wrapSource(Ctx, Source);
908
909 TrivialModuleLoader ModLoader;
910 auto PP = createPP(Source, ModLoader);
911
912 SmallVector<RootSignatureElement> Elements;
913 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
914 Signature, *PP);
915
916 // Test correct diagnostic produced
917 Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
918 ASSERT_TRUE(Parser.parse());
919
920 ASSERT_TRUE(Consumer->isSatisfied());
921}
922
923TEST_F(ParseHLSLRootSignatureTest, InvalidMissingRDParameterTest) {
924 // This test will check that the parsing fails due a mandatory
925 // parameter (register) not being specified
926 const llvm::StringLiteral Source = R"cc(
927 SRV()
928 )cc";
929
930 auto Ctx = createMinimalASTContext();
931 StringLiteral *Signature = wrapSource(Ctx, Source);
932
933 TrivialModuleLoader ModLoader;
934 auto PP = createPP(Source, ModLoader);
935
936 SmallVector<RootSignatureElement> Elements;
937 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
938 Signature, *PP);
939
940 // Test correct diagnostic produced
941 Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
942 ASSERT_TRUE(Parser.parse());
943
944 ASSERT_TRUE(Consumer->isSatisfied());
945}
946
947TEST_F(ParseHLSLRootSignatureTest, InvalidMissingRCParameterTest) {
948 // This test will check that the parsing fails due a mandatory
949 // parameter (num32BitConstants) not being specified
950 const llvm::StringLiteral Source = R"cc(
951 RootConstants(b0)
952 )cc";
953
954 auto Ctx = createMinimalASTContext();
955 StringLiteral *Signature = wrapSource(Ctx, Source);
956
957 TrivialModuleLoader ModLoader;
958 auto PP = createPP(Source, ModLoader);
959
960 SmallVector<RootSignatureElement> Elements;
961 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
962 Signature, *PP);
963
964 // Test correct diagnostic produced
965 Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
966 ASSERT_TRUE(Parser.parse());
967
968 ASSERT_TRUE(Consumer->isSatisfied());
969}
970
971TEST_F(ParseHLSLRootSignatureTest, InvalidRepeatedMandatoryDTParameterTest) {
972 // This test will check that the parsing fails due the same mandatory
973 // parameter being specified multiple times
974 const llvm::StringLiteral Source = R"cc(
975 DescriptorTable(
976 CBV(b32, b84)
977 )
978 )cc";
979
980 auto Ctx = createMinimalASTContext();
981 StringLiteral *Signature = wrapSource(Ctx, Source);
982
983 TrivialModuleLoader ModLoader;
984 auto PP = createPP(Source, ModLoader);
985
986 SmallVector<RootSignatureElement> Elements;
987 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
988 Signature, *PP);
989
990 // Test correct diagnostic produced
991 Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
992 ASSERT_TRUE(Parser.parse());
993
994 ASSERT_TRUE(Consumer->isSatisfied());
995}
996
997TEST_F(ParseHLSLRootSignatureTest, InvalidRepeatedMandatoryRCParameterTest) {
998 // This test will check that the parsing fails due the same mandatory
999 // parameter being specified multiple times
1000 const llvm::StringLiteral Source = R"cc(
1001 RootConstants(num32BitConstants = 32, num32BitConstants = 24)
1002 )cc";
1003
1004 auto Ctx = createMinimalASTContext();
1005 StringLiteral *Signature = wrapSource(Ctx, Source);
1006
1007 TrivialModuleLoader ModLoader;
1008 auto PP = createPP(Source, ModLoader);
1009
1010 SmallVector<RootSignatureElement> Elements;
1011 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1012 Signature, *PP);
1013
1014 // Test correct diagnostic produced
1015 Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
1016 ASSERT_TRUE(Parser.parse());
1017
1018 ASSERT_TRUE(Consumer->isSatisfied());
1019}
1020
1021TEST_F(ParseHLSLRootSignatureTest, InvalidRepeatedOptionalDTParameterTest) {
1022 // This test will check that the parsing fails due the same optional
1023 // parameter being specified multiple times
1024 const llvm::StringLiteral Source = R"cc(
1025 DescriptorTable(
1026 CBV(space = 2, space = 0)
1027 )
1028 )cc";
1029
1030 auto Ctx = createMinimalASTContext();
1031 StringLiteral *Signature = wrapSource(Ctx, Source);
1032
1033 TrivialModuleLoader ModLoader;
1034 auto PP = createPP(Source, ModLoader);
1035
1036 SmallVector<RootSignatureElement> Elements;
1037 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1038 Signature, *PP);
1039
1040 // Test correct diagnostic produced
1041 Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
1042 ASSERT_TRUE(Parser.parse());
1043
1044 ASSERT_TRUE(Consumer->isSatisfied());
1045}
1046
1047TEST_F(ParseHLSLRootSignatureTest, InvalidRepeatedOptionalRCParameterTest) {
1048 // This test will check that the parsing fails due the same optional
1049 // parameter being specified multiple times
1050 const llvm::StringLiteral Source = R"cc(
1051 RootConstants(
1052 visibility = Shader_Visibility_All,
1053 b0, num32BitConstants = 1,
1054 visibility = Shader_Visibility_Pixel
1055 )
1056 )cc";
1057
1058 auto Ctx = createMinimalASTContext();
1059 StringLiteral *Signature = wrapSource(Ctx, Source);
1060
1061 TrivialModuleLoader ModLoader;
1062 auto PP = createPP(Source, ModLoader);
1063
1064 SmallVector<RootSignatureElement> Elements;
1065 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1066 Signature, *PP);
1067
1068 // Test correct diagnostic produced
1069 Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
1070 ASSERT_TRUE(Parser.parse());
1071
1072 ASSERT_TRUE(Consumer->isSatisfied());
1073}
1074
1075TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedNumberTest) {
1076 // This test will check that the lexing fails due to an integer overflow
1077 const llvm::StringLiteral Source = R"cc(
1078 DescriptorTable(
1079 CBV(b4294967296)
1080 )
1081 )cc";
1082
1083 auto Ctx = createMinimalASTContext();
1084 StringLiteral *Signature = wrapSource(Ctx, Source);
1085
1086 TrivialModuleLoader ModLoader;
1087 auto PP = createPP(Source, ModLoader);
1088
1089 SmallVector<RootSignatureElement> Elements;
1090 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1091 Signature, *PP);
1092
1093 // Test correct diagnostic produced
1094 Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
1095 ASSERT_TRUE(Parser.parse());
1096
1097 ASSERT_TRUE(Consumer->isSatisfied());
1098}
1099
1100TEST_F(ParseHLSLRootSignatureTest, InvalidParseOverflowedNegativeNumberTest) {
1101 // This test will check that parsing fails due to a unsigned integer having
1102 // too large of a magnitude to be interpreted as its negative
1103 const llvm::StringLiteral Source = R"cc(
1104 StaticSampler(s0, mipLODBias = -4294967295)
1105 )cc";
1106
1107 auto Ctx = createMinimalASTContext();
1108 StringLiteral *Signature = wrapSource(Ctx, Source);
1109
1110 TrivialModuleLoader ModLoader;
1111 auto PP = createPP(Source, ModLoader);
1112
1113 SmallVector<RootSignatureElement> Elements;
1114 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1115 Signature, *PP);
1116
1117 // Test correct diagnostic produced
1118 Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
1119 ASSERT_TRUE(Parser.parse());
1120
1121 ASSERT_TRUE(Consumer->isSatisfied());
1122}
1123
1124TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedFloatTest) {
1125 // This test will check that the lexing fails due to a float overflow
1126 const llvm::StringLiteral Source = R"cc(
1127 StaticSampler(s0, mipLODBias = 3.402823467e+38F)
1128 )cc";
1129
1130 auto Ctx = createMinimalASTContext();
1131 StringLiteral *Signature = wrapSource(Ctx, Source);
1132
1133 TrivialModuleLoader ModLoader;
1134 auto PP = createPP(Source, ModLoader);
1135
1136 SmallVector<RootSignatureElement> Elements;
1137 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1138 Signature, *PP);
1139
1140 // Test correct diagnostic produced
1141 Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
1142 ASSERT_TRUE(Parser.parse());
1143
1144 ASSERT_TRUE(Consumer->isSatisfied());
1145}
1146
1147TEST_F(ParseHLSLRootSignatureTest, InvalidLexNegOverflowedFloatTest) {
1148 // This test will check that the lexing fails due to negative float overflow
1149 const llvm::StringLiteral Source = R"cc(
1150 StaticSampler(s0, mipLODBias = -3.402823467e+38F)
1151 )cc";
1152
1153 auto Ctx = createMinimalASTContext();
1154 StringLiteral *Signature = wrapSource(Ctx, Source);
1155
1156 TrivialModuleLoader ModLoader;
1157 auto PP = createPP(Source, ModLoader);
1158
1159 SmallVector<RootSignatureElement> Elements;
1160 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1161 Signature, *PP);
1162
1163 // Test correct diagnostic produced
1164 Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
1165 ASSERT_TRUE(Parser.parse());
1166
1167 ASSERT_TRUE(Consumer->isSatisfied());
1168}
1169
1170TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedDoubleTest) {
1171 // This test will check that the lexing fails due to an overflow of double
1172 const llvm::StringLiteral Source = R"cc(
1173 StaticSampler(s0, mipLODBias = 1.e+500)
1174 )cc";
1175
1176 auto Ctx = createMinimalASTContext();
1177 StringLiteral *Signature = wrapSource(Ctx, Source);
1178
1179 TrivialModuleLoader ModLoader;
1180 auto PP = createPP(Source, ModLoader);
1181
1182 SmallVector<RootSignatureElement> Elements;
1183 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1184 Signature, *PP);
1185
1186 // Test correct diagnostic produced
1187 Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
1188 ASSERT_TRUE(Parser.parse());
1189
1190 ASSERT_TRUE(Consumer->isSatisfied());
1191}
1192
1193TEST_F(ParseHLSLRootSignatureTest, InvalidLexUnderflowFloatTest) {
1194 // This test will check that the lexing fails due to double underflow
1195 const llvm::StringLiteral Source = R"cc(
1196 StaticSampler(s0, mipLODBias = 10e-309)
1197 )cc";
1198
1199 auto Ctx = createMinimalASTContext();
1200 StringLiteral *Signature = wrapSource(Ctx, Source);
1201
1202 TrivialModuleLoader ModLoader;
1203 auto PP = createPP(Source, ModLoader);
1204
1205 SmallVector<RootSignatureElement> Elements;
1206 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1207 Signature, *PP);
1208
1209 // Test correct diagnostic produced
1210 Consumer->setExpected(diag::err_hlsl_number_literal_underflow);
1211 ASSERT_TRUE(Parser.parse());
1212
1213 ASSERT_TRUE(Consumer->isSatisfied());
1214}
1215
1216TEST_F(ParseHLSLRootSignatureTest, InvalidNonZeroFlagsTest) {
1217 // This test will check that parsing fails when a non-zero integer literal
1218 // is given to flags
1219 const llvm::StringLiteral Source = R"cc(
1220 DescriptorTable(
1221 CBV(b0, flags = 3)
1222 )
1223 )cc";
1224
1225 auto Ctx = createMinimalASTContext();
1226 StringLiteral *Signature = wrapSource(Ctx, Source);
1227
1228 TrivialModuleLoader ModLoader;
1229 auto PP = createPP(Source, ModLoader);
1230
1231 SmallVector<RootSignatureElement> Elements;
1232 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1233 Signature, *PP);
1234
1235 // Test correct diagnostic produced
1236 Consumer->setExpected(diag::err_hlsl_rootsig_non_zero_flag);
1237 ASSERT_TRUE(Parser.parse());
1238
1239 ASSERT_TRUE(Consumer->isSatisfied());
1240}
1241
1242TEST_F(ParseHLSLRootSignatureTest, InvalidRootElementMissingCommaTest) {
1243 // This test will check that an error is produced when there is a missing
1244 // comma between parameters
1245 const llvm::StringLiteral Source = R"cc(
1246 RootFlags()
1247 RootConstants(num32BitConstants = 1, b0)
1248 )cc";
1249
1250 auto Ctx = createMinimalASTContext();
1251 StringLiteral *Signature = wrapSource(Ctx, Source);
1252
1253 TrivialModuleLoader ModLoader;
1254 auto PP = createPP(Source, ModLoader);
1255
1256 SmallVector<RootSignatureElement> Elements;
1257 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1258 Signature, *PP);
1259
1260 // Test correct diagnostic produced
1261 Consumer->setExpected(diag::err_expected_either);
1262 ASSERT_TRUE(Parser.parse());
1263
1264 ASSERT_TRUE(Consumer->isSatisfied());
1265}
1266
1267TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableMissingCommaTest) {
1268 // This test will check that an error is produced when there is a missing
1269 // comma between parameters
1270 const llvm::StringLiteral Source = R"cc(
1271 DescriptorTable(
1272 CBV(b0)
1273 visibility = SHADER_VISIBILITY_ALL
1274 )
1275 )cc";
1276
1277 auto Ctx = createMinimalASTContext();
1278 StringLiteral *Signature = wrapSource(Ctx, Source);
1279
1280 TrivialModuleLoader ModLoader;
1281 auto PP = createPP(Source, ModLoader);
1282
1283 SmallVector<RootSignatureElement> Elements;
1284 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1285 Signature, *PP);
1286
1287 // Test correct diagnostic produced
1288 Consumer->setExpected(diag::err_expected_either);
1289 ASSERT_TRUE(Parser.parse());
1290
1291 ASSERT_TRUE(Consumer->isSatisfied());
1292}
1293
1294TEST_F(ParseHLSLRootSignatureTest, InvalidRootConstantParamsCommaTest) {
1295 // This test will check that an error is produced when there is a missing
1296 // comma between parameters
1297 const llvm::StringLiteral Source = R"cc(
1298 RootConstants(
1299 num32BitConstants = 1
1300 b0
1301 )
1302 )cc";
1303
1304 auto Ctx = createMinimalASTContext();
1305 StringLiteral *Signature = wrapSource(Ctx, Source);
1306
1307 TrivialModuleLoader ModLoader;
1308 auto PP = createPP(Source, ModLoader);
1309
1310 SmallVector<RootSignatureElement> Elements;
1311 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1312 Signature, *PP);
1313
1314 // Test correct diagnostic produced
1315 Consumer->setExpected(diag::err_expected_either);
1316 ASSERT_TRUE(Parser.parse());
1317
1318 ASSERT_TRUE(Consumer->isSatisfied());
1319}
1320
1321TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorParamsCommaTest) {
1322 // This test will check that an error is produced when there is a missing
1323 // comma between parameters
1324 const llvm::StringLiteral Source = R"cc(
1325 CBV(
1326 b0
1327 flags = 0
1328 )
1329 )cc";
1330
1331 auto Ctx = createMinimalASTContext();
1332 StringLiteral *Signature = wrapSource(Ctx, Source);
1333
1334 TrivialModuleLoader ModLoader;
1335 auto PP = createPP(Source, ModLoader);
1336
1337 SmallVector<RootSignatureElement> Elements;
1338 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1339 Signature, *PP);
1340
1341 // Test correct diagnostic produced
1342 Consumer->setExpected(diag::err_expected_either);
1343 ASSERT_TRUE(Parser.parse());
1344
1345 ASSERT_TRUE(Consumer->isSatisfied());
1346}
1347
1348TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorClauseParamsCommaTest) {
1349 // This test will check that an error is produced when there is a missing
1350 // comma between parameters
1351 const llvm::StringLiteral Source = R"cc(
1352 DescriptorTable(
1353 UAV(
1354 u0
1355 flags = 0
1356 )
1357 )
1358 )cc";
1359
1360 auto Ctx = createMinimalASTContext();
1361 StringLiteral *Signature = wrapSource(Ctx, Source);
1362
1363 TrivialModuleLoader ModLoader;
1364 auto PP = createPP(Source, ModLoader);
1365
1366 SmallVector<RootSignatureElement> Elements;
1367 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1368 Signature, *PP);
1369
1370 // Test correct diagnostic produced
1371 Consumer->setExpected(diag::err_expected_either);
1372 ASSERT_TRUE(Parser.parse());
1373
1374 ASSERT_TRUE(Consumer->isSatisfied());
1375}
1376
1377TEST_F(ParseHLSLRootSignatureTest, InvalidStaticSamplerCommaTest) {
1378 // This test will check that an error is produced when there is a missing
1379 // comma between parameters
1380 const llvm::StringLiteral Source = R"cc(
1381 StaticSampler(
1382 s0
1383 maxLOD = 3
1384 )
1385 )cc";
1386
1387 auto Ctx = createMinimalASTContext();
1388 StringLiteral *Signature = wrapSource(Ctx, Source);
1389
1390 TrivialModuleLoader ModLoader;
1391 auto PP = createPP(Source, ModLoader);
1392
1393 SmallVector<RootSignatureElement> Elements;
1394 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1395 Signature, *PP);
1396
1397 // Test correct diagnostic produced
1398 Consumer->setExpected(diag::err_expected_either);
1399 ASSERT_TRUE(Parser.parse());
1400
1401 ASSERT_TRUE(Consumer->isSatisfied());
1402}
1403
1404TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorParamTest) {
1405 // This test will check that an error is produced when there is a invalid
1406 // value of a parameter
1407 const llvm::StringLiteral Source = R"cc(
1408 SRV(t0, invalid)
1409 )cc";
1410
1411 auto Ctx = createMinimalASTContext();
1412 StringLiteral *Signature = wrapSource(Ctx, Source);
1413
1414 TrivialModuleLoader ModLoader;
1415 auto PP = createPP(Source, ModLoader);
1416
1417 SmallVector<RootSignatureElement> Elements;
1418 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1419 Signature, *PP);
1420
1421 // Test correct diagnostic produced
1422 Consumer->setExpected(diag::err_hlsl_invalid_token);
1423 ASSERT_TRUE(Parser.parse());
1424
1425 ASSERT_TRUE(Consumer->isSatisfied());
1426}
1427
1428TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableParamTest) {
1429 // This test will check that an error is produced when there is a invalid
1430 // value of a parameter
1431 const llvm::StringLiteral Source = R"cc(
1432 DescriptorTable(
1433 visibility = SHADER_VISIBILITY_ALL,
1434 invalid
1435 )
1436 )cc";
1437
1438 auto Ctx = createMinimalASTContext();
1439 StringLiteral *Signature = wrapSource(Ctx, Source);
1440
1441 TrivialModuleLoader ModLoader;
1442 auto PP = createPP(Source, ModLoader);
1443
1444 SmallVector<RootSignatureElement> Elements;
1445 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1446 Signature, *PP);
1447
1448 // Test correct diagnostic produced
1449 Consumer->setExpected(diag::err_hlsl_invalid_token);
1450 ASSERT_TRUE(Parser.parse());
1451
1452 ASSERT_TRUE(Consumer->isSatisfied());
1453}
1454
1455TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableClauseParamTest) {
1456 // This test will check that an error is produced when there is a invalid
1457 // value of a parameter
1458 const llvm::StringLiteral Source = R"cc(
1459 DescriptorTable(
1460 CBV(invalid)
1461 )
1462 )cc";
1463
1464 auto Ctx = createMinimalASTContext();
1465 StringLiteral *Signature = wrapSource(Ctx, Source);
1466
1467 TrivialModuleLoader ModLoader;
1468 auto PP = createPP(Source, ModLoader);
1469
1470 SmallVector<RootSignatureElement> Elements;
1471 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1472 Signature, *PP);
1473
1474 // Test correct diagnostic produced
1475 Consumer->setExpected(diag::err_hlsl_invalid_token);
1476 ASSERT_TRUE(Parser.parse());
1477
1478 ASSERT_TRUE(Consumer->isSatisfied());
1479}
1480
1481TEST_F(ParseHLSLRootSignatureTest, InvalidStaticSamplerParamTest) {
1482 // This test will check that an error is produced when there is a invalid
1483 // value of a parameter
1484 const llvm::StringLiteral Source = R"cc(
1485 StaticSampler(
1486 s0,
1487 filter = FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT,
1488 invalid,
1489 comparisonFunc = COMPARISON_EQUAL,
1490 )
1491 )cc";
1492
1493 auto Ctx = createMinimalASTContext();
1494 StringLiteral *Signature = wrapSource(Ctx, Source);
1495
1496 TrivialModuleLoader ModLoader;
1497 auto PP = createPP(Source, ModLoader);
1498
1499 SmallVector<RootSignatureElement> Elements;
1500 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1501 Signature, *PP);
1502
1503 // Test correct diagnostic produced
1504 Consumer->setExpected(diag::err_hlsl_invalid_token);
1505 ASSERT_TRUE(Parser.parse());
1506
1507 ASSERT_TRUE(Consumer->isSatisfied());
1508}
1509
1510TEST_F(ParseHLSLRootSignatureTest, InvalidVisibilityValueTest) {
1511 // This test will check that an error is produced when there is a invalid
1512 // value of a parameter
1513 const llvm::StringLiteral Source = R"cc(
1514 UAV(
1515 u0,
1516 visibility = SHADER_VISIBILITY_TYPO
1517 )
1518 )cc";
1519
1520 auto Ctx = createMinimalASTContext();
1521 StringLiteral *Signature = wrapSource(Ctx, Source);
1522
1523 TrivialModuleLoader ModLoader;
1524 auto PP = createPP(Source, ModLoader);
1525
1526 SmallVector<RootSignatureElement> Elements;
1527 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1528 Signature, *PP);
1529
1530 // Test correct diagnostic produced
1531 Consumer->setExpected(diag::err_hlsl_invalid_token);
1532 ASSERT_TRUE(Parser.parse());
1533
1534 ASSERT_TRUE(Consumer->isSatisfied());
1535}
1536
1537TEST_F(ParseHLSLRootSignatureTest, InvalidRegisterValueTest) {
1538 // This test will check that an error is produced when there is a invalid
1539 // value of a parameter
1540 const llvm::StringLiteral Source = R"cc(
1541 StaticSampler(
1542 b0
1543 )
1544 )cc";
1545
1546 auto Ctx = createMinimalASTContext();
1547 StringLiteral *Signature = wrapSource(Ctx, Source);
1548
1549 TrivialModuleLoader ModLoader;
1550 auto PP = createPP(Source, ModLoader);
1551
1552 SmallVector<RootSignatureElement> Elements;
1553 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1554 Signature, *PP);
1555
1556 // Test correct diagnostic produced
1557 Consumer->setExpected(diag::err_hlsl_invalid_token);
1558 ASSERT_TRUE(Parser.parse());
1559
1560 ASSERT_TRUE(Consumer->isSatisfied());
1561}
1562
1563TEST_F(ParseHLSLRootSignatureTest, InvalidFilterValueTest) {
1564 // This test will check that an error is produced when there is a invalid
1565 // value of a parameter
1566 const llvm::StringLiteral Source = R"cc(
1567 StaticSampler(
1568 s0,
1569 filter = FILTER_TYPO
1570 )
1571 )cc";
1572
1573 auto Ctx = createMinimalASTContext();
1574 StringLiteral *Signature = wrapSource(Ctx, Source);
1575
1576 TrivialModuleLoader ModLoader;
1577 auto PP = createPP(Source, ModLoader);
1578
1579 SmallVector<RootSignatureElement> Elements;
1580 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1581 Signature, *PP);
1582
1583 // Test correct diagnostic produced
1584 Consumer->setExpected(diag::err_hlsl_invalid_token);
1585 ASSERT_TRUE(Parser.parse());
1586
1587 ASSERT_TRUE(Consumer->isSatisfied());
1588}
1589
1590TEST_F(ParseHLSLRootSignatureTest, InvalidTextureAddressModeValueTest) {
1591 // This test will check that an error is produced when there is a invalid
1592 // value of a parameter
1593 const llvm::StringLiteral Source = R"cc(
1594 StaticSampler(
1595 s0,
1596 addressU = TEXTURE_ADDRESS_MODE_TYPO
1597 )
1598 )cc";
1599
1600 auto Ctx = createMinimalASTContext();
1601 StringLiteral *Signature = wrapSource(Ctx, Source);
1602
1603 TrivialModuleLoader ModLoader;
1604 auto PP = createPP(Source, ModLoader);
1605
1606 SmallVector<RootSignatureElement> Elements;
1607 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1608 Signature, *PP);
1609
1610 // Test correct diagnostic produced
1611 Consumer->setExpected(diag::err_hlsl_invalid_token);
1612 ASSERT_TRUE(Parser.parse());
1613
1614 ASSERT_TRUE(Consumer->isSatisfied());
1615}
1616
1617TEST_F(ParseHLSLRootSignatureTest, InvalidComparisonFuncValueTest) {
1618 // This test will check that an error is produced when there is a invalid
1619 // value of a parameter
1620 const llvm::StringLiteral Source = R"cc(
1621 StaticSampler(
1622 s0,
1623 comparisonFunc = COMPARISON_FUNC_TYPO
1624 )
1625 )cc";
1626
1627 auto Ctx = createMinimalASTContext();
1628 StringLiteral *Signature = wrapSource(Ctx, Source);
1629
1630 TrivialModuleLoader ModLoader;
1631 auto PP = createPP(Source, ModLoader);
1632
1633 SmallVector<RootSignatureElement> Elements;
1634 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1635 Signature, *PP);
1636
1637 // Test correct diagnostic produced
1638 Consumer->setExpected(diag::err_hlsl_invalid_token);
1639 ASSERT_TRUE(Parser.parse());
1640
1641 ASSERT_TRUE(Consumer->isSatisfied());
1642}
1643
1644TEST_F(ParseHLSLRootSignatureTest, InvalidStaticBorderColorValueTest) {
1645 // This test will check that an error is produced when there is a invalid
1646 // value of a parameter
1647 const llvm::StringLiteral Source = R"cc(
1648 StaticSampler(
1649 s0,
1650 borderColor = STATIC_BORDER_COLOR_TYPO
1651 )
1652 )cc";
1653
1654 auto Ctx = createMinimalASTContext();
1655 StringLiteral *Signature = wrapSource(Ctx, Source);
1656
1657 TrivialModuleLoader ModLoader;
1658 auto PP = createPP(Source, ModLoader);
1659
1660 SmallVector<RootSignatureElement> Elements;
1661 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1662 Signature, *PP);
1663
1664 // Test correct diagnostic produced
1665 Consumer->setExpected(diag::err_hlsl_invalid_token);
1666 ASSERT_TRUE(Parser.parse());
1667
1668 ASSERT_TRUE(Consumer->isSatisfied());
1669}
1670
1671TEST_F(ParseHLSLRootSignatureTest, InvalidRootFlagsValueTest) {
1672 // This test will check that an error is produced when there is a invalid
1673 // value of a parameter
1674 const llvm::StringLiteral Source = R"cc(
1675 RootFlags( ROOT_FLAG_TYPO )
1676 )cc";
1677
1678 auto Ctx = createMinimalASTContext();
1679 StringLiteral *Signature = wrapSource(Ctx, Source);
1680
1681 TrivialModuleLoader ModLoader;
1682 auto PP = createPP(Source, ModLoader);
1683
1684 SmallVector<RootSignatureElement> Elements;
1685 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1686 Signature, *PP);
1687
1688 // Test correct diagnostic produced
1689 Consumer->setExpected(diag::err_hlsl_invalid_token);
1690 ASSERT_TRUE(Parser.parse());
1691
1692 ASSERT_TRUE(Consumer->isSatisfied());
1693}
1694
1695TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorFlagsValueTest) {
1696 // This test will check that an error is produced when there is a invalid
1697 // value of a parameter
1698 const llvm::StringLiteral Source = R"cc(
1699 CBV( flags = DATA_STATIC | ROOT_DESRIPTOR_FLAG_TYPO )
1700 )cc";
1701
1702 auto Ctx = createMinimalASTContext();
1703 StringLiteral *Signature = wrapSource(Ctx, Source);
1704
1705 TrivialModuleLoader ModLoader;
1706 auto PP = createPP(Source, ModLoader);
1707
1708 SmallVector<RootSignatureElement> Elements;
1709 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1710 Signature, *PP);
1711
1712 // Test correct diagnostic produced
1713 Consumer->setExpected(diag::err_hlsl_invalid_token);
1714 ASSERT_TRUE(Parser.parse());
1715
1716 ASSERT_TRUE(Consumer->isSatisfied());
1717}
1718
1719TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorRangeFlagsValueTest) {
1720 // This test will check that an error is produced when there is a invalid
1721 // value of a parameter
1722 const llvm::StringLiteral Source = R"cc(
1723 DescriptorTable(
1724 CBV(
1725 flags = DATA_STATIC | DESRIPTOR_RANGE_FLAG_TYPO | DESCRIPTORS_VOLATILE
1726 )
1727 )
1728 )cc";
1729
1730 auto Ctx = createMinimalASTContext();
1731 StringLiteral *Signature = wrapSource(Ctx, Source);
1732
1733 TrivialModuleLoader ModLoader;
1734 auto PP = createPP(Source, ModLoader);
1735
1736 SmallVector<RootSignatureElement> Elements;
1737 hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1738 Signature, *PP);
1739
1740 // Test correct diagnostic produced
1741 Consumer->setExpected(diag::err_hlsl_invalid_token);
1742 ASSERT_TRUE(Parser.parse());
1743
1744 ASSERT_TRUE(Consumer->isSatisfied());
1745}
1746
1747} // anonymous namespace
1748

source code of clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp