[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer a : register(b2, space1); + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer b : register(t2, space1); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture1D' (expected 't')}} +// NOT YET IMPLEMENTED Texture1D tex : register(u3); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 's' for register type 'Texture2D' (expected 't')}} +// NOT YET IMPLEMENTED Texture2D Texture : register(s0); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DMS T2DMS_t2 : register(u2) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWTexture3D' (expected 'u')}} +// NOT YET IMPLEMENTED RWTexture3D RWT3D_u1 : register(t1) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED TextureCube TCube_b2 : register(B2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED TextureCubeArray TCubeArray_t2 : register(b2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED Texture1DArray T1DArray_t2 : register(b2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED Texture2DArray T2DArray_b2 : register(B2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 'b' or 'c' or 'i')}} +// NOT YET IMPLEMENTED Texture2DMSArray msTextureArray : register(t2, space2); tex3d wrote: Expected would be 't', not `'b' or 'c' or 'i'`. In fact, that group ('b', 'c', 'i') were legacy constant register bindings for DX9, which is where I suspect this comes from, where 'b' meant a special bool constant and 'i' mapped to special loop constant values (used in DX9 shader models), and 'c' was a float constant value. 'b' was since used for constant buffer binding location as well, so there is a bit of a collision, but not on the same variable type, since the 'b', 'c', 'i' bindings were on global numeric variables, not on resource objects or cbuffer/tbuffer declarations. So, we no longer support the DX9 'b','c','i' numeric constant bindings the same way, but we do reuse 'c' for manual cbuffer layout, and 'b' for cbuffer or ConstantBuffer binding. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer a : register(b2, space1); + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer b : register(t2, space1); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture1D' (expected 't')}} +// NOT YET IMPLEMENTED Texture1D tex : register(u3); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 's' for register type 'Texture2D' (expected 't')}} +// NOT YET IMPLEMENTED Texture2D Texture : register(s0); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DMS T2DMS_t2 : register(u2) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWTexture3D' (expected 'u')}} +// NOT YET IMPLEMENTED RWTexture3D RWT3D_u1 : register(t1) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED TextureCube TCube_b2 : register(B2); tex3d wrote: Same with all other `(expected 't' or 's')` below. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer a : register(b2, space1); + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer b : register(t2, space1); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture1D' (expected 't')}} +// NOT YET IMPLEMENTED Texture1D tex : register(u3); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 's' for register type 'Texture2D' (expected 't')}} +// NOT YET IMPLEMENTED Texture2D Texture : register(s0); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DMS T2DMS_t2 : register(u2) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWTexture3D' (expected 'u')}} +// NOT YET IMPLEMENTED RWTexture3D RWT3D_u1 : register(t1) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED TextureCube TCube_b2 : register(B2); tex3d wrote: 's' should not be considered a valid register binding for TextureCube, and the message says 'Texture2DMS' instead of 'TextureCube'. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer a : register(b2, space1); + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer b : register(t2, space1); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture1D' (expected 't')}} +// NOT YET IMPLEMENTED Texture1D tex : register(u3); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 's' for register type 'Texture2D' (expected 't')}} +// NOT YET IMPLEMENTED Texture2D Texture : register(s0); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DMS T2DMS_t2 : register(u2) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWTexture3D' (expected 'u')}} +// NOT YET IMPLEMENTED RWTexture3D RWT3D_u1 : register(t1) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED TextureCube TCube_b2 : register(B2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED TextureCubeArray TCubeArray_t2 : register(b2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED Texture1DArray T1DArray_t2 : register(b2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't' or 's')}} +// NOT YET IMPLEMENTED Texture2DArray T2DArray_b2 : register(B2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 'b' or 'c' or 'i')}} +// NOT YET IMPLEMENTED Texture2DMSArray msTextureArray : register(t2, space2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'TCubeArray_f2' (expected 't' or 's')}} +// NOT YET IMPLEMENTED TextureCubeArray TCubeArray_f2 : register(u2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'TypedBuffer' (expected 't')}} +// NOT YET IMPLEMENTED TypedBuffer tbuf : register(u2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'RawBuffer' (expected 't')}} +// NOT YET IMPLEMENTED RawBuffer rbuf : register(u2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'StructuredBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED StructuredBuffer ROVStructuredBuff_t2 : register(T2); + +// expected-error@+1 {{invalid register name prefix 's' for register type 'cbuffer' (expected 'b')}} +cbuffer f : register(s2, space1) {} + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'Sampler' (expected 's')}} +// Can this type just be Sampler instead of SamplerState? +// NOT YET IMPLEMENTED SamplerState MySampler : register(t3, space1); + +// expected-error@+1 {{invalid register name prefix 's' for register type 'tbuffer' (expected 'b')}} +tbuffer f : register(s2, space1) {} tex3d wrote: As was stated in an earlier (resolved but seemingly not fixed) comment, tbuffer must be bound to `t`. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7334,6 +7334,81 @@ static void handleHLSLShaderAttr(Sema , Decl *D, const ParsedAttr ) { D->addAttr(NewAttr); } +static void DiagnoseHLSLResourceRegType(Sema , SourceLocation , +Decl *D, StringRef ) { + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + if (!SamplerUAVOrSRV && !CBufferOrTBuffer) +return; + + llvm::hlsl::ResourceClass DeclResourceClass; + StringRef varTy = ""; + if (SamplerUAVOrSRV) { +const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); +if (!Ty) + llvm_unreachable("Resource class should have an element type."); bogner wrote: I probably just read too many RFCs, but it'd be better to use "must" rather than "should" in this message. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -45,7 +45,7 @@ void foo2() { extern RWBuffer U2 : register(u5); } // FIXME: expect-error once fix https://github.com/llvm/llvm-project/issues/57886. -float b : register(u0, space1); +// float b : register(u0, space1) {} bogner wrote: Shouldn't we be adding the `// expected-error:` here rather than commenting this out? https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -478,33 +478,35 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() { /// Set up common members and attributes for buffer types static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , - ResourceClass RC, ResourceKind RK, - bool IsROV) { + ResourceClass RC) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } bogner wrote: Let's either remove this function (since it isn't buying us all that much at this point) or rename it to be specifically about setting up the buffer's handle (since that's all it does). https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// the below will cause an llvm unreachable, because RWBuffers don't have resource attributes yet +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'RWBuffer' (expected 'u')}} +// NOT YET IMPLEMENTED RWBuffer a : register(b2, space1); bogner wrote: This seems incorrect - RWBuffer is the one resource type that's actually available https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7334,6 +7334,81 @@ static void handleHLSLShaderAttr(Sema , Decl *D, const ParsedAttr ) { D->addAttr(NewAttr); } +static void DiagnoseHLSLResourceRegType(Sema , SourceLocation , +Decl *D, StringRef ) { + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + if (!SamplerUAVOrSRV && !CBufferOrTBuffer) +return; + + llvm::hlsl::ResourceClass DeclResourceClass; + StringRef varTy = ""; bogner wrote: LLVM style prefers `VarTy` https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -9,7 +9,7 @@ cbuffer A : register(b0, space2) { } // CHECK: @[[TB:.+]] = external constant { float, double } -tbuffer A : register(t2, space1) { +tbuffer A : register(b2, space1) { python3kgae wrote: This is tbuffer, it should use 't' instead of 'b'. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/7] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/6] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/5] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/5] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + bob80905 wrote: We do need to move it, since the attribute won't be available when it is time to diagnose otherwise. The extra parameters have been removed. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { farzonl wrote: just a small note to piggy back on Justin's There are Three changes I would like 1) spell out your variable names, VD,BD, RC don't really mean much when I'm reading the code and I find myself regularly looking what each of these are. Secon if you end up splitting behavior maybe move the dyn_casts into the if statement like you do with TDecl on line 7386. Third, try and reduce some of the conditional nesting you have. for example if you did ```cpp if(!VD) return; const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); if (!Ty) return; ``` you would not need to do: ```cpp if(VD) { if(!TY) return; ``` Less layers of nesting improve readability. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7337,8 +7337,8 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': farzonl wrote: Why make this change? if its for alphabetical reasons, stu should be the order, if not why leave as is? https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/4] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); bob80905 wrote: Correct, just a result of some debugging, I'll revert it. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; bogner wrote: Actually, is it even correct to just give up in some of these cases? Is it possible to get here with a type that isn't a resource, or did we diagnose that earlier? If this is possible, we probably need to diagnose that. If it isn't, we should probably just verify this with asserts. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "tbuffer"; + } +} +switch (RC) { +case llvm::hlsl::ResourceClass::SRV: { + if (Slot[0] != 't') +S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) +<< Slot.substr(0, 1) << varTy << "t"; bogner wrote: I think clang generally prefers using "select" in the diagnostic rather than passing in raw strings like "t" here. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; bogner wrote: This can be `StringRef` - you can get a `StringRef` with `RD->getName()` below and the only other assignments are constant strings. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { bogner wrote: It's probably worth breaking this logic out into a separate `checkHLSLResourceRegType` function. This would improve the readability and we can avoid some indentation by using early returns. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); bogner wrote: Avoid C-style cast https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); bogner wrote: This doesn't actually change anything, correct? Probably best to leave it as it was. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); bogner wrote: LLVM avoids C-style casting. This would normally be spelled `QualType QT = cast(D)->getType();`. In any case, this variable doesn't look like it's used. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + bogner wrote: Do we actually need to move the `annotateResourceClass` call to the forward declaration here, or can we get away with leaving it on the `onCompletion` callback? It's unfortunate that we need to repeat the resource class if we have to do it this way. Further, if we do need to move this, `setupBufferType` should be updated to remove the extra parameters, or maybe even removed completely since it really doesn't do much anymore. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,8 +7367,72 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; bogner wrote: These returns don't look correct - handleHLSLResourceBindingAttr still has work to do after this block of code. However, if you break this check out as I suggested elsewhere that will resolve this. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/3] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7403,41 +7403,36 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } switch (RC) { case llvm::hlsl::ResourceClass::SRV: { - if (Slot.substr(0, 1) != "t") + if (Slot[0] != 't') S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) << Slot.substr(0, 1) << varTy << "t"; break; } case llvm::hlsl::ResourceClass::UAV: { - if (Slot.substr(0, 1) != "u") + if (Slot[0] != 'u') S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) << Slot.substr(0, 1) << varTy << "u"; break; } case llvm::hlsl::ResourceClass::CBuffer: { - if (Slot.substr(0, 1) != "b") + if (Slot[0] != 'b') S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) << Slot.substr(0, 1) << varTy << "b"; break; } case llvm::hlsl::ResourceClass::Sampler: { - if (Slot.substr(0, 1) != "s") + if (Slot[0] != 's') S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) << Slot.substr(0, 1) << varTy << "s"; break; } -case llvm::hlsl::ResourceClass::Invalid: { +default: { llvm-beanz wrote: It would be better to have this be the Invalid case. Then the compiler will warn if new enum values get added that aren't handled. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/87578 >From 3960050439964fe3c0536696490b284a6c470cd1 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Apr 2024 13:15:59 -0700 Subject: [PATCH 1/2] implement binding type error for t/cbuffers and rwbuffers --- .../clang/Basic/DiagnosticSemaKinds.td| 1 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 19 +++-- clang/lib/Sema/SemaDeclAttr.cpp | 73 ++- .../resource_binding_attr_error_mismatch.hlsl | 65 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..9a0946276f80fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12149,6 +12149,7 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_mismatching_register_type_and_name: Error<"invalid register name prefix '%0' for register type '%1' (expected '%2')">; def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; def err_hlsl_unsupported_register_number : Error<"register number should be an integer">; def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1a1febf7a35241..479689ec82dcee 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -119,8 +119,10 @@ struct BuiltinTypeDeclBuilder { ResourceKind RK, bool IsROV) { if (Record->isCompleteDefinition()) return *this; -Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(), - RC, RK, IsROV)); +HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( +Record->getASTContext(), RC, RK, IsROV); + +Record->addAttr(attr); return *this; } @@ -482,15 +484,18 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema , bool IsROV) { return BuiltinTypeDeclBuilder(Decl) .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateResourceClass(RC, RK, IsROV); + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; - Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams({"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f25f3afd0f4af2..e720fe56c3ea17 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7333,12 +7333,12 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, } else { Slot = Str; } - + QualType Ty = ((clang::ValueDecl *)D)->getType(); // Validate. if (!Slot.empty()) { switch (Slot[0]) { -case 'u': case 'b': +case 'u': case 's': case 't': break; @@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "tbuffer"; + } +} +switch (RC) { +case llvm::hlsl::ResourceClass::SRV: { + if (Slot.substr(0, 1) != "t") llvm-beanz wrote: Or we could replace all the `Slot.substr(0,1)` calls just with `Slot[0]` and compare characters instead of strings. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch errors (PR #87578)
@@ -7367,6 +7367,75 @@ static void handleHLSLResourceBindingAttr(Sema , Decl *D, return; } + VarDecl *VD = dyn_cast(D); + HLSLBufferDecl *BD = dyn_cast(D); + + if (VD || BD) { +llvm::hlsl::ResourceClass RC; +std::string varTy = ""; +if (VD) { + + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +return; + QualType t = ((ElaboratedType *)Ty)->getNamedType(); + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (!RD) +return; + + if (auto TDecl = dyn_cast(RD)) +RD = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + RD = RD->getCanonicalDecl(); + const auto *Attr = RD->getAttr(); + if (!Attr) +return; + + RC = Attr->getResourceClass(); + varTy = RD->getNameAsString(); +} else { + if (BD->isCBuffer()) { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "cbuffer"; + } else { +RC = llvm::hlsl::ResourceClass::CBuffer; +varTy = "tbuffer"; + } +} +switch (RC) { +case llvm::hlsl::ResourceClass::SRV: { + if (Slot.substr(0, 1) != "t") +S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) +<< Slot.substr(0, 1) << varTy << "t"; + break; +} +case llvm::hlsl::ResourceClass::UAV: { + if (Slot.substr(0, 1) != "u") +S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) +<< Slot.substr(0, 1) << varTy << "u"; + break; +} +case llvm::hlsl::ResourceClass::CBuffer: { + if (Slot.substr(0, 1) != "b") +S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) +<< Slot.substr(0, 1) << varTy << "b"; + break; +} +case llvm::hlsl::ResourceClass::Sampler: { + if (Slot.substr(0, 1) != "s") +S.Diag(ArgLoc, diag::err_hlsl_mismatching_register_type_and_name) +<< Slot.substr(0, 1) << varTy << "s"; + break; +} +case llvm::hlsl::ResourceClass::Invalid: { + llvm_unreachable("Resource class should be valid."); + break; +} + +default: + break; +} llvm-beanz wrote: Or if we're covering all cases in the switch we should leave off the default case so that it produces a warning if we add a new resource class. https://github.com/llvm/llvm-project/pull/87578 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits