https://github.com/hekota created https://github.com/llvm/llvm-project/pull/155866
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 which is used by the static create methods. >From e5cfb97d26f63942eea3c9353680fa4e669b02e7 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Thu, 28 Aug 2025 08:22:41 -0700 Subject: [PATCH] [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 | 168 ++++++++++++++++-- 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, 353 insertions(+), 23 deletions(-) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 7830cdd18c6cd..2abc3d093f823 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,7 @@ 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 +573,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 +684,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 +698,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 +758,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}} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits