https://github.com/hekota updated 
https://github.com/llvm/llvm-project/pull/163465

>From 99831c12ece1b67295d8ddf522d114863dbddf92 Mon Sep 17 00:00:00 2001
From: Helena Kotas <[email protected]>
Date: Tue, 14 Oct 2025 15:24:34 -0700
Subject: [PATCH 1/5] [HLSL] Add __hlsl_resource_t to types recognized by clang
 TableGen for built-in functions

---
 clang/include/clang/Basic/Builtins.td         | 12 ++---
 clang/lib/AST/ASTContext.cpp                  |  3 ++
 clang/lib/Sema/SemaHLSL.cpp                   | 39 +++-------------
 clang/lib/Sema/SemaOverload.cpp               | 27 ++++++++----
 .../test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 12 ++---
 .../test/AST/HLSL/StructuredBuffers-AST.hlsl  | 44 +++++++++----------
 clang/test/AST/HLSL/TypedBuffers-AST.hlsl     | 12 ++---
 .../buffer_update_counter-errors.hlsl         |  4 +-
 clang/utils/TableGen/ClangBuiltinsEmitter.cpp |  1 +
 9 files changed, 70 insertions(+), 84 deletions(-)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 792e2e07ec594..8d8886ee8be3c 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4930,25 +4930,25 @@ def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
 def HLSLResourceUninitializedHandle : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_uninitializedhandle"];
   let Attributes = [NoThrow];
-  let Prototype = "void(...)";
+  let Prototype = "__hlsl_resource_t(__hlsl_resource_t)";
 }
 
 def HLSLResourceHandleFromBinding : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_handlefrombinding"];
   let Attributes = [NoThrow];
-  let Prototype = "void(...)";
+  let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t, 
int32_t, uint32_t, char const*)";
 }
 
 def HLSLResourceHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_handlefromimplicitbinding"];
   let Attributes = [NoThrow];
-  let Prototype = "void(...)";
+  let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t, 
int32_t, uint32_t, char const*)";
 }
 
 def HLSLResourceCounterHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_counterhandlefromimplicitbinding"];
-  let Attributes = [NoThrow, CustomTypeChecking];
-  let Prototype = "void(...)";
+  let Attributes = [NoThrow];
+  let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t)";
 }
 
 def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> {
@@ -5176,7 +5176,7 @@ def HLSLRadians : LangBuiltin<"HLSL_LANG"> {
 def HLSLBufferUpdateCounter : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_buffer_update_counter"];
   let Attributes = [NoThrow];
-  let Prototype = "uint32_t(...)";
+  let Prototype = "uint32_t(__hlsl_resource_t, int)";
 }
 
 def HLSLSplitDouble: LangBuiltin<"HLSL_LANG"> {
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a8b41ba18fa01..ace93a7b40311 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12603,6 +12603,9 @@ static QualType DecodeTypeFromStr(const char *&Str, 
const ASTContext &Context,
   case 'm':
     Type = Context.MFloat8Ty;
     break;
+  case 'r':
+    Type = Context.HLSLResourceTy;
+    break;
   }
 
   // If there are modifiers and if we're allowed to parse them, go for it.
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 72b2ac99ec53c..41495570e9fe9 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2947,54 +2947,29 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
     break;
   }
   case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
-    if (SemaRef.checkArgCount(TheCall, 1) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0))
-      return true;
+    assert(TheCall->getNumArgs() == 1 && "expected 1 arg");
     // use the type of the handle (arg0) as a return type
     QualType ResourceTy = TheCall->getArg(0)->getType();
     TheCall->setType(ResourceTy);
     break;
   }
   case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
-    ASTContext &AST = SemaRef.getASTContext();
-    if (SemaRef.checkArgCount(TheCall, 6) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(5),
-                            AST.getPointerType(AST.CharTy.withConst())))
-      return true;
+    assert(TheCall->getNumArgs() == 6 && "expected 6 args");
     // use the type of the handle (arg0) as a return type
     QualType ResourceTy = TheCall->getArg(0)->getType();
     TheCall->setType(ResourceTy);
     break;
   }
   case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
-    ASTContext &AST = SemaRef.getASTContext();
-    if (SemaRef.checkArgCount(TheCall, 6) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(5),
-                            AST.getPointerType(AST.CharTy.withConst())))
-      return true;
+    assert(TheCall->getNumArgs() == 6 && "expected 6 args");
     // use the type of the handle (arg0) as a return type
     QualType ResourceTy = TheCall->getArg(0)->getType();
     TheCall->setType(ResourceTy);
     break;
   }
   case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
+    assert(TheCall->getNumArgs() == 3 && "expected 3 args");
     ASTContext &AST = SemaRef.getASTContext();
-    if (SemaRef.checkArgCount(TheCall, 3) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy))
-      return true;
-
     QualType MainHandleTy = TheCall->getArg(0)->getType();
     auto *MainResType = MainHandleTy->getAs<HLSLAttributedResourceType>();
     auto MainAttrs = MainResType->getAttrs();
@@ -3302,14 +3277,12 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
     break;
   }
   case Builtin::BI__builtin_hlsl_buffer_update_counter: {
+    assert(TheCall->getNumArgs() == 2 && "expected 2 args");
     auto checkResTy = [](const HLSLAttributedResourceType *ResTy) -> bool {
       return !(ResTy->getAttrs().ResourceClass == ResourceClass::UAV &&
                ResTy->getAttrs().RawBuffer && ResTy->hasContainedType());
     };
-    if (SemaRef.checkArgCount(TheCall, 2) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0, checkResTy) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1),
-                            SemaRef.getASTContext().IntTy))
+    if (CheckResourceHandle(&SemaRef, TheCall, 0, checkResTy))
       return true;
     Expr *OffsetExpr = TheCall->getArg(1);
     std::optional<llvm::APSInt> Offset =
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8339bb19a1edc..4b59cd3c4f4ce 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1825,15 +1825,24 @@ TryImplicitConversion(Sema &S, Expr *From, QualType 
ToType,
     return ICS;
   }
 
-  if (S.getLangOpts().HLSL && ToType->isHLSLAttributedResourceType() &&
-      FromType->isHLSLAttributedResourceType()) {
-    auto *ToResType = cast<HLSLAttributedResourceType>(ToType);
-    auto *FromResType = cast<HLSLAttributedResourceType>(FromType);
-    if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
-                                         FromResType->getWrappedType()) &&
-        S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
-                                         FromResType->getContainedType()) &&
-        ToResType->getAttrs() == FromResType->getAttrs()) {
+  const Type *FromTy = FromType->getUnqualifiedDesugaredType();
+  if (S.getLangOpts().HLSL && FromTy->isHLSLAttributedResourceType()) {
+    bool CanConvert = false;
+    const Type *ToTy = ToType->getUnqualifiedDesugaredType();
+    if (ToTy->isHLSLAttributedResourceType()) {
+      auto *ToResType = cast<HLSLAttributedResourceType>(ToTy);
+      auto *FromResType = cast<HLSLAttributedResourceType>(FromTy);
+      if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
+                                          FromResType->getWrappedType()) &&
+          S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
+                                          FromResType->getContainedType()) &&
+          ToResType->getAttrs() == FromResType->getAttrs())
+        CanConvert = true;
+    }
+    else if (ToTy->isHLSLResourceType()) {
+      CanConvert = true;
+    }
+    if (CanConvert) {
       ICS.setStandard();
       ICS.Standard.setAsIdentityConversion();
       ICS.Standard.setFromType(FromType);
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl 
b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 43d8ddee6ccad..cf128c43481e6 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -50,8 +50,8 @@ RESOURCE Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
-// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_uninitializedhandle'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_uninitializedhandle' '__hlsl_resource_t 
(__hlsl_resource_t) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
 // CHECK-NEXT: AlwaysInlineAttr
@@ -97,8 +97,8 @@ RESOURCE Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]'
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefrombinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]'
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 
'unsigned int'
@@ -127,8 +127,8 @@ RESOURCE Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]'
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromimplicitbinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]'
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 
'unsigned int'
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl 
b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index e72207e10132c..1761754f5c076 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -97,8 +97,8 @@ RESOURCE<float> Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
-// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_uninitializedhandle'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_uninitializedhandle' '__hlsl_resource_t 
(__hlsl_resource_t) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: AlwaysInlineAttr
@@ -154,8 +154,8 @@ RESOURCE<float> Buffer;
 // CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue 
.__handle
 // CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 
lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-BINDING-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-BINDING-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept'
+// CHECK-BINDING-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefrombinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue 
.__handle
 // CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 
lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 
'registerNo' 'unsigned int'
@@ -182,8 +182,8 @@ RESOURCE<float> Buffer;
 // CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue 
.__handle
 // CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 
lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-BINDING-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-BINDING-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept'
+// CHECK-BINDING-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromimplicitbinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue 
.__handle
 // CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 
lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 
'orderId' 'unsigned int'
@@ -209,8 +209,8 @@ RESOURCE<float> Buffer;
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept'
+// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_handlefrombinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 
'registerNo' 'unsigned int'
@@ -222,8 +222,8 @@ RESOURCE<float> Buffer;
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__counter_handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_counterhandlefromimplicitbinding' 'void (...) 
noexcept'
+// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_counterhandlefromimplicitbinding' 
'__hlsl_resource_t (__hlsl_resource_t, unsigned int, unsigned int) noexcept'
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 
'counterOrderId' 'unsigned int'
@@ -246,8 +246,8 @@ RESOURCE<float> Buffer;
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept'
+// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 
'orderId' 'unsigned int'
@@ -259,8 +259,8 @@ RESOURCE<float> Buffer;
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__counter_handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_counterhandlefromimplicitbinding' 'void (...) 
noexcept'
+// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function 
{{.*}} '__builtin_hlsl_resource_counterhandlefromimplicitbinding' 
'__hlsl_resource_t (__hlsl_resource_t, unsigned int, unsigned int) noexcept'
 // CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' 
lvalue .__handle
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 
'hlsl::[[RESOURCE]]<element_type>' lvalue Var {{.*}} 'tmp' 
'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 
'counterOrderId' 'unsigned int'
@@ -332,8 +332,8 @@ RESOURCE<float> Buffer;
 // CHECK-COUNTER-NEXT: CompoundStmt
 // CHECK-COUNTER-NEXT: ReturnStmt
 // CHECK-COUNTER-NEXT: CallExpr {{.*}} 'unsigned int'
-// CHECK-COUNTER-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-COUNTER-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept'
+// CHECK-COUNTER-NEXT: ImplicitCastExpr {{.*}} 'unsigned int 
(*)(__hlsl_resource_t, int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-COUNTER-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (__hlsl_resource_t, int) 
noexcept'
 // CHECK-COUNTER-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
 // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]]
@@ -348,8 +348,8 @@ RESOURCE<float> Buffer;
 // CHECK-COUNTER-NEXT: CompoundStmt
 // CHECK-COUNTER-NEXT: ReturnStmt
 // CHECK-COUNTER-NEXT: CallExpr {{.*}} 'unsigned int'
-// CHECK-COUNTER-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-COUNTER-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept'
+// CHECK-COUNTER-NEXT: ImplicitCastExpr {{.*}} 'unsigned int 
(*)(__hlsl_resource_t, int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-COUNTER-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (__hlsl_resource_t, int) 
noexcept'
 // CHECK-COUNTER-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
 // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]]
@@ -374,8 +374,8 @@ RESOURCE<float> Buffer;
 // CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue 
.__handle
 // CHECK-APPEND-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 
lvalue implicit this
 // CHECK-APPEND-NEXT: CallExpr {{.*}} 'unsigned int'
-// CHECK-APPEND-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-APPEND-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept'
+// CHECK-APPEND-NEXT: ImplicitCastExpr {{.*}} 'unsigned int 
(*)(__hlsl_resource_t, int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-APPEND-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (__hlsl_resource_t, int) 
noexcept'
 // CHECK-APPEND-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
 // CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]]
@@ -399,8 +399,8 @@ RESOURCE<float> Buffer;
 // CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue 
.__handle
 // CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' 
lvalue implicit this
 // CHECK-CONSUME-NEXT: CallExpr {{.*}} 'unsigned int'
-// CHECK-CONSUME-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-CONSUME-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept'
+// CHECK-CONSUME-NEXT: ImplicitCastExpr {{.*}} 'unsigned int 
(*)(__hlsl_resource_t, int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-CONSUME-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_buffer_update_counter' 'unsigned int (__hlsl_resource_t, int) 
noexcept'
 // CHECK-CONSUME-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
 // CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]]
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl 
b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index 5182ce194cfb0..2f623a7301741 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -72,8 +72,8 @@ RESOURCE<float> Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
-// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_uninitializedhandle'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_uninitializedhandle' '__hlsl_resource_t 
(__hlsl_resource_t) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: AlwaysInlineAttr
@@ -119,8 +119,8 @@ RESOURCE<float> Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefrombinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 
'unsigned int'
@@ -147,8 +147,8 @@ RESOURCE<float> Buffer;
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const 
char *) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromimplicitbinding' '__hlsl_resource_t 
(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char 
*) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
 // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]<element_type>'
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 
'unsigned int'
diff --git a/clang/test/SemaHLSL/BuiltIns/buffer_update_counter-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/buffer_update_counter-errors.hlsl
index 4aa3ac183d3b1..faac8f07b240a 100644
--- a/clang/test/SemaHLSL/BuiltIns/buffer_update_counter-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/buffer_update_counter-errors.hlsl
@@ -16,7 +16,7 @@ void test_args(int x, bool b) {
   // expected-error@+1 {{too many arguments to function call, expected 2, have 
3}}
   __builtin_hlsl_buffer_update_counter(x, x, x);
 
-  // expected-error@+1 {{used type 'int' where __hlsl_resource_t is required}}
+  // expected-error@+1 {{cannot initialize a parameter of type 
'__hlsl_resource_t' with an lvalue of type 'int'}}
   __builtin_hlsl_buffer_update_counter(x, x);
 
   bad_handle_not_raw_t bad1;
@@ -37,7 +37,7 @@ void test_args(int x, bool b) {
   // expected-error@+1 {{argument 1 must be constant integer 1 or -1}}
   __builtin_hlsl_buffer_update_counter(res, x);
 
-  // expected-error@+1 {{passing 'const char *' to parameter of incompatible 
type 'int'}}
+  // expected-error@+1 {{cannot initialize a parameter of type 'int' with an 
lvalue of type 'const char[2]'}}
   __builtin_hlsl_buffer_update_counter(res, "1");
   
   // expected-error@+1 {{argument 1 must be constant integer 1 or -1}}
diff --git a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp 
b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
index 352765acf5338..165203b772a6c 100644
--- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
@@ -330,6 +330,7 @@ class PrototypeParser {
                                .Case("__builtin_va_list", "a")
                                .Case("__float128", "LLd")
                                .Case("__fp16", "h")
+                               .Case("__hlsl_resource_t", "r")
                                .Case("__int128_t", "LLLi")
                                .Case("_Float16", "x")
                                .Case("__bf16", "y")

>From 568bb70bfc7f9cce523ad6cb9a10ecf2e5c77ccb Mon Sep 17 00:00:00 2001
From: Helena Kotas <[email protected]>
Date: Fri, 31 Oct 2025 11:30:17 -0700
Subject: [PATCH 2/5] Change GetDimensions to use __hlsl_resource_t in the
 builtin signature

---
 clang/include/clang/Basic/Builtins.td          |  4 ++--
 clang/lib/Sema/SemaHLSL.cpp                    | 18 ------------------
 .../test/AST/HLSL/ByteAddressBuffers-AST.hlsl  |  4 ++--
 clang/test/AST/HLSL/StructuredBuffers-AST.hlsl |  8 ++++----
 clang/test/AST/HLSL/TypedBuffers-AST.hlsl      |  4 ++--
 5 files changed, 10 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index dc562321e090b..e13c1d004797a 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4967,13 +4967,13 @@ def HLSLResourceNonUniformIndex : 
LangBuiltin<"HLSL_LANG"> {
 def HLSLResourceGetDimensionsX : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getdimensions_x"];
   let Attributes = [NoThrow];
-  let Prototype = "void(...)";
+  let Prototype = "void(__hlsl_resource_t, uint32_t&)";
 }
 
 def HLSLResourceGetStride : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_getstride"];
   let Attributes = [NoThrow];
-  let Prototype = "void(...)";
+  let Prototype = "void(__hlsl_resource_t, uint32_t&)";
 }
 
 def HLSLAll : LangBuiltin<"HLSL_LANG"> {
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index f8038a0fb6226..5fb6b398db4d2 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3045,24 +3045,6 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
     TheCall->setType(CounterHandleTy);
     break;
   }
-  case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
-    ASTContext &AST = SemaRef.getASTContext();
-    if (SemaRef.checkArgCount(TheCall, 2) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
-        CheckModifiableLValue(&SemaRef, TheCall, 1))
-      return true;
-    break;
-  }
-  case Builtin::BI__builtin_hlsl_resource_getstride: {
-    ASTContext &AST = SemaRef.getASTContext();
-    if (SemaRef.checkArgCount(TheCall, 2) ||
-        CheckResourceHandle(&SemaRef, TheCall, 0) ||
-        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
-        CheckModifiableLValue(&SemaRef, TheCall, 1))
-      return true;
-    break;
-  }
   case Builtin::BI__builtin_hlsl_and:
   case Builtin::BI__builtin_hlsl_or: {
     if (SemaRef.checkArgCount(TheCall, 2))
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl 
b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 458ad6f7484bc..2713cc19ea2be 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -149,8 +149,8 @@ RESOURCE Buffer;
 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CallExpr {{.*}} 'void'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getdimensions_x' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(__hlsl_resource_t, unsigned 
int &) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getdimensions_x' 'void (__hlsl_resource_t, unsigned 
int &) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle 
{{.*}}
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}}  'dim' 
'unsigned int &__restrict'
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl 
b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index bb1f6aa70fae4..538eb5256f8d5 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -417,14 +417,14 @@ RESOURCE<float> Buffer;
 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CallExpr {{.*}} 'void'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getdimensions_x' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(__hlsl_resource_t, unsigned 
int &) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getdimensions_x' 'void (__hlsl_resource_t, unsigned 
int &) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle 
{{.*}}
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}}  'numStructs' 
'unsigned int &__restrict'
 // CHECK-NEXT: CallExpr {{.*}} 'void'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getstride' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(__hlsl_resource_t, unsigned 
int &) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getstride' 'void (__hlsl_resource_t, unsigned int &) 
noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle 
{{.*}}
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}}  'stride' 
'unsigned int &__restrict'
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl 
b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index 1f2caeb03794d..4b66faa79662a 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -221,8 +221,8 @@ RESOURCE<float> Buffer;
 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CallExpr {{.*}} 'void'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' 
<BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getdimensions_x' 'void (...) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(__hlsl_resource_t, unsigned 
int &) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_getdimensions_x' 'void (__hlsl_resource_t, unsigned 
int &) noexcept'
 // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle 
{{.*}}
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue 
implicit this
 // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}}  'dim' 
'unsigned int &__restrict'

>From 8621c01a003d83220f766fc968e7164467be6f49 Mon Sep 17 00:00:00 2001
From: Helena Kotas <[email protected]>
Date: Fri, 31 Oct 2025 11:40:45 -0700
Subject: [PATCH 3/5] clang-format & add comments

---
 clang/lib/Sema/SemaOverload.cpp | 49 ++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8d498d1c62c97..c12f92dfdab66 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1825,29 +1825,34 @@ TryImplicitConversion(Sema &S, Expr *From, QualType 
ToType,
     return ICS;
   }
 
