Skip to content

[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

Merged
merged 1 commit into from
Apr 30, 2025

Conversation

inbelic
Copy link
Contributor

@inbelic inbelic commented Apr 28, 2025

  • this takes care to add support to match the behaviour of DXC 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

- 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.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" HLSL HLSL Language Support labels Apr 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 28, 2025

@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)

Changes
  • this takes care to add support to match the behaviour of DXC 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


Full diff: https://github.com/llvm/llvm-project/pull/137720.diff

3 Files Affected:

  • (modified) clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def (+1)
  • (modified) clang/lib/Lex/LexHLSLRootSignature.cpp (+12-5)
  • (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+45-4)
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
 

@bogner bogner self-requested a review April 29, 2025 17:46
@inbelic inbelic merged commit 8e4dd21 into llvm:main Apr 30, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category HLSL HLSL Language Support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[HLSL] Add support for lexing floating-point literals in RootSignatureLexer
4 participants