https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/123985
>From 05c9523adaf9cc3e1585c02bed036ad83667b722 Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Wed, 22 Jan 2025 17:53:59 +0000 Subject: [PATCH 1/6] [HLSL] Define the HLSLRootSignature Attr - Defines HLSLRootSignature Attr in `Attr.td` - Define and implement handleHLSLRootSignature in `SemaHLSL` - Adds sample test case to show AST Node is generated in `RootSignatures-AST.hlsl` This commit will "hook-up" the seperately defined RootSignature parser and invoke it to create the RootElements, then store them on the ASTContext and finally store the reference to the Elements in RootSignatureAttr --- clang/include/clang/AST/Attr.h | 1 + clang/include/clang/Basic/Attr.td | 20 ++++++++++++ clang/include/clang/Basic/AttrDocs.td | 4 +++ clang/include/clang/Sema/SemaHLSL.h | 1 + clang/lib/Sema/SemaDeclAttr.cpp | 3 ++ clang/lib/Sema/SemaHLSL.cpp | 36 +++++++++++++++++++++ clang/test/AST/HLSL/RootSignatures-AST.hlsl | 28 ++++++++++++++++ 7 files changed, 93 insertions(+) create mode 100644 clang/test/AST/HLSL/RootSignatures-AST.hlsl diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 3365ebe4d9012be..d45b8891cf1a72a 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -26,6 +26,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Support/Compiler.h" #include "llvm/Frontend/HLSL/HLSLResource.h" +#include "llvm/Frontend/HLSL/HLSLRootSignature.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/VersionTuple.h" diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 52ad72eb608c319..36ae98730db031c 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4643,6 +4643,26 @@ def Error : InheritableAttr { let Documentation = [ErrorAttrDocs]; } +/// HLSL Root Signature Attribute +def HLSLRootSignature : Attr { + /// [RootSignature(Signature)] + let Spellings = [Microsoft<"RootSignature">]; + let Args = [StringArgument<"Signature">]; + let Subjects = SubjectList<[Function], + ErrorDiag, "'function'">; + let LangOpts = [HLSL]; + let Documentation = [HLSLRootSignatureDocs]; + let AdditionalMembers = [{ +private: + ArrayRef<llvm::hlsl::root_signature::RootElement> RootElements; +public: + void setElements(ArrayRef<llvm::hlsl::root_signature::RootElement> Elements) { + RootElements = Elements; + } + auto getElements() const { return RootElements; } +}]; +} + def HLSLNumThreads: InheritableAttr { let Spellings = [Microsoft<"numthreads">]; let Args = [IntArgument<"X">, IntArgument<"Y">, IntArgument<"Z">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fdad4c9a3ea1910..bb0934a11f9f3f0 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7783,6 +7783,10 @@ and https://microsoft.github.io/hlsl-specs/proposals/0013-wave-size-range.html }]; } +def HLSLRootSignatureDocs : Documentation { + let Category = DocCatUndocumented; +} + def NumThreadsDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index f4cd11f423a84a0..df4a5c8d88ba9e2 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -116,6 +116,7 @@ class SemaHLSL : public SemaBase { bool IsCompAssign); void emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, BinaryOperatorKind Opc); + void handleRootSignatureAttr(Decl *D, const ParsedAttr &AL); void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL); void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL); void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index bb4d33560b93b8d..c594d6e54ddbcd2 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7149,6 +7149,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, break; // HLSL attributes: + case ParsedAttr::AT_HLSLRootSignature: + S.HLSL().handleRootSignatureAttr(D, AL); + break; case ParsedAttr::AT_HLSLNumThreads: S.HLSL().handleNumThreadsAttr(D, AL); break; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 600c800029fd05a..ab8aa6f5a351be6 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -24,6 +24,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Parse/ParseHLSLRootSignature.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/ParsedAttr.h" #include "clang/Sema/Sema.h" @@ -647,6 +648,41 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, << NewFnName << FixItHint::CreateReplacement(FullRange, OS.str()); } +void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { + using namespace llvm::hlsl::root_signature; + + if (AL.getNumArgs() != 1) + return; + + StringRef Signature; + if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Signature)) + return; + + SourceLocation Loc = AL.getArgAsExpr(0)->getExprLoc(); + // FIXME: pass down below to lexer when fp is supported + // llvm::RoundingMode RM = SemaRef.CurFPFeatures.getRoundingMode(); + SmallVector<RootSignatureToken> Tokens; + RootSignatureLexer Lexer(Signature, Loc, SemaRef.getPreprocessor()); + if (Lexer.Lex(Tokens)) + return; + + SmallVector<RootElement> Elements; + RootSignatureParser Parser(Elements, Tokens); + if (Parser.Parse()) + return; + + unsigned N = Elements.size(); + auto RootElements = + MutableArrayRef<RootElement>(::new (getASTContext()) RootElement[N], N); + for (unsigned I = 0; I < N; ++I) + RootElements[I] = Elements[I]; + + auto *Result = ::new (getASTContext()) + HLSLRootSignatureAttr(getASTContext(), AL, Signature); + Result->setElements(ArrayRef<RootElement>(RootElements)); + D->addAttr(Result); +} + void SemaHLSL::handleNumThreadsAttr(Decl *D, const ParsedAttr &AL) { llvm::VersionTuple SMVersion = getASTContext().getTargetInfo().getTriple().getOSVersion(); diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl new file mode 100644 index 000000000000000..dbc06b61cffebe9 --- /dev/null +++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \ +// RUN: -disable-llvm-passes -o - %s | FileCheck %s + +// This test ensures that the sample root signature is parsed without error and +// the Attr AST Node is created succesfully. If an invalid root signature was +// passed in then we would exit out of Sema before the Attr is created. + +#define SampleRS \ + "DescriptorTable( " \ + " CBV(b1), " \ + " SRV(t1, numDescriptors = 8, " \ + " flags = DESCRIPTORS_VOLATILE), " \ + " UAV(u1, numDescriptors = 0, " \ + " flags = DESCRIPTORS_VOLATILE) " \ + "), " \ + "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" + +// CHECK: HLSLRootSignatureAttr 0x{{[0-9A-Fa-f]+}} <line:{{[0-9]+}}:{{[0-9]+}}, col:{{[0-9]+}}> +// CHECK-SAME: "DescriptorTable( +// CHECK-SAME: CBV(b1), +// CHECK-SAME: SRV(t1, numDescriptors = 8, +// CHECK-SAME: flags = DESCRIPTORS_VOLATILE), +// CHECK-SAME: UAV(u1, numDescriptors = 0, +// CHECK-SAME: flags = DESCRIPTORS_VOLATILE) +// CHECK-SAME: ), +// CHECK-SAME: DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" +[RootSignature(SampleRS)] +void main() {} >From d1044fe020174b50bf548492cda669cd24dd6451 Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Wed, 22 Jan 2025 19:08:16 +0000 Subject: [PATCH 2/6] add docs --- clang/include/clang/Basic/AttrDocs.td | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index bb0934a11f9f3f0..dc909cf0ae9b7d1 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7784,7 +7784,14 @@ and https://microsoft.github.io/hlsl-specs/proposals/0013-wave-size-range.html } def HLSLRootSignatureDocs : Documentation { - let Category = DocCatUndocumented; + let Category = DocCatFunction; + let Content = [{ +The ``RootSignature`` attribute applies to HLSL entry functions to define what +types of resources are bound to the graphics pipeline. + +For details about the use and specification of Root Signatures please see here: +https://learn.microsoft.com/en-us/windows/win32/direct3d12/root-signatures + }]; } def NumThreadsDocs : Documentation { >From b7d30e9c9c4a8ce8a11f22dc150405b1164dbbfa Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Tue, 28 Jan 2025 23:36:55 +0000 Subject: [PATCH 3/6] rebase onto updated lex/parser prs - we can now pass down the diagnostics for reporting - update the namespace --- clang/lib/Sema/SemaHLSL.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index ab8aa6f5a351be6..a1db8e29fb85782 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -650,6 +650,7 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { using namespace llvm::hlsl::root_signature; + using namespace clang::hlsl; if (AL.getNumArgs() != 1) return; @@ -667,7 +668,8 @@ void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { return; SmallVector<RootElement> Elements; - RootSignatureParser Parser(Elements, Tokens); + RootSignatureParser Parser(Elements, Tokens, + SemaRef.getPreprocessor().getDiagnostics()); if (Parser.Parse()) return; >From f1b7dc9f9af5c8df45e817f6cb67702fa4d3ec2f Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Wed, 29 Jan 2025 00:32:25 +0000 Subject: [PATCH 4/6] add some additional error testing --- clang/test/SemaHLSL/RootSignature-err.hlsl | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 clang/test/SemaHLSL/RootSignature-err.hlsl diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl b/clang/test/SemaHLSL/RootSignature-err.hlsl new file mode 100644 index 000000000000000..6c72418d7a2db8a --- /dev/null +++ b/clang/test/SemaHLSL/RootSignature-err.hlsl @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify + +// This file mirrors the diagnostics testing in ParseHLSLRootSignatureTest.cpp +// to verify that the correct diagnostics strings are output + +// Lexer related tests + +#define InvalidToken \ + "DescriptorTable( " \ + " invalid " \ + ")" + +[RootSignature(InvalidToken)] // expected-error {{unable to lex a valid Root Signature token}} +void bad_root_signature_1() {} + +#define InvalidEmptyNumber \ + "DescriptorTable( " \ + " CBV(t32, space = +) " \ + ")" + +[RootSignature(InvalidEmptyNumber)] // expected-error {{expected number literal is not a supported number literal of unsigned integer or integer}} +void bad_root_signature_2() {} + +#define InvalidOverflowNumber \ + "DescriptorTable( " \ + " CBV(t32, space = 98273498327498273487) " \ + ")" + +[RootSignature(InvalidOverflowNumber)] // expected-error {{provided unsigned integer literal '98273498327498273487' that overflows the maximum of 32 bits}} +void bad_root_signature_3() {} + +#define InvalidEOS \ + "DescriptorTable( " + +// Parser related tests + +[RootSignature(InvalidEOS)] // expected-error {{unexpected end to token stream}} +void bad_root_signature_4() {} + +#define InvalidTokenKind \ + "DescriptorTable( " \ + " DescriptorTable()" \ + ")" + +[RootSignature(InvalidTokenKind)] // expected-error {{expected the one of the following token kinds 'CBV, SRV, UAV, Sampler'}} +void bad_root_signature_5() {} + +#define InvalidRepeat \ + "DescriptorTable( " \ + " CBV(t0, space = 1, space = 2)" \ + ")" + +[RootSignature(InvalidRepeat)] // expected-error {{specified the same parameter 'space' multiple times}} +void bad_root_signature_6() {} >From 4f7a0e20b2c76c4681519b6eb51a8e9d3696ad35 Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Fri, 7 Feb 2025 18:02:23 +0000 Subject: [PATCH 5/6] review comments: - remove bad use of namespaces - simplify test case checking --- clang/lib/Sema/SemaHLSL.cpp | 15 ++++++--------- clang/test/AST/HLSL/RootSignatures-AST.hlsl | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index a1db8e29fb85782..b4ca5fa2aa62dae 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -649,9 +649,6 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, } void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { - using namespace llvm::hlsl::root_signature; - using namespace clang::hlsl; - if (AL.getNumArgs() != 1) return; @@ -662,26 +659,26 @@ void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { SourceLocation Loc = AL.getArgAsExpr(0)->getExprLoc(); // FIXME: pass down below to lexer when fp is supported // llvm::RoundingMode RM = SemaRef.CurFPFeatures.getRoundingMode(); - SmallVector<RootSignatureToken> Tokens; - RootSignatureLexer Lexer(Signature, Loc, SemaRef.getPreprocessor()); + SmallVector<hlsl::RootSignatureToken> Tokens; + hlsl::RootSignatureLexer Lexer(Signature, Loc, SemaRef.getPreprocessor()); if (Lexer.Lex(Tokens)) return; - SmallVector<RootElement> Elements; - RootSignatureParser Parser(Elements, Tokens, + SmallVector<llvm::hlsl::root_signature::RootElement> Elements; + hlsl::RootSignatureParser Parser(Elements, Tokens, SemaRef.getPreprocessor().getDiagnostics()); if (Parser.Parse()) return; unsigned N = Elements.size(); auto RootElements = - MutableArrayRef<RootElement>(::new (getASTContext()) RootElement[N], N); + MutableArrayRef<llvm::hlsl::root_signature::RootElement>(::new (getASTContext()) llvm::hlsl::root_signature::RootElement[N], N); for (unsigned I = 0; I < N; ++I) RootElements[I] = Elements[I]; auto *Result = ::new (getASTContext()) HLSLRootSignatureAttr(getASTContext(), AL, Signature); - Result->setElements(ArrayRef<RootElement>(RootElements)); + Result->setElements(ArrayRef<llvm::hlsl::root_signature::RootElement>(RootElements)); D->addAttr(Result); } diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl index dbc06b61cffebe9..9b0908c053254e3 100644 --- a/clang/test/AST/HLSL/RootSignatures-AST.hlsl +++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl @@ -15,7 +15,7 @@ "), " \ "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" -// CHECK: HLSLRootSignatureAttr 0x{{[0-9A-Fa-f]+}} <line:{{[0-9]+}}:{{[0-9]+}}, col:{{[0-9]+}}> +// CHECK: HLSLRootSignatureAttr // CHECK-SAME: "DescriptorTable( // CHECK-SAME: CBV(b1), // CHECK-SAME: SRV(t1, numDescriptors = 8, >From 7fde9d9879cd76923fc874a07dd54608394d20bb Mon Sep 17 00:00:00 2001 From: Finn Plummer <canadienf...@gmail.com> Date: Fri, 7 Feb 2025 18:08:49 +0000 Subject: [PATCH 6/6] rebase changes --- clang/include/clang/Basic/Attr.td | 4 ++-- clang/lib/Sema/SemaHLSL.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 36ae98730db031c..094aba5f6fadc19 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4654,9 +4654,9 @@ def HLSLRootSignature : Attr { let Documentation = [HLSLRootSignatureDocs]; let AdditionalMembers = [{ private: - ArrayRef<llvm::hlsl::root_signature::RootElement> RootElements; + ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements; public: - void setElements(ArrayRef<llvm::hlsl::root_signature::RootElement> Elements) { + void setElements(ArrayRef<llvm::hlsl::rootsig::RootElement> Elements) { RootElements = Elements; } auto getElements() const { return RootElements; } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index b4ca5fa2aa62dae..3b432998cf433af 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -664,21 +664,21 @@ void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { if (Lexer.Lex(Tokens)) return; - SmallVector<llvm::hlsl::root_signature::RootElement> Elements; + SmallVector<llvm::hlsl::rootsig::RootElement> Elements; hlsl::RootSignatureParser Parser(Elements, Tokens, - SemaRef.getPreprocessor().getDiagnostics()); + SemaRef.getPreprocessor().getDiagnostics()); if (Parser.Parse()) return; unsigned N = Elements.size(); - auto RootElements = - MutableArrayRef<llvm::hlsl::root_signature::RootElement>(::new (getASTContext()) llvm::hlsl::root_signature::RootElement[N], N); + auto RootElements = MutableArrayRef<llvm::hlsl::rootsig::RootElement>( + ::new (getASTContext()) llvm::hlsl::rootsig::RootElement[N], N); for (unsigned I = 0; I < N; ++I) RootElements[I] = Elements[I]; auto *Result = ::new (getASTContext()) HLSLRootSignatureAttr(getASTContext(), AL, Signature); - Result->setElements(ArrayRef<llvm::hlsl::root_signature::RootElement>(RootElements)); + Result->setElements(ArrayRef<llvm::hlsl::rootsig::RootElement>(RootElements)); D->addAttr(Result); } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits