llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-hlsl Author: Joshua Batista (bob80905) <details> <summary>Changes</summary> There are currently no diagnostics being emitted for when a resource is bound to a register with an incorrect binding type prefix. For example, a CBuffer type resource should be bound with a a binding type prefix of 'b', but if instead the prefix is 'u', no errors will be emitted. This PR implements a set of diagnostics for when the prefix is not expected. Fixes https://github.com/llvm/llvm-project/issues/57886 This is a continuation / refresh of this PR: https://github.com/llvm/llvm-project/pull/87578 --- Patch is 25.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97103.diff 12 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+1-1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4-1) - (modified) clang/include/clang/Sema/SemaHLSL.h (+2) - (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+14-12) - (modified) clang/lib/Sema/SemaHLSL.cpp (+228-4) - (modified) clang/test/AST/HLSL/ast-dump-comment-cbuffe-tbufferr.hlsl (+2) - (modified) clang/test/AST/HLSL/cbuffer_tbuffer.hlsl (+4-2) - (modified) clang/test/AST/HLSL/packoffset.hlsl (+1) - (modified) clang/test/AST/HLSL/pch_hlsl_buffer.hlsl (+2) - (modified) clang/test/AST/HLSL/resource_binding_attr.hlsl (+4-2) - (modified) clang/test/SemaHLSL/resource_binding_attr_error.hlsl (+10-11) - (added) clang/test/SemaHLSL/resource_binding_attr_error_mismatch.hlsl (+74) ``````````diff 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 vari... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/97103 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits