https://github.com/inbelic created 
https://github.com/llvm/llvm-project/pull/147084

The `SourceLocation` of a `RootSignatureToken` is incorrectly set to be the 
"offset" into the concatenated string that denotes the rootsignature. This 
causes an issue when the `StringLiteral` is a multi-line expansion macro as the 
offset will not account for the character between `StringLiteral` tokens.

This pr resolved by retaining the `SourceLocation` information that is kept in 
`StringLiteral` and then converting the offset in the concatenated string into 
the proper `SourceLocation` using the `StringLiteral::getLocationOfByte` 
interface. To do so, we will need to adjust the `RootSignatureToken` to only 
hold its offset into the root signature string. Then when the parser will use 
the token, it will need to compute its actual `SourceLocation`.

See linked issue for more context.

For example:

```
#define DemoRootSignature \
 "CBV(b0)," \
 "RootConstants(num32BitConstants = 3, b0, invalid)"
  expected caret location --------------------^
  actual caret location ------------------^
```

The caret points 5 characters early because the current offset did not account 
for the characters:
```
'"' ' ' '\' ' ' '"'
 1   2   3   4   5
```

- Updates `RootSignatureParser` to retain `SourceLocation` information by 
retaining the `StringLiteral` and passing the underlying `StringRef` to the 
`Lexer`
- Updates `RootSignatureLexer` so that the constructed tokens only reflect an 
offset into the `StringRef`
- Updates `RootSignatureParser` to directly construct its used `Lexer` so that 
the `StringLiteral` is directly tied with the string used in the 
`RootSignatureLexer`
- Updates `RootSignatureParser` to use `StringLiteral::getLocationOfByte` to 
get the actual token location for diagnostics
- Updates `ParseHLSLRootSignatureTest` to construct a phony 
`AST`/`StringLiteral` for the test cases
- Adds a test to `RootSignature-err.hlsl` showing that the `SourceLocation` is 
correctly set for diagnostics in a multi-line macro expansion

Resolves: https://github.com/llvm/llvm-project/issues/146967

>From 2a3ffdcd0c5ff66da59132438dfb3a2d91d2fb0c Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Fri, 4 Jul 2025 00:13:32 +0000
Subject: [PATCH 1/5] nfc: add phony ASTContext and StringLiteral to ParseHLSL

---
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 96 +++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 8831198e4b9c2..55c138186904e 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -6,6 +6,8 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -91,6 +93,22 @@ class ParseHLSLRootSignatureTest : public ::testing::Test {
     return PP;
   }
 
