Skip to content

[HLSL] Implement intangible AST type #97362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Aug 5, 2024
Merged

Conversation

hekota
Copy link
Member

@hekota hekota commented Jul 1, 2024

HLSL has a set of intangible types, which are described in in the draft HLSL Specification ([Basic.types]):

There are special implementation-defined types such as handle types, which fall into a category of standard intangible types. Intangible types are types that have no defined object representation or value representation, as such the size is unknown at compile time.

A class type T is an intangible class type if it contains an base classes or members of intangible class type, standard intangible type, or arrays of such types. Standard intangible types and intangible class types are collectively called intangible types(9).

This PR implements one standard intangible type __builtin_hlsl_resource_t and sets up the infrastructure that will make it easier to add more in the future, such as samplers or raytracing payload handles. The HLSL intangible types are declared in clang/include/clang/Basic/HLSLIntangibleTypes.def and this file is included with related macro definition in most places that require edits when a new type is added.

The new types are added as keywords and not typedefs to make sure they cannot be redeclared, and they can only be declared in builtin implicit headers. For example the __builtin_hlsl_resource_t type represents a handle to a memory resource and it is going to be used in builtin HLSL buffer types like this:

template <typename T>
class RWBuffer {
  [[hlsl::contained_type(T)]]
  [[hlsl::is_rov(false)]]
  [[hlsl::resource_class(uav)]]  
  __hlsl_resource_t Handle;
};

Part 1/3 of #90631.

bogner and others added 4 commits June 20, 2024 10:49
There are a couple of things that may be wrong here:

- Adding the PREDEF_TYPE to ASTBitCodes seems sketchy, but matches
  prior art.
- I skipped name mangling for now - can it come up?
- We use an unspellable name in a few places
- The type info matches `void *`. Does that make sense?
Modify all places where HLSLResource needs to be added to use the def file.

Future intangible types will be added just to HLSLIntangibleTypes.def and everything else should just work.

