[clang] [HLSL] Forward arguments in BuiltinTypeMethodBuilder::callBuiltin. NFC (PR #117789)

Justin Bogner via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 14:29:28 PST 2024


https://github.com/bogner updated https://github.com/llvm/llvm-project/pull/117789

>From 3b3e3bc67e28c4ac37939f6e249aecdfe7123b87 Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 26 Nov 2024 12:50:56 -0800
Subject: [PATCH 1/2] [HLSL] Forward arguments in
 BuiltinTypeMethodBuilder::callBuiltin. NFC

Introduce BuiltinTypeMethodBuilder::PlaceHolder values and use them in
the callBuiltin method in order to specify how we want to forward
arguments and pass the resource handle to builtins.
---
 clang/lib/Sema/HLSLExternalSemaSource.cpp | 60 ++++++++++++++---------
 1 file changed, 38 insertions(+), 22 deletions(-)

diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 886a4c098580ae..fae43d187e0532 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -455,7 +455,7 @@ struct TemplateParameterListBuilder {
 //
 //   BuiltinTypeMethodBuilder(Sema, RecordBuilder, "MethodName", ReturnType)
 //       .addParam("param_name", Type, InOutModifier)
-//       .callBuiltin("buildin_name", { BuiltinParams })
+//       .callBuiltin("buildin_name", BuiltinParams... )
 //       .finalizeMethod();
 //
 // The builder needs to have all of the method parameters before it can create
@@ -465,9 +465,9 @@ struct TemplateParameterListBuilder {
 // referenced from the body building methods. Destructor or an explicit call to
 // finalizeMethod() will complete the method definition.
 //
-// The callBuiltin helper method passes in the resource handle as the first
-// argument of the builtin call. If this is not desired it takes a bool flag to
-// disable this.
+// The callBuiltin helper method accepts constants via `Expr *` or placeholder
+// value arguments to indicate which function arguments to forward to the
+// builtin.
 //
 // If the method that is being built has a non-void return type the
 // finalizeMethod will create a return statent with the value of the last
@@ -489,6 +489,24 @@ struct BuiltinTypeMethodBuilder {
   llvm::SmallVector<MethodParam> Params;
   llvm::SmallVector<Stmt *> StmtsList;
 
+  // Argument placeholders, inspired by std::placeholder. These are the indices
+  // of arguments to forward to `callBuiltin`, and additionally `Handle` which
+  // refers to the resource handle.
+  enum class PlaceHolder { _0, _1, _2, _3, Handle = 127 };
+
+  Expr *convertPlaceholder(PlaceHolder PH) {
+    if (PH == PlaceHolder::Handle)
+      return getResourceHandleExpr();
+
+    ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
+    ParmVarDecl *ParamDecl = Method->getParamDecl(static_cast<unsigned>(PH));
+    return DeclRefExpr::Create(
+        AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl, false,
+        DeclarationNameInfo(ParamDecl->getDeclName(), SourceLocation()),
+        ParamDecl->getType(), VK_PRValue);
+  }
+  Expr *convertPlaceholder(Expr *E) { return E; }
+
 public:
   BuiltinTypeMethodBuilder(Sema &S, BuiltinTypeDeclBuilder &DB, StringRef Name,
                            QualType ReturnTy)
@@ -502,7 +520,10 @@ struct BuiltinTypeMethodBuilder {
                                      HLSLParamModifierAttr::Spelling Modifier =
                                          HLSLParamModifierAttr::Keyword_in) {
     assert(Method == nullptr && "Cannot add param, method already created");
-    llvm_unreachable("not yet implemented");
+    const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
+        Name, tok::TokenKind::identifier);
+    Params.emplace_back(II, Ty, Modifier);
+    return *this;
   }
 
 private:
@@ -564,9 +585,9 @@ struct BuiltinTypeMethodBuilder {
                                       OK_Ordinary);
   }
 
-  BuiltinTypeMethodBuilder &
-  callBuiltin(StringRef BuiltinName, ArrayRef<Expr *> CallParms,
-              bool AddResourceHandleAsFirstArg = true) {
+  template <typename... Ts>
+  BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName, Ts... ArgSpecs) {
+    SmallVector<Expr *> Args{convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
 
     // The first statement added to a method or access to 'this` creates the
     // declaration.
@@ -579,16 +600,9 @@ struct BuiltinTypeMethodBuilder {
         AST, NestedNameSpecifierLoc(), SourceLocation(), FD, false,
         FD->getNameInfo(), FD->getType(), VK_PRValue);
 
-    SmallVector<Expr *> NewCallParms;
-    if (AddResourceHandleAsFirstArg) {
-      NewCallParms.push_back(getResourceHandleExpr());
-      for (auto *P : CallParms)
-        NewCallParms.push_back(P);
-    }
-
-    Expr *Call = CallExpr::Create(
-        AST, DRE, AddResourceHandleAsFirstArg ? NewCallParms : CallParms,
-        FD->getReturnType(), VK_PRValue, SourceLocation(), FPOptionsOverride());
+    Expr *Call =
+        CallExpr::Create(AST, DRE, Args, FD->getReturnType(), VK_PRValue,
+                         SourceLocation(), FPOptionsOverride());
     StmtsList.push_back(Call);
     return *this;
   }
@@ -656,18 +670,20 @@ BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef<StringRef> Names,
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod() {
+  using PH = BuiltinTypeMethodBuilder::PlaceHolder;
   return BuiltinTypeMethodBuilder(SemaRef, *this, "IncrementCounter",
                                   SemaRef.getASTContext().UnsignedIntTy)
-      .callBuiltin("__builtin_hlsl_buffer_update_counter",
-                   {getConstantIntExpr(1)})
+      .callBuiltin("__builtin_hlsl_buffer_update_counter", PH::Handle,
+                   getConstantIntExpr(1))
       .finalizeMethod();
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() {
+  using PH = BuiltinTypeMethodBuilder::PlaceHolder;
   return BuiltinTypeMethodBuilder(SemaRef, *this, "DecrementCounter",
                                   SemaRef.getASTContext().UnsignedIntTy)
-      .callBuiltin("__builtin_hlsl_buffer_update_counter",
-                   {getConstantIntExpr(-1)})
+      .callBuiltin("__builtin_hlsl_buffer_update_counter", PH::Handle,
+                   getConstantIntExpr(-1))
       .finalizeMethod();
 }
 

>From a292f5702e8b3a65cf79b8f1c409c67c8cbfdacf Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 26 Nov 2024 14:29:13 -0800
Subject: [PATCH 2/2] fixup: Use array, Fix comment

---
 clang/lib/Sema/HLSLExternalSemaSource.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index fae43d187e0532..951375cc84ba82 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -455,7 +455,7 @@ struct TemplateParameterListBuilder {
 //
 //   BuiltinTypeMethodBuilder(Sema, RecordBuilder, "MethodName", ReturnType)
 //       .addParam("param_name", Type, InOutModifier)
-//       .callBuiltin("buildin_name", BuiltinParams... )
+//       .callBuiltin("builtin_name", BuiltinParams...)
 //       .finalizeMethod();
 //
 // The builder needs to have all of the method parameters before it can create
@@ -587,7 +587,8 @@ struct BuiltinTypeMethodBuilder {
 
   template <typename... Ts>
   BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName, Ts... ArgSpecs) {
-    SmallVector<Expr *> Args{convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
+    std::array<Expr *, sizeof...(ArgSpecs)> Args{
+        convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
 
     // The first statement added to a method or access to 'this` creates the
     // declaration.



More information about the cfe-commits mailing list