Skip to content

Commit 8e4dd21

Browse files
authored
[HLSL][RootSignature] Add lexing support for floating points (#137720)
- this takes care to add support to match the [behaviour of DXC](https://github.com/microsoft/DirectXShaderCompiler/blob/34b6d0f91e6afd523bdc574836093f021713cce7/tools/clang/lib/Parse/HLSLRootSignature.cpp#L74) acceptable floating point integers Namely: - Allow for specifying the decimal '.' - Allow for specifying exponents with 'e' or 'E' and allow for 'f' to denote an otherwise interpreted integer as a float This pr is simply responsible of creating a token that could be interpeted as a floating point integer by `NumericLiteralParser`. As such, we are not required to validate that the special characters only occur once and that 'f' is only at the end of the string. These will be validated when invoking `NumericLiteralParser` during parsing. Resolves #126565
1 parent ea3959e commit 8e4dd21

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
TOK(invalid, "invalid identifier")
5656
TOK(end_of_stream, "end of stream")
5757
TOK(int_literal, "integer literal")
58+
TOK(float_literal, "float literal")
5859

5960
// Register Tokens:
6061
TOK(bReg, "b register")

clang/lib/Lex/LexHLSLRootSignature.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ using TokenKind = RootSignatureToken::Kind;
1616
// Lexer Definitions
1717

1818
static bool isNumberChar(char C) {
19-
// TODO(#126565): extend for float support exponents
20-
return isdigit(C); // integer support
19+
return isdigit(C) // integer support
20+
|| C == '.' // float support
21+
|| C == 'e' || C == 'E' || C == '-' || C == '+' // exponent support
22+
|| C == 'f' || C == 'F'; // explicit float support
2123
}
2224

2325
RootSignatureToken RootSignatureLexer::lexToken() {
@@ -45,10 +47,15 @@ RootSignatureToken RootSignatureLexer::lexToken() {
4547
break;
4648
}
4749

48-
// Integer literal
49-
if (isdigit(C)) {
50-
Result.TokKind = TokenKind::int_literal;
50+
// Number literal
51+
if (isdigit(C) || C == '.') {
5152
Result.NumSpelling = Buffer.take_while(isNumberChar);
53+
54+
// If all values are digits then we have an int literal
55+
bool IsInteger = Result.NumSpelling.find_if_not(isdigit) == StringRef::npos;
56+
57+
Result.TokKind =
58+
IsInteger ? TokenKind::int_literal : TokenKind::float_literal;
5259
advanceBuffer(Result.NumSpelling.size());
5360
return Result;
5461
}

clang/unittests/Lex/LexHLSLRootSignatureTest.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
4343
// This test will check that we can lex different number tokens
4444
const llvm::StringLiteral Source = R"cc(
4545
-42 42 +42 +2147483648
46+
42. 4.2 .42
47+
42f 4.2F
48+
.42e+3 4.2E-12
49+
42.e+10f
4650
)cc";
4751

4852
auto TokLoc = SourceLocation();
@@ -51,9 +55,14 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
5155

5256
SmallVector<hlsl::RootSignatureToken> Tokens;
5357
SmallVector<TokenKind> Expected = {
54-
TokenKind::pu_minus, TokenKind::int_literal, TokenKind::int_literal,
55-
TokenKind::pu_plus, TokenKind::int_literal, TokenKind::pu_plus,
56-
TokenKind::int_literal,
58+
TokenKind::pu_minus, TokenKind::int_literal,
59+
TokenKind::int_literal, TokenKind::pu_plus,
60+
TokenKind::int_literal, TokenKind::pu_plus,
61+
TokenKind::int_literal, TokenKind::float_literal,
62+
TokenKind::float_literal, TokenKind::float_literal,
63+
TokenKind::float_literal, TokenKind::float_literal,
64+
TokenKind::float_literal, TokenKind::float_literal,
65+
TokenKind::float_literal,
5766
};
5867
checkTokens(Lexer, Tokens, Expected);
5968

@@ -73,13 +82,45 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
7382
// is treated as an unsigned integer instead
7483
IntToken = Tokens[6];
7584
ASSERT_EQ(IntToken.NumSpelling, "2147483648");
85+
86+
// Sample decimal end
87+
hlsl::RootSignatureToken FloatToken = Tokens[7];
88+
ASSERT_EQ(FloatToken.NumSpelling, "42.");
89+
90+
// Sample decimal middle
91+
FloatToken = Tokens[8];
92+
ASSERT_EQ(FloatToken.NumSpelling, "4.2");
93+
94+
// Sample decimal start
95+
FloatToken = Tokens[9];
96+
ASSERT_EQ(FloatToken.NumSpelling, ".42");
97+
98+
// Sample float lower
99+
FloatToken = Tokens[10];
100+
ASSERT_EQ(FloatToken.NumSpelling, "42f");
101+
102+
// Sample float upper
103+
FloatToken = Tokens[11];
104+
ASSERT_EQ(FloatToken.NumSpelling, "4.2F");
105+
106+
// Sample exp +
107+
FloatToken = Tokens[12];
108+
ASSERT_EQ(FloatToken.NumSpelling, ".42e+3");
109+
110+
// Sample exp -
111+
FloatToken = Tokens[13];
112+
ASSERT_EQ(FloatToken.NumSpelling, "4.2E-12");
113+
114+
// Sample all combined
115+
FloatToken = Tokens[14];
116+
ASSERT_EQ(FloatToken.NumSpelling, "42.e+10f");
76117
}
77118

78119
TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
79120
// This test will check that we can lex all defined tokens as defined in
80121
// HLSLRootSignatureTokenKinds.def, plus some additional integer variations
81122
const llvm::StringLiteral Source = R"cc(
82-
42
123+
42 42.0f
83124
84125
b0 t43 u987 s234
85126

0 commit comments

Comments
 (0)