Add getHLSLType virtual method to TargetCodeGenInfo to be overridden in future DirectXTargetCodeGenInfo class (llvm#95952).
@hekota hekota changed the title [HLSL] Intangible AST type [HLSL] Implement intangible AST type Jul 1, 2024
Copy link

github-actions bot commented Jul 2, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@hekota hekota force-pushed the intangible-ast-type branch from 0b82352 to 3b34eb3 Compare July 3, 2024 18:00
@hekota hekota marked this pull request as ready for review July 3, 2024 19:05
@hekota hekota requested a review from JDevlieghere as a code owner July 3, 2024 19:05
@llvmbot llvmbot added clang Clang issues not falling into any other category lldb clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang:codegen IR generation bugs: mangling, exceptions, etc. debuginfo HLSL HLSL Language Support labels Jul 3, 2024
@hekota hekota requested review from bogner and llvm-beanz July 3, 2024 19:05
@llvmbot
Copy link
Member

llvmbot commented Jul 3, 2024

@llvm/pr-subscribers-hlsl
@llvm/pr-subscribers-clang-modules
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-lldb

Author: Helena Kotas (hekota)

Changes

HLSL has a set of intangible types, which are described in in the draft HLSL Specification ([Basic.types]):
> There are special implementation-defined types such as handle types, which fall into a category of standard intangible types. Intangible types are types that have no defined object representation or value representation, as such the size is unknown at compile time.
>
> A class type T is an intangible class type if it contains an base classes or members of intangible class type, standard intangible type, or arrays of such types. Standard intangible types and intangible class types are collectively called intangible types(9).

This PR implements one standard intangible type __builtin_hlsl_resource_t and sets up the infrastructure that will make it easier to add more in the future, such as samplers or raytracing payload handles. The HLSL intangible types are declared in clang/include/clang/Basic/HLSLIntangibleTypes.def and this file is included with related macro definition in most places that require edits when a new type is added.

The new types are added as keywords and not typedefs to make sure they cannot be redeclared, and they can only be declared in builtin implicit headers. For example the __builtin_hlsl_resource_t type represents a handle to a memory resource and it is going to be used in builtin HLSL buffer types like this:

template &lt;typename T&gt;
class RWBuffer {
  [[clang::hlsl::resource::contained_type(T)]]
  [[clang::hlsl::resource::isROV(false)]]
  [[clang::hlsl::resource::class(uav)]]  
  __builtin_hlsl_resource_t Handle;
};

Part 1/3 of llvm/llvm-project#90631.


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

45 Files Affected:

  • (modified) clang/include/clang-c/Index.h (+4-1)
  • (modified) clang/include/clang/AST/ASTContext.h (+2)
  • (modified) clang/include/clang/AST/BuiltinTypes.def (+1)
  • (modified) clang/include/clang/AST/Type.h (+20)
  • (modified) clang/include/clang/AST/TypeProperties.td (+4)
  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4)
  • (added) clang/include/clang/Basic/HLSLIntangibleTypes.def (+33)
  • (modified) clang/include/clang/Basic/Specifiers.h (+3)
  • (modified) clang/include/clang/Basic/TokenKinds.def (+3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+3)
  • (modified) clang/include/clang/Serialization/ASTBitCodes.h (+4-1)
  • (modified) clang/include/module.modulemap (+1)
  • (modified) clang/lib/AST/ASTContext.cpp (+15-2)
  • (modified) clang/lib/AST/ASTImporter.cpp (+4)
  • (modified) clang/lib/AST/ExprConstant.cpp (+2)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+6)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+7-1)
  • (modified) clang/lib/AST/NSAPI.cpp (+2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+2)
  • (modified) clang/lib/AST/Type.cpp (+9)
  • (modified) clang/lib/AST/TypeLoc.cpp (+2)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+4)
  • (modified) clang/lib/CodeGen/CGDebugInfo.h (+3)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+13)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+2)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+2)
  • (modified) clang/lib/CodeGen/TargetInfo.h (+5)
  • (modified) clang/lib/Index/USRGeneration.cpp (+7-1)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+13)
  • (modified) clang/lib/Parse/ParseExpr.cpp (+2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+5)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+4)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+6)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+27-7)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+4)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+2)
  • (modified) clang/lib/Sema/SemaType.cpp (+6)
  • (modified) clang/lib/Serialization/ASTCommon.cpp (+5)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+5)
  • (added) clang/test/AST/HLSL/builtin_hlsl_resource_t.hlsl (+10)
  • (added) clang/test/SemaHLSL/BuiltIns/builtin_hlsl_resource_t.hlsl (+65)
  • (modified) clang/tools/libclang/CIndex.cpp (+2)
  • (modified) clang/tools/libclang/CXType.cpp (+7-3)
  • (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+2)
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index ce2282937f86c..34aac8d45398a 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2966,7 +2966,10 @@ enum CXTypeKind {
 
   CXType_ExtVector = 176,
   CXType_Atomic = 177,
-  CXType_BTFTagAttributed = 178
+  CXType_BTFTagAttributed = 178,
+
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) CXType_##Id,
+#include "clang/Basic/HLSLIntangibleTypes.def"
 };
 
 /**
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..f45d3c6a09cf9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1164,6 +1164,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
   mutable QualType AutoDeductTy;     // Deduction against 'auto'.
diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def
index 444be4311a743..80548014fb484 100644
--- a/clang/include/clang/AST/BuiltinTypes.def
+++ b/clang/include/clang/AST/BuiltinTypes.def
@@ -257,6 +257,7 @@ BUILTIN_TYPE(OCLQueue, OCLQueueTy)
 // OpenCL reserve_id_t.
 BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)
 
+
 // This represents the type of an expression whose type is
 // totally unknown, e.g. 'T::foo'.  It is permitted for this to
 // appear in situations where the structure of the type is
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 62836ec5c6312..4713e503862d0 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2628,6 +2628,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   bool isBitIntType() const;                    // Bit-precise integer type
   bool isOpenCLSpecificType() const;            // Any OpenCL specific type
 
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) bool is##Id##Type() const;
+#include "clang/Basic/HLSLIntangibleTypes.def"
+  bool isHLSLSpecificType() const; // Any HLSL specific type
+
   /// Determines if this type, which must satisfy
   /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
   /// than implicitly __strong.
@@ -3020,6 +3024,9 @@ class BuiltinType : public Type {
 // AMDGPU types
 #define AMDGPU_TYPE(Name, Id, SingletonId) Id,
 #include "clang/Basic/AMDGPUTypes.def"
+// HLSL intangible Types
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/HLSLIntangibleTypes.def"
 // All other builtin types
 #define BUILTIN_TYPE(Id, SingletonId) Id,
 #define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -8258,6 +8265,19 @@ inline bool Type::isOpenCLSpecificType() const {
          isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType();
 }
 
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  inline bool Type::is##Id##Type() const {                                     \
+    return isSpecificBuiltinType(BuiltinType::Id);                             \
+  }
+#include "clang/Basic/HLSLIntangibleTypes.def"
+
+inline bool Type::isHLSLSpecificType() const {
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) is##Id##Type() ||
+  return
+#include "clang/Basic/HLSLIntangibleTypes.def"
+      false; // end boolean or operation
+}
+
 inline bool Type::isTemplateTypeParmType() const {
   return isa<TemplateTypeParmType>(CanonicalType);
 }
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 7d4353c2773a3..33398ecf5b849 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -872,6 +872,10 @@ let Class = BuiltinType in {
       case BuiltinType::ID: return ctx.SINGLETON_ID;
 #include "clang/Basic/AMDGPUTypes.def"
 
+#define HLSL_INTANGIBLE_TYPE(NAME, ID, SINGLETON_ID) \
+      case BuiltinType::ID: return ctx.SINGLETON_ID;
+#include "clang/Basic/HLSLIntangibleTypes.def"
+
 #define BUILTIN_TYPE(ID, SINGLETON_ID) \
       case BuiltinType::ID: return ctx.SINGLETON_ID;
 #include "clang/AST/BuiltinTypes.def"
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3df64b2ecef1b..fc61770deb13a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12335,6 +12335,10 @@ def warn_hlsl_availability_unavailable :
   Warning<err_unavailable.Summary>,
   InGroup<HLSLAvailability>, DefaultError;
 
+def err_hlsl_intangible_type_cannot_be_declared : Error<
+"HLSL intangible type cannot be declared here">;
+def err_hlsl_intangible_type_as_function_arg_or_return : Error<
+"HLSL intangible type cannot be used as function %select{argument|return value}0">;
 def err_hlsl_export_not_on_function : Error<
   "export declaration can only be used on functions">;
 
diff --git a/clang/include/clang/Basic/HLSLIntangibleTypes.def b/clang/include/clang/Basic/HLSLIntangibleTypes.def
new file mode 100644
index 0000000000000..9a45d02a94b70
--- /dev/null
+++ b/clang/include/clang/Basic/HLSLIntangibleTypes.def
@@ -0,0 +1,33 @@
+//===-- HLSLIntangibleTypes.def - HLSL standard intangible types ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--------------------------------------------------------------------------===//
+//
+// This file defines HLSL standard intangible types. These are implementation-
+// defined types such as handle types that have no defined object 
+// representation or value representation and their size is unknown at compile
+// time.
+//
+// The macro is:
+//
+//    HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)
+//
+// where:
+//
+//  - Name is the name of the builtin type.
+//
+//  - BuiltinType::Id is the enumerator defining the type.
+//
+//  - Context.SingletonId is the global singleton of this type.
+//
+// To include this file, define HLSL_INTANGIBLE_TYPE.
+// The macro will be undefined after inclusion.
+//
+//===----------------------------------------------------------------------===//
+
+HLSL_INTANGIBLE_TYPE(__builtin_hlsl_resource_t, HLSLResource, HLSLResourceTy)
+
+#undef HLSL_INTANGIBLE_TYPE
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index fb11e8212f8b6..7bfa26543578d 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -98,6 +98,9 @@ namespace clang {
 #define GENERIC_IMAGE_TYPE(ImgType, Id)                                      \
     TST_##ImgType##_t, // OpenCL image types
 #include "clang/Basic/OpenCLImageTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                          \
+    TST_##Name, // HLSL Intangible Types
+#include "clang/Basic/HLSLIntangibleTypes.def"
     TST_error // erroneous type
   };
 
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 37d570ca5e75b..09cd593c41905 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -643,6 +643,9 @@ KEYWORD(groupshared                 , KEYHLSL)
 KEYWORD(in                          , KEYHLSL)
 KEYWORD(inout                       , KEYHLSL)
 KEYWORD(out                         , KEYHLSL)
+// HLSL Intangible Types
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL)
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
 // OpenMP Type Traits
 UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..b374ea49b8697 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -322,6 +322,9 @@ class DeclSpec {
 #define GENERIC_IMAGE_TYPE(ImgType, Id) \
   static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t;
 #include "clang/Basic/OpenCLImageTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  static const TST TST_##Name = clang::TST_##Name;
+#include "clang/Basic/HLSLIntangibleTypes.def"
   static const TST TST_error = clang::TST_error;
 
   // type-qualifiers
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 38502a23f805e..f525ac9c95bfe 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1124,6 +1124,9 @@ enum PredefinedTypeIDs {
 // \brief AMDGPU types with auto numeration
 #define AMDGPU_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
 #include "clang/Basic/AMDGPUTypes.def"
+// \brief HLSL intangible types with auto numeration
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
   /// The placeholder type for unresolved templates.
   PREDEF_TYPE_UNRESOLVED_TEMPLATE,
@@ -1136,7 +1139,7 @@ enum PredefinedTypeIDs {
 ///
 /// Type IDs for non-predefined types will start at
 /// NUM_PREDEF_TYPE_IDs.
-const unsigned NUM_PREDEF_TYPE_IDS = 504;
+const unsigned NUM_PREDEF_TYPE_IDS = 505;
 
 // Ensure we do not overrun the predefined types we reserved
 // in the enum PredefinedTypeIDs above.
diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap
index 00ecd47d35b62..b6ab99bb85d8a 100644
--- a/clang/include/module.modulemap
+++ b/clang/include/module.modulemap
@@ -70,6 +70,7 @@ module Clang_Basic {
   textual header "clang/Basic/DiagnosticOptions.def"
   textual header "clang/Basic/FPOptions.def"
   textual header "clang/Basic/Features.def"
+  textual header "clang/Basic/HLSLIntangibleTypes.def"
   textual header "clang/Basic/LangOptions.def"
   textual header "clang/Basic/MSP430Target.def"
   textual header "clang/Basic/OpenACCClauses.def"
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 84deaf5429df7..fcbab9ddfc40e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1379,11 +1379,17 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
     InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
     InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
 
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
-    InitBuiltinType(Id##Ty, BuiltinType::Id);
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext)                                      \
+  InitBuiltinType(Id##Ty, BuiltinType::Id);
 #include "clang/Basic/OpenCLExtensionTypes.def"
   }
 
+  if (LangOpts.HLSL) {
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  InitBuiltinType(SingletonId, BuiltinType::Id);
+#include "clang/Basic/HLSLIntangibleTypes.def"
+  }
+
   if (Target.hasAArch64SVETypes()) {
 #define SVE_TYPE(Name, Id, SingletonId) \
     InitBuiltinType(SingletonId, BuiltinType::Id);
@@ -2241,6 +2247,11 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
     Align = ALIGN;                                                             \
     break;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
+      Width = 0;
+      Align = 8;
+      break;
     }
     break;
   case Type::ObjCObjectPointer:
@@ -8253,6 +8264,8 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
 #define PPC_VECTOR_TYPE(Name, Id, Size) \
     case BuiltinType::Id:
 #include "clang/Basic/PPCTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
 #define BUILTIN_TYPE(KIND, ID)
 #define PLACEHOLDER_TYPE(KIND, ID) \
     case BuiltinType::KIND:
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4e1b3a5a94de7..a6cb0d00fa1c2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1103,6 +1103,10 @@ ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
   case BuiltinType::Id:                                                        \
     return Importer.getToContext().SingletonId;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    return Importer.getToContext().SingletonId;
+#include "clang/Basic/HLSLIntangibleTypes.def"
 #define SHARED_SINGLETON_TYPE(Expansion)
 #define BUILTIN_TYPE(Id, SingletonId) \
   case BuiltinType::Id: return Importer.getToContext().SingletonId;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 374a3acf7aa26..dd67e4cd31262 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11860,6 +11860,8 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
       return GCCTypeClass::None;
 
     case BuiltinType::Dependent:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 5444dcf027fe2..ce79695814401 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3428,6 +3428,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
     Out << 'u' << type_name.size() << type_name;                               \
     break;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    type_name = #Name;                                                         \
+    Out << type_name.size() << type_name;                                      \
+    break;
+#include "clang/Basic/HLSLIntangibleTypes.def"
   }
 }
 
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 7f1e9ab02ec26..dcd5f747b44be 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2662,8 +2662,14 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
     mangleArtificialTagType(TagTypeKind::Struct, MangledName);                 \
     mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"});    \
     break;
-
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
+
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    mangleArtificialTagType(TagTypeKind::Struct, #Name);                       \
+    break;
+#include "clang/Basic/HLSLIntangibleTypes.def"
+
 #define SVE_TYPE(Name, Id, SingletonId) \
   case BuiltinType::Id:
 #include "clang/Basic/AArch64SVEACLETypes.def"
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp
index 48d1763125e6c..3d1f8488a8927 100644
--- a/clang/lib/AST/NSAPI.cpp
+++ b/clang/lib/AST/NSAPI.cpp
@@ -455,6 +455,8 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
   case BuiltinType::BoundMember:
   case BuiltinType::UnresolvedTemplate:
   case BuiltinType::Dependent:
diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp
index 3031d76abbd75..3c6cd2d0f4341 100644
--- a/clang/lib/AST/PrintfFormatString.cpp
+++ b/clang/lib/AST/PrintfFormatString.cpp
@@ -867,6 +867,8 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
 #define SIGNED_TYPE(Id, SingletonId)
 #define UNSIGNED_TYPE(Id, SingletonId)
 #define FLOATING_TYPE(Id, SingletonId)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index d8b885870de3a..163ad8ff4e665 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2446,6 +2446,9 @@ bool Type::isSizelessBuiltinType() const {
       // WebAssembly reference types
 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
+      // HLSL intangible types
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
       return true;
     default:
       return false;
@@ -3513,6 +3516,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
   case Id:                                                                     \
     return Name;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case Id:                                                                     \
+    return #Name;
+#include "clang/Basic/HLSLIntangibleTypes.def"
   }
 
   llvm_unreachable("Invalid builtin type.");
@@ -4815,6 +4822,8 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
     case BuiltinType::BuiltinFn:
     case BuiltinType::NullPtr:
     case BuiltinType::IncompleteMatrixIdx:
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 33e6ccbadc12d..0d653d6faaa82 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -430,6 +430,8 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
   case BuiltinType::BuiltinFn:
   case BuiltinType::IncompleteMatrixIdx:
   case BuiltinType::ArraySection:
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3d8a715b692de..98d14325d8f0d 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -744,6 +744,10 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
   case BuiltinType::Id: \
     return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
 #include "clang/Basic/OpenCLExtensionTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    return getOrCreateStructPtrType(#Name, SingletonId);
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AArch64SVEACLETypes.def"
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index a0c419cf1e208..4ccff581cadb2 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -87,6 +87,9 @@ class CGDebugInfo {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) llvm::DIType *SingletonId = nullptr;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  llvm::DIType *SingletonId = nullptr;
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
   /// Cache of previously constructed Types.
   llvm::DenseMap<const void *, ...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 3, 2024

@llvm/pr-subscribers-debuginfo

Author: Helena Kotas (hekota)

Changes

HLSL has a set of intangible types, which are described in in the draft HLSL Specification ([Basic.types]):
> There are special implementation-defined types such as handle types, which fall into a category of standard intangible types. Intangible types are types that have no defined object representation or value representation, as such the size is unknown at compile time.
>
> A class type T is an intangible class type if it contains an base classes or members of intangible class type, standard intangible type, or arrays of such types. Standard intangible types and intangible class types are collectively called intangible types(9).

This PR implements one standard intangible type __builtin_hlsl_resource_t and sets up the infrastructure that will make it easier to add more in the future, such as samplers or raytracing payload handles. The HLSL intangible types are declared in clang/include/clang/Basic/HLSLIntangibleTypes.def and this file is included with related macro definition in most places that require edits when a new type is added.

The new types are added as keywords and not typedefs to make sure they cannot be redeclared, and they can only be declared in builtin implicit headers. For example the __builtin_hlsl_resource_t type represents a handle to a memory resource and it is going to be used in builtin HLSL buffer types like this:

template &lt;typename T&gt;
class RWBuffer {
  [[clang::hlsl::resource::contained_type(T)]]
  [[clang::hlsl::resource::isROV(false)]]
  [[clang::hlsl::resource::class(uav)]]  
  __builtin_hlsl_resource_t Handle;
};

Part 1/3 of llvm/llvm-project#90631.


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

45 Files Affected:

  • (modified) clang/include/clang-c/Index.h (+4-1)
  • (modified) clang/include/clang/AST/ASTContext.h (+2)
  • (modified) clang/include/clang/AST/BuiltinTypes.def (+1)
  • (modified) clang/include/clang/AST/Type.h (+20)
  • (modified) clang/include/clang/AST/TypeProperties.td (+4)
  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4)
  • (added) clang/include/clang/Basic/HLSLIntangibleTypes.def (+33)
  • (modified) clang/include/clang/Basic/Specifiers.h (+3)
  • (modified) clang/include/clang/Basic/TokenKinds.def (+3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+3)
  • (modified) clang/include/clang/Serialization/ASTBitCodes.h (+4-1)
  • (modified) clang/include/module.modulemap (+1)
  • (modified) clang/lib/AST/ASTContext.cpp (+15-2)
  • (modified) clang/lib/AST/ASTImporter.cpp (+4)
  • (modified) clang/lib/AST/ExprConstant.cpp (+2)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+6)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+7-1)
  • (modified) clang/lib/AST/NSAPI.cpp (+2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+2)
  • (modified) clang/lib/AST/Type.cpp (+9)
  • (modified) clang/lib/AST/TypeLoc.cpp (+2)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+4)
  • (modified) clang/lib/CodeGen/CGDebugInfo.h (+3)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+13)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+2)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+5)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+2)
  • (modified) clang/lib/CodeGen/TargetInfo.h (+5)
  • (modified) clang/lib/Index/USRGeneration.cpp (+7-1)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+13)
  • (modified) clang/lib/Parse/ParseExpr.cpp (+2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+5)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+4)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+6)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+27-7)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+4)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+2)
  • (modified) clang/lib/Sema/SemaType.cpp (+6)
  • (modified) clang/lib/Serialization/ASTCommon.cpp (+5)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+5)
  • (added) clang/test/AST/HLSL/builtin_hlsl_resource_t.hlsl (+10)
  • (added) clang/test/SemaHLSL/BuiltIns/builtin_hlsl_resource_t.hlsl (+65)
  • (modified) clang/tools/libclang/CIndex.cpp (+2)
  • (modified) clang/tools/libclang/CXType.cpp (+7-3)
  • (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+2)
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index ce2282937f86c..34aac8d45398a 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2966,7 +2966,10 @@ enum CXTypeKind {
 
   CXType_ExtVector = 176,
   CXType_Atomic = 177,
-  CXType_BTFTagAttributed = 178
+  CXType_BTFTagAttributed = 178,
+
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) CXType_##Id,
+#include "clang/Basic/HLSLIntangibleTypes.def"
 };
 
 /**
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..f45d3c6a09cf9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1164,6 +1164,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
   mutable QualType AutoDeductTy;     // Deduction against 'auto'.
diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def
index 444be4311a743..80548014fb484 100644
--- a/clang/include/clang/AST/BuiltinTypes.def
+++ b/clang/include/clang/AST/BuiltinTypes.def
@@ -257,6 +257,7 @@ BUILTIN_TYPE(OCLQueue, OCLQueueTy)
 // OpenCL reserve_id_t.
 BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)
 
+
 // This represents the type of an expression whose type is
 // totally unknown, e.g. 'T::foo'.  It is permitted for this to
 // appear in situations where the structure of the type is
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 62836ec5c6312..4713e503862d0 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2628,6 +2628,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   bool isBitIntType() const;                    // Bit-precise integer type
   bool isOpenCLSpecificType() const;            // Any OpenCL specific type
 
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) bool is##Id##Type() const;
+#include "clang/Basic/HLSLIntangibleTypes.def"
+  bool isHLSLSpecificType() const; // Any HLSL specific type
+
   /// Determines if this type, which must satisfy
   /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
   /// than implicitly __strong.
@@ -3020,6 +3024,9 @@ class BuiltinType : public Type {
 // AMDGPU types
 #define AMDGPU_TYPE(Name, Id, SingletonId) Id,
 #include "clang/Basic/AMDGPUTypes.def"
+// HLSL intangible Types
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/HLSLIntangibleTypes.def"
 // All other builtin types
 #define BUILTIN_TYPE(Id, SingletonId) Id,
 #define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -8258,6 +8265,19 @@ inline bool Type::isOpenCLSpecificType() const {
          isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType();
 }
 
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  inline bool Type::is##Id##Type() const {                                     \
+    return isSpecificBuiltinType(BuiltinType::Id);                             \
+  }
+#include "clang/Basic/HLSLIntangibleTypes.def"
+
+inline bool Type::isHLSLSpecificType() const {
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) is##Id##Type() ||
+  return
+#include "clang/Basic/HLSLIntangibleTypes.def"
+      false; // end boolean or operation
+}
+
 inline bool Type::isTemplateTypeParmType() const {
   return isa<TemplateTypeParmType>(CanonicalType);
 }
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 7d4353c2773a3..33398ecf5b849 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -872,6 +872,10 @@ let Class = BuiltinType in {
       case BuiltinType::ID: return ctx.SINGLETON_ID;
 #include "clang/Basic/AMDGPUTypes.def"
 
+#define HLSL_INTANGIBLE_TYPE(NAME, ID, SINGLETON_ID) \
+      case BuiltinType::ID: return ctx.SINGLETON_ID;
+#include "clang/Basic/HLSLIntangibleTypes.def"
+
 #define BUILTIN_TYPE(ID, SINGLETON_ID) \
       case BuiltinType::ID: return ctx.SINGLETON_ID;
 #include "clang/AST/BuiltinTypes.def"
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3df64b2ecef1b..fc61770deb13a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12335,6 +12335,10 @@ def warn_hlsl_availability_unavailable :
   Warning<err_unavailable.Summary>,
   InGroup<HLSLAvailability>, DefaultError;
 
+def err_hlsl_intangible_type_cannot_be_declared : Error<
+"HLSL intangible type cannot be declared here">;
+def err_hlsl_intangible_type_as_function_arg_or_return : Error<
+"HLSL intangible type cannot be used as function %select{argument|return value}0">;
 def err_hlsl_export_not_on_function : Error<
   "export declaration can only be used on functions">;
 
diff --git a/clang/include/clang/Basic/HLSLIntangibleTypes.def b/clang/include/clang/Basic/HLSLIntangibleTypes.def
new file mode 100644
index 0000000000000..9a45d02a94b70
--- /dev/null
+++ b/clang/include/clang/Basic/HLSLIntangibleTypes.def
@@ -0,0 +1,33 @@
+//===-- HLSLIntangibleTypes.def - HLSL standard intangible types ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--------------------------------------------------------------------------===//
+//
+// This file defines HLSL standard intangible types. These are implementation-
+// defined types such as handle types that have no defined object 
+// representation or value representation and their size is unknown at compile
+// time.
+//
+// The macro is:
+//
+//    HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)
+//
+// where:
+//
+//  - Name is the name of the builtin type.
+//
+//  - BuiltinType::Id is the enumerator defining the type.
+//
+//  - Context.SingletonId is the global singleton of this type.
+//
+// To include this file, define HLSL_INTANGIBLE_TYPE.
+// The macro will be undefined after inclusion.
+//
+//===----------------------------------------------------------------------===//
+
+HLSL_INTANGIBLE_TYPE(__builtin_hlsl_resource_t, HLSLResource, HLSLResourceTy)
+
+#undef HLSL_INTANGIBLE_TYPE
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index fb11e8212f8b6..7bfa26543578d 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -98,6 +98,9 @@ namespace clang {
 #define GENERIC_IMAGE_TYPE(ImgType, Id)                                      \
     TST_##ImgType##_t, // OpenCL image types
 #include "clang/Basic/OpenCLImageTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                          \
+    TST_##Name, // HLSL Intangible Types
+#include "clang/Basic/HLSLIntangibleTypes.def"
     TST_error // erroneous type
   };
 
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 37d570ca5e75b..09cd593c41905 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -643,6 +643,9 @@ KEYWORD(groupshared                 , KEYHLSL)
 KEYWORD(in                          , KEYHLSL)
 KEYWORD(inout                       , KEYHLSL)
 KEYWORD(out                         , KEYHLSL)
+// HLSL Intangible Types
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL)
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
 // OpenMP Type Traits
 UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..b374ea49b8697 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -322,6 +322,9 @@ class DeclSpec {
 #define GENERIC_IMAGE_TYPE(ImgType, Id) \
   static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t;
 #include "clang/Basic/OpenCLImageTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  static const TST TST_##Name = clang::TST_##Name;
+#include "clang/Basic/HLSLIntangibleTypes.def"
   static const TST TST_error = clang::TST_error;
 
   // type-qualifiers
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 38502a23f805e..f525ac9c95bfe 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1124,6 +1124,9 @@ enum PredefinedTypeIDs {
 // \brief AMDGPU types with auto numeration
 #define AMDGPU_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
 #include "clang/Basic/AMDGPUTypes.def"
+// \brief HLSL intangible types with auto numeration
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
   /// The placeholder type for unresolved templates.
   PREDEF_TYPE_UNRESOLVED_TEMPLATE,
@@ -1136,7 +1139,7 @@ enum PredefinedTypeIDs {
 ///
 /// Type IDs for non-predefined types will start at
 /// NUM_PREDEF_TYPE_IDs.
-const unsigned NUM_PREDEF_TYPE_IDS = 504;
+const unsigned NUM_PREDEF_TYPE_IDS = 505;
 
 // Ensure we do not overrun the predefined types we reserved
 // in the enum PredefinedTypeIDs above.
diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap
index 00ecd47d35b62..b6ab99bb85d8a 100644
--- a/clang/include/module.modulemap
+++ b/clang/include/module.modulemap
@@ -70,6 +70,7 @@ module Clang_Basic {
   textual header "clang/Basic/DiagnosticOptions.def"
   textual header "clang/Basic/FPOptions.def"
   textual header "clang/Basic/Features.def"
+  textual header "clang/Basic/HLSLIntangibleTypes.def"
   textual header "clang/Basic/LangOptions.def"
   textual header "clang/Basic/MSP430Target.def"
   textual header "clang/Basic/OpenACCClauses.def"
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 84deaf5429df7..fcbab9ddfc40e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1379,11 +1379,17 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
     InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
     InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
 
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
-    InitBuiltinType(Id##Ty, BuiltinType::Id);
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext)                                      \
+  InitBuiltinType(Id##Ty, BuiltinType::Id);
 #include "clang/Basic/OpenCLExtensionTypes.def"
   }
 
+  if (LangOpts.HLSL) {
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  InitBuiltinType(SingletonId, BuiltinType::Id);
+#include "clang/Basic/HLSLIntangibleTypes.def"
+  }
+
   if (Target.hasAArch64SVETypes()) {
 #define SVE_TYPE(Name, Id, SingletonId) \
     InitBuiltinType(SingletonId, BuiltinType::Id);
@@ -2241,6 +2247,11 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
     Align = ALIGN;                                                             \
     break;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
+      Width = 0;
+      Align = 8;
+      break;
     }
     break;
   case Type::ObjCObjectPointer:
@@ -8253,6 +8264,8 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
 #define PPC_VECTOR_TYPE(Name, Id, Size) \
     case BuiltinType::Id:
 #include "clang/Basic/PPCTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
 #define BUILTIN_TYPE(KIND, ID)
 #define PLACEHOLDER_TYPE(KIND, ID) \
     case BuiltinType::KIND:
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4e1b3a5a94de7..a6cb0d00fa1c2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1103,6 +1103,10 @@ ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
   case BuiltinType::Id:                                                        \
     return Importer.getToContext().SingletonId;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    return Importer.getToContext().SingletonId;
+#include "clang/Basic/HLSLIntangibleTypes.def"
 #define SHARED_SINGLETON_TYPE(Expansion)
 #define BUILTIN_TYPE(Id, SingletonId) \
   case BuiltinType::Id: return Importer.getToContext().SingletonId;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 374a3acf7aa26..dd67e4cd31262 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11860,6 +11860,8 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
       return GCCTypeClass::None;
 
     case BuiltinType::Dependent:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 5444dcf027fe2..ce79695814401 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3428,6 +3428,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
     Out << 'u' << type_name.size() << type_name;                               \
     break;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    type_name = #Name;                                                         \
+    Out << type_name.size() << type_name;                                      \
+    break;
+#include "clang/Basic/HLSLIntangibleTypes.def"
   }
 }
 
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 7f1e9ab02ec26..dcd5f747b44be 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2662,8 +2662,14 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
     mangleArtificialTagType(TagTypeKind::Struct, MangledName);                 \
     mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"});    \
     break;
-
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
+
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    mangleArtificialTagType(TagTypeKind::Struct, #Name);                       \
+    break;
+#include "clang/Basic/HLSLIntangibleTypes.def"
+
 #define SVE_TYPE(Name, Id, SingletonId) \
   case BuiltinType::Id:
 #include "clang/Basic/AArch64SVEACLETypes.def"
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp
index 48d1763125e6c..3d1f8488a8927 100644
--- a/clang/lib/AST/NSAPI.cpp
+++ b/clang/lib/AST/NSAPI.cpp
@@ -455,6 +455,8 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
   case BuiltinType::BoundMember:
   case BuiltinType::UnresolvedTemplate:
   case BuiltinType::Dependent:
diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp
index 3031d76abbd75..3c6cd2d0f4341 100644
--- a/clang/lib/AST/PrintfFormatString.cpp
+++ b/clang/lib/AST/PrintfFormatString.cpp
@@ -867,6 +867,8 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
 #define SIGNED_TYPE(Id, SingletonId)
 #define UNSIGNED_TYPE(Id, SingletonId)
 #define FLOATING_TYPE(Id, SingletonId)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index d8b885870de3a..163ad8ff4e665 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2446,6 +2446,9 @@ bool Type::isSizelessBuiltinType() const {
       // WebAssembly reference types
 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
+      // HLSL intangible types
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
       return true;
     default:
       return false;
@@ -3513,6 +3516,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
   case Id:                                                                     \
     return Name;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case Id:                                                                     \
+    return #Name;
+#include "clang/Basic/HLSLIntangibleTypes.def"
   }
 
   llvm_unreachable("Invalid builtin type.");
@@ -4815,6 +4822,8 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
     case BuiltinType::BuiltinFn:
     case BuiltinType::NullPtr:
     case BuiltinType::IncompleteMatrixIdx:
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 33e6ccbadc12d..0d653d6faaa82 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -430,6 +430,8 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
   case BuiltinType::BuiltinFn:
   case BuiltinType::IncompleteMatrixIdx:
   case BuiltinType::ArraySection:
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3d8a715b692de..98d14325d8f0d 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -744,6 +744,10 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
   case BuiltinType::Id: \
     return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
 #include "clang/Basic/OpenCLExtensionTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  case BuiltinType::Id:                                                        \
+    return getOrCreateStructPtrType(#Name, SingletonId);
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AArch64SVEACLETypes.def"
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index a0c419cf1e208..4ccff581cadb2 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -87,6 +87,9 @@ class CGDebugInfo {
 #include "clang/Basic/WebAssemblyReferenceTypes.def"
 #define AMDGPU_TYPE(Name, Id, SingletonId) llvm::DIType *SingletonId = nullptr;
 #include "clang/Basic/AMDGPUTypes.def"
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
+  llvm::DIType *SingletonId = nullptr;
+#include "clang/Basic/HLSLIntangibleTypes.def"
 
   /// Cache of previously constructed Types.
   llvm::DenseMap<const void *, ...
[truncated]

@hekota
Copy link
Member Author

hekota commented Jul 3, 2024

@ChuanqiXu9 - any idea why is your new test Modules/no-external-type-id.cppm failing on this PR?
It is expecting // CHECK: <DECL_FUNCTION {{.*}} op8=4048 in the llvm-bcanalyzer output and gets op8=4056.

@hekota hekota mentioned this pull request Jul 3, 2024
3 tasks
@damyanp
Copy link
Contributor

damyanp commented Jul 3, 2024

I see many places where extra cases have been added for the intangible types but no corresponding tests. Is that ok? How did you know to update these places?

I also don't see anywhere that actually successfully uses __builtin_hlsl_resource_t. Am I missing it, or should I not expect to see it?

@hekota
Copy link
Member Author

hekota commented Jul 4, 2024

I see many places where extra cases have been added for the intangible types but no corresponding tests. Is that ok? How did you know to update these places?

I looked at similar types in other languages, such as the image* types in OpenCL or __externref_t in WebAssembly. I used the same implementation style and defaults as these types (except __externref_t is a typedef and not a language keyword). Some of the cases are tested when the two builtin_hlsl_resource_t.hlsl files are parsed and AST dumped, but it is not possible to test all case until we can actually use the type (#84824).

I also don't see anywhere that actually successfully uses __builtin_hlsl_resource_t. Am I missing it, or should I not expect to see it?

You are correct - the type cannot be directly declared in user code, so the tests only check for errors and that the type shows up properly in AST. It is possible to use this type internally in Clang or in implicit headers though, which are two ways how we could define RWBuffer and other builtin types that will internally use __builtin_hlsl_resource_t handle. That will come alive in (#84824).

Copy link
Collaborator

@llvm-beanz llvm-beanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few comments, but mostly I really like this direction!

@bob80905
Copy link
Contributor

Just an FYI, the syntax for adding a resource_class attribute as currently implemented looks like this:
[[hlsl::resource_class(SRV)]]
In your description, you may want to update this and other similar attributes.

hekota added 3 commits July 23, 2024 11:14
- rename to __hlsl_resource_t
- allow instantiation of sizeless intangible types in fields

Update expected type ID in no-external-type-id.cppm - the test does not have a stable baseline when new builtin types are added.
@@ -1390,7 +1390,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
#include "clang/Basic/HLSLIntangibleTypes.def"
}

if (Target.hasAArch64SVETypes()) {
if (Target.hasAArch64SVETypes() ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this expected change for intangible AST type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this change in this PR diff. This change was done in #99446 and came in via merge from main.

@@ -23,7 +23,7 @@ export module b;
import a;
export int b();

// CHECK: <DECL_FUNCTION {{.*}} op8=4048
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChuanqiXu9 - FYI, I am updating the test baseline. The op8 parameter is type ID and it is based on the number of builtin types. When a new type is added the test fails because the expected type ID value does not match anymore. Please consider updating the test baseline to be resistant against this. :)

@hekota
Copy link
Member Author

hekota commented Aug 1, 2024

I also don't see anywhere that actually successfully uses __builtin_hlsl_resource_t. Am I missing it, or should I not expect to see it?

You are correct - the type cannot be directly declared in user code, so the tests only check for errors and that the type shows up properly in AST. It is possible to use this type internally in Clang or in implicit headers though, which are two ways how we could define RWBuffer and other builtin types that will internally use __builtin_hlsl_resource_t handle. That will come alive in (#84824).

@damyanp - FYI, the PR has been updated to allow instantiation of __hlsl_resource_t.

Copy link
Contributor

@bogner bogner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@hekota hekota merged commit 52956b0 into llvm:main Aug 5, 2024
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category debuginfo HLSL HLSL Language Support lldb
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants