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