Skip to content

Commit dc0c7ba

Browse files
committed
Add support for lexing registers
1 parent 5f43ed8 commit dc0c7ba

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ let CategoryName = "Root Signature Lexical Issue" in {
10251025
def err_hlsl_number_literal_overflow :
10261026
Error<"provided %select{unsigned integer|signed integer}0 literal '%1' that overflows the maximum of 32 bits">;
10271027
def err_hlsl_invalid_token: Error<"unable to lex a valid Root Signature token">;
1028+
def err_hlsl_invalid_register_literal: Error<"expected unsigned integer literal as part of register">;
10281029
}
10291030

10301031
}

clang/include/clang/Parse/HLSLRootSignatureTokenKinds.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
TOK(invalid)
2626
TOK(int_literal)
2727

28+
// Register Tokens:
29+
TOK(bReg)
30+
TOK(tReg)
31+
TOK(uReg)
32+
TOK(sReg)
33+
2834
// Punctuators:
2935
PUNCTUATOR(l_paren, '(')
3036
PUNCTUATOR(r_paren, ')')

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,53 @@ bool RootSignatureLexer::LexToken(RootSignatureToken &Result) {
100100
if (isdigit(C) || C == '-' || C == '+')
101101
return LexNumber(Result);
102102

103+
// All following tokens require at least one additional character
104+
if (Buffer.size() <= 1) {
105+
PP.getDiagnostics().Report(Result.TokLoc, diag::err_hlsl_invalid_token);
106+
return true;
107+
}
108+
109+
// Peek at the next character to deteremine token type
110+
char NextC = Buffer[1];
111+
112+
// Registers: [tsub][0-9+]
113+
if ((C == 't' || C == 's' || C == 'u' || C == 'b') && isdigit(NextC)) {
114+
AdvanceBuffer();
115+
116+
if (LexNumber(Result))
117+
return true; // Error parsing number which is already reported
118+
119+
// Lex number could also parse a float so ensure it was an unsigned int
120+
if (Result.Kind != TokenKind::int_literal ||
121+
Result.NumLiteral.getInt().isSigned()) {
122+
// Return invalid number literal for register error
123+
PP.getDiagnostics().Report(Result.TokLoc,
124+
diag::err_hlsl_invalid_register_literal);
125+
return true;
126+
}
127+
128+
// Convert character to the register type.
129+
// This is done after LexNumber to override the TokenKind
130+
switch (C) {
131+
case 'b':
132+
Result.Kind = TokenKind::bReg;
133+
break;
134+
case 't':
135+
Result.Kind = TokenKind::tReg;
136+
break;
137+
case 'u':
138+
Result.Kind = TokenKind::uReg;
139+
break;
140+
case 's':
141+
Result.Kind = TokenKind::sReg;
142+
break;
143+
default:
144+
llvm_unreachable("Switch for an expected token was not provided");
145+
return true;
146+
}
147+
return false;
148+
}
149+
103150
// Unable to match on any token type
104151
PP.getDiagnostics().Report(Result.TokLoc, diag::err_hlsl_invalid_token);
105152
return true;

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidLexAllTokensTest) {
144144
const llvm::StringLiteral Source = R"cc(
145145
42
146146
147+
b0 t43 u987 s234
148+
147149
(),|=
148150
)cc";
149151

@@ -213,6 +215,27 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidLexEmptyNumberTest) {
213215
ASSERT_TRUE(Consumer->IsSatisfied());
214216
}
215217

218+
TEST_F(ParseHLSLRootSignatureTest, InvalidLexRegNumberTest) {
219+
// This test will check that the lexing fails due to no integer being provided
220+
const llvm::StringLiteral Source = R"cc(
221+
b32.4
222+
)cc";
223+
224+
TrivialModuleLoader ModLoader;
225+
auto PP = CreatePP(Source, ModLoader);
226+
auto TokLoc = SourceLocation();
227+
228+
// Test correct diagnostic produced
229+
Consumer->SetExpected(diag::err_hlsl_invalid_register_literal);
230+
231+
hlsl::RootSignatureLexer Lexer(Source, TokLoc, *PP);
232+
233+
SmallVector<hlsl::RootSignatureToken> Tokens;
234+
ASSERT_TRUE(Lexer.Lex(Tokens));
235+
// FIXME(#120472): This should be TRUE once we can lex a floating
236+
ASSERT_FALSE(Consumer->IsSatisfied());
237+
}
238+
216239
TEST_F(ParseHLSLRootSignatureTest, InvalidLexIdentifierTest) {
217240
// This test will check that the lexing fails due to no valid token
218241
const llvm::StringLiteral Source = R"cc(

0 commit comments

Comments
 (0)