https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/116413
>From 92ccbe72ca95ad2df5a81b76244a8a8d7cedef40 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 15 Nov 2024 09:00:15 -0800 Subject: [PATCH 1/3] update new tests --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 210 +++++++++++++++++- .../AST/HLSL/AppendStructuredBuffer-AST.hlsl | 4 +- .../AST/HLSL/ConsumeStructuredBuffer-AST.hlsl | 4 +- clang/test/AST/HLSL/RWBuffer-AST.hlsl | 22 +- .../test/AST/HLSL/RWStructuredBuffer-AST.hlsl | 4 +- ...RasterizerOrderedStructuredBuffer-AST.hlsl | 4 +- clang/test/AST/HLSL/StructuredBuffer-AST.hlsl | 4 +- ...d_resource_element_compatible_concept.hlsl | 10 + clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl | 16 +- .../SemaHLSL/BuiltIns/StructuredBuffers.hlsl | 4 +- 10 files changed, 253 insertions(+), 29 deletions(-) create mode 100644 clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index cac15b974a276e..400d3334f6f0de 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -289,8 +289,9 @@ struct BuiltinTypeDeclBuilder { } TemplateParameterListBuilder addTemplateArgumentList(Sema &S); - BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S, - ArrayRef<StringRef> Names); + BuiltinTypeDeclBuilder & + addSimpleTemplateParams(Sema &S, ArrayRef<StringRef> Names, ConceptDecl *CD); + BuiltinTypeDeclBuilder &addConceptSpecializationExpr(Sema &S); }; struct TemplateParameterListBuilder { @@ -312,8 +313,9 @@ struct TemplateParameterListBuilder { S.Context, Builder.Record->getDeclContext(), SourceLocation(), SourceLocation(), /* TemplateDepth */ 0, Position, &S.Context.Idents.get(Name, tok::TokenKind::identifier), - /* Typename */ false, - /* ParameterPack */ false); + /* Typename */ true, + /* ParameterPack */ false, + /* HasTypeConstraint*/ false); if (!DefaultValue.isNull()) Decl->setDefaultArgument( S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), @@ -323,19 +325,114 @@ struct TemplateParameterListBuilder { return *this; } - BuiltinTypeDeclBuilder &finalizeTemplateArgs() { + /* +The concept specialization expression (CSE) constructed in +constructConceptSpecializationExpr is constructed so that it +matches the CSE that is constructed when parsing the below C++ code: +template<typename T> +concept is_typed_resource_element_compatible = sizeof(T) <= 16; +template<typename element_type> requires +is_typed_resource_element_compatible<element_type> +struct RWBuffer { + element_type Val; +}; +int fn() { + RWBuffer<int> Buf; +} +When dumping the AST and filtering for "RWBuffer", the resulting AST +structure is what we're trying to construct below, specifically the +CSE portion. +*/ + ConceptSpecializationExpr * + constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD) { + ASTContext &Context = S.getASTContext(); + SourceLocation Loc = Builder.Record->getBeginLoc(); + DeclarationNameInfo DNI(CD->getDeclName(), Loc); + NestedNameSpecifierLoc NNSLoc; + DeclContext *DC = Builder.Record->getDeclContext(); + TemplateArgumentListInfo TALI(Loc, Loc); + + // Assume that the concept decl has just one template parameter + // This parameter should have been added when CD was constructed + // in getTypedBufferConceptDecl + assert(CD->getTemplateParameters()->size() == 1 && + "unexpected concept decl parameter count"); + TemplateTypeParmDecl *ConceptTTPD = dyn_cast<TemplateTypeParmDecl>( + CD->getTemplateParameters()->getParam(0)); + + // this TemplateTypeParmDecl is the template for the resource, and is + // used to construct a template argumentthat will be used + // to construct the ImplicitConceptSpecializationDecl + TemplateTypeParmDecl *T = TemplateTypeParmDecl::Create( + Context, // AST context + Builder.Record->getDeclContext(), // DeclContext + SourceLocation(), SourceLocation(), + /*depth=*/0, // Depth in the template parameter list + /*position=*/0, // Position in the template parameter list + /*id=*/nullptr, // Identifier for 'T' + /*Typename=*/true, // Indicates this is a 'typename' or 'class' + /*ParameterPack=*/false, // Not a parameter pack + /*HasTypeConstraint=*/false // Has no type constraint + ); + + T->setDeclContext(DC); + + QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD); + + // this is the 2nd template argument node, on which + // the concept constraint is actually being applied: 'element_type' + TemplateArgument ConceptTA = TemplateArgument(ConceptTType); + + QualType CSETType = Context.getTypeDeclType(T); + + // this is the 1st template argument node, which represents + // the abstract type that a concept would refer to: 'T' + TemplateArgument CSETA = TemplateArgument(CSETType); + + ImplicitConceptSpecializationDecl *ImplicitCSEDecl = + ImplicitConceptSpecializationDecl::Create( + Context, Builder.Record->getDeclContext(), Loc, {CSETA}); + + // Constraint satisfaction is used to construct the + // ConceptSpecailizationExpr, and represents the 2nd Template Argument, + // located at the bottom of the sample AST above. + const ConstraintSatisfaction CS(CD, {ConceptTA}); + TemplateArgumentLoc TAL = S.getTrivialTemplateArgumentLoc( + ConceptTA, QualType(), SourceLocation()); + + TALI.addArgument(TAL); + const ASTTemplateArgumentListInfo *ATALI = + ASTTemplateArgumentListInfo::Create(Context, TALI); + + // In the concept reference, ATALI is what adds the extra + // TemplateArgument node underneath CSE + ConceptReference *CR = + ConceptReference::Create(Context, NNSLoc, Loc, DNI, CD, CD, ATALI); + + ConceptSpecializationExpr *CSE = + ConceptSpecializationExpr::Create(Context, CR, ImplicitCSEDecl, &CS); + + return CSE; + } + + BuiltinTypeDeclBuilder &finalizeTemplateArgs(ConceptDecl *CD = nullptr) { if (Params.empty()) return Builder; + ConceptSpecializationExpr *CSE = + CD ? constructConceptSpecializationExpr(S, CD) : nullptr; + auto *ParamList = TemplateParameterList::Create(S.Context, SourceLocation(), SourceLocation(), Params, - SourceLocation(), nullptr); + SourceLocation(), CSE); Builder.Template = ClassTemplateDecl::Create( S.Context, Builder.Record->getDeclContext(), SourceLocation(), DeclarationName(Builder.Record->getIdentifier()), ParamList, Builder.Record); + Builder.Record->setDescribedClassTemplate(Builder.Template); Builder.Template->setImplicit(true); Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext()); + // NOTE: setPreviousDecl before addDecl so new decl replace old decl when // make visible. Builder.Template->setPreviousDecl(Builder.PrevTemplate); @@ -355,13 +452,12 @@ BuiltinTypeDeclBuilder::addTemplateArgumentList(Sema &S) { return TemplateParameterListBuilder(S, *this); } -BuiltinTypeDeclBuilder & -BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, - ArrayRef<StringRef> Names) { +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addSimpleTemplateParams( + Sema &S, ArrayRef<StringRef> Names, ConceptDecl *CD = nullptr) { TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) Builder.addTypeParameter(Name); - return Builder.finalizeTemplateArgs(); + return Builder.finalizeTemplateArgs(CD); } HLSLExternalSemaSource::~HLSLExternalSemaSource() {} @@ -472,10 +568,102 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, .addDefaultHandleConstructor(S); } +BinaryOperator *constructSizeOfLEQ16Expr(ASTContext &Context, + SourceLocation NameLoc, + TemplateTypeParmDecl *T) { + // Obtain the QualType for 'unsigned long' + QualType UnsignedLongType = Context.UnsignedLongTy; + + // Create a QualType that points to this TemplateTypeParmDecl + QualType TType = Context.getTypeDeclType(T); + + // Create a TypeSourceInfo for the template type parameter 'T' + TypeSourceInfo *TTypeSourceInfo = + Context.getTrivialTypeSourceInfo(TType, NameLoc); + + UnaryExprOrTypeTraitExpr *sizeOfExpr = new (Context) UnaryExprOrTypeTraitExpr( + UETT_SizeOf, TTypeSourceInfo, UnsignedLongType, NameLoc, NameLoc); + + // Create an IntegerLiteral for the value '16' with size type + QualType SizeType = Context.getSizeType(); + llvm::APInt SizeValue = llvm::APInt(Context.getTypeSize(SizeType), 16); + IntegerLiteral *SizeLiteral = + new (Context) IntegerLiteral(Context, SizeValue, SizeType, NameLoc); + + QualType BoolTy = Context.BoolTy; + + BinaryOperator *binaryOperator = + BinaryOperator::Create(Context, sizeOfExpr, // Left-hand side expression + SizeLiteral, // Right-hand side expression + BO_LE, // Binary operator kind (<=) + BoolTy, // Result type (bool) + VK_LValue, // Value kind + OK_Ordinary, // Object kind + NameLoc, // Source location of operator + FPOptionsOverride()); + + return binaryOperator; +} + +Expr *constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, + TemplateTypeParmDecl *T) { + ASTContext &Context = S.getASTContext(); + + // first get the "sizeof(T) <= 16" expression, as a binary operator + BinaryOperator *SizeOfLEQ16 = constructSizeOfLEQ16Expr(Context, NameLoc, T); + // TODO: add the 'builtin_hlsl_is_typed_resource_element_compatible' builtin + // and return a binary operator that evaluates the builtin on the given + // template type parameter 'T'. + // Defined in issue https://github.com/llvm/llvm-project/issues/113223 + return SizeOfLEQ16; +} + +ConceptDecl *constructTypedBufferConceptDecl(Sema &S, NamespaceDecl *NSD) { + ASTContext &Context = S.getASTContext(); + DeclContext *DC = NSD->getDeclContext(); + SourceLocation DeclLoc = SourceLocation(); + + IdentifierInfo &ElementTypeII = Context.Idents.get("element_type"); + TemplateTypeParmDecl *T = TemplateTypeParmDecl::Create( + Context, NSD->getDeclContext(), DeclLoc, DeclLoc, + /*depth=*/0, + /*position=*/0, + /*id=*/&ElementTypeII, + /*Typename=*/true, + /*ParameterPack=*/false); + + T->setDeclContext(DC); + T->setReferenced(); + + // Create and Attach Template Parameter List to ConceptDecl + TemplateParameterList *ConceptParams = TemplateParameterList::Create( + Context, DeclLoc, DeclLoc, {T}, DeclLoc, nullptr); + + DeclarationName DeclName = DeclarationName( + &Context.Idents.get("__is_typed_resource_element_compatible")); + Expr *ConstraintExpr = constructTypedBufferConstraintExpr(S, DeclLoc, T); + + // Create a ConceptDecl + ConceptDecl *CD = + ConceptDecl::Create(Context, NSD->getDeclContext(), DeclLoc, DeclName, + ConceptParams, ConstraintExpr); + + // Attach the template parameter list to the ConceptDecl + CD->setTemplateParameters(ConceptParams); + + // Add the concept declaration to the Translation Unit Decl + NSD->getDeclContext()->addDecl(CD); + + return CD; +} + void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; + ConceptDecl *TypedBufferConcept = + constructTypedBufferConceptDecl(*SemaPtr, HLSLNamespace); Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams(*SemaPtr, {"element_type"}) + .addSimpleTemplateParams(*SemaPtr, {"element_type"}, + TypedBufferConcept) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { diff --git a/clang/test/AST/HLSL/AppendStructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/AppendStructuredBuffer-AST.hlsl index 5a13ca7735f999..8dbab44024d34d 100644 --- a/clang/test/AST/HLSL/AppendStructuredBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/AppendStructuredBuffer-AST.hlsl @@ -12,7 +12,7 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit AppendStructuredBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class AppendStructuredBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -26,7 +26,7 @@ AppendStructuredBuffer<int> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit AppendStructuredBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class AppendStructuredBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/AST/HLSL/ConsumeStructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/ConsumeStructuredBuffer-AST.hlsl index b75f3fcb959cfc..f27941b539b6a8 100644 --- a/clang/test/AST/HLSL/ConsumeStructuredBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/ConsumeStructuredBuffer-AST.hlsl @@ -12,7 +12,7 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit ConsumeStructuredBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class ConsumeStructuredBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -26,7 +26,7 @@ ConsumeStructuredBuffer<int> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit ConsumeStructuredBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class ConsumeStructuredBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl index ebddd72ddb1e0e..ab8f8d142169f5 100644 --- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl @@ -11,8 +11,15 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type -// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type +// EMPTY-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'bool' Concept 0x{{[0-9A-Fa-f]+}} '__is_typed_resource_element_compatible' +// EMPTY-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> +// EMPTY-NEXT: TemplateArgument type 'type-parameter-0-0' +// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' +// EMPTY-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' +// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type'// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final // There should be no more occurrences of RWBuffer @@ -25,8 +32,15 @@ RWBuffer<float> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type -// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type +// CHECK-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'bool' Concept 0x{{[0-9A-Fa-f]+}} '__is_typed_resource_element_compatible' +// CHECK-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> +// CHECK-NEXT: TemplateArgument type 'type-parameter-0-0' +// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' +// CHECK-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' +// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type'// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final // CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h '__hlsl_resource_t diff --git a/clang/test/AST/HLSL/RWStructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/RWStructuredBuffer-AST.hlsl index 4a1e1d7570e5e9..5058eab40b1aeb 100644 --- a/clang/test/AST/HLSL/RWStructuredBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWStructuredBuffer-AST.hlsl @@ -12,7 +12,7 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWStructuredBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWStructuredBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -26,7 +26,7 @@ RWStructuredBuffer<int> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWStructuredBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWStructuredBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/AST/HLSL/RasterizerOrderedStructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/RasterizerOrderedStructuredBuffer-AST.hlsl index f334e1bb6db3fc..bd05432a09e01c 100644 --- a/clang/test/AST/HLSL/RasterizerOrderedStructuredBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RasterizerOrderedStructuredBuffer-AST.hlsl @@ -12,7 +12,7 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RasterizerOrderedStructuredBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RasterizerOrderedStructuredBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -26,7 +26,7 @@ RasterizerOrderedStructuredBuffer<int> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RasterizerOrderedStructuredBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RasterizerOrderedStructuredBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl index 521c3d45b20225..081ab1355caaac 100644 --- a/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl @@ -12,7 +12,7 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit StructuredBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class StructuredBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -26,7 +26,7 @@ StructuredBuffer<float> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit StructuredBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> typename depth 0 index 0 element_type // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class StructuredBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl b/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl new file mode 100644 index 00000000000000..414ed6eb821246 --- /dev/null +++ b/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -ast-dump-filter=__is_typed_resource_element_compatible %s | FileCheck %s + +// CHECK: ConceptDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> __is_typed_resource_element_compatible +// CHECK: |-TemplateTypeParmDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> referenced typename depth 0 index 0 element_type +// CHECK: `-BinaryOperator 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' lvalue '<=' +// CHECK: |-UnaryExprOrTypeTraitExpr 0x{{[0-9a-f]+}} <<invalid sloc>> 'unsigned long' sizeof 'element_type' +// CHECK: `-IntegerLiteral 0x{{[0-9a-f]+}} <<invalid sloc>> 'unsigned long' 16 + + +RWBuffer<float> Buffer; diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl index 76b5d01b8036eb..438f8021f96a95 100644 --- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl @@ -5,13 +5,25 @@ typedef vector<float, 3> float3; RWBuffer<float3> Buffer; // expected-error@+2 {{class template 'RWBuffer' requires template arguments}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer {}}} RWBuffer BufferErr1; // expected-error@+2 {{too few template arguments for class template 'RWBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer {}}} RWBuffer<> BufferErr2; +struct threeDoubles { + double a; + double b; + double c; +}; + +// expected-error@+3 {{constraints not satisfied for class template 'RWBuffer'}} +// expected-note@*:* {{because 'threeDoubles' does not satisfy '__is_typed_resource_element_compatible'}} +// expected-note@*:* {{because 'sizeof(threeDoubles) <= 16UL' (24 <= 16) evaluated to false}} +RWBuffer<threeDoubles> BufferErr3; + + [numthreads(1,1,1)] void main() { (void)Buffer.h; // expected-error {{'h' is a private member of 'hlsl::RWBuffer<vector<float, 3>>'}} diff --git a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl index a472d5519dc51f..552624f13ee5f8 100644 --- a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl @@ -5,11 +5,11 @@ typedef vector<float, 3> float3; StructuredBuffer<float3> Buffer; // expected-error@+2 {{class template 'StructuredBuffer' requires template arguments}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class StructuredBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> class StructuredBuffer {}}} StructuredBuffer BufferErr1; // expected-error@+2 {{too few template arguments for class template 'StructuredBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class StructuredBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> class StructuredBuffer {}}} StructuredBuffer<> BufferErr2; [numthreads(1,1,1)] >From f369fb5318a51db23595748cfd9b081afa874fb4 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 15 Nov 2024 09:35:59 -0800 Subject: [PATCH 2/3] fix test --- clang/test/AST/HLSL/RWBuffer-AST.hlsl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl index ab8f8d142169f5..e3060a2dfa9677 100644 --- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl @@ -19,7 +19,8 @@ // EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' // EMPTY-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' // EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 -// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type'// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' +// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final // There should be no more occurrences of RWBuffer @@ -40,7 +41,8 @@ RWBuffer<float> Buffer; // CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' // CHECK-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' // CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 -// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type'// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' +// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final // CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h '__hlsl_resource_t >From 8d173d3697633bc20487f21dc835c3ac3c0a40db Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Mon, 18 Nov 2024 14:33:47 -0800 Subject: [PATCH 3/3] use // instead of /*..*/ for comment block --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 400d3334f6f0de..6c93afdfaa819b 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -325,24 +325,24 @@ struct TemplateParameterListBuilder { return *this; } - /* -The concept specialization expression (CSE) constructed in -constructConceptSpecializationExpr is constructed so that it -matches the CSE that is constructed when parsing the below C++ code: -template<typename T> -concept is_typed_resource_element_compatible = sizeof(T) <= 16; -template<typename element_type> requires -is_typed_resource_element_compatible<element_type> -struct RWBuffer { - element_type Val; -}; -int fn() { - RWBuffer<int> Buf; -} -When dumping the AST and filtering for "RWBuffer", the resulting AST -structure is what we're trying to construct below, specifically the -CSE portion. -*/ + // The concept specialization expression (CSE) constructed in + // constructConceptSpecializationExpr is constructed so that it + // matches the CSE that is constructed when parsing the below C++ code: + // + // template<typename T> + // concept is_typed_resource_element_compatible = sizeof(T) <= 16; + // template<typename element_type> requires + // is_typed_resource_element_compatible<element_type> + // struct RWBuffer { + // element_type Val; + // }; + // int fn() { + // RWBuffer<int> Buf; + // } + // + // When dumping the AST and filtering for "RWBuffer", the resulting AST + // structure is what we're trying to construct below, specifically the + // CSE portion. ConceptSpecializationExpr * constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD) { ASTContext &Context = S.getASTContext(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits