@@ -138,7 +138,16 @@ struct BuiltinTypeMethodBuilder {
138
138
// LastStmt - refers to the last statement in the method body; referencing
139
139
// LastStmt will remove the statement from the method body since
140
140
// it will be linked from the new expression being constructed.
141
- enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128 , LastStmt };
141
+ enum class PlaceHolder {
142
+ _0,
143
+ _1,
144
+ _2,
145
+ _3,
146
+ _4,
147
+ Handle = 128 ,
148
+ CounterHandle,
149
+ LastStmt
150
+ };
142
151
143
152
Expr *convertPlaceholder (PlaceHolder PH);
144
153
Expr *convertPlaceholder (LocalVar &Var);
@@ -178,10 +187,14 @@ struct BuiltinTypeMethodBuilder {
178
187
template <typename ResourceT, typename ValueT>
179
188
BuiltinTypeMethodBuilder &setHandleFieldOnResource (ResourceT ResourceRecord,
180
189
ValueT HandleValue);
190
+ template <typename T>
191
+ BuiltinTypeMethodBuilder &
192
+ accessCounterHandleFieldOnResource (T ResourceRecord);
181
193
template <typename T> BuiltinTypeMethodBuilder &returnValue (T ReturnValue);
182
194
BuiltinTypeMethodBuilder &returnThis ();
183
195
BuiltinTypeDeclBuilder &finalize ();
184
196
Expr *getResourceHandleExpr ();
197
+ Expr *getResourceCounterHandleExpr ();
185
198
186
199
private:
187
200
void createDecl ();
@@ -346,6 +359,8 @@ TemplateParameterListBuilder::finalizeTemplateArgs(ConceptDecl *CD) {
346
359
Expr *BuiltinTypeMethodBuilder::convertPlaceholder (PlaceHolder PH) {
347
360
if (PH == PlaceHolder::Handle)
348
361
return getResourceHandleExpr ();
362
+ if (PH == PlaceHolder::CounterHandle)
363
+ return getResourceCounterHandleExpr ();
349
364
350
365
if (PH == PlaceHolder::LastStmt) {
351
366
assert (!StmtsList.empty () && " no statements in the list" );
@@ -467,6 +482,18 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() {
467
482
OK_Ordinary);
468
483
}
469
484
485
+ Expr *BuiltinTypeMethodBuilder::getResourceCounterHandleExpr () {
486
+ ensureCompleteDecl ();
487
+
488
+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
489
+ CXXThisExpr *This = CXXThisExpr::Create (
490
+ AST, SourceLocation (), Method->getFunctionObjectParameterType (), true );
491
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField ();
492
+ return MemberExpr::CreateImplicit (AST, This, false , HandleField,
493
+ HandleField->getType (), VK_LValue,
494
+ OK_Ordinary);
495
+ }
496
+
470
497
BuiltinTypeMethodBuilder &
471
498
BuiltinTypeMethodBuilder::declareLocalVar (LocalVar &Var) {
472
499
ensureCompleteDecl ();
@@ -583,6 +610,22 @@ BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord,
583
610
return *this ;
584
611
}
585
612
613
+ template <typename T>
614
+ BuiltinTypeMethodBuilder &
615
+ BuiltinTypeMethodBuilder::accessCounterHandleFieldOnResource (T ResourceRecord) {
616
+ ensureCompleteDecl ();
617
+
618
+ Expr *ResourceExpr = convertPlaceholder (ResourceRecord);
619
+
620
+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
621
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField ();
622
+ MemberExpr *HandleExpr = MemberExpr::CreateImplicit (
623
+ AST, ResourceExpr, false , HandleField, HandleField->getType (), VK_LValue,
624
+ OK_Ordinary);
625
+ StmtsList.push_back (HandleExpr);
626
+ return *this ;
627
+ }
628
+
586
629
template <typename T>
587
630
BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue (T ReturnValue) {
588
631
ensureCompleteDecl ();
@@ -722,8 +765,31 @@ BuiltinTypeDeclBuilder::addMemberVariable(StringRef Name, QualType Type,
722
765
return *this ;
723
766
}
724
767
768
+ BuiltinTypeDeclBuilder &
769
+ BuiltinTypeDeclBuilder::addBufferHandles (ResourceClass RC, bool IsROV,
770
+ bool RawBuffer, bool HasCounter,
771
+ AccessSpecifier Access) {
772
+ addHandleMember (RC, IsROV, RawBuffer, Access);
773
+ if (HasCounter)
774
+ addCounterHandleMember (RC, IsROV, RawBuffer, Access);
775
+ return *this ;
776
+ }
777
+
725
778
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember (
726
779
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
780
+ return addResourceMember (" __handle" , RC, IsROV, RawBuffer,
781
+ /* IsCounter=*/ false , Access);
782
+ }
783
+
784
+ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember (
785
+ ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
786
+ return addResourceMember (" __counter_handle" , RC, IsROV, RawBuffer,
787
+ /* IsCounter=*/ true , Access);
788
+ }
789
+
790
+ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember (
791
+ StringRef MemberName, ResourceClass RC, bool IsROV, bool RawBuffer,
792
+ bool IsCounter, AccessSpecifier Access) {
727
793
assert (!Record->isCompleteDefinition () && " record is already complete" );
728
794
729
795
ASTContext &Ctx = SemaRef.getASTContext ();
@@ -739,9 +805,12 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
739
805
ElementTypeInfo
740
806
? HLSLContainedTypeAttr::CreateImplicit (Ctx, ElementTypeInfo)
741
807
: nullptr };
808
+ if (IsCounter)
809
+ Attrs.push_back (HLSLIsCounterAttr::CreateImplicit (Ctx));
810
+
742
811
if (CreateHLSLAttributedResourceType (SemaRef, Ctx.HLSLResourceTy , Attrs,
743
812
AttributedResTy))
744
- addMemberVariable (" __handle " , AttributedResTy, {}, Access);
813
+ addMemberVariable (MemberName , AttributedResTy, {}, Access);
745
814
return *this ;
746
815
}
747
816
@@ -844,12 +913,17 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() {
844
913
845
914
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
846
915
847
- return BuiltinTypeMethodBuilder (*this , /* Name=*/ " " , AST.VoidTy ,
848
- /* IsConst=*/ false , /* IsCtor=*/ true )
849
- .addParam (" other" , ConstRecordRefType)
916
+ BuiltinTypeMethodBuilder MMB (*this , /* Name=*/ " " , AST.VoidTy ,
917
+ /* IsConst=*/ false , /* IsCtor=*/ true );
918
+ MMB .addParam (" other" , ConstRecordRefType)
850
919
.accessHandleFieldOnResource (PH::_0)
851
- .assign (PH::Handle, PH::LastStmt)
852
- .finalize ();
920
+ .assign (PH::Handle, PH::LastStmt);
921
+
922
+ if (getResourceCounterHandleField ())
923
+ MMB.accessCounterHandleFieldOnResource (PH::_0).assign (PH::CounterHandle,
924
+ PH::LastStmt);
925
+
926
+ return MMB.finalize ();
853
927
}
854
928
855
929
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator () {
@@ -863,12 +937,16 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() {
863
937
864
938
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
865
939
DeclarationName Name = AST.DeclarationNames .getCXXOperatorName (OO_Equal);
866
- return BuiltinTypeMethodBuilder (*this , Name, RecordRefType)
867
- .addParam (" other" , ConstRecordRefType)
940
+ BuiltinTypeMethodBuilder MMB (*this , Name, RecordRefType);
941
+ MMB .addParam (" other" , ConstRecordRefType)
868
942
.accessHandleFieldOnResource (PH::_0)
869
- .assign (PH::Handle, PH::LastStmt)
870
- .returnThis ()
871
- .finalize ();
943
+ .assign (PH::Handle, PH::LastStmt);
944
+
945
+ if (getResourceCounterHandleField ())
946
+ MMB.accessCounterHandleFieldOnResource (PH::_0).assign (PH::CounterHandle,
947
+ PH::LastStmt);
948
+
949
+ return MMB.returnThis ().finalize ();
872
950
}
873
951
874
952
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators () {
@@ -903,6 +981,14 @@ FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
903
981
return I->second ;
904
982
}
905
983
984
+ FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField () const {
985
+ auto I = Fields.find (" __counter_handle" );
986
+ if (I == Fields.end () ||
987
+ !I->second ->getType ()->isHLSLAttributedResourceType ())
988
+ return nullptr ;
989
+ return I->second ;
990
+ }
991
+
906
992
QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam () {
907
993
assert (Template && " record it not a template" );
908
994
if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
0 commit comments