Skip to content

Commit ebc4a66

Browse files
authored
Implement resource binding type prefix mismatch diagnostic infrastructure (llvm#97103)
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 such diagnostics. The focus of this PR is to implement both the flag setting and diagnostic emisison steps specified in the relevant spec: microsoft/hlsl-specs#230 The relevant issue is: llvm#57886 This is a continuation / refresh of this PR: llvm#87578
1 parent fa089ef commit ebc4a66

22 files changed

+751
-60
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4538,7 +4538,7 @@ def HLSLSV_GroupIndex: HLSLAnnotationAttr {
45384538

45394539
def HLSLResourceBinding: InheritableAttr {
45404540
let Spellings = [HLSLAnnotation<"register">];
4541-
let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>;
4541+
let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar], ErrorDiag>;
45424542
let LangOpts = [HLSL];
45434543
let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>];
45444544
let Documentation = [HLSLResourceBindingDocs];
@@ -4622,7 +4622,7 @@ def HLSLROV : InheritableAttr {
46224622

46234623
def HLSLResourceClass : InheritableAttr {
46244624
let Spellings = [CXX11<"hlsl", "resource_class">];
4625-
let Subjects = SubjectList<[Struct]>;
4625+
let Subjects = SubjectList<[Field]>;
46264626
let LangOpts = [HLSL];
46274627
let Args = [
46284628
EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass",

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,9 @@ def DXILValidation : DiagGroup<"dxil-validation">;
15471547
// Warning for HLSL API availability
15481548
def HLSLAvailability : DiagGroup<"hlsl-availability">;
15491549

1550+
// Warnings for legacy binding behavior
1551+
def LegacyConstantRegisterBinding : DiagGroup<"legacy-constant-register-binding">;
1552+
15501553
// Warnings and notes related to const_var_decl_type attribute checks
15511554
def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;
15521555

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12352,7 +12352,13 @@ def err_hlsl_missing_semantic_annotation : Error<
1235212352
def err_hlsl_init_priority_unsupported : Error<
1235312353
"initializer priorities are not supported in HLSL">;
1235412354

12355-
def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">;
12355+
def warn_hlsl_user_defined_type_missing_member: Warning<"binding type '%select{t|u|b|s|c}0' only applies to types containing %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric types}0">, InGroup<LegacyConstantRegisterBinding>;
12356+
def err_hlsl_binding_type_mismatch: Error<"binding type '%select{t|u|b|s|c}0' only applies to %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric variables in the global scope}0">;
12357+
def err_hlsl_binding_type_invalid: Error<"binding type '%0' is invalid">;
12358+
def err_hlsl_duplicate_register_annotation: Error<"binding type '%select{t|u|b|s|c|i}0' cannot be applied more than once">;
12359+
def warn_hlsl_register_type_c_packoffset: Warning<"binding type 'c' ignored in buffer declaration. Did you mean 'packoffset'?">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
12360+
def warn_hlsl_deprecated_register_type_b: Warning<"binding type 'b' only applies to constant buffers. The 'bool constant' binding type is no longer supported">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
12361+
def warn_hlsl_deprecated_register_type_i: Warning<"binding type 'i' ignored. The 'integer constant' binding type is no longer supported">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
1235612362
def err_hlsl_unsupported_register_number : Error<"register number should be an integer">;
1235712363
def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">;
1235812364
def warn_hlsl_packoffset_mix : Warning<"cannot mix packoffset elements with nonpackoffset elements in a cbuffer">,

clang/include/clang/Parse/Parser.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3021,15 +3021,17 @@ class Parser : public CodeCompletionHandler {
30213021
SemaCodeCompletion::AttributeCompletion::None,
30223022
const IdentifierInfo *EnclosingScope = nullptr);
30233023

3024-
void MaybeParseHLSLAnnotations(Declarator &D,
3024+
bool MaybeParseHLSLAnnotations(Declarator &D,
30253025
SourceLocation *EndLoc = nullptr,
30263026
bool CouldBeBitField = false) {
30273027
assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only");
30283028
if (Tok.is(tok::colon)) {
30293029
ParsedAttributes Attrs(AttrFactory);
30303030
ParseHLSLAnnotations(Attrs, EndLoc, CouldBeBitField);
30313031
D.takeAttributes(Attrs);
3032+
return true;
30323033
}
3034+
return false;
30333035
}
30343036

30353037
void MaybeParseHLSLAnnotations(ParsedAttributes &Attrs,

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2326,7 +2326,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
23262326
}
23272327

23282328
if (getLangOpts().HLSL)
2329-
MaybeParseHLSLAnnotations(D);
2329+
while (MaybeParseHLSLAnnotations(D))
2330+
;
23302331

23312332
if (Tok.is(tok::kw_requires))
23322333
ParseTrailingRequiresClause(D);

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,11 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
503503
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer")
504504
.addSimpleTemplateParams(*SemaPtr, {"element_type"})
505505
.Record;
506+
506507
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
507508
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
508-
ResourceKind::TypedBuffer, /*IsROV=*/false)
509+
ResourceKind::TypedBuffer,
510+
/*IsROV=*/false)
509511
.addArraySubscriptOperators()
510512
.completeDefinition();
511513
});

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6889,6 +6889,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
68896889
case ParsedAttr::AT_HLSLSV_GroupIndex:
68906890
handleSimpleAttribute<HLSLSV_GroupIndexAttr>(S, D, AL);
68916891
break;
6892+
case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
6893+
handleSimpleAttribute<HLSLGroupSharedAddressSpaceAttr>(S, D, AL);
6894+
break;
68926895
case ParsedAttr::AT_HLSLSV_DispatchThreadID:
68936896
S.HLSL().handleSV_DispatchThreadIDAttr(D, AL);
68946897
break;

0 commit comments

Comments
 (0)