1//=== LexHLSLRootSignatureTest.cpp - Lex 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/Lex/LexHLSLRootSignature.h"
10#include "gtest/gtest.h"
11
12using namespace clang;
13using TokenKind = hlsl::RootSignatureToken::Kind;
14
15namespace {
16
17// The test fixture.
18class LexHLSLRootSignatureTest : public ::testing::Test {
19protected:
20 LexHLSLRootSignatureTest() {}
21
22 void checkTokens(hlsl::RootSignatureLexer &Lexer,
23 SmallVector<hlsl::RootSignatureToken> &Computed,
24 SmallVector<TokenKind> &Expected) {
25 for (unsigned I = 0, E = Expected.size(); I != E; ++I) {
26 // Skip these to help with the macro generated test
27 if (Expected[I] == TokenKind::invalid ||
28 Expected[I] == TokenKind::end_of_stream)
29 continue;
30 hlsl::RootSignatureToken Result = Lexer.consumeToken();
31 ASSERT_EQ(Result.TokKind, Expected[I]);
32 Computed.push_back(Elt: Result);
33 }
34 hlsl::RootSignatureToken EndOfStream = Lexer.consumeToken();
35 ASSERT_EQ(EndOfStream.TokKind, TokenKind::end_of_stream);
36 ASSERT_TRUE(Lexer.isEndOfBuffer());
37 }
38};
39
40// Lexing Tests
41
42TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
43 // This test will check that we can lex different number tokens
44 const llvm::StringLiteral Source = R"cc(
45 -42 42 +42 +2147483648
46 42. 4.2 .42
47 42f 4.2F
48 .42e+3 4.2E-12
49 42.e+10f
50 )cc";
51
52 hlsl::RootSignatureLexer Lexer(Source);
53
54 SmallVector<hlsl::RootSignatureToken> Tokens;
55 SmallVector<TokenKind> Expected = {
56 TokenKind::pu_minus, TokenKind::int_literal,
57 TokenKind::int_literal, TokenKind::pu_plus,
58 TokenKind::int_literal, TokenKind::pu_plus,
59 TokenKind::int_literal, TokenKind::float_literal,
60 TokenKind::float_literal, TokenKind::float_literal,
61 TokenKind::float_literal, TokenKind::float_literal,
62 TokenKind::float_literal, TokenKind::float_literal,
63 TokenKind::float_literal,
64 };
65 checkTokens(Lexer, Computed&: Tokens, Expected);
66
67 // Sample negative: int component
68 hlsl::RootSignatureToken IntToken = Tokens[1];
69 ASSERT_EQ(IntToken.NumSpelling, "42");
70
71 // Sample unsigned int
72 IntToken = Tokens[2];
73 ASSERT_EQ(IntToken.NumSpelling, "42");
74
75 // Sample positive: int component
76 IntToken = Tokens[4];
77 ASSERT_EQ(IntToken.NumSpelling, "42");
78
79 // Sample positive int that would overflow the signed representation but
80 // is treated as an unsigned integer instead
81 IntToken = Tokens[6];
82 ASSERT_EQ(IntToken.NumSpelling, "2147483648");
83
84 // Sample decimal end
85 hlsl::RootSignatureToken FloatToken = Tokens[7];
86 ASSERT_EQ(FloatToken.NumSpelling, "42.");
87
88 // Sample decimal middle
89 FloatToken = Tokens[8];
90 ASSERT_EQ(FloatToken.NumSpelling, "4.2");
91
92 // Sample decimal start
93 FloatToken = Tokens[9];
94 ASSERT_EQ(FloatToken.NumSpelling, ".42");
95
96 // Sample float lower
97 FloatToken = Tokens[10];
98 ASSERT_EQ(FloatToken.NumSpelling, "42f");
99
100 // Sample float upper
101 FloatToken = Tokens[11];
102 ASSERT_EQ(FloatToken.NumSpelling, "4.2F");
103
104 // Sample exp +
105 FloatToken = Tokens[12];
106 ASSERT_EQ(FloatToken.NumSpelling, ".42e+3");
107
108 // Sample exp -
109 FloatToken = Tokens[13];
110 ASSERT_EQ(FloatToken.NumSpelling, "4.2E-12");
111
112 // Sample all combined
113 FloatToken = Tokens[14];
114 ASSERT_EQ(FloatToken.NumSpelling, "42.e+10f");
115}
116
117TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
118 // This test will check that we can lex all defined tokens as defined in
119 // HLSLRootSignatureTokenKinds.def, plus some additional integer variations
120 const llvm::StringLiteral Source = R"cc(
121 42 42.0f
122
123 b0 t43 u987 s234
124
125 (),|=+-
126
127 RootSignature
128
129 RootFlags DescriptorTable RootConstants StaticSampler
130
131 num32BitConstants
132
133 CBV SRV UAV Sampler
134 space visibility flags
135 numDescriptors offset
136
137 filter mipLODBias addressU addressV addressW
138 maxAnisotropy comparisonFunc borderColor
139 minLOD maxLOD
140
141 unbounded
142 DESCRIPTOR_RANGE_OFFSET_APPEND
143
144 allow_input_assembler_input_layout
145 deny_vertex_shader_root_access
146 deny_hull_shader_root_access
147 deny_domain_shader_root_access
148 deny_geometry_shader_root_access
149 deny_pixel_shader_root_access
150 deny_amplification_shader_root_access
151 deny_mesh_shader_root_access
152 allow_stream_output
153 local_root_signature
154 cbv_srv_uav_heap_directly_indexed
155 sampler_heap_directly_indexed
156
157 DATA_VOLATILE
158 DATA_STATIC_WHILE_SET_AT_EXECUTE
159 DATA_STATIC
160 DESCRIPTORS_VOLATILE
161 DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS
162
163 shader_visibility_all
164 shader_visibility_vertex
165 shader_visibility_hull
166 shader_visibility_domain
167 shader_visibility_geometry
168 shader_visibility_pixel
169 shader_visibility_amplification
170 shader_visibility_mesh
171
172 FILTER_MIN_MAG_MIP_POINT
173 FILTER_MIN_MAG_POINT_MIP_LINEAR
174 FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT
175 FILTER_MIN_POINT_MAG_MIP_LINEAR
176 FILTER_MIN_LINEAR_MAG_MIP_POINT
177 FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR
178 FILTER_MIN_MAG_LINEAR_MIP_POINT
179 FILTER_MIN_MAG_MIP_LINEAR
180 FILTER_ANISOTROPIC
181 FILTER_COMPARISON_MIN_MAG_MIP_POINT
182 FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR
183 FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT
184 FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR
185 FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT
186 FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR
187 FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT
188 FILTER_COMPARISON_MIN_MAG_MIP_LINEAR
189 FILTER_COMPARISON_ANISOTROPIC
190 FILTER_MINIMUM_MIN_MAG_MIP_POINT
191 FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR
192 FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT
193 FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR
194 FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT
195 FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR
196 FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT
197 FILTER_MINIMUM_MIN_MAG_MIP_LINEAR
198 FILTER_MINIMUM_ANISOTROPIC
199 FILTER_MAXIMUM_MIN_MAG_MIP_POINT
200 FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR
201 FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT
202 FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR
203 FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT
204 FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR
205 FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT
206 FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR
207 FILTER_MAXIMUM_ANISOTROPIC
208
209 TEXTURE_ADDRESS_WRAP
210 TEXTURE_ADDRESS_MIRROR
211 TEXTURE_ADDRESS_CLAMP
212 TEXTURE_ADDRESS_BORDER
213 TEXTURE_ADDRESS_MIRRORONCE
214
215 comparison_never
216 comparison_less
217 comparison_equal
218 comparison_less_equal
219 comparison_greater
220 comparison_not_equal
221 comparison_greater_equal
222 comparison_always
223
224 STATIC_BORDER_COLOR_TRANSPARENT_BLACK
225 STATIC_BORDER_COLOR_OPAQUE_BLACK
226 STATIC_BORDER_COLOR_OPAQUE_WHITE
227 STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT
228 STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT
229 )cc";
230 hlsl::RootSignatureLexer Lexer(Source);
231
232 SmallVector<hlsl::RootSignatureToken> Tokens;
233 SmallVector<TokenKind> Expected = {
234#define TOK(NAME, SPELLING) TokenKind::NAME,
235#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
236 };
237
238 checkTokens(Lexer, Computed&: Tokens, Expected);
239}
240
241TEST_F(LexHLSLRootSignatureTest, ValidCaseInsensitiveKeywordsTest) {
242 // This test will check that we can lex keywords in an case-insensitive
243 // manner
244 const llvm::StringLiteral Source = R"cc(
245 DeScRiPtOrTaBlE
246
247 CBV srv UAV sampler
248 SPACE visibility FLAGS
249 numDescriptors OFFSET
250 )cc";
251 hlsl::RootSignatureLexer Lexer(Source);
252
253 SmallVector<hlsl::RootSignatureToken> Tokens;
254 SmallVector<TokenKind> Expected = {
255 TokenKind::kw_DescriptorTable,
256 TokenKind::kw_CBV,
257 TokenKind::kw_SRV,
258 TokenKind::kw_UAV,
259 TokenKind::kw_Sampler,
260 TokenKind::kw_space,
261 TokenKind::kw_visibility,
262 TokenKind::kw_flags,
263 TokenKind::kw_numDescriptors,
264 TokenKind::kw_offset,
265 };
266
267 checkTokens(Lexer, Computed&: Tokens, Expected);
268}
269
270TEST_F(LexHLSLRootSignatureTest, ValidLexPeekTest) {
271 // This test will check that we the peek api is correctly used
272 const llvm::StringLiteral Source = R"cc(
273 )1
274 )cc";
275 hlsl::RootSignatureLexer Lexer(Source);
276
277 // Test basic peek
278 hlsl::RootSignatureToken Res = Lexer.peekNextToken();
279 ASSERT_EQ(Res.TokKind, TokenKind::pu_r_paren);
280
281 // Ensure it doesn't peek past one element
282 Res = Lexer.peekNextToken();
283 ASSERT_EQ(Res.TokKind, TokenKind::pu_r_paren);
284
285 Res = Lexer.consumeToken();
286 ASSERT_EQ(Res.TokKind, TokenKind::pu_r_paren);
287
288 // Invoke after reseting the NextToken
289 Res = Lexer.peekNextToken();
290 ASSERT_EQ(Res.TokKind, TokenKind::int_literal);
291
292 // Ensure we can still consume the second token
293 Res = Lexer.consumeToken();
294 ASSERT_EQ(Res.TokKind, TokenKind::int_literal);
295
296 // Ensure end of stream token
297 Res = Lexer.peekNextToken();
298 ASSERT_EQ(Res.TokKind, TokenKind::end_of_stream);
299}
300
301} // anonymous namespace
302

source code of clang/unittests/Lex/LexHLSLRootSignatureTest.cpp