-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[HLSL][RootSignature] Add lexing support for floating points #137720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- 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.
@llvm/pr-subscribers-hlsl @llvm/pr-subscribers-clang Author: Finn Plummer (inbelic) Changes
Namely:
This pr is simply responsible of creating a token that could be interpeted as a floating point integer by Resolves #126565 Full diff: https://github.com/llvm/llvm-project/pull/137720.diff 3 Files Affected:
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index d94be66b420c7..b506f18eb7050 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -55,6 +55,7 @@
TOK(invalid, "invalid identifier")
TOK(end_of_stream, "end of stream")
TOK(int_literal, "integer literal")
+TOK(float_literal, "float literal")
// Register Tokens:
TOK(bReg, "b register")
diff --git a/clang/lib/Lex/LexHLSLRootSignature.cpp b/clang/lib/Lex/LexHLSLRootSignature.cpp
index 41ee572cf094a..e5de9ad15b07f 100644
--- a/clang/lib/Lex/LexHLSLRootSignature.cpp
+++ b/clang/lib/Lex/LexHLSLRootSignature.cpp
@@ -16,8 +16,10 @@ using TokenKind = RootSignatureToken::Kind;
// Lexer Definitions
static bool isNumberChar(char C) {
- // TODO(#126565): extend for float support exponents
- return isdigit(C); // integer support
+ return isdigit(C) // integer support
+ || C == '.' // float support
+ || C == 'e' || C == 'E' || C == '-' || C == '+' // exponent support
+ || C == 'f' || C == 'F'; // explicit float support
}
RootSignatureToken RootSignatureLexer::lexToken() {
@@ -45,10 +47,15 @@ RootSignatureToken RootSignatureLexer::lexToken() {
break;
}
- // Integer literal
- if (isdigit(C)) {
- Result.TokKind = TokenKind::int_literal;
+ // Number literal
+ if (isdigit(C) || C == '.') {
Result.NumSpelling = Buffer.take_while(isNumberChar);
+
+ // If all values are digits then we have an int literal
+ bool IsInteger = Result.NumSpelling.find_if_not(isdigit) == StringRef::npos;
+
+ Result.TokKind =
+ IsInteger ? TokenKind::int_literal : TokenKind::float_literal;
advanceBuffer(Result.NumSpelling.size());
return Result;
}
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index 2024ff3a7dba9..ca609b0b2e8b8 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -43,6 +43,10 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
// This test will check that we can lex different number tokens
const llvm::StringLiteral Source = R"cc(
-42 42 +42 +2147483648
+ 42. 4.2 .42
+ 42f 4.2F
+ .42e+3 4.2E-12
+ 42.e+10f
)cc";
auto TokLoc = SourceLocation();
@@ -51,9 +55,14 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
SmallVector<hlsl::RootSignatureToken> Tokens;
SmallVector<TokenKind> Expected = {
- TokenKind::pu_minus, TokenKind::int_literal, TokenKind::int_literal,
- TokenKind::pu_plus, TokenKind::int_literal, TokenKind::pu_plus,
- TokenKind::int_literal,
+ TokenKind::pu_minus, TokenKind::int_literal,
+ TokenKind::int_literal, TokenKind::pu_plus,
+ TokenKind::int_literal, TokenKind::pu_plus,
+ TokenKind::int_literal, TokenKind::float_literal,
+ TokenKind::float_literal, TokenKind::float_literal,
+ TokenKind::float_literal, TokenKind::float_literal,
+ TokenKind::float_literal, TokenKind::float_literal,
+ TokenKind::float_literal,
};
checkTokens(Lexer, Tokens, Expected);
@@ -73,13 +82,45 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
// is treated as an unsigned integer instead
IntToken = Tokens[6];
ASSERT_EQ(IntToken.NumSpelling, "2147483648");
+
+ // Sample decimal end
+ hlsl::RootSignatureToken FloatToken = Tokens[7];
+ ASSERT_EQ(FloatToken.NumSpelling, "42.");
+
+ // Sample decimal middle
+ FloatToken = Tokens[8];
+ ASSERT_EQ(FloatToken.NumSpelling, "4.2");
+
+ // Sample decimal start
+ FloatToken = Tokens[9];
+ ASSERT_EQ(FloatToken.NumSpelling, ".42");
+
+ // Sample float lower
+ FloatToken = Tokens[10];
+ ASSERT_EQ(FloatToken.NumSpelling, "42f");
+
+ // Sample float upper
+ FloatToken = Tokens[11];
+ ASSERT_EQ(FloatToken.NumSpelling, "4.2F");
+
+ // Sample exp +
+ FloatToken = Tokens[12];
+ ASSERT_EQ(FloatToken.NumSpelling, ".42e+3");
+
+ // Sample exp -
+ FloatToken = Tokens[13];
+ ASSERT_EQ(FloatToken.NumSpelling, "4.2E-12");
+
+ // Sample all combined
+ FloatToken = Tokens[14];
+ ASSERT_EQ(FloatToken.NumSpelling, "42.e+10f");
}
TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
// This test will check that we can lex all defined tokens as defined in
// HLSLRootSignatureTokenKinds.def, plus some additional integer variations
const llvm::StringLiteral Source = R"cc(
- 42
+ 42 42.0f
b0 t43 u987 s234
|
Namely:
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 invokingNumericLiteralParser
during parsing.Resolves #126565