-  const Type *FromTy = FromType->getUnqualifiedDesugaredType();
-  if (S.getLangOpts().HLSL && FromTy->isHLSLAttributedResourceType()) {
-    bool CanConvert = false;
-    const Type *ToTy = ToType->getUnqualifiedDesugaredType();
-    if (ToTy->isHLSLAttributedResourceType()) {
-      auto *ToResType = cast<HLSLAttributedResourceType>(ToTy);
-      auto *FromResType = cast<HLSLAttributedResourceType>(FromTy);
-      if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
-                                          FromResType->getWrappedType()) &&
-          S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
-                                          FromResType->getContainedType()) &&
-          ToResType->getAttrs() == FromResType->getAttrs())
+  if (S.getLangOpts().HLSL) {
+    // Handle conversion of the HLSL resource types.
+    const Type *FromTy = FromType->getUnqualifiedDesugaredType();
+    if (FromTy->isHLSLAttributedResourceType()) {
+      // Attributed resource types can convert to other attributed
+      // resource types with the same attributes and contained types,
+      // or to __hlsl_resource_t without any attributes.
+      bool CanConvert = false;
+      const Type *ToTy = ToType->getUnqualifiedDesugaredType();
+      if (ToTy->isHLSLAttributedResourceType()) {
+        auto *ToResType = cast<HLSLAttributedResourceType>(ToTy);
+        auto *FromResType = cast<HLSLAttributedResourceType>(FromTy);
+        if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
+                                             FromResType->getWrappedType()) &&
+            S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
+                                             FromResType->getContainedType()) 
&&
+            ToResType->getAttrs() == FromResType->getAttrs())
+          CanConvert = true;
+      } else if (ToTy->isHLSLResourceType()) {
         CanConvert = true;
-    }
-    else if (ToTy->isHLSLResourceType()) {
-      CanConvert = true;
-    }
-    if (CanConvert) {
-      ICS.setStandard();
-      ICS.Standard.setAsIdentityConversion();
-      ICS.Standard.setFromType(FromType);
-      ICS.Standard.setAllToTypes(ToType);
-      return ICS;
+      }
+      if (CanConvert) {
+        ICS.setStandard();
+        ICS.Standard.setAsIdentityConversion();
+        ICS.Standard.setFromType(FromType);
+        ICS.Standard.setAllToTypes(ToType);
+        return ICS;
+      }
     }
   }
 

>From bc12044c1e60845158672d8ee3ed48869231f52d Mon Sep 17 00:00:00 2001
From: Helena Kotas <[email protected]>
Date: Thu, 6 Nov 2025 12:37:29 -0800
Subject: [PATCH 4/5] [HLSL] Add internal linkage attribute to resources

HLSL resources should not be externally visible from the module.
We made sure of this by marking them `static` as soon as they were declared.
However, this prevents us fixing issue #166458 because there is no way
to know if a resource has been explicitly marked `static`
by the user, and can therefore be assigned to.

This change is moves from making all resources `static` to adding Clang internal
linkage attribute to all non-static resource declarations as a global scope.
Existing tests verify that there is no change in how the resource globals are
emitted: `internal global`.
---
 clang/lib/Sema/SemaHLSL.cpp      | 13 ++++++++-----
 clang/test/AST/HLSL/cbuffer.hlsl |  2 +-
 clang/test/AST/HLSL/private.hlsl |  2 +-
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 5fb6b398db4d2..68802813f74e5 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3802,12 +3802,15 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
     if (VD->getType()->isHLSLIntangibleType())
       collectResourceBindingsOnVarDecl(VD);
 
-    if (isResourceRecordTypeOrArrayOf(VD) ||
-        VD->hasAttr<HLSLVkConstantIdAttr>()) {
-      // Make the variable for resources static. The global externally visible
-      // storage is accessed through the handle, which is a member. The 
variable
-      // itself is not externally visible.
+    if (VD->hasAttr<HLSLVkConstantIdAttr>())
       VD->setStorageClass(StorageClass::SC_Static);
+
+    if (isResourceRecordTypeOrArrayOf(VD) &&
+        VD->getStorageClass() != SC_Static) {
+      // Add internal linkage attribute to non-static resource variables. The
+      // global externally visible storage is accessed through the handle, 
which
+      // is a member. The variable itself is not externally visible.
+      VD->addAttr(InternalLinkageAttr::CreateImplicit(getASTContext()));
     }
 
     // process explicit bindings
diff --git a/clang/test/AST/HLSL/cbuffer.hlsl b/clang/test/AST/HLSL/cbuffer.hlsl
index f3c6636232798..b0b5b989e36c2 100644
--- a/clang/test/AST/HLSL/cbuffer.hlsl
+++ b/clang/test/AST/HLSL/cbuffer.hlsl
@@ -153,7 +153,7 @@ cbuffer CB {
   static float SV;
   // CHECK: VarDecl {{.*}} s7 'EmptyStruct' callinit
   EmptyStruct s7;
-  // CHECK: VarDecl {{.*}} Buf 'RWBuffer<float>':'hlsl::RWBuffer<float>' 
static callinit
+  // CHECK: VarDecl {{.*}} Buf 'RWBuffer<float>':'hlsl::RWBuffer<float>' 
callinit
   RWBuffer<float> Buf;
   // CHECK: VarDecl {{.*}} ea 'EmptyArrayTypedef':'float[10][0]'
   EmptyArrayTypedef ea;
diff --git a/clang/test/AST/HLSL/private.hlsl b/clang/test/AST/HLSL/private.hlsl
index e00afb8f5cbd8..ba7380ec3cfda 100644
--- a/clang/test/AST/HLSL/private.hlsl
+++ b/clang/test/AST/HLSL/private.hlsl
@@ -3,7 +3,7 @@
 // CHECK: VarDecl {{.*}} global_scalar 'hlsl_private int' static cinit
 static int global_scalar = 0;
 
-// CHECK: VarDecl {{.*}} global_buffer 
'RWBuffer<float>':'hlsl::RWBuffer<float>' static callinit
+// CHECK: VarDecl {{.*}} global_buffer 
'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit
 RWBuffer<float> global_buffer;
 
 class A {

>From c10e6f3fd7c43bc7335a3e51aaf39ae1cba8835f Mon Sep 17 00:00:00 2001
From: Helena Kotas <[email protected]>
Date: Tue, 18 Nov 2025 13:42:15 -0800
Subject: [PATCH 5/5] Update shortcut to "Qr"

---
 clang/lib/AST/ASTContext.cpp                  | 7 ++++---
 clang/utils/TableGen/ClangBuiltinsEmitter.cpp | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 07ee39e5d474f..b929b0fc1aa8e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12540,6 +12540,10 @@ static QualType DecodeTypeFromStr(const char *&Str, 
const ASTContext &Context,
       Type = Context.AMDGPUTextureTy;
       break;
     }
+    case 'r': {
+      Type = Context.HLSLResourceTy;
+      break;
+    }
     default:
       llvm_unreachable("Unexpected target builtin type");
     }
@@ -12615,9 +12619,6 @@ static QualType DecodeTypeFromStr(const char *&Str, 
const ASTContext &Context,
   case 'm':
     Type = Context.MFloat8Ty;
     break;
-  case 'r':
-    Type = Context.HLSLResourceTy;
-    break;
   }
 
   // If there are modifiers and if we're allowed to parse them, go for it.
diff --git a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp 
b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
index 165203b772a6c..9b6dd37c7a4a9 100644
--- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp
@@ -330,7 +330,7 @@ class PrototypeParser {
                                .Case("__builtin_va_list", "a")
                                .Case("__float128", "LLd")
                                .Case("__fp16", "h")
-                               .Case("__hlsl_resource_t", "r")
+                               .Case("__hlsl_resource_t", "Qr")
                                .Case("__int128_t", "LLLi")
                                .Case("_Float16", "x")
                                .Case("__bf16", "y")

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to