@@ -57,6 +57,15 @@ CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
57
57
return CD;
58
58
return nullptr ;
59
59
}
60
+
61
+ // / Set up common members and attributes for buffer types
62
+ static bool resourceHasCounter (const CXXRecordDecl *Decl) {
63
+ StringRef Name = Decl->getName ();
64
+ return Name == " RWStructuredBuffer" || Name == " AppendStructuredBuffer" ||
65
+ Name == " ConsumeStructuredBuffer" ||
66
+ Name == " RasterizerOrderedStructuredBuffer" ;
67
+ }
68
+
60
69
} // namespace
61
70
62
71
// Builder for template arguments of builtin types. Used internally
@@ -138,7 +147,16 @@ struct BuiltinTypeMethodBuilder {
138
147
// LastStmt - refers to the last statement in the method body; referencing
139
148
// LastStmt will remove the statement from the method body since
140
149
// it will be linked from the new expression being constructed.
141
- enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128 , LastStmt };
150
+ enum class PlaceHolder {
151
+ _0,
152
+ _1,
153
+ _2,
154
+ _3,
155
+ _4,
156
+ Handle = 128 ,
157
+ CounterHandle,
158
+ LastStmt
159
+ };
142
160
143
161
Expr *convertPlaceholder (PlaceHolder PH);
144
162
Expr *convertPlaceholder (LocalVar &Var);
@@ -178,10 +196,17 @@ struct BuiltinTypeMethodBuilder {
178
196
template <typename ResourceT, typename ValueT>
179
197
BuiltinTypeMethodBuilder &setHandleFieldOnResource (ResourceT ResourceRecord,
180
198
ValueT HandleValue);
199
+ template <typename T>
200
+ BuiltinTypeMethodBuilder &
201
+ accessCounterHandleFieldOnResource (T ResourceRecord);
202
+ template <typename ResourceT, typename ValueT>
203
+ BuiltinTypeMethodBuilder &
204
+ setCounterHandleFieldOnResource (ResourceT ResourceRecord, ValueT HandleValue);
181
205
template <typename T> BuiltinTypeMethodBuilder &returnValue (T ReturnValue);
182
206
BuiltinTypeMethodBuilder &returnThis ();
183
207
BuiltinTypeDeclBuilder &finalize ();
184
208
Expr *getResourceHandleExpr ();
209
+ Expr *getResourceCounterHandleExpr ();
185
210
186
211
private:
187
212
void createDecl ();
@@ -346,6 +371,8 @@ TemplateParameterListBuilder::finalizeTemplateArgs(ConceptDecl *CD) {
346
371
Expr *BuiltinTypeMethodBuilder::convertPlaceholder (PlaceHolder PH) {
347
372
if (PH == PlaceHolder::Handle)
348
373
return getResourceHandleExpr ();
374
+ if (PH == PlaceHolder::CounterHandle)
375
+ return getResourceCounterHandleExpr ();
349
376
350
377
if (PH == PlaceHolder::LastStmt) {
351
378
assert (!StmtsList.empty () && " no statements in the list" );
@@ -467,6 +494,18 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() {
467
494
OK_Ordinary);
468
495
}
469
496
497
+ Expr *BuiltinTypeMethodBuilder::getResourceCounterHandleExpr () {
498
+ ensureCompleteDecl ();
499
+
500
+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
501
+ CXXThisExpr *This = CXXThisExpr::Create (
502
+ AST, SourceLocation (), Method->getFunctionObjectParameterType (), true );
503
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField ();
504
+ return MemberExpr::CreateImplicit (AST, This, false , HandleField,
505
+ HandleField->getType (), VK_LValue,
506
+ OK_Ordinary);
507
+ }
508
+
470
509
BuiltinTypeMethodBuilder &
471
510
BuiltinTypeMethodBuilder::declareLocalVar (LocalVar &Var) {
472
511
ensureCompleteDecl ();
@@ -583,6 +622,44 @@ BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord,
583
622
return *this ;
584
623
}
585
624
625
+ template <typename T>
626
+ BuiltinTypeMethodBuilder &
627
+ BuiltinTypeMethodBuilder::accessCounterHandleFieldOnResource (T ResourceRecord) {
628
+ ensureCompleteDecl ();
629
+
630
+ Expr *ResourceExpr = convertPlaceholder (ResourceRecord);
631
+
632
+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
633
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField ();
634
+ MemberExpr *HandleExpr = MemberExpr::CreateImplicit (
635
+ AST, ResourceExpr, false , HandleField, HandleField->getType (), VK_LValue,
636
+ OK_Ordinary);
637
+ StmtsList.push_back (HandleExpr);
638
+ return *this ;
639
+ }
640
+
641
+ template <typename ResourceT, typename ValueT>
642
+ BuiltinTypeMethodBuilder &
643
+ BuiltinTypeMethodBuilder::setCounterHandleFieldOnResource (
644
+ ResourceT ResourceRecord, ValueT HandleValue) {
645
+ ensureCompleteDecl ();
646
+
647
+ Expr *ResourceExpr = convertPlaceholder (ResourceRecord);
648
+ Expr *HandleValueExpr = convertPlaceholder (HandleValue);
649
+
650
+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
651
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField ();
652
+ MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit (
653
+ AST, ResourceExpr, false , HandleField, HandleField->getType (), VK_LValue,
654
+ OK_Ordinary);
655
+ Stmt *AssignStmt = BinaryOperator::Create (
656
+ DeclBuilder.SemaRef .getASTContext (), HandleMemberExpr, HandleValueExpr,
657
+ BO_Assign, HandleMemberExpr->getType (), ExprValueKind::VK_PRValue,
658
+ ExprObjectKind::OK_Ordinary, SourceLocation (), FPOptionsOverride ());
659
+ StmtsList.push_back (AssignStmt);
660
+ return *this ;
661
+ }
662
+
586
663
template <typename T>
587
664
BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue (T ReturnValue) {
588
665
ensureCompleteDecl ();
@@ -722,6 +799,15 @@ BuiltinTypeDeclBuilder::addMemberVariable(StringRef Name, QualType Type,
722
799
return *this ;
723
800
}
724
801
802
+ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMembers (
803
+ ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
804
+ addHandleMember (RC, IsROV, RawBuffer, Access);
805
+ if (resourceHasCounter (Record)) {
806
+ addCounterHandleMember (RC, IsROV, RawBuffer, Access);
807
+ }
808
+ return *this ;
809
+ }
810
+
725
811
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember (
726
812
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
727
813
assert (!Record->isCompleteDefinition () && " record is already complete" );
@@ -745,6 +831,30 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
745
831
return *this ;
746
832
}
747
833
834
+ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember (
835
+ ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
836
+ assert (!Record->isCompleteDefinition () && " record is already complete" );
837
+
838
+ ASTContext &Ctx = SemaRef.getASTContext ();
839
+ TypeSourceInfo *ElementTypeInfo =
840
+ Ctx.getTrivialTypeSourceInfo (getHandleElementType (), SourceLocation ());
841
+
842
+ // add handle member with resource type attributes
843
+ QualType AttributedResTy = QualType ();
844
+ SmallVector<const Attr *> Attrs = {
845
+ HLSLResourceClassAttr::CreateImplicit (Ctx, RC),
846
+ IsROV ? HLSLROVAttr::CreateImplicit (Ctx) : nullptr ,
847
+ RawBuffer ? HLSLRawBufferAttr::CreateImplicit (Ctx) : nullptr ,
848
+ ElementTypeInfo
849
+ ? HLSLContainedTypeAttr::CreateImplicit (Ctx, ElementTypeInfo)
850
+ : nullptr ,
851
+ HLSLIsCounterAttr::CreateImplicit (Ctx)};
852
+ if (CreateHLSLAttributedResourceType (SemaRef, Ctx.HLSLResourceTy , Attrs,
853
+ AttributedResTy))
854
+ addMemberVariable (" __counter_handle" , AttributedResTy, {}, Access);
855
+ return *this ;
856
+ }
857
+
748
858
// Adds default constructor to the resource class:
749
859
// Resource::Resource()
750
860
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor () {
@@ -848,12 +958,18 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() {
848
958
849
959
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
850
960
851
- return BuiltinTypeMethodBuilder (*this , /* Name=*/ " " , AST.VoidTy ,
852
- /* IsConst=*/ false , /* IsCtor=*/ true )
853
- .addParam (" other" , ConstRecordRefType)
961
+ BuiltinTypeMethodBuilder MMB (*this , /* Name=*/ " " , AST.VoidTy ,
962
+ /* IsConst=*/ false , /* IsCtor=*/ true );
963
+ MMB .addParam (" other" , ConstRecordRefType)
854
964
.accessHandleFieldOnResource (PH::_0)
855
- .assign (PH::Handle, PH::LastStmt)
856
- .finalize ();
965
+ .assign (PH::Handle, PH::LastStmt);
966
+
967
+ if (getResourceCounterHandleField ()) {
968
+ MMB.accessCounterHandleFieldOnResource (PH::_0).assign (PH::CounterHandle,
969
+ PH::LastStmt);
970
+ }
971
+
972
+ return MMB.finalize ();
857
973
}
858
974
859
975
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator () {
@@ -868,12 +984,17 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() {
868
984
869
985
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
870
986
DeclarationName Name = AST.DeclarationNames .getCXXOperatorName (OO_Equal);
871
- return BuiltinTypeMethodBuilder (*this , Name, RecordRefType)
872
- .addParam (" other" , ConstRecordRefType)
987
+ BuiltinTypeMethodBuilder MMB (*this , Name, RecordRefType);
988
+ MMB .addParam (" other" , ConstRecordRefType)
873
989
.accessHandleFieldOnResource (PH::_0)
874
- .assign (PH::Handle, PH::LastStmt)
875
- .returnThis ()
876
- .finalize ();
990
+ .assign (PH::Handle, PH::LastStmt);
991
+
992
+ if (getResourceCounterHandleField ()) {
993
+ MMB.accessCounterHandleFieldOnResource (PH::_0).assign (PH::CounterHandle,
994
+ PH::LastStmt);
995
+ }
996
+
997
+ return MMB.returnThis ().finalize ();
877
998
}
878
999
879
1000
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators () {
@@ -909,6 +1030,13 @@ FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
909
1030
return I->second ;
910
1031
}
911
1032
1033
+ FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField () const {
1034
+ auto I = Fields.find (" __counter_handle" );
1035
+ if (I == Fields.end ())
1036
+ return nullptr ;
1037
+ return I->second ;
1038
+ }
1039
+
912
1040
QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam () {
913
1041
assert (Template && " record it not a template" );
914
1042
if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
0 commit comments