https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/97103
>From c784272b3f66ca06be4ab8e72a0963e5ebb6a869 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 28 Jun 2024 12:40:56 -0700 Subject: [PATCH 1/3] update tests, update code --- clang/include/clang/Basic/Attr.td | 2 +- .../clang/Basic/DiagnosticSemaKinds.td | 5 +- clang/include/clang/Sema/SemaHLSL.h | 2 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 26 +- clang/lib/Sema/SemaHLSL.cpp | 232 +++++++++++++++++- .../ast-dump-comment-cbuffe-tbufferr.hlsl | 2 + clang/test/AST/HLSL/cbuffer_tbuffer.hlsl | 6 +- clang/test/AST/HLSL/packoffset.hlsl | 1 + clang/test/AST/HLSL/pch_hlsl_buffer.hlsl | 2 + .../test/AST/HLSL/resource_binding_attr.hlsl | 6 +- .../SemaHLSL/resource_binding_attr_error.hlsl | 21 +- .../resource_binding_attr_error_mismatch.hlsl | 74 ++++++ 12 files changed, 346 insertions(+), 33 deletions(-) create mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 452cd1810f653..c3d67e19656da 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4467,7 +4467,7 @@ def HLSLSV_GroupIndex: HLSLAnnotationAttr { def HLSLResourceBinding: InheritableAttr { let Spellings = [HLSLAnnotation<"register">]; - let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>; + let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar], ErrorDiag>; let LangOpts = [HLSL]; let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>]; let Documentation = [HLSLResourceBindingDocs]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 96f0c0f0205c2..3bf15ff5f2657 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12303,7 +12303,10 @@ def err_hlsl_missing_semantic_annotation : Error< def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; -def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">; +def err_hlsl_mismatching_register_resource_type_and_name: Error<"invalid register name prefix '%0' for register resource type '%1' (expected %select{'t'|'u'|'b'|'s'}2)">; +def err_hlsl_mismatching_register_builtin_type_and_name: Error<"invalid register name prefix '%0' for '%1' (expected %2)">; +def err_hlsl_unsupported_register_prefix : Error<"invalid resource class specifier '%0' used; expected 't', 'u', 'b', or 's'">; +def err_hlsl_unsupported_register_resource_type : Error<"invalid resource '%0' used">; 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">; def warn_hlsl_packoffset_mix : Warning<"cannot mix packoffset elements with nonpackoffset elements in a cbuffer">, diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 4d6958a1be3e5..d3d36d04d1019 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -22,6 +22,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaBase.h" +#include "clang/Sema/Sema.h" #include <initializer_list> namespace clang { @@ -31,6 +32,7 @@ class SemaHLSL : public SemaBase { public: SemaHLSL(Sema &S); + HLSLResourceAttr *mergeHLSLResourceAttr(bool CBuffer); Decl *ActOnStartBuffer(Scope *BufferScope, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *Ident, SourceLocation IdentLoc, SourceLocation LBrace); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index a2b29a7bdf505..b82cd8373403a 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -490,23 +490,24 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() { } /// Set up common members and attributes for buffer types -static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, - ResourceClass RC, ResourceKind RK, - bool IsROV) { +static BuiltinTypeDeclBuilder setupBufferHandle(CXXRecordDecl *Decl, Sema &S, + ResourceClass RC) { 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(*SemaPtr, {"element_type"}) - .Record; + Decl = + BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") + .addSimpleTemplateParams(*SemaPtr, {"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/false) + .Record; + onCompletion(Decl, [this](CXXRecordDecl *Decl) { - setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, - ResourceKind::TypedBuffer, /*IsROV=*/false) + setupBufferHandle(Decl, *SemaPtr, ResourceClass::UAV) .addArraySubscriptOperators() .completeDefinition(); }); @@ -514,10 +515,11 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer") .addSimpleTemplateParams(*SemaPtr, {"element_type"}) + .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer, + /*IsROV=*/true) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { - setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, - ResourceKind::TypedBuffer, /*IsROV=*/true) + setupBufferHandle(Decl, *SemaPtr, ResourceClass::UAV) .addArraySubscriptOperators() .completeDefinition(); }); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index eebe17a5b4bf7..d2b2f163231c9 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -29,6 +29,25 @@ using namespace clang; SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S) {} +HLSLResourceAttr *SemaHLSL::mergeHLSLResourceAttr(bool CBuffer) { + // cbuffer case + if (CBuffer) { + HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( + getASTContext(), llvm::hlsl::ResourceClass::CBuffer, + llvm::hlsl::ResourceKind::CBuffer, + /*IsROV=*/false); + return attr; + } + // tbuffer case + else { + HLSLResourceAttr *attr = HLSLResourceAttr::CreateImplicit( + getASTContext(), llvm::hlsl::ResourceClass::SRV, + llvm::hlsl::ResourceKind::TBuffer, + /*IsROV=*/false); + return attr; + } +} + Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *Ident, SourceLocation IdentLoc, @@ -38,6 +57,10 @@ Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer, HLSLBufferDecl *Result = HLSLBufferDecl::Create( getASTContext(), LexicalParent, CBuffer, KwLoc, Ident, IdentLoc, LBrace); + HLSLResourceAttr *NewAttr = mergeHLSLResourceAttr(CBuffer); + if (NewAttr) + Result->addAttr(NewAttr); + SemaRef.PushOnScopeChains(Result, BufferScope); SemaRef.PushDeclContext(BufferScope, Result); @@ -437,7 +460,206 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) + return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { + if (isa<HLSLBufferDecl>(context)) { + return true; + } + context = context->getParent(); + } + + return false; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) + llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) { + /* QualType QT = SamplerUAVOrSRV->getType(); + PrintingPolicy PP = S.getPrintingPolicy(); + std::string typestr = QualType::getAsString(QT.split(), PP); + + S.Diag(ArgLoc, diag::err_hlsl_unsupported_register_resource_type) + << typestr; + return; */ + return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) + llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(TheRecordDecl)) + TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr<HLSLResourceAttr>(); + return Attr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { + r.contains_numeric = true; + return; + } else if (const RecordType *RT = T->getAs<RecordType>()) { + RecordDecl *SubRD = RT->getDecl(); + if (auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr<HLSLResourceAttr>(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { + r.srv = true; + break; + } + case llvm::hlsl::ResourceClass::UAV: { + r.uav = true; + break; + } + case llvm::hlsl::ResourceClass::CBuffer: { + r.cbv = true; + break; + } + case llvm::hlsl::ResourceClass::Sampler: { + r.sampler = true; + break; + } + } + } + + else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); + } + } + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) + return; + + if (RD->isCompleteDefinition()) { + for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); + } + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { + // make sure the type is a basic / numeric type + if (VarDecl *v = dyn_cast<VarDecl>(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) + r.default_globals = true; + } + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast<VarDecl>(D); + + if (CBufferOrTBuffer) { + r.resource = true; + if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; + else + r.srv = true; + } else if (SamplerUAVOrSRV) { + const HLSLResourceAttr *res_attr = + getHLSLResourceAttrFromVarDecl(SamplerUAVOrSRV); + if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { + r.srv = true; + break; + } + case llvm::hlsl::ResourceClass::UAV: { + r.uav = true; + break; + } + case llvm::hlsl::ResourceClass::CBuffer: { + r.cbv = true; + break; + } + case llvm::hlsl::ResourceClass::Sampler: { + r.sampler = true; + break; + } + } + } else { + if (SamplerUAVOrSRV->getType()->isBuiltinType()) + r.basic = true; + else if (SamplerUAVOrSRV->getType()->isAggregateType()) { + r.udt = true; + QualType VarType = SamplerUAVOrSRV->getType(); + if (const RecordType *RT = VarType->getAs<RecordType>()) { + const RecordDecl *RD = RT->getDecl(); + // recurse through members, set appropriate resource class flags. + setResourceClassFlagsFromRecordDecl(r, RD); + } + } else + r.other = true; + } + } else { + llvm_unreachable("unknown decl type"); + } + return r; +} + +static void DiagnoseHLSLResourceRegType(Sema &S, SourceLocation &ArgLoc, + Decl *D, StringRef &Slot) { + + register_binding_flags f = HLSLFillRegisterBindingFlags(S, D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast<VarDecl>(D); + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(D); + if (!SamplerUAVOrSRV && !CBufferOrTBuffer) + return; + + // TODO: emit diagnostic code based on the flags set in f. +} + + void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) { + if (dyn_cast<VarDecl>(D)) { + if (SemaRef.RequireCompleteType(D->getBeginLoc(), cast<ValueDecl>(D)->getType(), + diag::err_incomplete_type)) + return; + } StringRef Space = "space0"; StringRef Slot = ""; @@ -470,13 +692,15 @@ void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) { // Validate. if (!Slot.empty()) { switch (Slot[0]) { + case 't': case 'u': case 'b': case 's': - case 't': + case 'c': + case 'i': break; default: - Diag(ArgLoc, diag::err_hlsl_unsupported_register_type) + Diag(ArgLoc, diag::err_hlsl_unsupported_register_prefix) << Slot.substr(0, 1); return; } @@ -500,8 +724,8 @@ void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) { return; } - // FIXME: check reg type match decl. Issue - // https://github.com/llvm/llvm-project/issues/57886. + DiagnoseHLSLResourceRegType(SemaRef, ArgLoc, D, Slot); + HLSLResourceBindingAttr *NewAttr = HLSLResourceBindingAttr::Create(getASTContext(), Slot, Space, AL); if (NewAttr) diff --git a/clang/test/AST/HLSL/ast-dump-comment-cbuffe-tbufferr.hlsl b/clang/test/AST/HLSL/ast-dump-comment-cbuffe-tbufferr.hlsl index a98dc0f4ce431..727d505471bcb 100644 --- a/clang/test/AST/HLSL/ast-dump-comment-cbuffe-tbufferr.hlsl +++ b/clang/test/AST/HLSL/ast-dump-comment-cbuffe-tbufferr.hlsl @@ -38,12 +38,14 @@ tbuffer B { } // AST:HLSLBufferDecl {{.*}}:11:1, line:20:1> line:11:9 cbuffer A +// AST-NEXT:-HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit CBuffer CBuffer // AST-NEXT:FullComment {{.*}}<line:10:4, col:17> // AST-NEXT:`-ParagraphComment {{.*}}<col:4, col:17> // AST-NEXT:`-TextComment {{.*}}<col:4, col:17> Text=" CBuffer decl." // AST-NEXT:-VarDecl {{.*}}<line:15:5, col:11> col:11 a 'float' // AST-NEXT:`-VarDecl {{.*}}<line:19:5, col:9> col:9 b 'int' // AST-NEXT:HLSLBufferDecl {{.*}}<line:29:1, line:38:1> line:29:9 tbuffer B +// AST-NEXT:-HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit SRV TBuffer // AST-NEXT:-FullComment {{.*}}<line:28:4, col:17> // AST-NEXT: `-ParagraphComment {{.*}}<col:4, col:17> // AST-NEXT: `-TextComment {{.*}}<col:4, col:17> Text=" TBuffer decl." diff --git a/clang/test/AST/HLSL/cbuffer_tbuffer.hlsl b/clang/test/AST/HLSL/cbuffer_tbuffer.hlsl index 7204dcd16e0a9..a67688d510ea6 100644 --- a/clang/test/AST/HLSL/cbuffer_tbuffer.hlsl +++ b/clang/test/AST/HLSL/cbuffer_tbuffer.hlsl @@ -1,12 +1,14 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s -// CHECK:HLSLBufferDecl 0x[[CB:[0-9a-f]+]] {{.*}} line:5:9 cbuffer CB +// CHECK:HLSLBufferDecl 0x[[CB:[0-9a-f]+]] {{.*}} line:6:9 cbuffer CB +// CHECK-NEXT:HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit CBuffer CBuffer // CHECK-NEXT:VarDecl 0x[[A:[0-9a-f]+]] {{.*}} col:9 used a 'float' cbuffer CB { float a; } -// CHECK:HLSLBufferDecl 0x[[TB:[0-9a-f]+]] {{.*}} line:11:9 tbuffer TB +// CHECK:HLSLBufferDecl 0x[[TB:[0-9a-f]+]] {{.*}} line:13:9 tbuffer TB +// CHECK-NEXT:HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit SRV TBuffer // CHECK-NEXT:VarDecl 0x[[B:[0-9a-f]+]] {{.*}} col:9 used b 'float' tbuffer TB { float b; diff --git a/clang/test/AST/HLSL/packoffset.hlsl b/clang/test/AST/HLSL/packoffset.hlsl index 060288c2f7f76..1dc99620c55c4 100644 --- a/clang/test/AST/HLSL/packoffset.hlsl +++ b/clang/test/AST/HLSL/packoffset.hlsl @@ -4,6 +4,7 @@ // CHECK: HLSLBufferDecl {{.*}} cbuffer A cbuffer A { + // CHECK-NEXT:-HLSLResourceAttr {{.*}} <<invalid sloc>> line:5:9 cbuffer A // CHECK-NEXT: VarDecl {{.*}} A1 'float4' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 0 float4 A1 : packoffset(c); diff --git a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl index e9a6ea1a16312..e264241e62e92 100644 --- a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl +++ b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl @@ -17,8 +17,10 @@ float foo() { } // Make sure cbuffer/tbuffer works for PCH. // CHECK:HLSLBufferDecl 0x{{[0-9a-f]+}} <{{.*}}:7:1, line:9:1> line:7:9 imported <undeserialized declarations> cbuffer A +// CHECK-NEXT:HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit CBuffer CBuffer // CHECK-NEXT:`-VarDecl 0x[[A:[0-9a-f]+]] <line:8:3, col:9> col:9 imported used a 'float' // CHECK-NEXT:HLSLBufferDecl 0x{{[0-9a-f]+}} <line:11:1, line:13:1> line:11:9 imported <undeserialized declarations> tbuffer B +// CHECK-NEXT:HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit SRV TBuffer // CHECK-NEXT:`-VarDecl 0x[[B:[0-9a-f]+]] <line:12:3, col:9> col:9 imported used b 'float' // CHECK-NEXT:FunctionDecl 0x{{[0-9a-f]+}} <line:15:1, line:17:1> line:15:7 imported foo 'float ()' // CHECK-NEXT:CompoundStmt 0x{{[0-9a-f]+}} <col:13, line:17:1> diff --git a/clang/test/AST/HLSL/resource_binding_attr.hlsl b/clang/test/AST/HLSL/resource_binding_attr.hlsl index 71900f2dbda55..9752494f5adc9 100644 --- a/clang/test/AST/HLSL/resource_binding_attr.hlsl +++ b/clang/test/AST/HLSL/resource_binding_attr.hlsl @@ -1,13 +1,15 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s -// CHECK:HLSLBufferDecl 0x[[CB:[0-9a-f]+]] {{.*}} line:6:9 cbuffer CB +// CHECK:HLSLBufferDecl 0x[[CB:[0-9a-f]+]] {{.*}} line:7:9 cbuffer CB +// CHECK-NEXT:HLSLResourceAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit CBuffer CBuffer // CHECK-NEXT:HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:14> "b3" "space2" // CHECK-NEXT:VarDecl 0x[[A:[0-9a-f]+]] {{.*}} col:9 used a 'float' cbuffer CB : register(b3, space2) { float a; } -// CHECK:HLSLBufferDecl 0x[[TB:[0-9a-f]+]] {{.*}} line:13:9 tbuffer TB +// CHECK:HLSLBufferDecl 0x[[TB:[0-9a-f]+]] {{.*}} line:15:9 tbuffer TB +// CHECK-NEXT:HLSLResourceAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit SRV TBuffer // CHECK-NEXT:HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:14> "t2" "space1" // CHECK-NEXT:VarDecl 0x[[B:[0-9a-f]+]] {{.*}} col:9 used b 'float' tbuffer TB : register(t2, space1) { diff --git a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl index 2f8aa098db701..58a1f3f1f64d7 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify -// expected-error@+1 {{invalid resource class specifier 'c' used; expected 'b', 's', 't', or 'u'}} +// FIXME: emit a diagnostic because float doesn't match the 'c' register type float a : register(c0, space1); -// expected-error@+1 {{invalid resource class specifier 'i' used; expected 'b', 's', 't', or 'u'}} +// FIXME: emit a diagnostic because cbuffer doesn't match the 'i' register type cbuffer b : register(i0) { } @@ -33,28 +33,27 @@ cbuffer C : register(b 2) {} // expected-error@+1 {{wrong argument format for hlsl attribute, use space3 instead}} cbuffer D : register(b 2, space 3) {} -// expected-warning@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} +// expected-error@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} static RWBuffer<float> U : register(u5); void foo() { - // expected-warning@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} + // expected-error@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} RWBuffer<float> U : register(u3); } void foo2() { - // expected-warning@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} + // expected-error@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} extern RWBuffer<float> U2 : register(u5); } -// FIXME: expect-error once fix https://github.com/llvm/llvm-project/issues/57886. + +// FIXME: emit a diagnostic because float doesn't match the 'u' register type float b : register(u0, space1); -// expected-warning@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} +// expected-error@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} void bar(RWBuffer<float> U : register(u3)) { } -struct S { - // FIXME: generate better error when support semantic on struct field. - // See https://github.com/llvm/llvm-project/issues/57889. - // expected-warning@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} +struct S { + // expected-error@+1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}} RWBuffer<float> U : register(u3); }; diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl new file mode 100644 index 0000000000000..b47171f878436 --- /dev/null +++ b/clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + + +// expected-error@+1 {{invalid register name prefix 'b' for register resource type 'RWBuffer' (expected 'u')}} +RWBuffer<int> a : register(b2, space1); + +// expected-error@+1 {{invalid register name prefix 't' for register resource type 'RWBuffer' (expected 'u')}} +RWBuffer<int> b : register(t2, space1); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture1D' (expected 't')}} +// NOT YET IMPLEMENTED Texture1D<float> tex : register(u3); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 's' for register type 'Texture2D' (expected 't')}} +// NOT YET IMPLEMENTED Texture2D<float> Texture : register(s0); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DMS<float4, 4> T2DMS_t2 : register(u2) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWTexture3D' (expected 'u')}} +// NOT YET IMPLEMENTED RWTexture3D<float4> RWT3D_u1 : register(t1) + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'TextureCube' (expected 't')}} +// NOT YET IMPLEMENTED TextureCube <float> t8 : register(b8); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'TextureCubeArray' (expected 't')}} +// NOT YET IMPLEMENTED TextureCubeArray TCubeArray_t2 : register(b2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture1DArray' (expected 't')}} +// NOT YET IMPLEMENTED Texture1DArray T1DArray_t2 : register(b2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'B' for register type 'Texture2DArray' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DArray T2DArray_b2 : register(B2); + + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMSArray' (expected 't')}} +// NOT YET IMPLEMENTED Texture2DMSArray<float4> msTextureArray : register(u2, space2); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'TextureCubeArray' (expected 't')}} +// 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 resource 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 resource type 'tbuffer' (expected 't')}} +tbuffer f : register(s2, space1) {} + +// NOT YET IMPLEMENTED : RTAccelerationStructure doesn't have any example tests in DXC + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'FeedbackTexture2D' (expected 't')}} +// NOT YET IMPLEMENTED FeedbackTexture2D<float> FBTex2D[3][] : register(u0, space26); + +// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'FeedbackTexture2DArray' (expected 't')}} +// NOT YET IMPLEMENTED FeedbackTexture2DArray<float> FBTex2DArr[3][2][] : register(u0, space27); + + +// empty binding prefix cases: +// expected-error@+1 {{expected identifier}} +RWBuffer<int> c: register(); + +// expected-error@+1 {{expected identifier}} +RWBuffer<int> d: register(""); >From 8e20fce2dbb0e88bc6c286815d36339f37d34d80 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 28 Jun 2024 16:18:43 -0700 Subject: [PATCH 2/3] remove mismatch test, will be applied in step 2 PR. update packoffset --- clang/test/AST/HLSL/packoffset.hlsl | 2 +- .../resource_binding_attr_error_mismatch.hlsl | 74 ------------------- 2 files changed, 1 insertion(+), 75 deletions(-) delete mode 100644 clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl diff --git a/clang/test/AST/HLSL/packoffset.hlsl b/clang/test/AST/HLSL/packoffset.hlsl index 1dc99620c55c4..9deb63caa500a 100644 --- a/clang/test/AST/HLSL/packoffset.hlsl +++ b/clang/test/AST/HLSL/packoffset.hlsl @@ -4,7 +4,7 @@ // CHECK: HLSLBufferDecl {{.*}} cbuffer A cbuffer A { - // CHECK-NEXT:-HLSLResourceAttr {{.*}} <<invalid sloc>> line:5:9 cbuffer A + // CHECK-NEXT:-HLSLResourceAttr {{.*}} <<invalid sloc>> Implicit CBuffer CBuffer // CHECK-NEXT: VarDecl {{.*}} A1 'float4' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 0 float4 A1 : packoffset(c); diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl deleted file mode 100644 index b47171f878436..0000000000000 --- a/clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl +++ /dev/null @@ -1,74 +0,0 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify - - -// expected-error@+1 {{invalid register name prefix 'b' for register resource type 'RWBuffer' (expected 'u')}} -RWBuffer<int> a : register(b2, space1); - -// expected-error@+1 {{invalid register name prefix 't' for register resource type 'RWBuffer' (expected 'u')}} -RWBuffer<int> b : register(t2, space1); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture1D' (expected 't')}} -// NOT YET IMPLEMENTED Texture1D<float> tex : register(u3); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 's' for register type 'Texture2D' (expected 't')}} -// NOT YET IMPLEMENTED Texture2D<float> Texture : register(s0); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMS' (expected 't')}} -// NOT YET IMPLEMENTED Texture2DMS<float4, 4> T2DMS_t2 : register(u2) - -// NOT YET IMPLEMENTED : {{invalid register name prefix 't' for register type 'RWTexture3D' (expected 'u')}} -// NOT YET IMPLEMENTED RWTexture3D<float4> RWT3D_u1 : register(t1) - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'TextureCube' (expected 't')}} -// NOT YET IMPLEMENTED TextureCube <float> t8 : register(b8); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'TextureCubeArray' (expected 't')}} -// NOT YET IMPLEMENTED TextureCubeArray TCubeArray_t2 : register(b2); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'b' for register type 'Texture1DArray' (expected 't')}} -// NOT YET IMPLEMENTED Texture1DArray T1DArray_t2 : register(b2); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'B' for register type 'Texture2DArray' (expected 't')}} -// NOT YET IMPLEMENTED Texture2DArray T2DArray_b2 : register(B2); - - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'Texture2DMSArray' (expected 't')}} -// NOT YET IMPLEMENTED Texture2DMSArray<float4> msTextureArray : register(u2, space2); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'TextureCubeArray' (expected 't')}} -// 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 resource 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 resource type 'tbuffer' (expected 't')}} -tbuffer f : register(s2, space1) {} - -// NOT YET IMPLEMENTED : RTAccelerationStructure doesn't have any example tests in DXC - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'FeedbackTexture2D' (expected 't')}} -// NOT YET IMPLEMENTED FeedbackTexture2D<float> FBTex2D[3][] : register(u0, space26); - -// NOT YET IMPLEMENTED : {{invalid register name prefix 'u' for register type 'FeedbackTexture2DArray' (expected 't')}} -// NOT YET IMPLEMENTED FeedbackTexture2DArray<float> FBTex2DArr[3][2][] : register(u0, space27); - - -// empty binding prefix cases: -// expected-error@+1 {{expected identifier}} -RWBuffer<int> c: register(); - -// expected-error@+1 {{expected identifier}} -RWBuffer<int> d: register(""); >From 8e19f3dd702e0e65b991b2a741405c224a066ba0 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 28 Jun 2024 16:29:20 -0700 Subject: [PATCH 3/3] clang-format --- clang/include/clang/Sema/SemaHLSL.h | 2 +- clang/lib/Sema/SemaHLSL.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index d3d36d04d1019..4e2a93209386e 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -21,8 +21,8 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Scope.h" -#include "clang/Sema/SemaBase.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaBase.h" #include <initializer_list> namespace clang { diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index d2b2f163231c9..8b6ecc6b7d992 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -546,7 +546,7 @@ void traverseType(QualType T, register_binding_flags &r) { case llvm::hlsl::ResourceClass::Sampler: { r.sampler = true; break; - } + } } } @@ -617,7 +617,7 @@ register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { case llvm::hlsl::ResourceClass::Sampler: { r.sampler = true; break; - } + } } } else { if (SamplerUAVOrSRV->getType()->isBuiltinType()) @@ -653,11 +653,11 @@ static void DiagnoseHLSLResourceRegType(Sema &S, SourceLocation &ArgLoc, // TODO: emit diagnostic code based on the flags set in f. } - void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) { - if (dyn_cast<VarDecl>(D)) { - if (SemaRef.RequireCompleteType(D->getBeginLoc(), cast<ValueDecl>(D)->getType(), - diag::err_incomplete_type)) + if (dyn_cast<VarDecl>(D)) { + if (SemaRef.RequireCompleteType(D->getBeginLoc(), + cast<ValueDecl>(D)->getType(), + diag::err_incomplete_type)) return; } StringRef Space = "space0"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits