305 lines · cpp
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-exception6//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 test27 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(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 Tests41 42TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {43 // This test will check that we can lex different number tokens44 const llvm::StringLiteral Source = R"cc(45 -42 42 +42 +214748364846 42. 4.2 .4247 42f 4.2F48 .42e+3 4.2E-1249 42.e+10f50 )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, Tokens, Expected);66 67 // Sample negative: int component68 hlsl::RootSignatureToken IntToken = Tokens[1];69 ASSERT_EQ(IntToken.NumSpelling, "42");70 71 // Sample unsigned int72 IntToken = Tokens[2];73 ASSERT_EQ(IntToken.NumSpelling, "42");74 75 // Sample positive: int component76 IntToken = Tokens[4];77 ASSERT_EQ(IntToken.NumSpelling, "42");78 79 // Sample positive int that would overflow the signed representation but80 // is treated as an unsigned integer instead81 IntToken = Tokens[6];82 ASSERT_EQ(IntToken.NumSpelling, "2147483648");83 84 // Sample decimal end85 hlsl::RootSignatureToken FloatToken = Tokens[7];86 ASSERT_EQ(FloatToken.NumSpelling, "42.");87 88 // Sample decimal middle89 FloatToken = Tokens[8];90 ASSERT_EQ(FloatToken.NumSpelling, "4.2");91 92 // Sample decimal start93 FloatToken = Tokens[9];94 ASSERT_EQ(FloatToken.NumSpelling, ".42");95 96 // Sample float lower97 FloatToken = Tokens[10];98 ASSERT_EQ(FloatToken.NumSpelling, "42f");99 100 // Sample float upper101 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 combined113 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 in119 // HLSLRootSignatureTokenKinds.def, plus some additional integer variations120 const llvm::StringLiteral Source = R"cc(121 42 42.0f122 123 b0 t43 u987 s234124 125 (),|=+-126 127 RootSignature128 129 RootFlags DescriptorTable RootConstants StaticSampler130 131 num32BitConstants132 133 CBV SRV UAV Sampler134 space visibility flags135 numDescriptors offset136 137 filter mipLODBias addressU addressV addressW138 maxAnisotropy comparisonFunc borderColor139 minLOD maxLOD140 141 unbounded142 DESCRIPTOR_RANGE_OFFSET_APPEND143 144 allow_input_assembler_input_layout145 deny_vertex_shader_root_access146 deny_hull_shader_root_access147 deny_domain_shader_root_access148 deny_geometry_shader_root_access149 deny_pixel_shader_root_access150 deny_amplification_shader_root_access151 deny_mesh_shader_root_access152 allow_stream_output153 local_root_signature154 cbv_srv_uav_heap_directly_indexed155 sampler_heap_directly_indexed156 157 DATA_VOLATILE158 DATA_STATIC_WHILE_SET_AT_EXECUTE159 DATA_STATIC160 DESCRIPTORS_VOLATILE161 DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS162 163 shader_visibility_all164 shader_visibility_vertex165 shader_visibility_hull166 shader_visibility_domain167 shader_visibility_geometry168 shader_visibility_pixel169 shader_visibility_amplification170 shader_visibility_mesh171 172 FILTER_MIN_MAG_MIP_POINT173 FILTER_MIN_MAG_POINT_MIP_LINEAR174 FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT175 FILTER_MIN_POINT_MAG_MIP_LINEAR176 FILTER_MIN_LINEAR_MAG_MIP_POINT177 FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR178 FILTER_MIN_MAG_LINEAR_MIP_POINT179 FILTER_MIN_MAG_MIP_LINEAR180 FILTER_ANISOTROPIC181 FILTER_COMPARISON_MIN_MAG_MIP_POINT182 FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR183 FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT184 FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR185 FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT186 FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR187 FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT188 FILTER_COMPARISON_MIN_MAG_MIP_LINEAR189 FILTER_COMPARISON_ANISOTROPIC190 FILTER_MINIMUM_MIN_MAG_MIP_POINT191 FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR192 FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT193 FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR194 FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT195 FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR196 FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT197 FILTER_MINIMUM_MIN_MAG_MIP_LINEAR198 FILTER_MINIMUM_ANISOTROPIC199 FILTER_MAXIMUM_MIN_MAG_MIP_POINT200 FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR201 FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT202 FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR203 FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT204 FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR205 FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT206 FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR207 FILTER_MAXIMUM_ANISOTROPIC208 209 TEXTURE_ADDRESS_WRAP210 TEXTURE_ADDRESS_MIRROR211 TEXTURE_ADDRESS_CLAMP212 TEXTURE_ADDRESS_BORDER213 TEXTURE_ADDRESS_MIRRORONCE214 215 comparison_never216 comparison_less217 comparison_equal218 comparison_less_equal219 comparison_greater220 comparison_not_equal221 comparison_greater_equal222 comparison_always223 224 STATIC_BORDER_COLOR_TRANSPARENT_BLACK225 STATIC_BORDER_COLOR_OPAQUE_BLACK226 STATIC_BORDER_COLOR_OPAQUE_WHITE227 STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT228 STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT229 230 UINT_BORDER_COLOR231 NON_NORMALIZED_COORDINATES232 )cc";233 hlsl::RootSignatureLexer Lexer(Source);234 235 SmallVector<hlsl::RootSignatureToken> Tokens;236 SmallVector<TokenKind> Expected = {237#define TOK(NAME, SPELLING) TokenKind::NAME,238#include "clang/Lex/HLSLRootSignatureTokenKinds.def"239 };240 241 checkTokens(Lexer, Tokens, Expected);242}243 244TEST_F(LexHLSLRootSignatureTest, ValidCaseInsensitiveKeywordsTest) {245 // This test will check that we can lex keywords in an case-insensitive246 // manner247 const llvm::StringLiteral Source = R"cc(248 DeScRiPtOrTaBlE249 250 CBV srv UAV sampler251 SPACE visibility FLAGS252 numDescriptors OFFSET253 )cc";254 hlsl::RootSignatureLexer Lexer(Source);255 256 SmallVector<hlsl::RootSignatureToken> Tokens;257 SmallVector<TokenKind> Expected = {258 TokenKind::kw_DescriptorTable,259 TokenKind::kw_CBV,260 TokenKind::kw_SRV,261 TokenKind::kw_UAV,262 TokenKind::kw_Sampler,263 TokenKind::kw_space,264 TokenKind::kw_visibility,265 TokenKind::kw_flags,266 TokenKind::kw_numDescriptors,267 TokenKind::kw_offset,268 };269 270 checkTokens(Lexer, Tokens, Expected);271}272 273TEST_F(LexHLSLRootSignatureTest, ValidLexPeekTest) {274 // This test will check that we the peek api is correctly used275 const llvm::StringLiteral Source = R"cc(276 )1277 )cc";278 hlsl::RootSignatureLexer Lexer(Source);279 280 // Test basic peek281 hlsl::RootSignatureToken Res = Lexer.peekNextToken();282 ASSERT_EQ(Res.TokKind, TokenKind::pu_r_paren);283 284 // Ensure it doesn't peek past one element285 Res = Lexer.peekNextToken();286 ASSERT_EQ(Res.TokKind, TokenKind::pu_r_paren);287 288 Res = Lexer.consumeToken();289 ASSERT_EQ(Res.TokKind, TokenKind::pu_r_paren);290 291 // Invoke after reseting the NextToken292 Res = Lexer.peekNextToken();293 ASSERT_EQ(Res.TokKind, TokenKind::int_literal);294 295 // Ensure we can still consume the second token296 Res = Lexer.consumeToken();297 ASSERT_EQ(Res.TokKind, TokenKind::int_literal);298 299 // Ensure end of stream token300 Res = Lexer.peekNextToken();301 ASSERT_EQ(Res.TokKind, TokenKind::end_of_stream);302}303 304} // anonymous namespace305