[clang] [llvm] [HLSL] Add implicit resource element type concepts to AST (PR #116413)
Joshua Batista via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 21 22:42:12 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/7] 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/7] 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/7] 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/7] 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), "");
+
>From 4d15d89baca46b9cae9c4d478d669bbdb1dbce40 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 20 Nov 2024 18:08:57 -0800
Subject: [PATCH 5/7] remove extraneous file, simplify constraint expression by
removing intangible
---
"asa1qqqq\357\200\233" | 217 ------------------
clang/lib/Sema/HLSLExternalSemaSource.cpp | 26 +--
...d_resource_element_compatible_concept.hlsl | 11 +-
3 files changed, 8 insertions(+), 246 deletions(-)
delete mode 100644 "asa1qqqq\357\200\233"
diff --git "a/asa1qqqq\357\200\233" "b/asa1qqqq\357\200\233"
deleted file mode 100644
index 7f93726bb4a45f..00000000000000
--- "a/asa1qqqq\357\200\233"
+++ /dev/null
@@ -1,217 +0,0 @@
-[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 a2f6e46c4a112b..0a772c04bceab3 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -331,12 +331,14 @@ struct TemplateParameterListBuilder {
//
// template<typename T>
// concept is_typed_resource_element_compatible =
- // __builtin_hlsl_typed_resource_element_compatible<T> &&
- // !__builtin_hlsl_is_intangible<T> template<typename element_type> requires
+ // __builtin_hlsl_typed_resource_element_compatible<T>
+ //
+ // template<typename element_type> requires
// is_typed_resource_element_compatible<element_type>
// struct RWBuffer {
// element_type Val;
// };
+ //
// int fn() {
// RWBuffer<int> Buf;
// }
@@ -587,25 +589,7 @@ Expr *constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc,
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 TypedResourceConstraintExpr;
+ return TypedResExpr;
}
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 362ce96e808f62..68aa3a32e7d11b 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,13 +2,8 @@
// 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: |-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'
+// 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'
RWBuffer<float> Buffer;
>From fa8d50e11736c3819a32aaab2e98d9c4b1a1377a Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 20 Nov 2024 22:53:04 -0800
Subject: [PATCH 6/7] update tests
---
.../SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl | 2 ++
.../Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
index 0467844e1cab8c..493e34b03f3486 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -7,7 +7,9 @@ _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float), "");
_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float4), "");
_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(double2), "");
+// types must be complete
_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>), "");
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");
struct s {
int x;
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
index cb3e9ae7a61509..29e45f77bdbf23 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
@@ -1,7 +1,7 @@
// 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;
>From a8fae57097c301924f064e2395628c3406a92a0e Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 21 Nov 2024 14:40:32 -0800
Subject: [PATCH 7/7] remove require complete type, update tests
---
clang/lib/Sema/SemaExprCXX.cpp | 3 +--
clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl | 16 ++++++----------
.../Traits/IsTypedResourceElementCompatible.hlsl | 4 ++++
.../IsTypedResourceElementCompatibleErrors.hlsl | 10 ----------
4 files changed, 11 insertions(+), 22 deletions(-)
delete mode 100644 clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 616481d62de887..d85819b21c8265 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5720,8 +5720,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
case UTT_IsTypedResourceElementCompatible:
assert(Self.getLangOpts().HLSL &&
"typed resource element compatible types are an HLSL-only feature");
- if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
- diag::err_incomplete_type))
+ if (T->isIncompleteType())
return false;
return Self.HLSL().IsTypedResourceElementCompatible(T);
diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
index 15f5fae347411e..03624230048bad 100644
--- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
@@ -48,18 +48,14 @@ RWBuffer<s> r6;
// 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}}
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'TemplatedBuffer<int>' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-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}}
+// expected-error at +3 {{constraints not satisfied for class template 'RWBuffer'}}
+// expected-note@*:* {{because 'TemplatedVector<int>' does not satisfy '__is_typed_resource_element_compatible'}}
+// expected-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'}}
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
index 493e34b03f3486..abe022af73cc63 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -11,6 +11,10 @@ _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(double2), "")
_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>), "");
_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");
+struct notComplete;
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notComplete), "");
+
+
struct s {
int x;
};
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
deleted file mode 100644
index 29e45f77bdbf23..00000000000000
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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), "");
-
-// 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