https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/155866
>From 7a0d3ca684a2d95e0528d5f4ee77bc1306ddfe1d Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 28 Aug 2025 08:17:31 -0700 Subject: [PATCH 1/4] [HLSL] Reorder the arguments of handle initialization builtins Reorder the arguments of handle initialization builtins to match the order of the llvm intrinsics, and also to match the arguments on the static create methods for resources (coming soon). --- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 8 ++++---- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 2 +- clang/lib/Sema/SemaHLSL.cpp | 4 ++-- clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 2 +- clang/test/AST/HLSL/StructuredBuffers-AST.hlsl | 2 +- clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 58165185b6711..483920f2392cd 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -348,10 +348,10 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, } case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: { llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType()); - Value *SpaceOp = EmitScalarExpr(E->getArg(1)); - Value *RangeOp = EmitScalarExpr(E->getArg(2)); - Value *IndexOp = EmitScalarExpr(E->getArg(3)); - Value *OrderID = EmitScalarExpr(E->getArg(4)); + Value *OrderID = EmitScalarExpr(E->getArg(1)); + Value *SpaceOp = EmitScalarExpr(E->getArg(2)); + Value *RangeOp = EmitScalarExpr(E->getArg(3)); + Value *IndexOp = EmitScalarExpr(E->getArg(4)); Value *Name = EmitScalarExpr(E->getArg(5)); // FIXME: NonUniformResourceIndex bit is not yet implemented // (llvm/llvm-project#135452) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 806800cb7b213..7830cdd18c6cd 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -670,7 +670,7 @@ BuiltinTypeDeclBuilder::addHandleConstructorFromImplicitBinding() { .addParam("orderId", AST.UnsignedIntTy) .addParam("name", AST.getPointerType(AST.CharTy.withConst())) .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", - HandleType, PH::Handle, PH::_0, PH::_1, PH::_2, PH::_3, + HandleType, PH::Handle, PH::_3, PH::_0, PH::_1, PH::_2, PH::_4) .assign(PH::Handle, PH::LastStmt) .finalize(); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 6a68fa2ed7a8b..c12b35308e127 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2853,8 +2853,8 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaRef.checkArgCount(TheCall, 6) || CheckResourceHandle(&SemaRef, TheCall, 0) || CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) || - CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.IntTy) || - CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.UnsignedIntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) || CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy) || CheckArgTypeMatches(&SemaRef, TheCall->getArg(5), AST.getPointerType(AST.CharTy.withConst()))) diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index f85194496942b..90794eb69ef46 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -97,10 +97,10 @@ RESOURCE Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' // CHECK-NEXT: AlwaysInlineAttr diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index 6ee7145c7e538..e028936e397ac 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -144,10 +144,10 @@ RESOURCE<float> Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' // CHECK-NEXT: AlwaysInlineAttr diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index e7f000e9c1b70..02c8cf86c8c8b 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -119,10 +119,10 @@ RESOURCE<float> Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' // CHECK-NEXT: AlwaysInlineAttr >From dcbbda45ce7d3341ad74025a02b3f8c9b0391dc0 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 28 Aug 2025 08:22:41 -0700 Subject: [PATCH 2/4] [HLSL] Add static methods for resource initialization and a constructor from handle Adds static methods `__createFromBinding` and `__createFromImplicitBinding` to resource classes. These methods will be used for resource initialization instead of the resource constructors that take binding information. Also adds a private resource constructor that takes an initialized resource handle. This constructor will be called from the static create methods. --- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 169 ++++++++++++++++-- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 9 +- clang/lib/Sema/HLSLExternalSemaSource.cpp | 5 +- .../test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 67 ++++++- .../test/AST/HLSL/StructuredBuffers-AST.hlsl | 63 +++++++ clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 63 +++++++ clang/test/SemaHLSL/Language/InitLists.hlsl | 1 + 7 files changed, 354 insertions(+), 23 deletions(-) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 7830cdd18c6cd..4eac9043dab86 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -19,6 +19,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaHLSL.h" @@ -110,8 +111,11 @@ struct BuiltinTypeMethodBuilder { CXXMethodDecl *Method; bool IsConst; bool IsCtor; + AccessSpecifier Access; + StorageClass SC; llvm::SmallVector<Param> Params; llvm::SmallVector<Stmt *> StmtsList; + llvm::SmallVector<VarDecl *> LocalVars; // Argument placeholders, inspired by std::placeholder. These are the indices // of arguments to forward to `callBuiltin` and other method builder methods. @@ -120,7 +124,16 @@ struct BuiltinTypeMethodBuilder { // LastStmt - refers to the last statement in the method body; referencing // LastStmt will remove the statement from the method body since // it will be linked from the new expression being constructed. - enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128, LastStmt }; + enum class PlaceHolder { + _0, + _1, + _2, + _3, + _4, + LocalVar_0 = 64, + Handle = 128, + LastStmt + }; Expr *convertPlaceholder(PlaceHolder PH); Expr *convertPlaceholder(Expr *E) { return E; } @@ -130,13 +143,17 @@ struct BuiltinTypeMethodBuilder { BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, QualType ReturnTy, bool IsConst = false, - bool IsCtor = false) + bool IsCtor = false, + AccessSpecifier Access = AS_public, + StorageClass SC = SC_None) : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr), - IsConst(IsConst), IsCtor(IsCtor) {} + IsConst(IsConst), IsCtor(IsCtor), Access(Access), SC(SC) {} BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr, QualType ReturnTy, bool IsConst = false, - bool IsCtor = false); + bool IsCtor = false, + AccessSpecifier Access = AS_public, + StorageClass SC = SC_None); BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other) = delete; ~BuiltinTypeMethodBuilder() { finalize(); } @@ -147,13 +164,15 @@ struct BuiltinTypeMethodBuilder { BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier = HLSLParamModifierAttr::Keyword_in); + BuiltinTypeMethodBuilder &createLocalVar(StringRef Name, QualType Ty); template <typename... Ts> BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts... ArgSpecs); + template <typename T> BuiltinTypeMethodBuilder &callHandleCtor(T HandleExpr); template <typename TLHS, typename TRHS> BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS); template <typename T> BuiltinTypeMethodBuilder &dereference(T Ptr); - BuiltinTypeDeclBuilder &finalize(); + BuiltinTypeDeclBuilder &finalize(CXXMethodDecl **OutMethod = nullptr); Expr *getResourceHandleExpr(); private: @@ -328,6 +347,17 @@ Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { } ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + if (PH >= PlaceHolder::LocalVar_0) { + unsigned Index = static_cast<unsigned>(PH) - + static_cast<unsigned>(PlaceHolder::LocalVar_0); + assert(Index < LocalVars.size() && "local var index out of range"); + VarDecl *VD = LocalVars[Index]; + return DeclRefExpr::Create( + AST, NestedNameSpecifierLoc(), SourceLocation(), VD, false, + DeclarationNameInfo(VD->getDeclName(), SourceLocation()), VD->getType(), + VK_LValue); + } + ParmVarDecl *ParamDecl = Method->getParamDecl(static_cast<unsigned>(PH)); return DeclRefExpr::Create( AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl, false, @@ -335,12 +365,11 @@ Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { ParamDecl->getType(), VK_PRValue); } -BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, - StringRef NameStr, - QualType ReturnTy, - bool IsConst, bool IsCtor) +BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder( + BuiltinTypeDeclBuilder &DB, StringRef NameStr, QualType ReturnTy, + bool IsConst, bool IsCtor, AccessSpecifier Access, StorageClass SC) : DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst), - IsCtor(IsCtor) { + IsCtor(IsCtor), Access(Access), SC(SC) { assert((!NameStr.empty() || IsCtor) && "method needs a name"); assert(((IsCtor && !IsConst) || !IsCtor) && "constructor cannot be const"); @@ -390,10 +419,9 @@ void BuiltinTypeMethodBuilder::createDecl() { ExplicitSpecifier(), false, true, false, ConstexprSpecKind::Unspecified); else - Method = - CXXMethodDecl::Create(AST, DeclBuilder.Record, SourceLocation(), - NameInfo, FuncTy, TSInfo, SC_None, false, false, - ConstexprSpecKind::Unspecified, SourceLocation()); + Method = CXXMethodDecl::Create( + AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC, + false, false, ConstexprSpecKind::Unspecified, SourceLocation()); // create params & set them to the function prototype SmallVector<ParmVarDecl *> ParmDecls; @@ -431,15 +459,31 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() { OK_Ordinary); } +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::createLocalVar(StringRef Name, QualType Ty) { + ensureCompleteDecl(); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + VarDecl *VD = + VarDecl::Create(AST, Method, SourceLocation(), SourceLocation(), + &AST.Idents.get(Name, tok::TokenKind::identifier), Ty, + AST.getTrivialTypeSourceInfo(Ty), SC_None); + LocalVars.push_back(VD); + DeclStmt *DS = new (AST) + clang::DeclStmt(DeclGroupRef(VD), SourceLocation(), SourceLocation()); + StmtsList.push_back(DS); + return *this; +} + template <typename... Ts> BuiltinTypeMethodBuilder & BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts... ArgSpecs) { + ensureCompleteDecl(); + std::array<Expr *, sizeof...(ArgSpecs)> Args{ convertPlaceholder(std::forward<Ts>(ArgSpecs))...}; - ensureCompleteDecl(); - ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName); DeclRefExpr *DRE = DeclRefExpr::Create( @@ -459,6 +503,25 @@ BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName, return *this; } +template <typename T> +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::callHandleCtor(T Handle) { + ensureCompleteDecl(); + + Expr *HandleExpr = convertPlaceholder(Handle); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(DeclBuilder.Record)); + CXXConstructorDecl *Ctor = DeclBuilder.HandleCtor; + assert(Ctor && "Handle constructor not created"); + + CXXConstructExpr *CtorExpr = CXXConstructExpr::Create( + AST, RecordType, SourceLocation(), Ctor, false, {HandleExpr}, false, + false, false, false, CXXConstructionKind::Complete, SourceRange()); + + StmtsList.push_back(CtorExpr); + return *this; +} + template <typename TLHS, typename TRHS> BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::assign(TLHS LHS, TRHS RHS) { Expr *LHSExpr = convertPlaceholder(LHS); @@ -483,7 +546,8 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::dereference(T Ptr) { return *this; } -BuiltinTypeDeclBuilder &BuiltinTypeMethodBuilder::finalize() { +BuiltinTypeDeclBuilder & +BuiltinTypeMethodBuilder::finalize(CXXMethodDecl **OutMethod) { assert(!DeclBuilder.Record->isCompleteDefinition() && "record is already complete"); @@ -510,11 +574,13 @@ BuiltinTypeDeclBuilder &BuiltinTypeMethodBuilder::finalize() { Method->setBody(CompoundStmt::Create(AST, StmtsList, FPOptionsOverride(), SourceLocation(), SourceLocation())); Method->setLexicalDeclContext(DeclBuilder.Record); - Method->setAccess(AccessSpecifier::AS_public); + Method->setAccess(Access); Method->addAttr(AlwaysInlineAttr::CreateImplicit( AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline)); DeclBuilder.Record->addDecl(Method); } + if (OutMethod) + *OutMethod = Method; return DeclBuilder; } @@ -619,7 +685,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember( // Adds default constructor to the resource class: // Resource::Resource() -BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() { +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultConstructor() { if (Record->isCompleteDefinition()) return *this; @@ -633,6 +699,23 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() { .finalize(); } +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleConstructor() { + if (Record->isCompleteDefinition()) + return *this; + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + CXXMethodDecl *OutMethod = nullptr; + + BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true, AS_public) + .addParam("handle", HandleType) + .assign(PH::Handle, PH::_0) + .finalize(&OutMethod); + HandleCtor = cast<CXXConstructorDecl>(OutMethod); + return *this; +} + BuiltinTypeDeclBuilder & BuiltinTypeDeclBuilder::addHandleConstructorFromBinding() { if (Record->isCompleteDefinition()) @@ -676,6 +759,54 @@ BuiltinTypeDeclBuilder::addHandleConstructorFromImplicitBinding() { .finalize(); } +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCreateFromBinding() { + if (Record->isCompleteDefinition()) + return *this; + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record)); + + return BuiltinTypeMethodBuilder(*this, "__createFromBinding", RecordType, + false, false, AS_public, SC_Static) + .addParam("registerNo", AST.UnsignedIntTy) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("name", AST.getPointerType(AST.CharTy.withConst())) + .createLocalVar("tmp", HandleType) + .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType, + PH::LocalVar_0, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) + .callHandleCtor(PH::LastStmt) + .finalize(); +} + +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCreateFromImplicitBinding() { + if (Record->isCompleteDefinition()) + return *this; + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record)); + + return BuiltinTypeMethodBuilder(*this, "__createFromImplicitBinding", + RecordType, false, false, AS_public, + SC_Static) + .addParam("orderId", AST.UnsignedIntTy) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("name", AST.getPointerType(AST.CharTy.withConst())) + .createLocalVar("tmp", HandleType) + .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", + HandleType, PH::LocalVar_0, PH::_0, PH::_1, PH::_2, PH::_3, + PH::_4) + .callHandleCtor(PH::LastStmt) + .finalize(); +} + BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() { ASTContext &AST = Record->getASTContext(); DeclarationName Subscript = diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index 098b72692bd3a..be67e150775e2 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -25,6 +25,7 @@ namespace clang { class ClassTemplateDecl; class NamespaceDecl; class CXXRecordDecl; +class CXXConstructorDecl; class FieldDecl; namespace hlsl { @@ -52,6 +53,7 @@ class BuiltinTypeDeclBuilder { ClassTemplateDecl *PrevTemplate = nullptr; NamespaceDecl *HLSLNamespace = nullptr; llvm::StringMap<FieldDecl *> Fields; + CXXConstructorDecl *HandleCtor = nullptr; public: friend struct TemplateParameterListBuilder; @@ -77,10 +79,15 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addArraySubscriptOperators(); // Builtin types constructors - BuiltinTypeDeclBuilder &addDefaultHandleConstructor(); + BuiltinTypeDeclBuilder &addDefaultConstructor(); + BuiltinTypeDeclBuilder &addHandleConstructor(); BuiltinTypeDeclBuilder &addHandleConstructorFromBinding(); BuiltinTypeDeclBuilder &addHandleConstructorFromImplicitBinding(); + // Static create methods + BuiltinTypeDeclBuilder &addCreateFromBinding(); + BuiltinTypeDeclBuilder &addCreateFromImplicitBinding(); + // Builtin types methods BuiltinTypeDeclBuilder &addLoadMethods(); BuiltinTypeDeclBuilder &addIncrementCounterMethod(); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 726581d131623..17843c4e6c751 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -131,7 +131,10 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, bool RawBuffer) { return BuiltinTypeDeclBuilder(S, Decl) .addHandleMember(RC, IsROV, RawBuffer) - .addDefaultHandleConstructor() + .addDefaultConstructor() + .addHandleConstructor() + .addCreateFromBinding() + .addCreateFromImplicitBinding() .addHandleConstructorFromBinding() .addHandleConstructorFromImplicitBinding(); } diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index 90794eb69ef46..8336bf00ed4cb 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -56,6 +56,69 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// Constructor from handle + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (__hlsl_resource_t +// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]] +// CHECK-SAME: )' inline +// CHECK-NEXT: ParmVarDecl {{.*}} handle '__hlsl_resource_t +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' ParmVar {{.*}} 'handle' '__hlsl_resource_t {{.*}} +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// Static __createFromBinding method + +// CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ReturnStmt {{.*}} +// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// Static __createFromImplicitBinding method + +// CHECK: CXXMethodDecl {{.*}} __createFromImplicitBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-NEXT: ParmVarDecl {{.*}} orderId 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: DeclStmt {{.*}} +// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ReturnStmt {{.*}} +// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + // Constructor from binding // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline @@ -104,5 +167,5 @@ RESOURCE Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' // CHECK-NEXT: AlwaysInlineAttr -// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const element_type &(unsigned int) const' -// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'element_type &(unsigned int)' +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const char8_t &(unsigned int) const' +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'char8_t &(unsigned int)' diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index e028936e397ac..ad481ca68b248 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -103,6 +103,69 @@ RESOURCE<float> Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// Constructor from handle +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (__hlsl_resource_t +// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME: )' inline +// CHECK-NEXT: ParmVarDecl {{.*}} handle '__hlsl_resource_t +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' ParmVar {{.*}} 'handle' '__hlsl_resource_t {{.*}} +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// Static __createFromBinding method + +// CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]]<element_type> (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ReturnStmt {{.*}} +// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// Static __createFromImplicitBinding method + +// CHECK: CXXMethodDecl {{.*}} __createFromImplicitBinding 'hlsl::[[RESOURCE]]<element_type> (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-NEXT: ParmVarDecl {{.*}} orderId 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: DeclStmt {{.*}} +// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ReturnStmt {{.*}} +// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + // Constructor from binding // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index 02c8cf86c8c8b..3484d088eb17a 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -78,6 +78,69 @@ RESOURCE<float> Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// Constructor from handle + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (__hlsl_resource_t +// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME: )' inline +// CHECK-NEXT: ParmVarDecl {{.*}} handle '__hlsl_resource_t +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' ParmVar {{.*}} 'handle' '__hlsl_resource_t {{.*}} +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// Static __createFromBinding method + +// CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]]<element_type> (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ReturnStmt {{.*}} +// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// Static __createFromImplicitBinding method + +// CHECK: CXXMethodDecl {{.*}} __createFromImplicitBinding 'hlsl::[[RESOURCE]]<element_type> (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-NEXT: ParmVarDecl {{.*}} orderId 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: DeclStmt {{.*}} +// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ReturnStmt {{.*}} +// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + // Constructor from binding // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline diff --git a/clang/test/SemaHLSL/Language/InitLists.hlsl b/clang/test/SemaHLSL/Language/InitLists.hlsl index 3607dfd8aedbc..524f6ac220092 100644 --- a/clang/test/SemaHLSL/Language/InitLists.hlsl +++ b/clang/test/SemaHLSL/Language/InitLists.hlsl @@ -124,3 +124,4 @@ void Err2(RWBuffer<float4> B) { // These notes refer to the RWBuffer constructors that do not have source locations // expected-note@*{{candidate constructor (the implicit copy constructor) not viable}} // expected-note@*{{candidate constructor (the implicit move constructor) not viable}} +// expected-note@*{{candidate constructor not viable}} >From dfc07bd4df196ac59cb2ec1a0620fc7840534a77 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Wed, 3 Sep 2025 17:55:11 -0700 Subject: [PATCH 3/4] Remove handle constructor, update create methods body and expected AST structure --- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 102 ++++++++++-------- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 1 - clang/lib/Sema/HLSLExternalSemaSource.cpp | 1 - .../test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 39 +++---- .../test/AST/HLSL/StructuredBuffers-AST.hlsl | 39 +++---- clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 39 +++---- clang/test/SemaHLSL/Language/InitLists.hlsl | 1 - 7 files changed, 107 insertions(+), 115 deletions(-) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 4eac9043dab86..d635664b449c2 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -168,10 +168,13 @@ struct BuiltinTypeMethodBuilder { template <typename... Ts> BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts... ArgSpecs); - template <typename T> BuiltinTypeMethodBuilder &callHandleCtor(T HandleExpr); template <typename TLHS, typename TRHS> BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS); template <typename T> BuiltinTypeMethodBuilder &dereference(T Ptr); + template <typename T> BuiltinTypeMethodBuilder &getResourceHandle(T ResourceRecord); + template <typename TResource, typename TValue> + BuiltinTypeMethodBuilder &setHandleFieldOnResource(TResource ResourceRecord, TValue HandleValue); + template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue); BuiltinTypeDeclBuilder &finalize(CXXMethodDecl **OutMethod = nullptr); Expr *getResourceHandleExpr(); @@ -503,25 +506,6 @@ BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName, return *this; } -template <typename T> -BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::callHandleCtor(T Handle) { - ensureCompleteDecl(); - - Expr *HandleExpr = convertPlaceholder(Handle); - - ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); - QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(DeclBuilder.Record)); - CXXConstructorDecl *Ctor = DeclBuilder.HandleCtor; - assert(Ctor && "Handle constructor not created"); - - CXXConstructExpr *CtorExpr = CXXConstructExpr::Create( - AST, RecordType, SourceLocation(), Ctor, false, {HandleExpr}, false, - false, false, false, CXXConstructionKind::Complete, SourceRange()); - - StmtsList.push_back(CtorExpr); - return *this; -} - template <typename TLHS, typename TRHS> BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::assign(TLHS LHS, TRHS RHS) { Expr *LHSExpr = convertPlaceholder(LHS); @@ -546,6 +530,51 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::dereference(T Ptr) { return *this; } +template <typename T> +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::getResourceHandle(T ResourceRecord) { + ensureCompleteDecl(); + + Expr *ResourceExpr = convertPlaceholder(ResourceRecord); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + FieldDecl *HandleField = DeclBuilder.getResourceHandleField(); + MemberExpr *HandleExpr = MemberExpr::CreateImplicit( + AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue, + OK_Ordinary); + StmtsList.push_back(HandleExpr); + return *this; +} + +template <typename TResource, typename TValue> +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::setHandleFieldOnResource(TResource ResourceRecord, TValue HandleValue) { + ensureCompleteDecl(); + + Expr *ResourceExpr = convertPlaceholder(ResourceRecord); + Expr *HandleValueExpr = convertPlaceholder(HandleValue); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + FieldDecl *HandleField = DeclBuilder.getResourceHandleField(); + MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit( + AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue, + OK_Ordinary); + Stmt *AssignStmt = BinaryOperator::Create( + DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr, BO_Assign, + HandleMemberExpr->getType(), ExprValueKind::VK_PRValue, + ExprObjectKind::OK_Ordinary, SourceLocation(), FPOptionsOverride()); + StmtsList.push_back(AssignStmt); + return *this; +} + +template <typename T> +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) { + ensureCompleteDecl(); + + Expr *ReturnValueExpr = convertPlaceholder(ReturnValue); + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + StmtsList.push_back(ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr)); + return *this; +} + BuiltinTypeDeclBuilder & BuiltinTypeMethodBuilder::finalize(CXXMethodDecl **OutMethod) { assert(!DeclBuilder.Record->isCompleteDefinition() && @@ -699,23 +728,6 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultConstructor() { .finalize(); } -BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleConstructor() { - if (Record->isCompleteDefinition()) - return *this; - - using PH = BuiltinTypeMethodBuilder::PlaceHolder; - ASTContext &AST = SemaRef.getASTContext(); - QualType HandleType = getResourceHandleField()->getType(); - CXXMethodDecl *OutMethod = nullptr; - - BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true, AS_public) - .addParam("handle", HandleType) - .assign(PH::Handle, PH::_0) - .finalize(&OutMethod); - HandleCtor = cast<CXXConstructorDecl>(OutMethod); - return *this; -} - BuiltinTypeDeclBuilder & BuiltinTypeDeclBuilder::addHandleConstructorFromBinding() { if (Record->isCompleteDefinition()) @@ -775,10 +787,12 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCreateFromBinding() { .addParam("range", AST.IntTy) .addParam("index", AST.UnsignedIntTy) .addParam("name", AST.getPointerType(AST.CharTy.withConst())) - .createLocalVar("tmp", HandleType) + .createLocalVar("tmp", RecordType) + .getResourceHandle(PH::LocalVar_0) .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType, - PH::LocalVar_0, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) - .callHandleCtor(PH::LastStmt) + PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) + .setHandleFieldOnResource(PH::LocalVar_0, PH::LastStmt) + .returnValue(PH::LocalVar_0) .finalize(); } @@ -799,11 +813,13 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCreateFromImplicitBinding() { .addParam("range", AST.IntTy) .addParam("index", AST.UnsignedIntTy) .addParam("name", AST.getPointerType(AST.CharTy.withConst())) - .createLocalVar("tmp", HandleType) + .createLocalVar("tmp", RecordType) + .getResourceHandle(PH::LocalVar_0) .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", - HandleType, PH::LocalVar_0, PH::_0, PH::_1, PH::_2, PH::_3, + HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) - .callHandleCtor(PH::LastStmt) + .setHandleFieldOnResource(PH::LocalVar_0, PH::LastStmt) + .returnValue(PH::LocalVar_0) .finalize(); } diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index be67e150775e2..f38bbd63b2ac1 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -80,7 +80,6 @@ class BuiltinTypeDeclBuilder { // Builtin types constructors BuiltinTypeDeclBuilder &addDefaultConstructor(); - BuiltinTypeDeclBuilder &addHandleConstructor(); BuiltinTypeDeclBuilder &addHandleConstructorFromBinding(); BuiltinTypeDeclBuilder &addHandleConstructorFromImplicitBinding(); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 17843c4e6c751..cfc222af45f8c 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -132,7 +132,6 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, return BuiltinTypeDeclBuilder(S, Decl) .addHandleMember(RC, IsROV, RawBuffer) .addDefaultConstructor() - .addHandleConstructor() .addCreateFromBinding() .addCreateFromImplicitBinding() .addHandleConstructorFromBinding() diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index 8336bf00ed4cb..1fef4901d7404 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -56,21 +56,6 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr -// Constructor from handle - -// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (__hlsl_resource_t -// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] -// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]] -// CHECK-SAME: )' inline -// CHECK-NEXT: ParmVarDecl {{.*}} handle '__hlsl_resource_t -// CHECK-NEXT: CompoundStmt {{.*}} -// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}} '=' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}} lvalue .__handle -// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' ParmVar {{.*}} 'handle' '__hlsl_resource_t {{.*}} -// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline - // Static __createFromBinding method // CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static @@ -81,18 +66,22 @@ RESOURCE Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt -// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ReturnStmt {{.*}} -// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Static __createFromImplicitBinding method @@ -105,18 +94,22 @@ RESOURCE Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' // CHECK-NEXT: CompoundStmt {{.*}} // CHECK-NEXT: DeclStmt {{.*}} -// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ReturnStmt {{.*}} -// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Constructor from binding diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index ad481ca68b248..798af6232b124 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -103,21 +103,6 @@ RESOURCE<float> Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr -// Constructor from handle -// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (__hlsl_resource_t -// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] -// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SAME: )' inline -// CHECK-NEXT: ParmVarDecl {{.*}} handle '__hlsl_resource_t -// CHECK-NEXT: CompoundStmt {{.*}} -// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}} '=' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}} lvalue .__handle -// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' ParmVar {{.*}} 'handle' '__hlsl_resource_t {{.*}} -// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline - // Static __createFromBinding method // CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]]<element_type> (unsigned int, unsigned int, int, unsigned int, const char *)' static @@ -128,18 +113,22 @@ RESOURCE<float> Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt -// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ReturnStmt {{.*}} -// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]<element_type>' +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Static __createFromImplicitBinding method @@ -152,18 +141,22 @@ RESOURCE<float> Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' // CHECK-NEXT: CompoundStmt {{.*}} // CHECK-NEXT: DeclStmt {{.*}} -// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ReturnStmt {{.*}} -// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]<element_type>' +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Constructor from binding diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index 3484d088eb17a..cc3d9cc399499 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -78,21 +78,6 @@ RESOURCE<float> Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr -// Constructor from handle - -// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (__hlsl_resource_t -// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] -// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SAME: )' inline -// CHECK-NEXT: ParmVarDecl {{.*}} handle '__hlsl_resource_t -// CHECK-NEXT: CompoundStmt {{.*}} -// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}} '=' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}} lvalue .__handle -// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' ParmVar {{.*}} 'handle' '__hlsl_resource_t {{.*}} -// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline - // Static __createFromBinding method // CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]]<element_type> (unsigned int, unsigned int, int, unsigned int, const char *)' static @@ -103,18 +88,22 @@ RESOURCE<float> Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt -// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ReturnStmt {{.*}} -// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]<element_type>' +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Static __createFromImplicitBinding method @@ -127,18 +116,22 @@ RESOURCE<float> Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' // CHECK-NEXT: CompoundStmt {{.*}} // CHECK-NEXT: DeclStmt {{.*}} -// CHECK-NEXT: VarDecl {{.*}} tmp '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ReturnStmt {{.*}} -// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 'void (__hlsl_resource_t {{.*}})' +// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]<element_type>' +// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue Var {{.*}} 'tmp' '__hlsl_resource_t {{.*}}' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Constructor from binding diff --git a/clang/test/SemaHLSL/Language/InitLists.hlsl b/clang/test/SemaHLSL/Language/InitLists.hlsl index 524f6ac220092..3607dfd8aedbc 100644 --- a/clang/test/SemaHLSL/Language/InitLists.hlsl +++ b/clang/test/SemaHLSL/Language/InitLists.hlsl @@ -124,4 +124,3 @@ void Err2(RWBuffer<float4> B) { // These notes refer to the RWBuffer constructors that do not have source locations // expected-note@*{{candidate constructor (the implicit copy constructor) not viable}} // expected-note@*{{candidate constructor (the implicit move constructor) not viable}} -// expected-note@*{{candidate constructor not viable}} >From e7641e13fb3f85e8978a7f4c25847e0fd817ace9 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Wed, 3 Sep 2025 18:56:32 -0700 Subject: [PATCH 4/4] cleanup --- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 8 +++----- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 4 +--- clang/lib/Sema/HLSLExternalSemaSource.cpp | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index d635664b449c2..3ccda084f3813 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -175,7 +175,7 @@ struct BuiltinTypeMethodBuilder { template <typename TResource, typename TValue> BuiltinTypeMethodBuilder &setHandleFieldOnResource(TResource ResourceRecord, TValue HandleValue); template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue); - BuiltinTypeDeclBuilder &finalize(CXXMethodDecl **OutMethod = nullptr); + BuiltinTypeDeclBuilder &finalize(); Expr *getResourceHandleExpr(); private: @@ -576,7 +576,7 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) { } BuiltinTypeDeclBuilder & -BuiltinTypeMethodBuilder::finalize(CXXMethodDecl **OutMethod) { +BuiltinTypeMethodBuilder::finalize() { assert(!DeclBuilder.Record->isCompleteDefinition() && "record is already complete"); @@ -608,8 +608,6 @@ BuiltinTypeMethodBuilder::finalize(CXXMethodDecl **OutMethod) { AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline)); DeclBuilder.Record->addDecl(Method); } - if (OutMethod) - *OutMethod = Method; return DeclBuilder; } @@ -714,7 +712,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember( // Adds default constructor to the resource class: // Resource::Resource() -BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultConstructor() { +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() { if (Record->isCompleteDefinition()) return *this; diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index f38bbd63b2ac1..ba860a9080cea 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -25,7 +25,6 @@ namespace clang { class ClassTemplateDecl; class NamespaceDecl; class CXXRecordDecl; -class CXXConstructorDecl; class FieldDecl; namespace hlsl { @@ -53,7 +52,6 @@ class BuiltinTypeDeclBuilder { ClassTemplateDecl *PrevTemplate = nullptr; NamespaceDecl *HLSLNamespace = nullptr; llvm::StringMap<FieldDecl *> Fields; - CXXConstructorDecl *HandleCtor = nullptr; public: friend struct TemplateParameterListBuilder; @@ -79,7 +77,7 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addArraySubscriptOperators(); // Builtin types constructors - BuiltinTypeDeclBuilder &addDefaultConstructor(); + BuiltinTypeDeclBuilder &addDefaultHandleConstructor(); BuiltinTypeDeclBuilder &addHandleConstructorFromBinding(); BuiltinTypeDeclBuilder &addHandleConstructorFromImplicitBinding(); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index cfc222af45f8c..a5d51ca7d35be 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -131,7 +131,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, bool RawBuffer) { return BuiltinTypeDeclBuilder(S, Decl) .addHandleMember(RC, IsROV, RawBuffer) - .addDefaultConstructor() + .addDefaultHandleConstructor() .addCreateFromBinding() .addCreateFromImplicitBinding() .addHandleConstructorFromBinding() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits