llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Finn Plummer (inbelic) <details> <summary>Changes</summary> - Defines a new declaration node `HLSLRootSignature` in `DeclNodes.td` that will hold a reference to an in-memory construction of the root signature, namely an array of `hlsl::rootsig::RootElement`s - Defines a new clang attr `RootSignature` which simply holds an identifier to a corresponding root signature declration as above It was previously proposed that we could have the root elements reference be stored directly as an additional member of the attribute and to not have a seperate root signature decl. In contrast, by defining them seperately as this change proposes, we will allow a unique root signature to have its own declaration in the AST tree. This allows us to only construct a single root signature for all duplicate rootsignature attributes. Having it located directly as a declaration might also prove advantageous when we consider root signature libraries. Resolves https://github.com/llvm/llvm-project/issues/119011 --- Patch is 20.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137690.diff 20 Files Affected: - (modified) clang/include/clang/AST/Decl.h (+24) - (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+2) - (modified) clang/include/clang/AST/TextNodeDumper.h (+1) - (modified) clang/include/clang/Basic/Attr.td (+11) - (modified) clang/include/clang/Basic/AttrDocs.td (+11) - (modified) clang/include/clang/Basic/DeclNodes.td (+1) - (modified) clang/include/clang/Parse/Parser.h (+1) - (modified) clang/include/clang/Sema/SemaHLSL.h (+1) - (modified) clang/lib/AST/Decl.cpp (+25) - (modified) clang/lib/AST/DeclBase.cpp (+1) - (modified) clang/lib/AST/TextNodeDumper.cpp (+4) - (modified) clang/lib/CodeGen/CGDecl.cpp (+1) - (modified) clang/lib/Parse/ParseDeclCXX.cpp (+90) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3) - (modified) clang/lib/Sema/SemaHLSL.cpp (+18) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5) - (modified) clang/lib/Serialization/ASTCommon.cpp (+1) - (added) clang/test/AST/HLSL/RootSignatures-AST.hlsl (+58) - (added) clang/test/SemaHLSL/RootSignature-err.hlsl (+11) - (modified) clang/tools/libclang/CIndex.cpp (+1) ``````````diff diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 3faf63e395a08..8e45c19061b1d 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -41,6 +41,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Frontend/HLSL/HLSLRootSignature.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" @@ -5178,6 +5179,29 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { friend class ASTDeclWriter; }; +class HLSLRootSignatureDecl final : public NamedDecl { + ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements; + + HLSLRootSignatureDecl( + DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, + ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements); + +public: + static HLSLRootSignatureDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, + ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements); + static HLSLRootSignatureDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); + + ArrayRef<llvm::hlsl::rootsig::RootElement> &getRootElements() { + return RootElements; + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == HLSLRootSignature; } +}; + /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 3edc8684d0a19..23a8c4f1f7380 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1599,6 +1599,8 @@ DEF_TRAVERSE_DECL(EmptyDecl, {}) DEF_TRAVERSE_DECL(HLSLBufferDecl, {}) +DEF_TRAVERSE_DECL(HLSLRootSignatureDecl, {}) + DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, { TRY_TO(TraverseStmt(D->getTemporaryExpr())); }) diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index ea3a0f058a8ed..1917a8ac29f05 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -408,6 +408,7 @@ class TextNodeDumper void VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D); void VisitHLSLBufferDecl(const HLSLBufferDecl *D); + void VisitHLSLRootSignatureDecl(const HLSLRootSignatureDecl *D); void VisitHLSLOutArgExpr(const HLSLOutArgExpr *E); void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S); void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S); diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index d48aed5b73cf5..81b411e8f8d01 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4698,6 +4698,17 @@ def Error : InheritableAttr { let Documentation = [ErrorAttrDocs]; } +/// HLSL Root Signature Attribute +def RootSignature : Attr { + /// [RootSignature(Signature)] + let Spellings = [Microsoft<"RootSignature">]; + let Args = [IdentifierArgument<"Signature">]; + let Subjects = SubjectList<[Function], + ErrorDiag, "'function'">; + let LangOpts = [HLSL]; + let Documentation = [RootSignatureDocs]; +} + 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 98468034e71a8..adf4e0624a657 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -8184,6 +8184,17 @@ and https://microsoft.github.io/hlsl-specs/proposals/0013-wave-size-range.html }]; } +def RootSignatureDocs : Documentation { + 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 { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td index 20debd67a31a5..f1ebaf1db3fc0 100644 --- a/clang/include/clang/Basic/DeclNodes.td +++ b/clang/include/clang/Basic/DeclNodes.td @@ -111,5 +111,6 @@ def Empty : DeclNode<Decl>; def RequiresExprBody : DeclNode<Decl>, DeclContext; def LifetimeExtendedTemporary : DeclNode<Decl>; def HLSLBuffer : DeclNode<Named, "HLSLBuffer">, DeclContext; +def HLSLRootSignature : DeclNode<Named, "HLSLRootSignature">; def OpenACCDeclare : DeclNode<Decl, "#pragma acc declare">; def OpenACCRoutine : DeclNode<Decl, "#pragma acc routine">; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 645df4aabc374..1c1092b49a142 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3070,6 +3070,7 @@ class Parser : public CodeCompletionHandler { } } void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs); + void ParseMicrosoftRootSignatureAttributeArgs(ParsedAttributes &Attrs); void ParseMicrosoftAttributes(ParsedAttributes &Attrs); bool MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) { if (getLangOpts().DeclSpecKeyword && Tok.is(tok::kw___declspec)) { diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index e97736b18eee3..bfcbfebdd49d7 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -118,6 +118,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/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1d9208f0e1c72..4dd3f53f430ce 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5839,6 +5839,31 @@ bool HLSLBufferDecl::buffer_decls_empty() { return DefaultBufferDecls.empty() && decls_empty(); } +//===----------------------------------------------------------------------===// +// HLSLRootSignatureDecl Implementation +//===----------------------------------------------------------------------===// + +HLSLRootSignatureDecl::HLSLRootSignatureDecl( + DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, + ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements) + : NamedDecl(Decl::Kind::HLSLRootSignature, DC, Loc, DeclarationName(ID)), + RootElements(RootElements) {} + +HLSLRootSignatureDecl *HLSLRootSignatureDecl::Create( + ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, + ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements) { + HLSLRootSignatureDecl *Result = + new (C, DC) HLSLRootSignatureDecl(DC, Loc, ID, RootElements); + return Result; +} + +HLSLRootSignatureDecl * +HLSLRootSignatureDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { + HLSLRootSignatureDecl *Result = + new (C, ID) HLSLRootSignatureDecl(nullptr, SourceLocation(), nullptr, {}); + return Result; +} + //===----------------------------------------------------------------------===// // ImportDecl Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 1afda9aac9e18..abca645cdd6af 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -882,6 +882,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCProperty: case MSProperty: case HLSLBuffer: + case HLSLRootSignature: return IDNS_Ordinary; case Label: return IDNS_Label; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 51f7d17be4158..8263bbc992fc0 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -3037,6 +3037,10 @@ void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) { dumpName(D); } +void TextNodeDumper::VisitHLSLRootSignatureDecl(const HLSLRootSignatureDecl *D) { + dumpName(D); +} + void TextNodeDumper::VisitHLSLOutArgExpr(const HLSLOutArgExpr *E) { OS << (E->isInOut() ? " inout" : " out"); } diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index db34e2738b4cf..e93e35a9d585f 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -106,6 +106,7 @@ void CodeGenFunction::EmitDecl(const Decl &D, bool EvaluateConditionDecl) { case Decl::Binding: case Decl::UnresolvedUsingIfExists: case Decl::HLSLBuffer: + case Decl::HLSLRootSignature: llvm_unreachable("Declaration should not be in declstmts!"); case Decl::Record: // struct/union/class X; case Decl::CXXRecord: // struct/union/class X; [C++] diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 51fe0663a8d1a..6d594af54aed6 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -21,10 +21,12 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/LiteralSupport.h" +#include "clang/Parse/ParseHLSLRootSignature.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" +#include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCodeCompletion.h" @@ -5209,6 +5211,92 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) { } } +void Parser::ParseMicrosoftRootSignatureAttributeArgs(ParsedAttributes &Attrs) { + assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list"); + IdentifierInfo *RootSignatureIdent = Tok.getIdentifierInfo(); + assert(RootSignatureIdent->getName() == "RootSignature" && + "Not a Microsoft attribute list"); + + SourceLocation RootSignatureLoc = Tok.getLocation(); + ConsumeToken(); + + // Ignore the left paren location for now. + BalancedDelimiterTracker T(*this, tok::l_paren); + if (T.consumeOpen()) { + Diag(Tok, diag::err_expected) << tok::l_paren; + return; + } + + if (!isTokenStringLiteral()) { + Diag(Tok, diag::err_expected_string_literal) + << /*in attributes...*/ 4 << RootSignatureIdent->getName(); + SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch); + if (Tok.is(tok::r_paren)) + T.consumeClose(); + return; + } + + ExprResult StringResult = ParseUnevaluatedStringLiteralExpression(); + if (StringResult.isInvalid()) { + SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch); + if (Tok.is(tok::r_paren)) + T.consumeClose(); + return; + } + + ArgsVector Args; + if (auto Lit = dyn_cast<StringLiteral>(StringResult.get())) { + // Construct our identifier + StringRef Signature = Lit->getString(); + auto Hash = llvm::hash_value(Signature); + std::string IdStr = "__hlsl_rootsig_decl_" + std::to_string(Hash); + IdentifierInfo *DeclIdent = &(Actions.getASTContext().Idents.get(IdStr)); + + LookupResult R(Actions, DeclIdent, SourceLocation(), + Sema::LookupOrdinaryName); + // Check if we have already found a decl of the same name, if we haven't + // then parse the root signature string and construct the in-memory elements + if (!Actions.LookupQualifiedName(R, Actions.CurContext)) { + // Invoke the root signature parser to construct the in-memory constructs + hlsl::RootSignatureLexer Lexer(Signature, RootSignatureLoc); + SmallVector<llvm::hlsl::rootsig::RootElement> Elements; + hlsl::RootSignatureParser Parser(Elements, Lexer, PP); + if (Parser.parse()) { + SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch); + if (Tok.is(tok::r_paren)) + T.consumeClose(); + return; + } + + // Allocate the root elements onto ASTContext + unsigned N = Elements.size(); + auto RootElements = MutableArrayRef<llvm::hlsl::rootsig::RootElement>( + ::new (Actions.getASTContext()) llvm::hlsl::rootsig::RootElement[N], + N); + for (unsigned I = 0; I < N; ++I) + RootElements[I] = Elements[I]; + + // Create the Root Signature + auto *SignatureDecl = HLSLRootSignatureDecl::Create( + Actions.getASTContext(), /*FIXME?*/ Actions.CurContext, + RootSignatureLoc, DeclIdent, RootElements); + SignatureDecl->setImplicit(); + Actions.PushOnScopeChains(SignatureDecl, getCurScope()); + } + + // Create the arg for the ParsedAttr + IdentifierLoc *ILoc = ::new (Actions.getASTContext()) + IdentifierLoc(RootSignatureLoc, DeclIdent); + Args.push_back(ILoc); + } + + if (!T.consumeClose()) + Attrs.addNew(RootSignatureIdent, + SourceRange(RootSignatureLoc, T.getCloseLocation()), nullptr, + SourceLocation(), Args.data(), Args.size(), + ParsedAttr::Form::Microsoft()); +} + /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr] /// /// [MS] ms-attribute: @@ -5243,6 +5331,8 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { break; if (Tok.getIdentifierInfo()->getName() == "uuid") ParseMicrosoftUuidAttributeArgs(Attrs); + else if (Tok.getIdentifierInfo()->getName() == "RootSignature") + ParseMicrosoftRootSignatureAttributeArgs(Attrs); else { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c960868badb52..8c44c1a4a6a06 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7461,6 +7461,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, break; // HLSL attributes: + case ParsedAttr::AT_RootSignature: + 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 38322e6ba063b..353217961121c 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -29,6 +29,7 @@ #include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" +#include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedAttr.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Template.h" @@ -949,6 +950,23 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, << NewFnName << FixItHint::CreateReplacement(FullRange, OS.str()); } +void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { + if (AL.getNumArgs() != 1) { + Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1; + return; + } + + IdentifierInfo *Ident = AL.getArgAsIdent(0)->getIdentifierInfo(); + LookupResult R(SemaRef, Ident, SourceLocation(), Sema::LookupOrdinaryName); + if (SemaRef.LookupQualifiedName(R, D->getDeclContext())) + if (auto *SignatureDecl = + dyn_cast<HLSLRootSignatureDecl>(R.getFoundDecl())) { + // Perform validation of constructs here + D->addAttr(::new (getASTContext()) + RootSignatureAttr(getASTContext(), AL, Ident)); + } +} + void SemaHLSL::handleNumThreadsAttr(Decl *D, const ParsedAttr &AL) { llvm::VersionTuple SMVersion = getASTContext().getTargetInfo().getTriple().getOSVersion(); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 76c055d28f091..9d70d06451e48 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -999,6 +999,11 @@ Decl *TemplateDeclInstantiator::VisitHLSLBufferDecl(HLSLBufferDecl *Decl) { llvm_unreachable("HLSL buffer declarations cannot be instantiated"); } +Decl *TemplateDeclInstantiator::VisitHLSLRootSignatureDecl( + HLSLRootSignatureDecl *Decl) { + llvm_unreachable("HLSL root signature declarations cannot be instantiated"); +} + Decl * TemplateDeclInstantiator::VisitPragmaCommentDecl(PragmaCommentDecl *D) { llvm_unreachable("pragma comment cannot be instantiated"); diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 320ee0e65dbea..480ce78e6b08b 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -458,6 +458,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::RequiresExprBody: case Decl::UnresolvedUsingIfExists: case Decl::HLSLBuffer: + case Decl::HLSLRootSignature: case Decl::OpenACCDeclare: case Decl::OpenACCRoutine: return false; diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl new file mode 100644 index 0000000000000..e6ed27b62588a --- /dev/null +++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl @@ -0,0 +1,58 @@ +// 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: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[SAMPLE_RS_DECL:__hlsl_rootsig_decl_.*]] + +// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]] +[RootSignature(SampleRS)] +void rs_main() {} + +// Ensure that if multiple root signatures are specified at different entry +// points that we point to the correct root signature + +// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]] +[RootSignature(SampleRS)] +void same_rs_main() {} + +// Define the same root signature to ensure that the entry point will still +// link to the same root signature declaration + +#define SampleSameRS \ + "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: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]] +[RootSignature(SampleSameRS)] +void same_rs_string_main() {} + +#define SampleDifferentRS \ + "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" + +// Ensure that when we define a different type root signature that it creates +// a seperate decl and identifier to reference + +// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[DIFF_RS_DECL:__hlsl_rootsig_decl_.*]] + +// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[DIFF_RS_DECL]] +[RootSignature(SampleDifferentRS)] +void different_rs_string_main() {} diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl b/clang/test/SemaHLSL/RootSignature-err.hlsl new file mode 100644 index 0000000000000..6427c78b38455 --- /dev/null +++ b/clang/test/SemaHLSL/RootSignature-err.hlsl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify + +// Attr test + +[RootSignature()] // expected-error {{expected string literal as argument of 'RootSignature' attribute}} +void bad_root_signature_0() {} + +// expected-error@+2 {{expected ')'}} +// expected-note@... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/137690 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits