[clang] [lldb] [Clang][SPIRV] Add __spirv_event_t builtin type (PR #207077)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 13 11:53:51 PDT 2026
https://github.com/elizabethandrews updated https://github.com/llvm/llvm-project/pull/207077
>From f8a82d3009e6329c9028af5a9c08b5d1bc89082b Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 26 Jun 2026 12:43:47 -0700
Subject: [PATCH 1/6] Implement ocl_event_t
---
clang/lib/AST/ASTContext.cpp | 5 +++-
clang/lib/CodeGen/CodeGenModule.cpp | 4 +++-
clang/lib/Sema/Sema.cpp | 3 +++
.../CodeGenSYCL/builtin-ocl-event-type.cpp | 14 +++++++++++
.../test/SemaSYCL/builtin-ocl-event-type.cpp | 24 +++++++++++++++++++
5 files changed, 48 insertions(+), 2 deletions(-)
create mode 100644 clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp
create mode 100644 clang/test/SemaSYCL/builtin-ocl-event-type.cpp
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index abf0cd5e18c2b..df9a4d3c30b61 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1426,13 +1426,16 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
+ if (LangOpts.OpenCL || Target.getTriple().isSPIROrSPIRV()) {
+ InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
+ }
+
if (LangOpts.OpenCL) {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
InitBuiltinType(SingletonId, BuiltinType::Id);
#include "clang/Basic/OpenCLImageTypes.def"
InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler);
- InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 41049d85121be..504d32b0a825c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -497,7 +497,9 @@ CodeGenModule::CodeGenModule(ASTContext &C,
if (LangOpts.ObjC)
createObjCRuntime();
- if (LangOpts.OpenCL)
+ // OpenCL types (e.g., event_t) are used by SPIR-V targets in SYCL device
+ // compilation. OpenCL runtime provides the required type conversions.
+ if (LangOpts.OpenCL || getTriple().isSPIROrSPIRV())
createOpenCLRuntime();
if (LangOpts.OpenMP)
createOpenMPRuntime();
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 78fbc9e31842d..6552819c7aedc 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -447,6 +447,9 @@ void Sema::Initialize() {
addImplicitTypedef("size_t", Context.getSizeType());
}
+ if (Context.getTargetInfo().getTriple().isSPIROrSPIRV())
+ addImplicitTypedef("__ocl_event_t", Context.OCLEventTy);
+
// Initialize predefined OpenCL types and supported extensions and (optional)
// core features.
if (getLangOpts().OpenCL) {
diff --git a/clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp b/clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp
new file mode 100644
index 0000000000000..3b19d18ec36cd
--- /dev/null
+++ b/clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
+
+// Test that __ocl_event_t is available in SYCL device code and lowers to
+// target("spirv.Event") in LLVM IR for SPIR-V targets.
+
+[[clang::sycl_external]] void test_ocl_event_param(__ocl_event_t evt) {}
+// CHECK: define{{.*}} void @_Z20test_ocl_event_param9ocl_event(target("spirv.Event") %evt)
+
+[[clang::sycl_external]] void test_ocl_event() {
+ __ocl_event_t evt;
+ // CHECK: %evt = alloca target("spirv.Event")
+ test_ocl_event_param(evt);
+ // CHECK: call spir_func void @_Z20test_ocl_event_param9ocl_event(target("spirv.Event") %0)
+}
diff --git a/clang/test/SemaSYCL/builtin-ocl-event-type.cpp b/clang/test/SemaSYCL/builtin-ocl-event-type.cpp
new file mode 100644
index 0000000000000..e42a2ccc36970
--- /dev/null
+++ b/clang/test/SemaSYCL/builtin-ocl-event-type.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Test that __ocl_event_t is available in SYCL device code
+
+// A generic kernel launch function.
+template<typename KernelName, typename... Ts>
+void sycl_kernel_launch(const char *, Ts...) {}
+
+template<typename KNT, typename T>
+[[clang::sycl_kernel_entry_point(KNT)]]
+void kernel_single_task(T t) {
+ t();
+}
+
+struct KernelName;
+
+void test_ocl_event_t() {
+ kernel_single_task<KernelName>([]() {
+ // Test that __ocl_event_t is defined and can be used
+ __ocl_event_t evt;
+ (void)evt;
+ });
+}
>From 9686460ce89f87d3fd855799101288f066367793 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Mon, 29 Jun 2026 14:01:54 -0700
Subject: [PATCH 2/6] Revert "Implement ocl_event_t"
This reverts commit f8a82d3009 to implement SPIR-V builtin type.
---
clang/lib/AST/ASTContext.cpp | 5 +---
clang/lib/CodeGen/CodeGenModule.cpp | 4 +---
clang/lib/Sema/Sema.cpp | 3 ---
.../CodeGenSYCL/builtin-ocl-event-type.cpp | 14 -----------
.../test/SemaSYCL/builtin-ocl-event-type.cpp | 24 -------------------
5 files changed, 2 insertions(+), 48 deletions(-)
delete mode 100644 clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp
delete mode 100644 clang/test/SemaSYCL/builtin-ocl-event-type.cpp
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index df9a4d3c30b61..abf0cd5e18c2b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1426,16 +1426,13 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
- if (LangOpts.OpenCL || Target.getTriple().isSPIROrSPIRV()) {
- InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
- }
-
if (LangOpts.OpenCL) {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
InitBuiltinType(SingletonId, BuiltinType::Id);
#include "clang/Basic/OpenCLImageTypes.def"
InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler);
+ InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 504d32b0a825c..41049d85121be 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -497,9 +497,7 @@ CodeGenModule::CodeGenModule(ASTContext &C,
if (LangOpts.ObjC)
createObjCRuntime();
- // OpenCL types (e.g., event_t) are used by SPIR-V targets in SYCL device
- // compilation. OpenCL runtime provides the required type conversions.
- if (LangOpts.OpenCL || getTriple().isSPIROrSPIRV())
+ if (LangOpts.OpenCL)
createOpenCLRuntime();
if (LangOpts.OpenMP)
createOpenMPRuntime();
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 6552819c7aedc..78fbc9e31842d 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -447,9 +447,6 @@ void Sema::Initialize() {
addImplicitTypedef("size_t", Context.getSizeType());
}
- if (Context.getTargetInfo().getTriple().isSPIROrSPIRV())
- addImplicitTypedef("__ocl_event_t", Context.OCLEventTy);
-
// Initialize predefined OpenCL types and supported extensions and (optional)
// core features.
if (getLangOpts().OpenCL) {
diff --git a/clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp b/clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp
deleted file mode 100644
index 3b19d18ec36cd..0000000000000
--- a/clang/test/CodeGenSYCL/builtin-ocl-event-type.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
-
-// Test that __ocl_event_t is available in SYCL device code and lowers to
-// target("spirv.Event") in LLVM IR for SPIR-V targets.
-
-[[clang::sycl_external]] void test_ocl_event_param(__ocl_event_t evt) {}
-// CHECK: define{{.*}} void @_Z20test_ocl_event_param9ocl_event(target("spirv.Event") %evt)
-
-[[clang::sycl_external]] void test_ocl_event() {
- __ocl_event_t evt;
- // CHECK: %evt = alloca target("spirv.Event")
- test_ocl_event_param(evt);
- // CHECK: call spir_func void @_Z20test_ocl_event_param9ocl_event(target("spirv.Event") %0)
-}
diff --git a/clang/test/SemaSYCL/builtin-ocl-event-type.cpp b/clang/test/SemaSYCL/builtin-ocl-event-type.cpp
deleted file mode 100644
index e42a2ccc36970..0000000000000
--- a/clang/test/SemaSYCL/builtin-ocl-event-type.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -verify -fsyntax-only %s
-// expected-no-diagnostics
-
-// Test that __ocl_event_t is available in SYCL device code
-
-// A generic kernel launch function.
-template<typename KernelName, typename... Ts>
-void sycl_kernel_launch(const char *, Ts...) {}
-
-template<typename KNT, typename T>
-[[clang::sycl_kernel_entry_point(KNT)]]
-void kernel_single_task(T t) {
- t();
-}
-
-struct KernelName;
-
-void test_ocl_event_t() {
- kernel_single_task<KernelName>([]() {
- // Test that __ocl_event_t is defined and can be used
- __ocl_event_t evt;
- (void)evt;
- });
-}
>From bae6f2a6569afec9abc1b1171da4d2d657026203 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 1 Jul 2026 12:32:38 -0700
Subject: [PATCH 3/6] [Clang][SPIRV] Add __spirv_event_t builtin type
Add a new builtin type __spirv_event_t for SPIR-V targets. It represents
SPIR-V's OpTypeEvent and lowers to the target("spirv.Event") extension
type.
We would like to expose SPIR-V instructions to users via builtins (not yet
implemented). The builtins return an event type.
---
clang/include/clang/AST/ASTContext.h | 2 ++
clang/include/clang/AST/TypeBase.h | 3 ++
clang/include/clang/AST/TypeProperties.td | 4 +++
clang/include/clang/Basic/SPIRVTypes.def | 22 ++++++++++++
.../include/clang/Serialization/ASTBitCodes.h | 5 ++-
clang/lib/AST/ASTContext.cpp | 15 ++++++++
clang/lib/AST/ASTImporter.cpp | 4 +++
clang/lib/AST/ExprConstant.cpp | 2 ++
clang/lib/AST/ItaniumMangle.cpp | 5 +++
clang/lib/AST/NSAPI.cpp | 2 ++
clang/lib/AST/PrintfFormatString.cpp | 3 ++
clang/lib/AST/Type.cpp | 6 ++++
clang/lib/AST/TypeLoc.cpp | 2 ++
clang/lib/CodeGen/CGDebugInfo.cpp | 9 +++++
clang/lib/CodeGen/CGDebugInfo.h | 2 ++
clang/lib/CodeGen/CodeGenTypes.cpp | 4 +++
clang/lib/CodeGen/ItaniumCXXABI.cpp | 2 ++
clang/lib/Sema/Sema.cpp | 8 +++++
clang/lib/Sema/SemaExpr.cpp | 4 +++
clang/lib/Serialization/ASTCommon.cpp | 5 +++
clang/lib/Serialization/ASTReader.cpp | 5 +++
.../UnifiedSymbolResolution/USRGeneration.cpp | 5 +++
clang/test/AST/spirv-event-type.cpp | 15 ++++++++
clang/test/CodeGenCXX/spirv-event-type.cpp | 34 +++++++++++++++++++
clang/test/SemaCXX/spirv-event.cpp | 21 ++++++++++++
clang/tools/libclang/CIndex.cpp | 2 ++
26 files changed, 190 insertions(+), 1 deletion(-)
create mode 100644 clang/include/clang/Basic/SPIRVTypes.def
create mode 100644 clang/test/AST/spirv-event-type.cpp
create mode 100644 clang/test/CodeGenCXX/spirv-event-type.cpp
create mode 100644 clang/test/SemaCXX/spirv-event.cpp
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index a4ed852d36442..798c59e5449c9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1373,6 +1373,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
+#include "clang/Basic/SPIRVTypes.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/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index e3141a82b54d2..00a11770f6832 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -3250,6 +3250,9 @@ class BuiltinType : public Type {
// HLSL intangible Types
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/HLSLIntangibleTypes.def"
+// SPIRV types
+#define SPIRV_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/SPIRVTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 0f3722b36774a..3e02fc5125a8f 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -867,6 +867,10 @@ let Class = BuiltinType in {
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(NAME, ID, SINGLETON_ID) \
+ case BuiltinType::ID: return ctx.SINGLETON_ID;
+#include "clang/Basic/SPIRVTypes.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/SPIRVTypes.def b/clang/include/clang/Basic/SPIRVTypes.def
new file mode 100644
index 0000000000000..e8c536c007ccd
--- /dev/null
+++ b/clang/include/clang/Basic/SPIRVTypes.def
@@ -0,0 +1,22 @@
+//===-- SPIRVTypes.def - Metadata about SPIRV 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 various SPIRV builtin types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SPIRV_OPAQUE_TYPE
+#define SPIRV_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
+ SPIRV_TYPE(Name, Id, SingletonId)
+#endif
+
+SPIRV_OPAQUE_TYPE("__spirv_event_t", "__spirv_event_t", SPIRVEvent, SPIRVEventTy)
+
+#undef SPIRV_TYPE
+#undef SPIRV_OPAQUE_TYPE
+
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 279380de2f7fe..ff9fc7b2be9ea 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1154,6 +1154,9 @@ enum PredefinedTypeIDs {
// \brief HLSL intangible types with auto numeration
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/HLSLIntangibleTypes.def"
+// \brief SPIRV types with auto numeration
+#define SPIRV_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
+#include "clang/Basic/SPIRVTypes.def"
/// The placeholder type for unresolved templates.
PREDEF_TYPE_UNRESOLVED_TEMPLATE,
@@ -1166,7 +1169,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
-const unsigned NUM_PREDEF_TYPE_IDS = 529;
+const unsigned NUM_PREDEF_TYPE_IDS = 530;
// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index abf0cd5e18c2b..c5b7bc5ae3f07 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1488,6 +1488,13 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
#include "clang/Basic/AMDGPUTypes.def"
}
+ if (Target.getTriple().isSPIRV() ||
+ (AuxTarget && AuxTarget->getTriple().isSPIRV())) {
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ InitBuiltinType(SingletonId, BuiltinType::Id);
+#include "clang/Basic/SPIRVTypes.def"
+ }
+
// Builtin type for __objc_yes and __objc_no
ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?
SignedCharTy : BoolTy);
@@ -2438,6 +2445,12 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Target->getPointerWidth(LangAS::Default);
Align = Target->getPointerAlign(LangAS::Default);
break;
+#define SPIRV_OPAQUE_TYPE(NAME, MANGLEDNAME, ID, SINGLETONID) \
+ case BuiltinType::ID: \
+ Width = Target->getPointerWidth(LangAS::Default); \
+ Align = Target->getPointerAlign(LangAS::Default); \
+ break;
+#include "clang/Basic/SPIRVTypes.def"
}
break;
case Type::ObjCObjectPointer:
@@ -9281,6 +9294,8 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
#include "clang/Basic/AMDGPUTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
{
DiagnosticsEngine &Diags = C->getDiagnostics();
Diags.Report(diag::err_unsupported_objc_primitive_encoding)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index f5848d154f49e..156ae82bbaa28 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1365,6 +1365,10 @@ ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
case BuiltinType::Id: \
return Importer.getToContext().SingletonId;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ return Importer.getToContext().SingletonId;
+#include "clang/Basic/SPIRVTypes.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 1642c41a99a2f..d877d0d4cd402 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15830,6 +15830,8 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
return GCCTypeClass::None;
case BuiltinType::Dependent:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 2e74aeb558e3d..b448d53fac7e2 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3513,6 +3513,11 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
mangleVendorType(#Name); \
break;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ mangleVendorType(Name); \
+ break;
+#include "clang/Basic/SPIRVTypes.def"
}
}
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp
index 17f5ee5dee3d1..7142ded5a551d 100644
--- a/clang/lib/AST/NSAPI.cpp
+++ b/clang/lib/AST/NSAPI.cpp
@@ -457,6 +457,8 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.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 4b56157d64a5d..e0cff04069d59 100644
--- a/clang/lib/AST/PrintfFormatString.cpp
+++ b/clang/lib/AST/PrintfFormatString.cpp
@@ -957,6 +957,9 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.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 55c3e5c3ead17..0a7542a19cd2b 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3664,6 +3664,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
case Id: \
return #Name;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case Id: \
+ return Name;
+#include "clang/Basic/SPIRVTypes.def"
}
llvm_unreachable("Invalid builtin type.");
@@ -5251,6 +5255,8 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.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 7e72a85136966..c2f83e7f5cbae 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -421,6 +421,8 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.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 3d429d0d78e82..286940f5f099e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1141,6 +1141,15 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
return SingletonId; \
}
#include "clang/Basic/AMDGPUTypes.def"
+#define SPIRV_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
+ case BuiltinType::Id: { \
+ if (!SingletonId) \
+ SingletonId = \
+ DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
+ MangledName, TheCU, TheCU->getFile(), 0); \
+ return SingletonId; \
+ }
+#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::UChar:
case BuiltinType::Char_U:
Encoding = llvm::dwarf::DW_ATE_unsigned_char;
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 4c385c26efc4e..f9cec24b2b4d7 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -97,6 +97,8 @@ class CGDebugInfo {
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
llvm::DIType *SingletonId = nullptr;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) llvm::DIType *SingletonId = nullptr;
+#include "clang/Basic/SPIRVTypes.def"
/// Cache of previously constructed Types.
llvm::DenseMap<const void *, llvm::TrackingMDRef> TypeCache;
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index b28a0eb82f302..8d6547195360e 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -617,6 +617,10 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
#include "clang/Basic/HLSLIntangibleTypes.def"
ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
break;
+#define SPIRV_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
+ case BuiltinType::Id: \
+ return llvm::TargetExtType::get(getLLVMContext(), "spirv.Event");
+#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::Dependent:
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) \
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index b4b3284f752ae..090e18b5f3512 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3778,6 +3778,8 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::ShortAccum:
case BuiltinType::Accum:
case BuiltinType::LongAccum:
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 78fbc9e31842d..a741261163b9e 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -580,6 +580,14 @@ void Sema::Initialize() {
#include "clang/Basic/AMDGPUTypes.def"
}
+ if (Context.getTargetInfo().getTriple().isSPIRV() ||
+ (Context.getAuxTargetInfo() &&
+ Context.getAuxTargetInfo()->getTriple().isSPIRV())) {
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ addImplicitTypedef(Name, Context.SingletonId);
+#include "clang/Basic/SPIRVTypes.def"
+ }
+
if (Context.getTargetInfo().hasBuiltinMSVaList()) {
DeclarationName MSVaList = &Context.Idents.get("__builtin_ms_va_list");
if (IdResolver.begin(MSVaList) == IdResolver.end())
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ad6e7183cb3a4..6d2772827001e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6448,6 +6448,8 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
#define PLACEHOLDER_TYPE(ID, SINGLETON_ID)
#define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID:
#include "clang/AST/BuiltinTypes.def"
@@ -22028,6 +22030,8 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
#define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id:
#define PLACEHOLDER_TYPE(Id, SingletonId)
#include "clang/AST/BuiltinTypes.def"
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index 49e6fe8004cec..d10de5c288d69 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -268,6 +268,11 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
ID = PREDEF_TYPE_##Id##_ID; \
break;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ ID = PREDEF_TYPE_##Id##_ID; \
+ break;
+#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::BuiltinFn:
ID = PREDEF_TYPE_BUILTIN_FN;
break;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f8a6a38bb9b5c..098e7acf86eaf 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8146,6 +8146,11 @@ QualType ASTReader::GetType(TypeID ID) {
T = Context.SingletonId; \
break;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case PREDEF_TYPE_##Id##_ID: \
+ T = Context.SingletonId; \
+ break;
+#include "clang/Basic/SPIRVTypes.def"
}
assert(!T.isNull() && "Unknown predefined type");
diff --git a/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp b/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp
index c4788dd6917f2..eec09795d922b 100644
--- a/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp
+++ b/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp
@@ -826,6 +826,11 @@ void USRGenerator::VisitType(QualType T) {
Out << "@BT@" << #Name; \
break;
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ Out << "@BT@" << Name; \
+ break;
+#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::ShortAccum:
Out << "@BT at ShortAccum";
break;
diff --git a/clang/test/AST/spirv-event-type.cpp b/clang/test/AST/spirv-event-type.cpp
new file mode 100644
index 0000000000000..8f29c6215b64d
--- /dev/null
+++ b/clang/test/AST/spirv-event-type.cpp
@@ -0,0 +1,15 @@
+// REQUIRES: spirv-registered-target
+// Test without serialization:
+// RUN: %clang_cc1 -triple spirv64 -ast-dump %s | FileCheck %s
+//
+// Test with serialization:
+// RUN: %clang_cc1 -triple spirv64 -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -triple spirv64 -include-pch %t -ast-dump-all /dev/null | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" | FileCheck %s
+
+void test(void) {
+ __spirv_event_t e;
+}
+
+// CHECK: TypedefDecl {{.*}} implicit {{.*}}__spirv_event_t '__spirv_event_t'
+// CHECK-NEXT: -BuiltinType {{.*}} '__spirv_event_t'
+// CHECK: VarDecl {{.*}} e '__spirv_event_t'
diff --git a/clang/test/CodeGenCXX/spirv-event-type.cpp b/clang/test/CodeGenCXX/spirv-event-type.cpp
new file mode 100644
index 0000000000000..edf27336d9612
--- /dev/null
+++ b/clang/test/CodeGenCXX/spirv-event-type.cpp
@@ -0,0 +1,34 @@
+// REQUIRES: spirv-registered-target
+// RUN: %clang_cc1 -triple spirv64 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple spirv64 -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s --check-prefix=DEBUG
+
+// Verify that __spirv_event_t lowers to the target("spirv.Event") extension
+// type and that it mangles as a vendor extended type.
+
+namespace std { class type_info; }
+
+__spirv_event_t getEvent();
+void consumeEvent(__spirv_event_t e);
+
+const std::type_info &ti = typeid(__spirv_event_t);
+// CHECK: @_ZTIu15__spirv_event_t = {{.*}}constant { {{.*}} } { {{.*}}@_ZTVN10__cxxabiv123__fundamental_type_infoE{{.*}}, {{.*}}@_ZTSu15__spirv_event_t {{.*}}}
+// CHECK: @_ZTSu15__spirv_event_t = {{.*}}constant [19 x i8] c"u15__spirv_event_t\00"
+
+void test() {
+ __spirv_event_t e = getEvent();
+ consumeEvent(e);
+}
+// CHECK-LABEL: define spir_func void @_Z4testv()
+// CHECK: %e = alloca target("spirv.Event")
+// CHECK: %call = call spir_func target("spirv.Event") @_Z8getEventv()
+// CHECK: store target("spirv.Event") %call, ptr %e
+// CHECK: %[[LD:.*]] = load target("spirv.Event"), ptr %e
+// CHECK: call spir_func void @_Z12consumeEventu15__spirv_event_t(target("spirv.Event") %[[LD]])
+
+// CHECK: declare spir_func target("spirv.Event") @_Z8getEventv()
+// CHECK: declare spir_func void @_Z12consumeEventu15__spirv_event_t(target("spirv.Event"))
+
+// DEBUG: !DILocalVariable(name: "e", {{.*}} type: ![[TD:[0-9]+]])
+// DEBUG: ![[TD]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__spirv_event_t", {{.*}} baseType: ![[BT:[0-9]+]])
+// DEBUG: ![[BT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "__spirv_event_t", {{.*}} flags: DIFlagFwdDecl)
+
diff --git a/clang/test/SemaCXX/spirv-event.cpp b/clang/test/SemaCXX/spirv-event.cpp
new file mode 100644
index 0000000000000..335d43d243883
--- /dev/null
+++ b/clang/test/SemaCXX/spirv-event.cpp
@@ -0,0 +1,21 @@
+// REQUIRES: spirv-registered-target
+// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 -triple spirv64 -Wno-unused-value %s
+
+// __spirv_event_t is an opaque type: it cannot be initialized from, converted
+// to, or cast from other types, nor used in arithmetic.
+void foo() {
+ int n = 100;
+ __spirv_event_t v = 0; // expected-error {{cannot initialize a variable of type '__spirv_event_t' with an rvalue of type 'int'}}
+ static_cast<__spirv_event_t>(n); // expected-error {{static_cast from 'int' to '__spirv_event_t' is not allowed}}
+ reinterpret_cast<__spirv_event_t>(n); // expected-error {{reinterpret_cast from 'int' to '__spirv_event_t' is not allowed}}
+ (void)(v + v); // expected-error {{invalid operands to binary expression ('__spirv_event_t' and '__spirv_event_t')}}
+ int x(v); // expected-error {{cannot initialize a variable of type 'int' with an lvalue of type '__spirv_event_t'}}
+ __spirv_event_t k;
+ int *ip = (int *)k; // expected-error {{cannot cast from type '__spirv_event_t' to pointer type 'int *'}}
+}
+
+// __spirv_event_t can be used as a function parameter, a template argument, and
+// a struct field.
+template <class T> void bar(T);
+void use(__spirv_event_t r) { bar(r); }
+struct S { __spirv_event_t r; int a; };
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index ac2fad38a1348..a373528c2f2fa 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1586,6 +1586,8 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
#define BUILTIN_TYPE(Id, SingletonId)
#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
>From f556bc6f5a25da35be38521cea6532414c86278b Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Tue, 7 Jul 2026 12:32:43 -0700
Subject: [PATCH 4/6] Apply review comments
---
clang/include/clang/Basic/SPIRVTypes.def | 24 +++++++++++++++---------
clang/lib/AST/ASTContext.cpp | 4 ++--
clang/lib/CodeGen/CGDebugInfo.cpp | 6 +++---
clang/lib/CodeGen/CodeGenTypes.cpp | 2 +-
clang/test/SemaCXX/spirv-event.cpp | 7 ++++++-
5 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/clang/include/clang/Basic/SPIRVTypes.def b/clang/include/clang/Basic/SPIRVTypes.def
index e8c536c007ccd..01495fdbbeaca 100644
--- a/clang/include/clang/Basic/SPIRVTypes.def
+++ b/clang/include/clang/Basic/SPIRVTypes.def
@@ -6,17 +6,23 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines various SPIRV builtin types.
+// This file defines SPIRV builtin opaque types. The macro is:
+//
+// SPIRV_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 SPIRV_TYPE. The macro will be undefined after
+// inclusion.
//
//===----------------------------------------------------------------------===//
-#ifndef SPIRV_OPAQUE_TYPE
-#define SPIRV_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
- SPIRV_TYPE(Name, Id, SingletonId)
-#endif
-
-SPIRV_OPAQUE_TYPE("__spirv_event_t", "__spirv_event_t", SPIRVEvent, SPIRVEventTy)
+SPIRV_TYPE("__spirv_event_t", SPIRVEvent, SPIRVEventTy)
#undef SPIRV_TYPE
-#undef SPIRV_OPAQUE_TYPE
-
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c5b7bc5ae3f07..b102f066dac27 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2445,8 +2445,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Target->getPointerWidth(LangAS::Default);
Align = Target->getPointerAlign(LangAS::Default);
break;
-#define SPIRV_OPAQUE_TYPE(NAME, MANGLEDNAME, ID, SINGLETONID) \
- case BuiltinType::ID: \
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
Width = Target->getPointerWidth(LangAS::Default); \
Align = Target->getPointerAlign(LangAS::Default); \
break;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 286940f5f099e..198c77097505c 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1141,12 +1141,12 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
return SingletonId; \
}
#include "clang/Basic/AMDGPUTypes.def"
-#define SPIRV_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
+#define SPIRV_TYPE(Name, Id, SingletonId) \
case BuiltinType::Id: { \
if (!SingletonId) \
SingletonId = \
- DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
- MangledName, TheCU, TheCU->getFile(), 0); \
+ DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
+ TheCU, TheCU->getFile(), 0); \
return SingletonId; \
}
#include "clang/Basic/SPIRVTypes.def"
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 8d6547195360e..9d63e295f2309 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -617,7 +617,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
#include "clang/Basic/HLSLIntangibleTypes.def"
ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
break;
-#define SPIRV_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
+#define SPIRV_TYPE(Name, Id, SingletonId) \
case BuiltinType::Id: \
return llvm::TargetExtType::get(getLLVMContext(), "spirv.Event");
#include "clang/Basic/SPIRVTypes.def"
diff --git a/clang/test/SemaCXX/spirv-event.cpp b/clang/test/SemaCXX/spirv-event.cpp
index 335d43d243883..913e2d1f8b226 100644
--- a/clang/test/SemaCXX/spirv-event.cpp
+++ b/clang/test/SemaCXX/spirv-event.cpp
@@ -2,7 +2,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 -triple spirv64 -Wno-unused-value %s
// __spirv_event_t is an opaque type: it cannot be initialized from, converted
-// to, or cast from other types, nor used in arithmetic.
+// to, or cast from other types, nor used in arithmetic. It cannot be used in
+// constant evaluation.
void foo() {
int n = 100;
__spirv_event_t v = 0; // expected-error {{cannot initialize a variable of type '__spirv_event_t' with an rvalue of type 'int'}}
@@ -12,10 +13,14 @@ void foo() {
int x(v); // expected-error {{cannot initialize a variable of type 'int' with an lvalue of type '__spirv_event_t'}}
__spirv_event_t k;
int *ip = (int *)k; // expected-error {{cannot cast from type '__spirv_event_t' to pointer type 'int *'}}
+ constexpr __spirv_event_t e; // expected-error {{constexpr variable cannot have non-literal type 'const __spirv_event_t'}}
}
+template <__spirv_event_t V> void baz(); // expected-error {{a non-type template parameter cannot have type '__spirv_event_t'}}
+
// __spirv_event_t can be used as a function parameter, a template argument, and
// a struct field.
template <class T> void bar(T);
void use(__spirv_event_t r) { bar(r); }
struct S { __spirv_event_t r; int a; };
+
>From a8fba91942f05acbe8843f20120f6fb47e6ead78 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 10 Jul 2026 10:01:44 -0700
Subject: [PATCH 5/6] Apply Review Comments
---
clang/include/clang/AST/TypeBase.h | 9 +++++
clang/lib/AST/ASTContext.cpp | 2 ++
clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 2 ++
clang/lib/CodeGen/QualTypeMapper.cpp | 4 +++
clang/test/CodeGenCXX/spirv-event-type.cpp | 34 +++++++++++++------
clang/test/SemaCXX/spirv-event.cpp | 10 ++++++
6 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index 00a11770f6832..b89303da6271f 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -2801,6 +2801,9 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isHLSLIntangibleType()
const; // Any HLSL intangible type (builtin, array, class)
+#define SPIRV_TYPE(Name, Id, SingletonId) bool is##Id##Type() const;
+#include "clang/Basic/SPIRVTypes.def"
+
/// Determines if this type, which must satisfy
/// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
/// than implicitly __strong.
@@ -8988,6 +8991,12 @@ inline bool Type::isOpenCLSpecificType() const {
}
#include "clang/Basic/HLSLIntangibleTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) \
+ inline bool Type::is##Id##Type() const { \
+ return isSpecificBuiltinType(BuiltinType::Id); \
+ }
+#include "clang/Basic/SPIRVTypes.def"
+
inline bool Type::isHLSLBuiltinIntangibleType() const {
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) is##Id##Type() ||
return
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b102f066dac27..e0670a9cc6a7e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3597,6 +3597,8 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
case BuiltinType::WasmExternRef:
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
llvm_unreachable("not yet implemented");
}
llvm_unreachable("should never get here");
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 552d73966e97b..296d5b0d5ac04 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -738,6 +738,8 @@ static bool typeInfoIsInStandardLibrary(const BuiltinType *ty) {
#include "clang/Basic/RISCVVTypes.def"
#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
#include "clang/Basic/AMDGPUTypes.def"
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::ShortAccum:
case BuiltinType::Accum:
case BuiltinType::LongAccum:
diff --git a/clang/lib/CodeGen/QualTypeMapper.cpp b/clang/lib/CodeGen/QualTypeMapper.cpp
index 31d9250a48ec9..212a138f9b7b7 100644
--- a/clang/lib/CodeGen/QualTypeMapper.cpp
+++ b/clang/lib/CodeGen/QualTypeMapper.cpp
@@ -267,6 +267,10 @@ QualTypeMapper::convertBuiltinType(const BuiltinType *BT) {
#include "clang/Basic/HLSLIntangibleTypes.def"
llvm::reportFatalInternalError(
"HLSL intangible types not yet Supported in ABI lowering library");
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
+ llvm::reportFatalInternalError(
+ "SPIR-V types not yet supported in ABI lowering library");
// Placeholder types should never reach ABI lowering.
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
diff --git a/clang/test/CodeGenCXX/spirv-event-type.cpp b/clang/test/CodeGenCXX/spirv-event-type.cpp
index edf27336d9612..c2224c5dd1d9b 100644
--- a/clang/test/CodeGenCXX/spirv-event-type.cpp
+++ b/clang/test/CodeGenCXX/spirv-event-type.cpp
@@ -5,6 +5,8 @@
// Verify that __spirv_event_t lowers to the target("spirv.Event") extension
// type and that it mangles as a vendor extended type.
+// Verify debug information generated for spirv.Event.
+
namespace std { class type_info; }
__spirv_event_t getEvent();
@@ -14,21 +16,31 @@ const std::type_info &ti = typeid(__spirv_event_t);
// CHECK: @_ZTIu15__spirv_event_t = {{.*}}constant { {{.*}} } { {{.*}}@_ZTVN10__cxxabiv123__fundamental_type_infoE{{.*}}, {{.*}}@_ZTSu15__spirv_event_t {{.*}}}
// CHECK: @_ZTSu15__spirv_event_t = {{.*}}constant [19 x i8] c"u15__spirv_event_t\00"
-void test() {
- __spirv_event_t e = getEvent();
- consumeEvent(e);
-}
-// CHECK-LABEL: define spir_func void @_Z4testv()
-// CHECK: %e = alloca target("spirv.Event")
-// CHECK: %call = call spir_func target("spirv.Event") @_Z8getEventv()
-// CHECK: store target("spirv.Event") %call, ptr %e
-// CHECK: %[[LD:.*]] = load target("spirv.Event"), ptr %e
+void test(__spirv_event_t e) {
+// CHECK: define spir_func void @_Z4testu15__spirv_event_t(target("spirv.Event") %e)
+ __spirv_event_t copyConstructed = e;
+// CHECK: %[[CC:.*]] = load target("spirv.Event"), ptr %e.addr
+// CHECK: store target("spirv.Event") %[[CC]], ptr %copyConstructed
+ __spirv_event_t moveConstructed = getEvent();
+// CHECK: %[[MC:.*]] = call spir_func target("spirv.Event") @_Z8getEventv()
+// CHECK: store target("spirv.Event") %[[MC]], ptr %moveConstructed
+ copyConstructed = e;
+// CHECK: %[[CA:.*]] = load target("spirv.Event"), ptr %e.addr
+// CHECK: store target("spirv.Event") %[[CA]], ptr %copyConstructed
+ moveConstructed = getEvent();
+// CHECK: %[[MA:.*]] = call spir_func target("spirv.Event") @_Z8getEventv()
+// CHECK: store target("spirv.Event") %[[MA]], ptr %moveConstructed
+ consumeEvent(copyConstructed);
+// CHECK: %[[LD:.*]] = load target("spirv.Event"), ptr %copyConstructed
// CHECK: call spir_func void @_Z12consumeEventu15__spirv_event_t(target("spirv.Event") %[[LD]])
+}
// CHECK: declare spir_func target("spirv.Event") @_Z8getEventv()
// CHECK: declare spir_func void @_Z12consumeEventu15__spirv_event_t(target("spirv.Event"))
-// DEBUG: !DILocalVariable(name: "e", {{.*}} type: ![[TD:[0-9]+]])
-// DEBUG: ![[TD]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__spirv_event_t", {{.*}} baseType: ![[BT:[0-9]+]])
+// DEBUG: ![[TD:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__spirv_event_t", {{.*}} baseType: ![[BT:[0-9]+]])
// DEBUG: ![[BT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "__spirv_event_t", {{.*}} flags: DIFlagFwdDecl)
+// DEBUG-DAG: !DILocalVariable(name: "e", {{.*}} type: ![[TD]])
+// DEBUG-DAG: !DILocalVariable(name: "copyConstructed", {{.*}} type: ![[TD]])
+// DEBUG-DAG: !DILocalVariable(name: "moveConstructed", {{.*}} type: ![[TD]])
diff --git a/clang/test/SemaCXX/spirv-event.cpp b/clang/test/SemaCXX/spirv-event.cpp
index 913e2d1f8b226..fb5640788080e 100644
--- a/clang/test/SemaCXX/spirv-event.cpp
+++ b/clang/test/SemaCXX/spirv-event.cpp
@@ -24,3 +24,13 @@ template <class T> void bar(T);
void use(__spirv_event_t r) { bar(r); }
struct S { __spirv_event_t r; int a; };
+// __spirv_event_t is copyable and moveable.
+__spirv_event_t get();
+void copy_and_move(__spirv_event_t a) {
+ __spirv_event_t copyConstructed = a;
+ __spirv_event_t moveConstructed = get();
+ __spirv_event_t assigned;
+ assigned = a;
+ assigned = get();
+}
+
>From 242715bb9c9f1f6d5f61bc38cafffd864330106a Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Mon, 13 Jul 2026 11:48:26 -0700
Subject: [PATCH 6/6] Apply review comments and fix lldb build error
---
clang/lib/AST/MicrosoftMangle.cpp | 5 +++++
clang/lib/CodeGen/CGDebugInfo.cpp | 9 ++-------
clang/test/CodeGenCXX/spirv-event-type.cpp | 3 ++-
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 5 +++++
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index adfe260a0d091..efef5e174b2ae 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3026,6 +3026,11 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
mangleArtificialTagType(TagTypeKind::Struct, "__SVCount_t", {"__clang"});
break;
+#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
+ Error(Range.getBegin(), "SPIR-V built-in type") << Range;
+ break;
+
// Issue an error for any type not explicitly handled.
default:
Error(Range.getBegin(), "built-in type: ",
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 198c77097505c..a6bc270d884a4 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1142,13 +1142,8 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
}
#include "clang/Basic/AMDGPUTypes.def"
#define SPIRV_TYPE(Name, Id, SingletonId) \
- case BuiltinType::Id: { \
- if (!SingletonId) \
- SingletonId = \
- DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, \
- TheCU, TheCU->getFile(), 0); \
- return SingletonId; \
- }
+ case BuiltinType::Id: \
+ return getOrCreateStructPtrType(Name, SingletonId);
#include "clang/Basic/SPIRVTypes.def"
case BuiltinType::UChar:
case BuiltinType::Char_U:
diff --git a/clang/test/CodeGenCXX/spirv-event-type.cpp b/clang/test/CodeGenCXX/spirv-event-type.cpp
index c2224c5dd1d9b..8cd42b3ef68f8 100644
--- a/clang/test/CodeGenCXX/spirv-event-type.cpp
+++ b/clang/test/CodeGenCXX/spirv-event-type.cpp
@@ -38,7 +38,8 @@ void test(__spirv_event_t e) {
// CHECK: declare spir_func target("spirv.Event") @_Z8getEventv()
// CHECK: declare spir_func void @_Z12consumeEventu15__spirv_event_t(target("spirv.Event"))
-// DEBUG: ![[TD:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__spirv_event_t", {{.*}} baseType: ![[BT:[0-9]+]])
+// DEBUG: ![[TD:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__spirv_event_t", {{.*}} baseType: ![[PTR:[0-9]+]])
+// DEBUG: ![[PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BT:[0-9]+]]
// DEBUG: ![[BT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "__spirv_event_t", {{.*}} flags: DIFlagFwdDecl)
// DEBUG-DAG: !DILocalVariable(name: "e", {{.*}} type: ![[TD]])
// DEBUG-DAG: !DILocalVariable(name: "copyConstructed", {{.*}} type: ![[TD]])
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 82fd9844cf96a..d6c258211c8f8 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -5004,6 +5004,11 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type) {
case clang::BuiltinType::Id:
#include "clang/Basic/AMDGPUTypes.def"
break;
+
+ // SPIR-V builtin types.
+#define SPIRV_TYPE(Name, Id, SingletonId) case clang::BuiltinType::Id:
+#include "clang/Basic/SPIRVTypes.def"
+ break;
}
break;
// All pointer types are represented as unsigned integer encodings. We may
More information about the cfe-commits
mailing list