diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index b8591b0fe475a..ecf9cfde8aa72 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" @@ -102,6 +103,13 @@ struct BuiltinTypeMethodBuilder { : NameII(NameII), Ty(Ty), Modifier(Modifier) {} }; + struct LocalVar { + StringRef Name; + QualType Ty; + VarDecl *Decl; + LocalVar(StringRef Name, QualType Ty) : Name(Name), Ty(Ty), Decl(nullptr) {} + }; + BuiltinTypeDeclBuilder &DeclBuilder; DeclarationName Name; QualType ReturnTy; @@ -110,6 +118,7 @@ struct BuiltinTypeMethodBuilder { CXXMethodDecl *Method; bool IsConst; bool IsCtor; + StorageClass SC; llvm::SmallVector Params; llvm::SmallVector StmtsList; @@ -123,6 +132,7 @@ struct BuiltinTypeMethodBuilder { enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128, LastStmt }; Expr *convertPlaceholder(PlaceHolder PH); + Expr *convertPlaceholder(LocalVar &Var); Expr *convertPlaceholder(Expr *E) { return E; } public: @@ -130,13 +140,13 @@ struct BuiltinTypeMethodBuilder { BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, QualType ReturnTy, bool IsConst = false, - bool IsCtor = false) + bool IsCtor = false, StorageClass SC = SC_None) : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr), - IsConst(IsConst), IsCtor(IsCtor) {} + IsConst(IsConst), IsCtor(IsCtor), SC(SC) {} BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr, QualType ReturnTy, bool IsConst = false, - bool IsCtor = false); + bool IsCtor = false, StorageClass SC = SC_None); BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other) = delete; ~BuiltinTypeMethodBuilder() { finalize(); } @@ -147,18 +157,22 @@ struct BuiltinTypeMethodBuilder { BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier = HLSLParamModifierAttr::Keyword_in); + BuiltinTypeMethodBuilder &declareLocalVar(LocalVar &Var); template BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts... ArgSpecs); template BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS); template BuiltinTypeMethodBuilder &dereference(T Ptr); - BuiltinTypeDeclBuilder &finalize(); - Expr *getResourceHandleExpr(); - template - BuiltinTypeMethodBuilder &getResourceHandle(T ResourceRecord); + BuiltinTypeMethodBuilder &accessHandleFieldOnResource(T ResourceRecord); + template + BuiltinTypeMethodBuilder &setHandleFieldOnResource(ResourceT ResourceRecord, + ValueT HandleValue); + template BuiltinTypeMethodBuilder &returnValue(T ReturnValue); BuiltinTypeMethodBuilder &returnThis(); + BuiltinTypeDeclBuilder &finalize(); + Expr *getResourceHandleExpr(); private: void createDecl(); @@ -339,12 +353,22 @@ Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { ParamDecl->getType().getNonReferenceType(), VK_PRValue); } +Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) { + VarDecl *VD = Var.Decl; + assert(VD && "local variable is not declared"); + return DeclRefExpr::Create( + VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD, + false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()), + VD->getType(), VK_LValue); +} + BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr, QualType ReturnTy, - bool IsConst, bool IsCtor) + bool IsConst, bool IsCtor, + StorageClass SC) : DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst), - IsCtor(IsCtor) { + IsCtor(IsCtor), SC(SC) { assert((!NameStr.empty() || IsCtor) && "method needs a name"); assert(((IsCtor && !IsConst) || !IsCtor) && "constructor cannot be const"); @@ -394,10 +418,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 ParmDecls; @@ -435,19 +458,20 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() { OK_Ordinary); } -template BuiltinTypeMethodBuilder & -BuiltinTypeMethodBuilder::getResourceHandle(T ResourceRecord) { +BuiltinTypeMethodBuilder::declareLocalVar(LocalVar &Var) { ensureCompleteDecl(); - Expr *ResourceExpr = convertPlaceholder(ResourceRecord); + assert(Var.Decl == nullptr && "local variable is already declared"); ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); - FieldDecl *HandleField = DeclBuilder.getResourceHandleField(); - MemberExpr *HandleExpr = MemberExpr::CreateImplicit( - AST, ResourceExpr, /*IsArrow=*/false, HandleField, HandleField->getType(), - VK_LValue, OK_Ordinary); - StmtsList.push_back(HandleExpr); + Var.Decl = VarDecl::Create( + AST, Method, SourceLocation(), SourceLocation(), + &AST.Idents.get(Var.Name, tok::TokenKind::identifier), Var.Ty, + AST.getTrivialTypeSourceInfo(Var.Ty, SourceLocation()), SC_None); + DeclStmt *DS = new (AST) clang::DeclStmt(DeclGroupRef(Var.Decl), + SourceLocation(), SourceLocation()); + StmtsList.push_back(DS); return *this; } @@ -464,11 +488,11 @@ template BuiltinTypeMethodBuilder & BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts... ArgSpecs) { + ensureCompleteDecl(); + std::array Args{ convertPlaceholder(std::forward(ArgSpecs))...}; - ensureCompleteDecl(); - ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName); DeclRefExpr *DRE = DeclRefExpr::Create( @@ -512,6 +536,55 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::dereference(T Ptr) { return *this; } +template +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::accessHandleFieldOnResource(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 +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord, + ValueT 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 +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() { assert(!DeclBuilder.Record->isCompleteDefinition() && "record is already complete"); @@ -539,7 +612,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeMethodBuilder::finalize() { Method->setBody(CompoundStmt::Create(AST, StmtsList, FPOptionsOverride(), SourceLocation(), SourceLocation())); Method->setLexicalDeclContext(DeclBuilder.Record); - Method->setAccess(AccessSpecifier::AS_public); + Method->setAccess(AS_public); Method->addAttr(AlwaysInlineAttr::CreateImplicit( AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline)); DeclBuilder.Record->addDecl(Method); @@ -705,6 +778,82 @@ BuiltinTypeDeclBuilder::addHandleConstructorFromImplicitBinding() { .finalize(); } +// Adds static method that initializes resource from binding: +// +// static Resource __createFromBinding(unsigned registerNo, +// unsigned spaceNo, int range, +// unsigned index, const char *name) { +// Resource tmp; +// tmp.__handle = __builtin_hlsl_resource_handlefrombinding( +// tmp.__handle, registerNo, spaceNo, +// range, index, name); +// return tmp; +// } +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(Record)); + BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType); + + return BuiltinTypeMethodBuilder(*this, "__createFromBinding", RecordType, + false, false, 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())) + .declareLocalVar(TmpVar) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType, + PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) + .setHandleFieldOnResource(TmpVar, PH::LastStmt) + .returnValue(TmpVar) + .finalize(); +} + +// Adds static method that initializes resource from binding: +// +// static Resource __createFromImplicitBinding(unsigned orderId, +// unsigned spaceNo, int range, +// unsigned index, +// const char *name) { +// Resource tmp; +// tmp.__handle = __builtin_hlsl_resource_handlefromimplicitbinding( +// tmp.__handle, spaceNo, +// range, index, orderId, name); +// return tmp; +// } +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(Record)); + BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType); + + return BuiltinTypeMethodBuilder(*this, "__createFromImplicitBinding", + RecordType, false, false, 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())) + .declareLocalVar(TmpVar) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, + PH::_4) + .setHandleFieldOnResource(TmpVar, PH::LastStmt) + .returnValue(TmpVar) + .finalize(); +} + BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() { if (Record->isCompleteDefinition()) return *this; @@ -719,7 +868,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() { return BuiltinTypeMethodBuilder(*this, /*Name=*/"", AST.VoidTy, /*IsConst=*/false, /*IsCtor=*/true) .addParam("other", ConstRecordRefType) - .getResourceHandle(PH::_0) + .accessHandleFieldOnResource(PH::_0) .assign(PH::Handle, PH::LastStmt) .finalize(); } @@ -738,7 +887,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() { DeclarationName Name = AST.DeclarationNames.getCXXOperatorName(OO_Equal); return BuiltinTypeMethodBuilder(*this, Name, RecordRefType) .addParam("other", ConstRecordRefType) - .getResourceHandle(PH::_0) + .accessHandleFieldOnResource(PH::_0) .assign(PH::Handle, PH::LastStmt) .returnThis() .finalize(); diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index 4c4c2083a8440..b898417e9fe14 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -83,6 +83,10 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addCopyConstructor(); BuiltinTypeDeclBuilder &addCopyAssignmentOperator(); + // 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 8c893c0c30baf..3386d8da281e9 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -134,6 +134,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, .addDefaultHandleConstructor() .addCopyConstructor() .addCopyAssignmentOperator() + .addCreateFromBinding() + .addCreateFromImplicitBinding() .addHandleConstructorFromBinding() .addHandleConstructorFromImplicitBinding(); } diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index f2a3a74931a6a..8d2e36f4bb7d1 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -82,6 +82,62 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// 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]]' +// 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' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// 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 + +// 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]]' +// 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' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// 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 // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline @@ -130,5 +186,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 23ed410a8efce..52a2c20686c53 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -129,6 +129,62 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// 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]]' +// 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' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// 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 + +// 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]]' +// 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' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// 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 // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] '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 4e3cdeab74b31..95f578947a904 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -104,6 +104,62 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// 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]]' +// 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' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// 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 + +// 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]]' +// 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' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// 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 // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline