[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-19 Thread Chris B via cfe-commits

https://github.com/llvm-beanz commented:

I think the way that you're staging these changes is awkward and results in 
more review time than we strictly need. We're also going to need to re-review a 
bunch of this code in a wider context in the near future, so I'm not sure I'm 
comfortable with this approach.

In a future change, you're going to introduce a new builtin 
(`__builtin_hlsl_is_typed_resource_element_compatible`), and a bunch of the 
code here will go away, and a bunch of the tests will be extended and updated 
to use that builtin. At that time we'll need to re-review this work.

Why not introduce the new builtin first so that this code can be merged in its 
completed state rather than in an intermediate state?

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-19 Thread Joshua Batista via cfe-commits


@@ -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
+  // concept is_typed_resource_element_compatible = sizeof(T) <= 16;

bob80905 wrote:

The purpose of this change is to just verify concept validation works. A very 
simple constraint expression is used, size <= 16 bytes. This is tested by 
inspecting the AST, and seeing the CSE in the AST. It's also verified by 
running simple tests that fail when size > 16, and pass when <= 16. 
I wanted to keep things separate because I want the PR to be kept as atomic as 
possible. This PR accomplishes the single purpose of introducing concept 
infrastructure and testing concept validation.
I intend the next and final PR to finalize the constraint expression, which 
will involve adding a bunch of tests that test each corner case of the 
constraint expression. This will also be a sizeable PR, which I figured would 
be best kept separate.

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-19 Thread Chris B via cfe-commits


@@ -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
+  // concept is_typed_resource_element_compatible = sizeof(T) <= 16;

llvm-beanz wrote:

Sure, it needs to be a vector or a scalar 
(https://github.com/llvm/wg-hlsl/blob/main/proposals/0011-resource-element-type-validation.md?plain=1#L31).

I guess I maybe don't understand why we're breaking this into so many separate 
changes where the intermediate steps aren't fully testable.

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-19 Thread Joshua Batista via cfe-commits


@@ -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
+  // concept is_typed_resource_element_compatible = sizeof(T) <= 16;

bob80905 wrote:

I don't believe that's absolutely required. For example, one can have 
`RWBuffer`, where the element type, `float`, is not a vector. If we 
require vectors, then I would think `RWBuffer` would be invalid, and 
only things like `RWBuffer` would be accepted.

Additionally, this comment block will be changed when the finalized constraint 
expression is added, since the concept is more complex than just comparing the 
size to 16 bytes.

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-19 Thread Chris B via cfe-commits


@@ -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
+  // concept is_typed_resource_element_compatible = sizeof(T) <= 16;

llvm-beanz wrote:

Shouldn't this also require that `T` is a vector type?

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-18 Thread Joshua Batista via cfe-commits

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 
Date: Fri, 15 Nov 2024 09:00:15 -0800
Subject: [PATCH 1/3] update new tests

---
 clang/lib/Sema/HLSLExternalSemaSource.cpp | 210 +-
 .../AST/HLSL/AppendStructuredBuffer-AST.hlsl  |   4 +-
 .../AST/HLSL/ConsumeStructuredBuffer-AST.hlsl |   4 +-
 clang/test/AST/HLSL/RWBuffer-AST.hlsl |  22 +-
 .../test/AST/HLSL/RWStructuredBuffer-AST.hlsl |   4 +-
 ...RasterizerOrderedStructuredBuffer-AST.hlsl |   4 +-
 clang/test/AST/HLSL/StructuredBuffer-AST.hlsl |   4 +-
 ...d_resource_element_compatible_concept.hlsl |  10 +
 clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl   |  16 +-
 .../SemaHLSL/BuiltIns/StructuredBuffers.hlsl  |   4 +-
 10 files changed, 253 insertions(+), 29 deletions(-)
 create mode 100644 
clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl

diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp 
b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index cac15b974a276e..400d3334f6f0de 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -289,8 +289,9 @@ struct BuiltinTypeDeclBuilder {
   }
 
   TemplateParameterListBuilder addTemplateArgumentList(Sema &S);
-  BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S,
-  ArrayRef Names);
+  BuiltinTypeDeclBuilder &
+  addSimpleTemplateParams(Sema &S, ArrayRef 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
+concept is_typed_resource_element_compatible = sizeof(T) <= 16;
+template requires
+is_typed_resource_element_compatible
+struct RWBuffer {
+element_type Val;
+};
+int fn() {
+RWBuffer 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(
+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 argume

[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-18 Thread Chris B via cfe-commits


@@ -323,19 +325,114 @@ struct TemplateParameterListBuilder {
 return *this;
   }
 
-  BuiltinTypeDeclBuilder &finalizeTemplateArgs() {
+  /*
+The concept specialization expression (CSE) constructed in

llvm-beanz wrote:

nit: generally LLVM does per-line comment tokens for blocks (`//` rather than 
`/* ... */`)

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-18 Thread Damyan Pepper via cfe-commits

damyanp wrote:

@bob80905 - can you associate this with an issue please?

https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-18 Thread Joshua Batista via cfe-commits

https://github.com/bob80905 edited 
https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-18 Thread Damyan Pepper via cfe-commits

https://github.com/damyanp approved this pull request.


https://github.com/llvm/llvm-project/pull/116413
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-hlsl

Author: Joshua Batista (bob80905)


Changes

This PR is step one on the journey to implement resource element type 
validation via C++20 concepts. The PR sets up the infrastructure for injecting 
implicit concept decls / concept specialization expressions into the AST, which 
will then be evaluated after template arguments are instantiated. This is not 
meant to be a complete implementation of the desired validation for HLSL,
there are a couple of missing elements:

We need the __builtin_hlsl_is_typed_resource_element_compatible builtin to be 
implemented.
We need other constraints, like is_intangible
We need to put the first 2 points together, and construct a finalized 
constraint expression, which should differ between typed and raw buffers
This is just an initial PR that puts some of the core infrastructure in place.

This PR is an edit of #112600, so that new tests that were put into 
main don't fail

---

Patch is 25.49 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/116413.diff


10 Files Affected:

- (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+199-11) 
- (modified) clang/test/AST/HLSL/AppendStructuredBuffer-AST.hlsl (+2-2) 
- (modified) clang/test/AST/HLSL/ConsumeStructuredBuffer-AST.hlsl (+2-2) 
- (modified) clang/test/AST/HLSL/RWBuffer-AST.hlsl (+18-2) 
- (modified) clang/test/AST/HLSL/RWStructuredBuffer-AST.hlsl (+2-2) 
- (modified) clang/test/AST/HLSL/RasterizerOrderedStructuredBuffer-AST.hlsl 
(+2-2) 
- (modified) clang/test/AST/HLSL/StructuredBuffer-AST.hlsl (+2-2) 
- (added) clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl 
(+10) 
- (modified) clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl (+14-2) 
- (modified) clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl (+2-2) 


``diff
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 Names);
+  BuiltinTypeDeclBuilder &
+  addSimpleTemplateParams(Sema &S, ArrayRef 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
+concept is_typed_resource_element_compatible = sizeof(T) <= 16;
+template requires
+is_typed_resource_element_compatible
+struct RWBuffer {
+element_type Val;
+};
+int fn() {
+RWBuffer 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(
+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
+  

[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-15 Thread Joshua Batista via cfe-commits

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 
Date: Fri, 15 Nov 2024 09:00:15 -0800
Subject: [PATCH 1/2] 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 Names);
+  BuiltinTypeDeclBuilder &
+  addSimpleTemplateParams(Sema &S, ArrayRef 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
+concept is_typed_resource_element_compatible = sizeof(T) <= 16;
+template requires
+is_typed_resource_element_compatible
+struct RWBuffer {
+element_type Val;
+};
+int fn() {
+RWBuffer 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(
+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 argume

[clang] [HLSL] Add implicit resource element type concepts to AST (PR #116413)

2024-11-15 Thread Joshua Batista via cfe-commits

https://github.com/bob80905 created 
https://github.com/llvm/llvm-project/pull/116413

This PR is step one on the journey to implement resource element type 
validation via C++20 concepts. The PR sets up the infrastructure for injecting 
implicit concept decls / concept specialization expressions into the AST, which 
will then be evaluated after template arguments are instantiated. This is not 
meant to be a complete implementation of the desired validation for HLSL,
there are a couple of missing elements:

We need the __builtin_hlsl_is_typed_resource_element_compatible builtin to be 
implemented.
We need other constraints, like is_intangible
We need to put the first 2 points together, and construct a finalized 
constraint expression, which should differ between typed and raw buffers
This is just an initial PR that puts some of the core infrastructure in place.

This PR is an edit of #112600, so that new tests that were put into main don't 
fail

>From 92ccbe72ca95ad2df5a81b76244a8a8d7cedef40 Mon Sep 17 00:00:00 2001
From: Joshua Batista 
Date: Fri, 15 Nov 2024 09:00:15 -0800
Subject: [PATCH 1/2] 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 Names);
+  BuiltinTypeDeclBuilder &
+  addSimpleTemplateParams(Sema &S, ArrayRef 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
+concept is_typed_resource_element_compatible = sizeof(T) <= 16;
+template requires
+is_typed_resource_element_compatible
+struct RWBuffer {
+element_type Val;
+};
+int fn() {
+RWBuffer 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(
+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(), // DeclCon