+  std::unique_ptr<ASTContext> createMinimalASTContext() {
+    IdentifierTable Idents(LangOpts);
+    SelectorTable Selectors;
+    Builtin::Context Builtins;
+
+    return std::make_unique<ASTContext>(LangOpts, SourceMgr, Idents, Selectors,
+                                        Builtins, TU_Complete);
+  }
+
+  StringLiteral *wrapSource(std::unique_ptr<ASTContext> &Ctx,
+                            StringRef Source) {
+    SourceLocation Locs[1] = {SourceLocation()};
+    return StringLiteral::Create(*Ctx, Source, StringLiteralKind::Unevaluated,
+                                 false, Ctx->VoidTy, Locs);
+  }
+
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
@@ -109,6 +127,9 @@ class ParseHLSLRootSignatureTest : public ::testing::Test {
 TEST_F(ParseHLSLRootSignatureTest, ValidParseEmptyTest) {
   const llvm::StringLiteral Source = R"cc()cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -143,6 +164,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
     DescriptorTable()
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -246,6 +270,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -331,6 +358,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseFloatsTest) {
     StaticSampler(s0, mipLODBias = 2147483648),
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -406,6 +436,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
     DescriptorTable(Sampler(s0, flags = DESCRIPTORS_VOLATILE))
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -437,6 +470,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootConsantsTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -494,6 +530,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) 
{
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -547,6 +586,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootDescriptorsTest) {
     CBV(b0, flags = 0),
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -621,6 +663,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -645,6 +690,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
     space
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -665,6 +713,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
     notAnIdentifier
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -685,6 +736,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedEndOfStreamTest) {
     DescriptorTable
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -710,6 +764,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingDTParameterTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -732,6 +789,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRDParameterTest) {
     SRV()
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -754,6 +814,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRCParameterTest) {
     RootConstants(b0)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -778,6 +841,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryDTParameterTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -800,6 +866,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryRCParameterTest) {
     RootConstants(num32BitConstants = 32, num32BitConstants = 24)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -824,6 +893,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalDTParameterTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -850,6 +922,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalRCParameterTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -873,6 +948,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedNumberTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -895,6 +973,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseOverflowedNegativeNumberTest) {
     StaticSampler(s0, mipLODBias = -4294967295)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -916,6 +997,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedFloatTest) {
     StaticSampler(s0, mipLODBias = 3.402823467e+38F)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -937,6 +1021,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexNegOverflowedFloatTest) {
     StaticSampler(s0, mipLODBias = -3.402823467e+38F)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -958,6 +1045,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedDoubleTest) {
     StaticSampler(s0, mipLODBias = 1.e+500)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -979,6 +1069,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexUnderflowFloatTest) {
     StaticSampler(s0, mipLODBias = 10e-309)
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -1003,6 +1096,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidNonZeroFlagsTest) {
     )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();

>From df0c899e0df065ffd6adabd3f3311b346fe7d87d Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Fri, 4 Jul 2025 00:22:12 +0000
Subject: [PATCH 2/5] nfc: add StringLiteral as a member of RootSignatureParser

---
 .../clang/Parse/ParseHLSLRootSignature.h      |  5 +-
 clang/lib/Parse/ParseDeclCXX.cpp              | 10 ++--
 clang/lib/Parse/ParseHLSLRootSignature.cpp    |  3 +-
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 52 +++++++++----------
 4 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 18cd1f379e62c..20239211f823e 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_PARSE_PARSEHLSLROOTSIGNATURE_H
 #define LLVM_CLANG_PARSE_PARSEHLSLROOTSIGNATURE_H
 
+#include "clang/AST/Expr.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Lex/LexHLSLRootSignature.h"
 #include "clang/Lex/Preprocessor.h"
@@ -28,7 +29,8 @@ namespace hlsl {
 class RootSignatureParser {
 public:
   RootSignatureParser(SmallVector<llvm::hlsl::rootsig::RootElement> &Elements,
-                      RootSignatureLexer &Lexer, clang::Preprocessor &PP);
+                      RootSignatureLexer &Lexer, StringLiteral *Signature,
+                      Preprocessor &PP);
 
   /// Consumes tokens from the Lexer and constructs the in-memory
   /// representations of the RootElements. Tokens are consumed until an
@@ -190,6 +192,7 @@ class RootSignatureParser {
   SmallVector<llvm::hlsl::rootsig::RootElement> &Elements;
   RootSignatureLexer &Lexer;
 
+  clang::StringLiteral *Signature;
   clang::Preprocessor &PP;
 
   RootSignatureToken CurToken;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index bd5c28b1992c4..743b146112316 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4944,19 +4944,19 @@ void 
Parser::ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs) {
   }
 
   // Construct our identifier
-  StringRef Signature = StrLiteral.value()->getString();
+  StringLiteral *Signature = StrLiteral.value();
   auto [DeclIdent, Found] =
-      Actions.HLSL().ActOnStartRootSignatureDecl(Signature);
+      Actions.HLSL().ActOnStartRootSignatureDecl(Signature->getString());
   // If we haven't found an already defined DeclIdent then parse the root
   // signature string and construct the in-memory elements
   if (!Found) {
     // Offset location 1 to account for '"'
     SourceLocation SignatureLoc =
-        StrLiteral.value()->getExprLoc().getLocWithOffset(1);
+        Signature->getExprLoc().getLocWithOffset(1);
     // Invoke the root signature parser to construct the in-memory constructs
-    hlsl::RootSignatureLexer Lexer(Signature, SignatureLoc);
+    hlsl::RootSignatureLexer Lexer(Signature->getString(), SignatureLoc);
     SmallVector<llvm::hlsl::rootsig::RootElement> RootElements;
-    hlsl::RootSignatureParser Parser(RootElements, Lexer, PP);
+    hlsl::RootSignatureParser Parser(RootElements, Lexer, Signature, PP);
     if (Parser.parse()) {
       T.consumeClose();
       return;
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 18d3644114eef..042977c91a2c4 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -19,8 +19,9 @@ using TokenKind = RootSignatureToken::Kind;
 
 RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements,
                                          RootSignatureLexer &Lexer,
+                                         StringLiteral *Signature,
                                          Preprocessor &PP)
-    : Elements(Elements), Lexer(Lexer), PP(PP), CurToken(SourceLocation()) {}
+    : Elements(Elements), Lexer(Lexer), Signature(Signature), PP(PP), 
CurToken(SourceLocation()) {}
 
 bool RootSignatureParser::parse() {
   // Iterate as many RootElements as possible
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 55c138186904e..8395ffdd68d7d 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -136,7 +136,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseEmptyTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -173,7 +173,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -279,7 +279,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -367,7 +367,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseFloatsTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -445,7 +445,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -479,7 +479,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootConsantsTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -539,7 +539,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) 
{
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -595,7 +595,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootDescriptorsTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -672,7 +672,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -699,7 +699,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
@@ -722,7 +722,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced - invalid token
   Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
@@ -745,7 +745,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedEndOfStreamTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced - end of stream
   Consumer->setExpected(diag::err_expected_after);
@@ -773,7 +773,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingDTParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
@@ -798,7 +798,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRDParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
@@ -823,7 +823,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRCParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
@@ -850,7 +850,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryDTParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -875,7 +875,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryRCParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -902,7 +902,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalDTParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -931,7 +931,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalRCParameterTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -957,7 +957,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedNumberTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -982,7 +982,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseOverflowedNegativeNumberTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1006,7 +1006,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedFloatTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1030,7 +1030,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexNegOverflowedFloatTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1054,7 +1054,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedDoubleTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1078,7 +1078,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexUnderflowFloatTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_underflow);
@@ -1105,7 +1105,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidNonZeroFlagsTest) {
 
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_non_zero_flag);

>From ed07290774129c660eea079cfbdf19448b4ce65d Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Fri, 4 Jul 2025 15:55:48 +0000
Subject: [PATCH 3/5] update `RootSignatureToken` to hold the offset into the
 signature string

---
 .../include/clang/Lex/LexHLSLRootSignature.h  |  22 ++-
 .../clang/Parse/ParseHLSLRootSignature.h      |   6 +
 clang/lib/Lex/LexHLSLRootSignature.cpp        |   6 +-
 clang/lib/Parse/ParseDeclCXX.cpp              |   5 +-
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 143 +++++++++++-------
 .../Lex/LexHLSLRootSignatureTest.cpp          |  13 +-
 .../Parse/ParseHLSLRootSignatureTest.cpp      |  78 ++++------
 7 files changed, 142 insertions(+), 131 deletions(-)

diff --git a/clang/include/clang/Lex/LexHLSLRootSignature.h 
b/clang/include/clang/Lex/LexHLSLRootSignature.h
index 9901485b44d38..9bfefc96335b8 100644
--- a/clang/include/clang/Lex/LexHLSLRootSignature.h
+++ b/clang/include/clang/Lex/LexHLSLRootSignature.h
@@ -31,16 +31,17 @@ struct RootSignatureToken {
 
   Kind TokKind = Kind::invalid;
 
-  // Retain the SouceLocation of the token for diagnostics
-  clang::SourceLocation TokLoc;
+  // Retain the location offset of the token in the Signature
+  // string
+  uint32_t LocOffset;
 
   // Retain spelling of an numeric constant to be parsed later
   StringRef NumSpelling;
 
   // Constructors
-  RootSignatureToken(clang::SourceLocation TokLoc) : TokLoc(TokLoc) {}
-  RootSignatureToken(Kind TokKind, clang::SourceLocation TokLoc)
-      : TokKind(TokKind), TokLoc(TokLoc) {}
+  RootSignatureToken(uint32_t LocOffset) : LocOffset(LocOffset) {}
+  RootSignatureToken(Kind TokKind, uint32_t LocOffset)
+      : TokKind(TokKind), LocOffset(LocOffset) {}
 };
 
 inline const DiagnosticBuilder &
@@ -61,8 +62,7 @@ operator<<(const DiagnosticBuilder &DB, const 
RootSignatureToken::Kind Kind) {
 
 class RootSignatureLexer {
 public:
-  RootSignatureLexer(StringRef Signature, clang::SourceLocation SourceLoc)
-      : Buffer(Signature), SourceLoc(SourceLoc) {}
+  RootSignatureLexer(StringRef Signature) : Buffer(Signature) {}
 
   /// Consumes and returns the next token.
   RootSignatureToken consumeToken();
@@ -76,15 +76,13 @@ class RootSignatureLexer {
   }
 
 private:
-  // Internal buffer to iterate over
+  // Internal buffer state
   StringRef Buffer;
+  uint32_t LocOffset = 0;
 
   // Current peek state
   std::optional<RootSignatureToken> NextToken = std::nullopt;
 
-  // Passed down parameters from Sema
-  clang::SourceLocation SourceLoc;
-
   /// Consumes the buffer and returns the lexed token.
   RootSignatureToken lexToken();
 
@@ -92,7 +90,7 @@ class RootSignatureLexer {
   /// Updates the SourceLocation appropriately.
   void advanceBuffer(unsigned NumCharacters = 1) {
     Buffer = Buffer.drop_front(NumCharacters);
-    SourceLoc = SourceLoc.getLocWithOffset(NumCharacters);
+    LocOffset += NumCharacters;
   }
 };
 
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 20239211f823e..d3d8eecaa56ca 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -188,6 +188,12 @@ class RootSignatureParser {
   bool tryConsumeExpectedToken(RootSignatureToken::Kind Expected);
   bool tryConsumeExpectedToken(ArrayRef<RootSignatureToken::Kind> Expected);
 
+  /// Convert the token's offset in the signature string to its SourceLocation
+  ///
+  /// This allows to currently retrieve the location for multi-token
+  /// StringLiterals
+  SourceLocation getTokenLocation(RootSignatureToken Tok);
+
 private:
   SmallVector<llvm::hlsl::rootsig::RootElement> &Elements;
   RootSignatureLexer &Lexer;
diff --git a/clang/lib/Lex/LexHLSLRootSignature.cpp 
b/clang/lib/Lex/LexHLSLRootSignature.cpp
index e5de9ad15b07f..a89462c13c8e3 100644
--- a/clang/lib/Lex/LexHLSLRootSignature.cpp
+++ b/clang/lib/Lex/LexHLSLRootSignature.cpp
@@ -27,10 +27,10 @@ RootSignatureToken RootSignatureLexer::lexToken() {
   advanceBuffer(Buffer.take_while(isspace).size());
 
   if (isEndOfBuffer())
-    return RootSignatureToken(TokenKind::end_of_stream, SourceLoc);
+    return RootSignatureToken(TokenKind::end_of_stream, LocOffset);
 
   // Record where this token is in the text for usage in parser diagnostics
-  RootSignatureToken Result(SourceLoc);
+  RootSignatureToken Result(LocOffset);
 
   char C = Buffer.front();
 
@@ -62,7 +62,7 @@ RootSignatureToken RootSignatureLexer::lexToken() {
 
   // All following tokens require at least one additional character
   if (Buffer.size() <= 1) {
-    Result = RootSignatureToken(TokenKind::invalid, SourceLoc);
+    Result = RootSignatureToken(TokenKind::invalid, LocOffset);
     return Result;
   }
 
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 743b146112316..cd624814f8c8c 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4950,11 +4950,8 @@ void 
Parser::ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs) {
   // If we haven't found an already defined DeclIdent then parse the root
   // signature string and construct the in-memory elements
   if (!Found) {
-    // Offset location 1 to account for '"'
-    SourceLocation SignatureLoc =
-        Signature->getExprLoc().getLocWithOffset(1);
     // Invoke the root signature parser to construct the in-memory constructs
-    hlsl::RootSignatureLexer Lexer(Signature->getString(), SignatureLoc);
+    hlsl::RootSignatureLexer Lexer(Signature->getString());
     SmallVector<llvm::hlsl::rootsig::RootElement> RootElements;
     hlsl::RootSignatureParser Parser(RootElements, Lexer, Signature, PP);
     if (Parser.parse()) {
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 042977c91a2c4..49139489db451 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -21,7 +21,8 @@ 
RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements,
                                          RootSignatureLexer &Lexer,
                                          StringLiteral *Signature,
                                          Preprocessor &PP)
-    : Elements(Elements), Lexer(Lexer), Signature(Signature), PP(PP), 
CurToken(SourceLocation()) {}
+    : Elements(Elements), Lexer(Lexer), Signature(Signature), PP(PP),
+      CurToken(0) {}
 
 bool RootSignatureParser::parse() {
   // Iterate as many RootElements as possible
@@ -90,7 +91,8 @@ std::optional<llvm::dxbc::RootFlags> 
RootSignatureParser::parseRootFlags() {
   // Handle the edge-case of '0' to specify no flags set
   if (tryConsumeExpectedToken(TokenKind::int_literal)) {
     if (!verifyZeroFlag()) {
-      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_non_zero_flag);
+      getDiags().Report(getTokenLocation(CurToken),
+                        diag::err_hlsl_rootsig_non_zero_flag);
       return std::nullopt;
     }
   } else {
@@ -140,7 +142,8 @@ std::optional<RootConstants> 
RootSignatureParser::parseRootConstants() {
 
   // Check mandatory parameters where provided
   if (!Params->Num32BitConstants.has_value()) {
-    getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+    getDiags().Report(getTokenLocation(CurToken),
+                      diag::err_hlsl_rootsig_missing_param)
         << TokenKind::kw_num32BitConstants;
     return std::nullopt;
   }
@@ -148,7 +151,8 @@ std::optional<RootConstants> 
RootSignatureParser::parseRootConstants() {
   Constants.Num32BitConstants = Params->Num32BitConstants.value();
 
   if (!Params->Reg.has_value()) {
-    getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+    getDiags().Report(getTokenLocation(CurToken),
+                      diag::err_hlsl_rootsig_missing_param)
         << TokenKind::bReg;
     return std::nullopt;
   }
@@ -208,7 +212,8 @@ std::optional<RootDescriptor> 
RootSignatureParser::parseRootDescriptor() {
 
   // Check mandatory parameters were provided
   if (!Params->Reg.has_value()) {
-    getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+    getDiags().Report(getTokenLocation(CurToken),
+                      diag::err_hlsl_rootsig_missing_param)
         << ExpectedReg;
     return std::nullopt;
   }
@@ -257,7 +262,8 @@ std::optional<DescriptorTable> 
RootSignatureParser::parseDescriptorTable() {
 
     if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
       if (Visibility.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -327,7 +333,8 @@ RootSignatureParser::parseDescriptorTableClause() {
 
   // Check mandatory parameters were provided
   if (!Params->Reg.has_value()) {
-    getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+    getDiags().Report(getTokenLocation(CurToken),
+                      diag::err_hlsl_rootsig_missing_param)
         << ExpectedReg;
     return std::nullopt;
   }
@@ -371,7 +378,8 @@ std::optional<StaticSampler> 
RootSignatureParser::parseStaticSampler() {
 
   // Check mandatory parameters were provided
   if (!Params->Reg.has_value()) {
-    getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+    getDiags().Report(getTokenLocation(CurToken),
+                      diag::err_hlsl_rootsig_missing_param)
         << TokenKind::sReg;
     return std::nullopt;
   }
@@ -436,7 +444,8 @@ RootSignatureParser::parseRootConstantParams() {
     // `num32BitConstants` `=` POS_INT
     if (tryConsumeExpectedToken(TokenKind::kw_num32BitConstants)) {
       if (Params.Num32BitConstants.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -453,7 +462,8 @@ RootSignatureParser::parseRootConstantParams() {
     // `b` POS_INT
     if (tryConsumeExpectedToken(TokenKind::bReg)) {
       if (Params.Reg.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -466,7 +476,8 @@ RootSignatureParser::parseRootConstantParams() {
     // `space` `=` POS_INT
     if (tryConsumeExpectedToken(TokenKind::kw_space)) {
       if (Params.Space.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -483,7 +494,8 @@ RootSignatureParser::parseRootConstantParams() {
     // `visibility` `=` SHADER_VISIBILITY
     if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
       if (Params.Visibility.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -511,7 +523,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
RegType) {
     // ( `b` | `t` | `u`) POS_INT
     if (tryConsumeExpectedToken(RegType)) {
       if (Params.Reg.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -524,7 +537,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
RegType) {
     // `space` `=` POS_INT
     if (tryConsumeExpectedToken(TokenKind::kw_space)) {
       if (Params.Space.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -541,7 +555,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
RegType) {
     // `visibility` `=` SHADER_VISIBILITY
     if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
       if (Params.Visibility.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -558,7 +573,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
RegType) {
     // `flags` `=` ROOT_DESCRIPTOR_FLAGS
     if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
       if (Params.Flags.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -586,7 +602,8 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
     // ( `b` | `t` | `u` | `s`) POS_INT
     if (tryConsumeExpectedToken(RegType)) {
       if (Params.Reg.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -599,7 +616,8 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
     // `numDescriptors` `=` POS_INT | unbounded
     if (tryConsumeExpectedToken(TokenKind::kw_numDescriptors)) {
       if (Params.NumDescriptors.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -622,7 +640,8 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
     // `space` `=` POS_INT
     if (tryConsumeExpectedToken(TokenKind::kw_space)) {
       if (Params.Space.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -639,7 +658,8 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
     // `offset` `=` POS_INT | DESCRIPTOR_RANGE_OFFSET_APPEND
     if (tryConsumeExpectedToken(TokenKind::kw_offset)) {
       if (Params.Offset.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -662,7 +682,8 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
     // `flags` `=` DESCRIPTOR_RANGE_FLAGS
     if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
       if (Params.Flags.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -691,7 +712,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `s` POS_INT
     if (tryConsumeExpectedToken(TokenKind::sReg)) {
       if (Params.Reg.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -704,7 +726,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `filter` `=` FILTER
     if (tryConsumeExpectedToken(TokenKind::kw_filter)) {
       if (Params.Filter.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -721,7 +744,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `addressU` `=` TEXTURE_ADDRESS
     if (tryConsumeExpectedToken(TokenKind::kw_addressU)) {
       if (Params.AddressU.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -738,7 +762,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `addressV` `=` TEXTURE_ADDRESS
     if (tryConsumeExpectedToken(TokenKind::kw_addressV)) {
       if (Params.AddressV.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -755,7 +780,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `addressW` `=` TEXTURE_ADDRESS
     if (tryConsumeExpectedToken(TokenKind::kw_addressW)) {
       if (Params.AddressW.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -772,7 +798,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `mipLODBias` `=` NUMBER
     if (tryConsumeExpectedToken(TokenKind::kw_mipLODBias)) {
       if (Params.MipLODBias.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -789,7 +816,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `maxAnisotropy` `=` POS_INT
     if (tryConsumeExpectedToken(TokenKind::kw_maxAnisotropy)) {
       if (Params.MaxAnisotropy.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -806,7 +834,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `comparisonFunc` `=` COMPARISON_FUNC
     if (tryConsumeExpectedToken(TokenKind::kw_comparisonFunc)) {
       if (Params.CompFunc.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -823,7 +852,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `borderColor` `=` STATIC_BORDER_COLOR
     if (tryConsumeExpectedToken(TokenKind::kw_borderColor)) {
       if (Params.BorderColor.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -840,7 +870,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `minLOD` `=` NUMBER
     if (tryConsumeExpectedToken(TokenKind::kw_minLOD)) {
       if (Params.MinLOD.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -857,7 +888,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `maxLOD` `=` NUMBER
     if (tryConsumeExpectedToken(TokenKind::kw_maxLOD)) {
       if (Params.MaxLOD.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -874,7 +906,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `space` `=` POS_INT
     if (tryConsumeExpectedToken(TokenKind::kw_space)) {
       if (Params.Space.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -891,7 +924,8 @@ RootSignatureParser::parseStaticSamplerParams() {
     // `visibility` `=` SHADER_VISIBILITY
     if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
       if (Params.Visibility.has_value()) {
-        getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+        getDiags().Report(getTokenLocation(CurToken),
+                          diag::err_hlsl_rootsig_repeat_param)
             << CurToken.TokKind;
         return std::nullopt;
       }
@@ -1123,7 +1157,8 @@ RootSignatureParser::parseRootDescriptorFlags() {
   // Handle the edge-case of '0' to specify no flags set
   if (tryConsumeExpectedToken(TokenKind::int_literal)) {
     if (!verifyZeroFlag()) {
-      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_non_zero_flag);
+      getDiags().Report(getTokenLocation(CurToken),
+                        diag::err_hlsl_rootsig_non_zero_flag);
       return std::nullopt;
     }
     return llvm::dxbc::RootDescriptorFlags::None;
@@ -1162,7 +1197,8 @@ RootSignatureParser::parseDescriptorRangeFlags() {
   // Handle the edge-case of '0' to specify no flags set
   if (tryConsumeExpectedToken(TokenKind::int_literal)) {
     if (!verifyZeroFlag()) {
-      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_non_zero_flag);
+      getDiags().Report(getTokenLocation(CurToken),
+                        diag::err_hlsl_rootsig_non_zero_flag);
       return std::nullopt;
     }
     return llvm::dxbc::DescriptorRangeFlags::None;
@@ -1195,9 +1231,9 @@ RootSignatureParser::parseDescriptorRangeFlags() {
 
 std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
   // Parse the numeric value and do semantic checks on its specification
-  clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
-                                      PP.getSourceManager(), PP.getLangOpts(),
-                                      PP.getTargetInfo(), PP.getDiagnostics());
+  clang::NumericLiteralParser Literal(
+      CurToken.NumSpelling, getTokenLocation(CurToken), PP.getSourceManager(),
+      PP.getLangOpts(), PP.getTargetInfo(), PP.getDiagnostics());
   if (Literal.hadError)
     return std::nullopt; // Error has already been reported so just return
 
@@ -1207,7 +1243,7 @@ std::optional<uint32_t> 
RootSignatureParser::handleUIntLiteral() {
   llvm::APSInt Val(32, /*IsUnsigned=*/true);
   if (Literal.GetIntegerValue(Val)) {
     // Report that the value has overflowed
-    PP.getDiagnostics().Report(CurToken.TokLoc,
+    PP.getDiagnostics().Report(getTokenLocation(CurToken),
                                diag::err_hlsl_number_literal_overflow)
         << /*integer type*/ 0 << /*is signed*/ 0;
     return std::nullopt;
@@ -1218,9 +1254,9 @@ std::optional<uint32_t> 
RootSignatureParser::handleUIntLiteral() {
 
 std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) {
   // Parse the numeric value and do semantic checks on its specification
-  clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
-                                      PP.getSourceManager(), PP.getLangOpts(),
-                                      PP.getTargetInfo(), PP.getDiagnostics());
+  clang::NumericLiteralParser Literal(
+      CurToken.NumSpelling, getTokenLocation(CurToken), PP.getSourceManager(),
+      PP.getLangOpts(), PP.getTargetInfo(), PP.getDiagnostics());
   if (Literal.hadError)
     return std::nullopt; // Error has already been reported so just return
 
@@ -1241,7 +1277,7 @@ std::optional<int32_t> 
RootSignatureParser::handleIntLiteral(bool Negated) {
 
   if (Overflowed) {
     // Report that the value has overflowed
-    PP.getDiagnostics().Report(CurToken.TokLoc,
+    PP.getDiagnostics().Report(getTokenLocation(CurToken),
                                diag::err_hlsl_number_literal_overflow)
         << /*integer type*/ 0 << /*is signed*/ 1;
     return std::nullopt;
@@ -1255,9 +1291,9 @@ std::optional<int32_t> 
RootSignatureParser::handleIntLiteral(bool Negated) {
 
 std::optional<float> RootSignatureParser::handleFloatLiteral(bool Negated) {
   // Parse the numeric value and do semantic checks on its specification
-  clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
-                                      PP.getSourceManager(), PP.getLangOpts(),
-                                      PP.getTargetInfo(), PP.getDiagnostics());
+  clang::NumericLiteralParser Literal(
+      CurToken.NumSpelling, getTokenLocation(CurToken), PP.getSourceManager(),
+      PP.getLangOpts(), PP.getTargetInfo(), PP.getDiagnostics());
   if (Literal.hadError)
     return std::nullopt; // Error has already been reported so just return
 
@@ -1285,14 +1321,14 @@ std::optional<float> 
RootSignatureParser::handleFloatLiteral(bool Negated) {
 
   if (Status & llvm::APFloat::opStatus::opUnderflow) {
     // Report that the value has underflowed
-    PP.getDiagnostics().Report(CurToken.TokLoc,
+    PP.getDiagnostics().Report(getTokenLocation(CurToken),
                                diag::err_hlsl_number_literal_underflow);
     return std::nullopt;
   }
 
   if (Status & llvm::APFloat::opStatus::opOverflow) {
     // Report that the value has overflowed
-    PP.getDiagnostics().Report(CurToken.TokLoc,
+    PP.getDiagnostics().Report(getTokenLocation(CurToken),
                                diag::err_hlsl_number_literal_overflow)
         << /*float type*/ 1;
     return std::nullopt;
@@ -1305,7 +1341,7 @@ std::optional<float> 
RootSignatureParser::handleFloatLiteral(bool Negated) {
   double FloatMax = double(std::numeric_limits<float>::max());
   if (FloatMax < DoubleVal || DoubleVal < -FloatMax) {
     // Report that the value has overflowed
-    PP.getDiagnostics().Report(CurToken.TokLoc,
+    PP.getDiagnostics().Report(getTokenLocation(CurToken),
                                diag::err_hlsl_number_literal_overflow)
         << /*float type*/ 1;
     return std::nullopt;
@@ -1336,7 +1372,7 @@ bool RootSignatureParser::consumeExpectedToken(TokenKind 
Expected,
     return false;
 
   // Report unexpected token kind error
-  DiagnosticBuilder DB = getDiags().Report(CurToken.TokLoc, DiagID);
+  DiagnosticBuilder DB = getDiags().Report(getTokenLocation(CurToken), DiagID);
   switch (DiagID) {
   case diag::err_expected:
     DB << Expected;
@@ -1365,5 +1401,10 @@ bool RootSignatureParser::tryConsumeExpectedToken(
   return true;
 }
 
+SourceLocation RootSignatureParser::getTokenLocation(RootSignatureToken Tok) {
+  return Signature->getLocationOfByte(Tok.LocOffset, PP.getSourceManager(),
+                                      PP.getLangOpts(), PP.getTargetInfo());
+}
+
 } // namespace hlsl
 } // namespace clang
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp 
b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index b5bd233c52557..01f8d4f97b092 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -49,9 +49,7 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
     42.e+10f
   )cc";
 
-  auto TokLoc = SourceLocation();
-
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
 
   SmallVector<hlsl::RootSignatureToken> Tokens;
   SmallVector<TokenKind> Expected = {
@@ -229,8 +227,7 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
     STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT
     STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT
   )cc";
-  auto TokLoc = SourceLocation();
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
 
   SmallVector<hlsl::RootSignatureToken> Tokens;
   SmallVector<TokenKind> Expected = {
@@ -251,8 +248,7 @@ TEST_F(LexHLSLRootSignatureTest, 
ValidCaseInsensitiveKeywordsTest) {
     SPACE visibility FLAGS
     numDescriptors OFFSET
   )cc";
-  auto TokLoc = SourceLocation();
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
 
   SmallVector<hlsl::RootSignatureToken> Tokens;
   SmallVector<TokenKind> Expected = {
@@ -276,8 +272,7 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexPeekTest) {
   const llvm::StringLiteral Source = R"cc(
     )1
   )cc";
-  auto TokLoc = SourceLocation();
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
 
   // Test basic peek
   hlsl::RootSignatureToken Res = Lexer.peekNextToken();
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 8395ffdd68d7d..d9f577a82881d 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -132,9 +132,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseEmptyTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -169,9 +168,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -275,9 +273,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -363,9 +360,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseFloatsTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -441,9 +437,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -475,9 +470,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootConsantsTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -535,9 +529,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) 
{
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -591,9 +584,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootDescriptorsTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -668,9 +660,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -695,9 +686,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -718,9 +708,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -741,9 +730,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedEndOfStreamTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -769,9 +757,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingDTParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -794,9 +781,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRDParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -819,9 +805,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRCParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -846,9 +831,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryDTParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -871,9 +855,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryRCParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -898,9 +881,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalDTParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -927,9 +909,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalRCParameterTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -953,9 +934,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedNumberTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -978,9 +958,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseOverflowedNegativeNumberTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -1002,9 +981,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedFloatTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -1026,9 +1004,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexNegOverflowedFloatTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -1050,9 +1027,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedDoubleTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -1074,9 +1050,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexUnderflowFloatTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 
@@ -1101,9 +1076,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidNonZeroFlagsTest) {
 
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
-  auto TokLoc = SourceLocation();
 
-  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
   hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
 

>From aae1f682ec49e65f0053062ec3cb28d8bbbf5bb7 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Fri, 4 Jul 2025 16:01:12 +0000
Subject: [PATCH 4/5] nfc: instaniate the Lexer for the Parser

- the StringLiteral between the Lexer and Parser is now inherently
coupled together and this constructor will enforce such
---
 .../clang/Parse/ParseHLSLRootSignature.h      |  5 +-
 clang/lib/Parse/ParseDeclCXX.cpp              |  3 +-
 clang/lib/Parse/ParseHLSLRootSignature.cpp    |  5 +-
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 78 +++++++------------
 4 files changed, 31 insertions(+), 60 deletions(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index d3d8eecaa56ca..a1aa04ca1b665 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -29,8 +29,7 @@ namespace hlsl {
 class RootSignatureParser {
 public:
   RootSignatureParser(SmallVector<llvm::hlsl::rootsig::RootElement> &Elements,
-                      RootSignatureLexer &Lexer, StringLiteral *Signature,
-                      Preprocessor &PP);
+                      StringLiteral *Signature, Preprocessor &PP);
 
   /// Consumes tokens from the Lexer and constructs the in-memory
   /// representations of the RootElements. Tokens are consumed until an
@@ -196,7 +195,7 @@ class RootSignatureParser {
 
 private:
   SmallVector<llvm::hlsl::rootsig::RootElement> &Elements;
-  RootSignatureLexer &Lexer;
+  RootSignatureLexer Lexer;
 
   clang::StringLiteral *Signature;
   clang::Preprocessor &PP;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index cd624814f8c8c..2763e67c8fe5b 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4951,9 +4951,8 @@ void 
Parser::ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs) {
   // signature string and construct the in-memory elements
   if (!Found) {
     // Invoke the root signature parser to construct the in-memory constructs
-    hlsl::RootSignatureLexer Lexer(Signature->getString());
     SmallVector<llvm::hlsl::rootsig::RootElement> RootElements;
-    hlsl::RootSignatureParser Parser(RootElements, Lexer, Signature, PP);
+    hlsl::RootSignatureParser Parser(RootElements, Signature, PP);
     if (Parser.parse()) {
       T.consumeClose();
       return;
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 49139489db451..fb59dffdb8422 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -18,11 +18,10 @@ namespace hlsl {
 using TokenKind = RootSignatureToken::Kind;
 
 RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements,
-                                         RootSignatureLexer &Lexer,
                                          StringLiteral *Signature,
                                          Preprocessor &PP)
-    : Elements(Elements), Lexer(Lexer), Signature(Signature), PP(PP),
-      CurToken(0) {}
+    : Elements(Elements), Lexer(Signature->getString()), Signature(Signature),
+      PP(PP), CurToken(0) {}
 
 bool RootSignatureParser::parse() {
   // Iterate as many RootElements as possible
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index d9f577a82881d..c6e0e5b65949d 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -133,9 +133,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseEmptyTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -169,9 +168,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -274,9 +272,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -361,9 +358,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseFloatsTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -438,9 +434,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -471,9 +466,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootConsantsTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -530,9 +524,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) 
{
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -585,9 +578,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootDescriptorsTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -661,9 +653,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test no diagnostics produced
   Consumer->setNoDiag();
@@ -687,9 +678,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
@@ -709,9 +699,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced - invalid token
   Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
@@ -731,9 +720,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedEndOfStreamTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced - end of stream
   Consumer->setExpected(diag::err_expected_after);
@@ -758,9 +746,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingDTParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
@@ -782,9 +769,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRDParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
@@ -806,9 +792,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidMissingRCParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_missing_param);
@@ -832,9 +817,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryDTParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -856,9 +840,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedMandatoryRCParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -882,9 +865,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalDTParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -910,9 +892,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRepeatedOptionalRCParameterTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_repeat_param);
@@ -935,9 +916,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedNumberTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -959,9 +939,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseOverflowedNegativeNumberTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -982,9 +961,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedFloatTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1005,9 +983,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexNegOverflowedFloatTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1028,9 +1005,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexOverflowedDoubleTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
@@ -1051,9 +1027,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidLexUnderflowFloatTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_number_literal_underflow);
@@ -1077,9 +1052,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidNonZeroFlagsTest) {
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
 
-  hlsl::RootSignatureLexer Lexer(Source);
   SmallVector<RootElement> Elements;
-  hlsl::RootSignatureParser Parser(Elements, Lexer, Signature, *PP);
+  hlsl::RootSignatureParser Parser(Elements, Signature, *PP);
 
   // Test correct diagnostic produced
   Consumer->setExpected(diag::err_hlsl_rootsig_non_zero_flag);

>From 28522fc6abcb5eaa936209cbd6da31a5b2e88135 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Fri, 4 Jul 2025 16:20:17 +0000
Subject: [PATCH 5/5] add sample testcase

---
 clang/test/SemaHLSL/RootSignature-err.hlsl | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index aec8a15f8ed7f..a5fd76e73b04e 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s 
-verify
+// RUN: not %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s 
2>&1 | FileCheck %s
 
 // Attr test
 
@@ -22,3 +23,14 @@ void bad_root_signature_4() {}
 // expected-error@+1 {{expected ')' to denote end of parameters, or, another 
valid parameter of RootConstants}}
 [RootSignature("RootConstants(b0, num32BitConstants = 1, invalid)")]
 void bad_root_signature_5() {}
+
+#define MultiLineRootSignature \
+ "CBV(b0)," \
+ "RootConstants(num32BitConstants = 3, b0, invalid)"
+
+// CHECK: note: expanded from macro 'MultiLineRootSignature'
+// CHECK-NEXT: [[@LINE-3]] | "RootConstants(num32BitConstants = 3, b0, 
invalid)"
+// CHECK-NEXT:             |                                         ^
+// expected-error@+1 {{expected ')' to denote end of parameters, or, another 
valid parameter of RootConstants}}
+[RootSignature(MultiLineRootSignature)]
+void bad_root_signature_6() {}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to