[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits

https://github.com/inbelic edited 
https://github.com/llvm/llvm-project/pull/147084
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)


Changes

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

---

Patch is 53.74 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/147084.diff


8 Files Affected:

- (modified) clang/include/clang/Lex/LexHLSLRootSignature.h (+10-12) 
- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+10-3) 
- (modified) clang/lib/Lex/LexHLSLRootSignature.cpp (+3-3) 
- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+3-7) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+93-53) 
- (modified) clang/test/SemaHLSL/RootSignature-err.hlsl (+12) 
- (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+4-9) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+158-112) 


``diff
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 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 += NumCharacte

[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits

https://github.com/inbelic ready_for_review 
https://github.com/llvm/llvm-project/pull/147084
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits

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

>From 34d3879022f65d51002d3abe3aec50a952ca6e18 Mon Sep 17 00:00:00 2001
From: Finn Plummer 
Date: Fri, 4 Jul 2025 00:13:32 +
Subject: [PATCH 1/6] 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 871f12ef3cce3..6f00c042404b0 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"
@@ -93,6 +95,22 @@ class ParseHLSLRootSignatureTest : public ::testing::Test {
 return PP;
   }
 
+  std::unique_ptr createMinimalASTContext() {
+IdentifierTable Idents(LangOpts);
+SelectorTable Selectors;
+Builtin::Context Builtins;
+
+return std::make_unique(LangOpts, SourceMgr, Idents, Selectors,
+Builtins, TU_Complete);
+  }
+
+  StringLiteral *wrapSource(std::unique_ptr &Ctx,
+StringRef Source) {
+SourceLocation Locs[1] = {SourceLocation()};
+return StringLiteral::Create(*Ctx, Source, StringLiteralKind::Unevaluated,
+ false, Ctx->VoidTy, Locs);
+  }
+
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr DiagID;
@@ -111,6 +129,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();
@@ -146,6 +167,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();
@@ -250,6 +274,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -336,6 +363,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();
@@ -412,6 +442,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();
@@ -444,6 +477,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseRootConsantsTest) {
 )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -502,6 +538,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) 
{
 )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -556,6 +595,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();
@@ -631,6 +673,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
 )
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleLoader ModLoader;
   auto PP = createPP(Source, ModLoader);
   auto TokLoc = SourceLocation();
@@ -802,6 +847,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
 space
   )cc";
 
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
   TrivialModuleL

[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits

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

>From abef31336baec05dafe2cc7ae32e753790322f68 Mon Sep 17 00:00:00 2001
From: Finn Plummer 
Date: Fri, 4 Jul 2025 00:13:32 +
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 createMinimalASTContext() {
+IdentifierTable Idents(LangOpts);
+SelectorTable Selectors;
+Builtin::Context Builtins;
+
+return std::make_unique(LangOpts, SourceMgr, Idents, Selectors,
+Builtins, TU_Complete);
+  }
+
+  StringLiteral *wrapSource(std::unique_ptr &Ctx,
+StringRef Source) {
+SourceLocation Locs[1] = {SourceLocation()};
+return StringLiteral::Create(*Ctx, Source, StringLiteralKind::Unevaluated,
+ false, Ctx->VoidTy, Locs);
+  }
+
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr 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);
+
   TrivialModuleL

[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits

https://github.com/inbelic edited 
https://github.com/llvm/llvm-project/pull/147084
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits


@@ -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'

inbelic wrote:

the generation is checked using FileCheck because the `expanded from macro` 
note is generated by the preprocessor, which is not matchable in `verify`.

If I am missing something to make it work with `verify` that would be preferred!

https://github.com/llvm/llvm-project/pull/147084
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL][RootSignature] Correct `RootSignatureParser` to use correct `SourceLocation` in diagnostics (PR #147084)

2025-07-04 Thread Finn Plummer via cfe-commits

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 
Date: Fri, 4 Jul 2025 00:13:32 +
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 createMinimalASTContext() {
+IdentifierTable Idents(LangOpts);
+SelectorTable Selectors;
+Builtin::Context Builtins;
+
+return std::make_unique(LangOpts, SourceMgr, Idents, Selectors,
+Builtins, TU_Complete);
+  }
+
+  StringLiteral *wrapSource(std::unique_ptr &Ctx,
+StringRef Source) {
+SourceLocation Locs[1] = {SourceLocation()};
+return StringLiteral::Create(*Ctx, Source, StringLiteralKind::Unevaluated,
+ false, Ctx->VoidTy, Locs);
+  }
+
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr 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();
+