[clang] [llvm] [HLSL] Add implicit resource element type concepts to AST (PR #116413)
Joshua Batista via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 20 15:22:43 PST 2024
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 <jbatista at microsoft.com>
Date: Fri, 15 Nov 2024 09:00:15 -0800
Subject: [PATCH 1/4] 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 at +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 at +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 at +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 at +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 at +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 <jbatista at microsoft.com>
Date: Fri, 15 Nov 2024 09:35:59 -0800
Subject: [PATCH 2/4] 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 <jbatista at microsoft.com>
Date: Mon, 18 Nov 2024 14:33:47 -0800
Subject: [PATCH 3/4] 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();
>From 7c58efd1a9756dbde6e158ace0d01374cab04039 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 20 Nov 2024 15:22:28 -0800
Subject: [PATCH 4/4] add tests for rwbuffer concept validation
---
"asa1qqqq\357\200\233" | 217 ++++++++++++++++++
clang/lib/Sema/HLSLExternalSemaSource.cpp | 66 +++---
...d_resource_element_compatible_concept.hlsl | 12 +-
clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl | 99 +++++++-
...sTypedResourceElementCompatibleErrors.hlsl | 3 +-
5 files changed, 348 insertions(+), 49 deletions(-)
create mode 100644 "asa1qqqq\357\200\233"
diff --git "a/asa1qqqq\357\200\233" "b/asa1qqqq\357\200\233"
new file mode 100644
index 00000000000000..7f93726bb4a45f
--- /dev/null
+++ "b/asa1qqqq\357\200\233"
@@ -0,0 +1,217 @@
+[1mdiff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp[m
+[1mindex 6c93afdfaa81..e36bfeab7b49 100644[m
+[1m--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp[m
+[1m+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp[m
+[36m@@ -330,7 +330,7 @@[m [mstruct TemplateParameterListBuilder {[m
+ // matches the CSE that is constructed when parsing the below C++ code:[m
+ //[m
+ // template<typename T>[m
+[31m- // concept is_typed_resource_element_compatible = sizeof(T) <= 16;[m
+[32m+[m[32m // concept is_typed_resource_element_compatible = __builtin_hlsl_typed_resource_element_compatible<T> && !__builtin_hlsl_is_intangible<T>[m
+ // template<typename element_type> requires[m
+ // is_typed_resource_element_compatible<element_type>[m
+ // struct RWBuffer {[m
+[36m@@ -568,11 +568,11 @@[m [mstatic BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,[m
+ .addDefaultHandleConstructor(S);[m
+ }[m
+ [m
+[31m-BinaryOperator *constructSizeOfLEQ16Expr(ASTContext &Context,[m
+[32m+[m[32mBinaryOperator *constructTypedResourceConstraintExpr(ASTContext &Context,[m
+ SourceLocation NameLoc,[m
+ TemplateTypeParmDecl *T) {[m
+ // Obtain the QualType for 'unsigned long'[m
+[31m- QualType UnsignedLongType = Context.UnsignedLongTy;[m
+[32m+[m[32m QualType BoolTy = Context.BoolTy;[m
+ [m
+ // Create a QualType that points to this TemplateTypeParmDecl[m
+ QualType TType = Context.getTypeDeclType(T);[m
+[36m@@ -581,21 +581,22 @@[m [mBinaryOperator *constructSizeOfLEQ16Expr(ASTContext &Context,[m
+ TypeSourceInfo *TTypeSourceInfo =[m
+ Context.getTrivialTypeSourceInfo(TType, NameLoc);[m
+ [m
+[31m- UnaryExprOrTypeTraitExpr *sizeOfExpr = new (Context) UnaryExprOrTypeTraitExpr([m
+[31m- UETT_SizeOf, TTypeSourceInfo, UnsignedLongType, NameLoc, NameLoc);[m
+[32m+[m[32m TypeTraitExpr *TypedResExpr = TypeTraitExpr::Create([m
+[32m+[m[32m Context, BoolTy, NameLoc, UTT_IsTypedResourceElementCompatible,[m
+[32m+[m[32m {TTypeSourceInfo}, NameLoc, true);[m
+ [m
+[31m- // Create an IntegerLiteral for the value '16' with size type[m
+[31m- QualType SizeType = Context.getSizeType();[m
+[31m- llvm::APInt SizeValue = llvm::APInt(Context.getTypeSize(SizeType), 16);[m
+[31m- IntegerLiteral *SizeLiteral =[m
+[31m- new (Context) IntegerLiteral(Context, SizeValue, SizeType, NameLoc);[m
+[32m+[m[32m TypeTraitExpr *IsIntangibleExpr =[m
+[32m+[m[32m TypeTraitExpr::Create(Context, BoolTy, NameLoc, UTT_IsIntangibleType,[m
+[32m+[m[32m {TTypeSourceInfo}, NameLoc, true);[m
+ [m
+[31m- QualType BoolTy = Context.BoolTy;[m
+[32m+[m[32m UnaryOperator *NotIntangibleExpr = UnaryOperator::Create([m
+[32m+[m[32m Context, IsIntangibleExpr, UO_Not, BoolTy, VK_LValue, OK_Ordinary,[m
+[32m+[m[32m NameLoc, false, FPOptionsOverride());[m
+ [m
+ BinaryOperator *binaryOperator =[m
+[31m- BinaryOperator::Create(Context, sizeOfExpr, // Left-hand side expression[m
+[31m- SizeLiteral, // Right-hand side expression[m
+[31m- BO_LE, // Binary operator kind (<=)[m
+[32m+[m[32m BinaryOperator::Create(Context, TypedResExpr, // Left-hand side expression[m
+[32m+[m[32m NotIntangibleExpr, // Right-hand side expression[m
+[32m+[m[32m BO_LAnd, // Binary operator kind (&&)[m
+ BoolTy, // Result type (bool)[m
+ VK_LValue, // Value kind[m
+ OK_Ordinary, // Object kind[m
+[36m@@ -609,13 +610,10 @@[m [mExpr *constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc,[m
+ TemplateTypeParmDecl *T) {[m
+ ASTContext &Context = S.getASTContext();[m
+ [m
+[31m- // first get the "sizeof(T) <= 16" expression, as a binary operator[m
+[31m- BinaryOperator *SizeOfLEQ16 = constructSizeOfLEQ16Expr(Context, NameLoc, T);[m
+[31m- // TODO: add the 'builtin_hlsl_is_typed_resource_element_compatible' builtin[m
+[31m- // and return a binary operator that evaluates the builtin on the given[m
+[31m- // template type parameter 'T'.[m
+[31m- // Defined in issue https://github.com/llvm/llvm-project/issues/113223[m
+[31m- return SizeOfLEQ16;[m
+[32m+[m[32m BinaryOperator *TypedResourceConstraintExpr =[m
+[32m+[m[32m constructTypedResourceConstraintExpr(Context, NameLoc, T);[m
+[32m+[m
+[32m+[m[32m return TypedResourceConstraintExpr;[m
+ }[m
+ [m
+ ConceptDecl *constructTypedBufferConceptDecl(Sema &S, NamespaceDecl *NSD) {[m
+[1mdiff --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[m
+[1mindex 414ed6eb8212..362ce96e808f 100644[m
+[1m--- a/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl[m
+[1m+++ b/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl[m
+[36m@@ -2,9 +2,13 @@[m
+ [m
+ // CHECK: ConceptDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> __is_typed_resource_element_compatible[m
+ // CHECK: |-TemplateTypeParmDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> referenced typename depth 0 index 0 element_type[m
+[31m-// CHECK: `-BinaryOperator 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' lvalue '<='[m
+[31m-// CHECK: |-UnaryExprOrTypeTraitExpr 0x{{[0-9a-f]+}} <<invalid sloc>> 'unsigned long' sizeof 'element_type'[m
+[31m-// CHECK: `-IntegerLiteral 0x{{[0-9a-f]+}} <<invalid sloc>> 'unsigned long' 16[m
+[31m-[m
+[32m+[m[32m// CHECK: `-BinaryOperator 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' lvalue '&&'[m[41m
[m
+[32m+[m[32m// CHECK: |-TypeTraitExpr 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' __builtin_hlsl_is_typed_resource_element_compatible[m[41m
[m
+[32m+[m[32m// CHECK: `-TemplateTypeParmType 0x{{[0-9a-f]+}} 'element_type' dependent depth 0 index 0[m[41m
[m
+[32m+[m[32m// CHECK: `-TemplateTypeParm 0x{{[0-9a-f]+}} 'element_type'[m[41m
[m
+[32m+[m[32m// CHECK: `-UnaryOperator 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' lvalue prefix '~' cannot overflow[m[41m
[m
+[32m+[m[32m// CHECK: `-TypeTraitExpr 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' __builtin_hlsl_is_intangible[m[41m
[m
+[32m+[m[32m// CHECK: `-TemplateTypeParmType 0x{{[0-9a-f]+}} 'element_type' dependent depth 0 index 0[m[41m
[m
+[32m+[m[32m// CHECK: `-TemplateTypeParm 0x{{[0-9a-f]+}} 'element_type'[m[41m
[m
+ [m
+ RWBuffer<float> Buffer;[m
+[1mdiff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl[m
+[1mindex 438f8021f96a..8d018bacea7f 100644[m
+[1m--- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl[m
+[1m+++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl[m
+[36m@@ -1,16 +1,79 @@[m
+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify %s[m
+ [m
+ typedef vector<float, 3> float3;[m
+[32m+[m[32mtypedef vector<double, 2> double2;[m
+[32m+[m[32mtypedef vector<double, 3> double3;[m
+ [m
+[31m-RWBuffer<float3> Buffer;[m
+ [m
+[31m-// expected-error at +2 {{class template 'RWBuffer' requires template arguments}}[m
+[31m-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer {}}}[m
+[31m-RWBuffer BufferErr1;[m
+[32m+[m[32m// expected-error at +4 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}[m
+[32m+[m[32m// expected-note@*:* {{because 'hlsl::RWBuffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(hlsl::RWBuffer<int>)' evaluated to false}}[m
+[32m+[m[32mRWBuffer<RWBuffer<int> > r5;[m
+[32m+[m
+[32m+[m[32mstruct s {[m
+[32m+[m[32m int x;[m
+[32m+[m[32m};[m
+[32m+[m
+[32m+[m[32mstruct Empty {};[m
+[32m+[m
+[32m+[m[32mtemplate<typename T> struct TemplatedBuffer {[m
+[32m+[m[32m T a;[m
+[32m+[m[32m};[m
+[32m+[m
+[32m+[m[32mtemplate<typename T> struct TemplatedVector {[m
+[32m+[m[32m vector<T, 4> v;[m
+[32m+[m[32m};[m
+[32m+[m
+[32m+[m
+[32m+[m[32m// expected-error at +4 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}[m
+[32m+[m[32m// expected-note@*:* {{because 'TemplatedBuffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(TemplatedBuffer<int>)' evaluated to false}}[m
+[32m+[m[32mRWBuffer<TemplatedBuffer<int> > r8;[m
+[32m+[m[32m// expected-error at +4 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}[m
+[32m+[m[32m// expected-note@*:* {{because 'TemplatedVector<int>' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(TemplatedVector<int>)' evaluated to false}}[m
+[32m+[m[32mRWBuffer<TemplatedVector<int> > r9;[m
+[32m+[m
+[32m+[m[32m// arrays not allowed[m
+[32m+[m[32m// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{because 'half[4]' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(__fp16[4])' evaluated to false}}[m
+[32m+[m[32mRWBuffer<half[4]> r10;[m
+[32m+[m
+[32m+[m[32mtypedef vector<int, 8> int8;[m
+[32m+[m[32m// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{because 'vector<int, 8>' (vector of 8 'int' values) does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(int __attribute__((ext_vector_type(8))))' evaluated to false}}[m
+[32m+[m[32mRWBuffer<int8> r11;[m
+[32m+[m
+[32m+[m[32mtypedef int MyInt;[m
+[32m+[m[32mRWBuffer<MyInt> r12;[m
+[32m+[m
+[32m+[m[32m// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{because 'bool' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(_Bool)' evaluated to false}}[m
+[32m+[m[32mRWBuffer<bool> r13;[m
+[32m+[m
+[32m+[m[32m// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{because 'vector<bool, 2>' (vector of 2 'bool' values) does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(_Bool __attribute__((ext_vector_type(2))))' evaluated to false}}[m
+[32m+[m[32mRWBuffer<vector<bool, 2>> r14;[m
+[32m+[m
+[32m+[m[32menum numbers { one, two, three };[m
+[32m+[m
+[32m+[m[32m// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{because 'numbers' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(numbers)' evaluated to false}}[m
+[32m+[m[32mRWBuffer<numbers> r15;[m
+[32m+[m
+[32m+[m[32m// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+[32m+[m[32m// expected-note@*:* {{because 'vector<double, 3>' (vector of 3 'double' values) does not satisfy '__is_typed_resource_element_compatible'}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(double __attribute__((ext_vector_type(3))))' evaluated to false}}[m
+[32m+[m[32mRWBuffer<double3> r16;[m
+ [m
+[31m-// expected-error at +2 {{too few template arguments for class template 'RWBuffer'}}[m
+[31m-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer {}}}[m
+[31m-RWBuffer<> BufferErr2;[m
+ [m
+ struct threeDoubles {[m
+ double a;[m
+[36m@@ -20,7 +83,7 @@[m [mstruct threeDoubles {[m
+ [m
+ // expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}[m
+ // expected-note@*:* {{because 'threeDoubles' does not satisfy '__is_typed_resource_element_compatible'}}[m
+[31m-// expected-note@*:* {{because 'sizeof(threeDoubles) <= 16UL' (24 <= 16) evaluated to false}}[m
+[32m+[m[32m// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(threeDoubles)' evaluated to false}}[m
+ RWBuffer<threeDoubles> BufferErr3;[m
+ [m
+ [m
+[1mdiff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl[m
+[1mindex d3d79aa0499e..cb3e9ae7a615 100644[m
+[1m--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl[m
+[1m+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl[m
+[36m@@ -1,9 +1,10 @@[m
+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s[m
+ [m
+ // types must be complete[m
+[31m-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");[m
+[32m+[m[32m_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");[m[41m
[m
+ [m
+ // expected-note at +1{{forward declaration of 'notComplete'}}[m
+ struct notComplete;[m
+ // expected-error at +1{{incomplete type 'notComplete' where a complete type is required}}[m
+ _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notComplete), "");[m
+[41m+ [m
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 6c93afdfaa819b..a2f6e46c4a112b 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -330,8 +330,9 @@ struct TemplateParameterListBuilder {
// 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
+ // concept is_typed_resource_element_compatible =
+ // __builtin_hlsl_typed_resource_element_compatible<T> &&
+ // !__builtin_hlsl_is_intangible<T> template<typename element_type> requires
// is_typed_resource_element_compatible<element_type>
// struct RWBuffer {
// element_type Val;
@@ -568,11 +569,12 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
.addDefaultHandleConstructor(S);
}
-BinaryOperator *constructSizeOfLEQ16Expr(ASTContext &Context,
- SourceLocation NameLoc,
+Expr *constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc,
TemplateTypeParmDecl *T) {
+ ASTContext &Context = S.getASTContext();
+
// Obtain the QualType for 'unsigned long'
- QualType UnsignedLongType = Context.UnsignedLongTy;
+ QualType BoolTy = Context.BoolTy;
// Create a QualType that points to this TemplateTypeParmDecl
QualType TType = Context.getTypeDeclType(T);
@@ -581,41 +583,29 @@ BinaryOperator *constructSizeOfLEQ16Expr(ASTContext &Context,
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
+ TypeTraitExpr *TypedResExpr = TypeTraitExpr::Create(
+ Context, BoolTy, NameLoc, UTT_IsTypedResourceElementCompatible,
+ {TTypeSourceInfo}, NameLoc, true);
+
+ TypeTraitExpr *IsIntangibleExpr =
+ TypeTraitExpr::Create(Context, BoolTy, NameLoc, UTT_IsIntangibleType,
+ {TTypeSourceInfo}, NameLoc, true);
+
+ UnaryOperator *NotIntangibleExpr = UnaryOperator::Create(
+ Context, IsIntangibleExpr, UO_Not, BoolTy, VK_LValue, OK_Ordinary,
+ NameLoc, false, FPOptionsOverride());
+
+ BinaryOperator *TypedResourceConstraintExpr =
+ BinaryOperator::Create(Context, TypedResExpr, // Left-hand side expression
+ NotIntangibleExpr, // Right-hand side expression
+ BO_LAnd, // 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;
+ return TypedResourceConstraintExpr;
}
ConceptDecl *constructTypedBufferConceptDecl(Sema &S, NamespaceDecl *NSD) {
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
index 414ed6eb821246..362ce96e808f62 100644
--- a/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl
+++ b/clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl
@@ -2,9 +2,13 @@
// 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
-
+// CHECK: `-BinaryOperator 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' lvalue '&&'
+// CHECK: |-TypeTraitExpr 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' __builtin_hlsl_is_typed_resource_element_compatible
+// CHECK: `-TemplateTypeParmType 0x{{[0-9a-f]+}} 'element_type' dependent depth 0 index 0
+// CHECK: `-TemplateTypeParm 0x{{[0-9a-f]+}} 'element_type'
+// CHECK: `-UnaryOperator 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' lvalue prefix '~' cannot overflow
+// CHECK: `-TypeTraitExpr 0x{{[0-9a-f]+}} <<invalid sloc>> 'bool' __builtin_hlsl_is_intangible
+// CHECK: `-TemplateTypeParmType 0x{{[0-9a-f]+}} 'element_type' dependent depth 0 index 0
+// CHECK: `-TemplateTypeParm 0x{{[0-9a-f]+}} 'element_type'
RWBuffer<float> Buffer;
diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
index 438f8021f96a95..15f5fae347411e 100644
--- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
@@ -1,17 +1,104 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify %s
typedef vector<float, 3> float3;
+typedef vector<double, 2> double2;
+typedef vector<double, 3> double3;
-RWBuffer<float3> Buffer;
-// expected-error at +2 {{class template 'RWBuffer' requires template arguments}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer {}}}
+// expected-error at +1 {{class template 'RWBuffer' requires template arguments}}
RWBuffer BufferErr1;
-// expected-error at +2 {{too few template arguments for class template 'RWBuffer'}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer {}}}
+// expected-error at +1 {{too few template arguments for class template 'RWBuffer'}}
RWBuffer<> BufferErr2;
+// test implicit RWBuffer concept
+RWBuffer<int> r1;
+RWBuffer<float> r2;
+RWBuffer<float3> Buffer;
+RWBuffer<double2> r4;
+
+// expected-error at +4 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
+// expected-note@*:* {{because 'hlsl::RWBuffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(hlsl::RWBuffer<int>)' evaluated to false}}
+RWBuffer<RWBuffer<int> > r5;
+
+struct s {
+ int x;
+};
+
+struct Empty {};
+
+template<typename T> struct TemplatedBuffer {
+ T a;
+};
+
+template<typename T> struct TemplatedVector {
+ vector<T, 4> v;
+};
+
+// structs not allowed
+// expected-error at +4 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
+// expected-note@*:* {{because 's' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(s)' evaluated to false}}
+RWBuffer<s> r6;
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'Empty' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(Empty)' evaluated to false}}
+RWBuffer<Empty> r7;
+
+/* TODO: fix issue with incomplete type
+// error at +4 {{constraints not satisfied for class template 'RWBuffer'}}
+// note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
+// note@*:* {{because 'TemplatedBuffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}
+// note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(TemplatedBuffer<int>)' evaluated to false}}
+RWBuffer<TemplatedBuffer<int> > r8;
+// error at +4 {{constraints not satisfied for class template 'RWBuffer'}}
+// note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
+// note@*:* {{because 'TemplatedVector<int>' does not satisfy '__is_typed_resource_element_compatible'}}
+// note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(TemplatedVector<int>)' evaluated to false}}
+RWBuffer<TemplatedVector<int> > r9;
+*/
+
+// arrays not allowed
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'half[4]' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(__fp16[4])' evaluated to false}}
+RWBuffer<half[4]> r10;
+
+typedef vector<int, 8> int8;
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'vector<int, 8>' (vector of 8 'int' values) does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(int __attribute__((ext_vector_type(8))))' evaluated to false}}
+RWBuffer<int8> r11;
+
+typedef int MyInt;
+RWBuffer<MyInt> r12;
+
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'bool' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(_Bool)' evaluated to false}}
+RWBuffer<bool> r13;
+
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'vector<bool, 2>' (vector of 2 'bool' values) does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(_Bool __attribute__((ext_vector_type(2))))' evaluated to false}}
+RWBuffer<vector<bool, 2>> r14;
+
+enum numbers { one, two, three };
+
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'numbers' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(numbers)' evaluated to false}}
+RWBuffer<numbers> r15;
+
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'vector<double, 3>' (vector of 3 'double' values) does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(double __attribute__((ext_vector_type(3))))' evaluated to false}}
+RWBuffer<double3> r16;
+
+
struct threeDoubles {
double a;
double b;
@@ -20,7 +107,7 @@ struct threeDoubles {
// expected-error at +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}}
+// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(threeDoubles)' evaluated to false}}
RWBuffer<threeDoubles> BufferErr3;
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
index d3d79aa0499e54..cb3e9ae7a61509 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
@@ -1,9 +1,10 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
// types must be complete
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");
// expected-note at +1{{forward declaration of 'notComplete'}}
struct notComplete;
// expected-error at +1{{incomplete type 'notComplete' where a complete type is required}}
_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notComplete), "");
+
More information about the cfe-commits
mailing list