@@ -120,7 +120,15 @@ struct BuiltinTypeMethodBuilder {
120120 // LastStmt - refers to the last statement in the method body; referencing
121121 // LastStmt will remove the statement from the method body since
122122 // it will be linked from the new expression being constructed.
123- enum class PlaceHolder { _0, _1, _2, _3, Handle = 128 , LastStmt };
123+ enum class PlaceHolder {
124+ _0,
125+ _1,
126+ _2,
127+ _3,
128+ Handle = 128 ,
129+ CounterHandle,
130+ LastStmt
131+ };
124132
125133 Expr *convertPlaceholder (PlaceHolder PH);
126134 Expr *convertPlaceholder (Expr *E) { return E; }
@@ -155,6 +163,7 @@ struct BuiltinTypeMethodBuilder {
155163 template <typename T> BuiltinTypeMethodBuilder &dereference (T Ptr);
156164 BuiltinTypeDeclBuilder &finalize ();
157165 Expr *getResourceHandleExpr ();
166+ Expr *getResourceCounterHandleExpr ();
158167
159168private:
160169 void createDecl ();
@@ -322,6 +331,8 @@ TemplateParameterListBuilder::finalizeTemplateArgs(ConceptDecl *CD) {
322331Expr *BuiltinTypeMethodBuilder::convertPlaceholder (PlaceHolder PH) {
323332 if (PH == PlaceHolder::Handle)
324333 return getResourceHandleExpr ();
334+ if (PH == PlaceHolder::CounterHandle)
335+ return getResourceCounterHandleExpr ();
325336
326337 if (PH == PlaceHolder::LastStmt) {
327338 assert (!StmtsList.empty () && " no statements in the list" );
@@ -432,6 +443,18 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() {
432443 OK_Ordinary);
433444}
434445
446+ Expr *BuiltinTypeMethodBuilder::getResourceCounterHandleExpr () {
447+ ensureCompleteDecl ();
448+
449+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
450+ CXXThisExpr *This = CXXThisExpr::Create (
451+ AST, SourceLocation (), Method->getFunctionObjectParameterType (), true );
452+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField ();
453+ return MemberExpr::CreateImplicit (AST, This, false , HandleField,
454+ HandleField->getType (), VK_LValue,
455+ OK_Ordinary);
456+ }
457+
435458template <typename ... Ts>
436459BuiltinTypeMethodBuilder &
437460BuiltinTypeMethodBuilder::callBuiltin (StringRef BuiltinName,
@@ -626,6 +649,30 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
626649 return *this ;
627650}
628651
652+ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember (
653+ ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
654+ assert (!Record->isCompleteDefinition () && " record is already complete" );
655+
656+ ASTContext &Ctx = SemaRef.getASTContext ();
657+ TypeSourceInfo *ElementTypeInfo =
658+ Ctx.getTrivialTypeSourceInfo (getHandleElementType (), SourceLocation ());
659+
660+ // add handle member with resource type attributes
661+ QualType AttributedResTy = QualType ();
662+ SmallVector<const Attr *> Attrs = {
663+ HLSLResourceClassAttr::CreateImplicit (Ctx, RC),
664+ IsROV ? HLSLROVAttr::CreateImplicit (Ctx) : nullptr ,
665+ RawBuffer ? HLSLRawBufferAttr::CreateImplicit (Ctx) : nullptr ,
666+ ElementTypeInfo
667+ ? HLSLContainedTypeAttr::CreateImplicit (Ctx, ElementTypeInfo)
668+ : nullptr ,
669+ HLSLCounterAttr::CreateImplicit (Ctx)};
670+ if (CreateHLSLAttributedResourceType (SemaRef, Ctx.HLSLResourceTy , Attrs,
671+ AttributedResTy))
672+ addMemberVariable (" __counter_handle" , AttributedResTy, {}, Access);
673+ return *this ;
674+ }
675+
629676// Adds default constructor to the resource class:
630677// Resource::Resource()
631678BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor () {
@@ -671,6 +718,14 @@ FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() {
671718 return I->second ;
672719}
673720
721+ FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField () {
722+ auto I = Fields.find (" __counter_handle" );
723+ assert (I != Fields.end () &&
724+ I->second ->getType ()->isHLSLAttributedResourceType () &&
725+ " record does not have resource handle field" );
726+ return I->second ;
727+ }
728+
674729QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam () {
675730 assert (Template && " record it not a template" );
676731 if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
@@ -730,7 +785,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod() {
730785 return BuiltinTypeMethodBuilder (*this , " IncrementCounter" ,
731786 SemaRef.getASTContext ().UnsignedIntTy )
732787 .callBuiltin (" __builtin_hlsl_buffer_update_counter" , QualType (),
733- PH::Handle , getConstantIntExpr (1 ))
788+ PH::CounterHandle , getConstantIntExpr (1 ))
734789 .finalize ();
735790}
736791
@@ -739,7 +794,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() {
739794 return BuiltinTypeMethodBuilder (*this , " DecrementCounter" ,
740795 SemaRef.getASTContext ().UnsignedIntTy )
741796 .callBuiltin (" __builtin_hlsl_buffer_update_counter" , QualType (),
742- PH::Handle , getConstantIntExpr (-1 ))
797+ PH::CounterHandle , getConstantIntExpr (-1 ))
743798 .finalize ();
744799}
745800
@@ -774,7 +829,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() {
774829 return BuiltinTypeMethodBuilder (*this , " Append" , AST.VoidTy )
775830 .addParam (" value" , ElemTy)
776831 .callBuiltin (" __builtin_hlsl_buffer_update_counter" , AST.UnsignedIntTy ,
777- PH::Handle , getConstantIntExpr (1 ))
832+ PH::CounterHandle , getConstantIntExpr (1 ))
778833 .callBuiltin (" __builtin_hlsl_resource_getpointer" ,
779834 AST.getPointerType (ElemTy), PH::Handle, PH::LastStmt)
780835 .dereference (PH::LastStmt)
@@ -788,7 +843,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
788843 QualType ElemTy = getHandleElementType ();
789844 return BuiltinTypeMethodBuilder (*this , " Consume" , ElemTy)
790845 .callBuiltin (" __builtin_hlsl_buffer_update_counter" , AST.UnsignedIntTy ,
791- PH::Handle , getConstantIntExpr (-1 ))
846+ PH::CounterHandle , getConstantIntExpr (-1 ))
792847 .callBuiltin (" __builtin_hlsl_resource_getpointer" ,
793848 AST.getPointerType (ElemTy), PH::Handle, PH::LastStmt)
794849 .dereference (PH::LastStmt)
0 commit comments