pmatos updated this revision to Diff 461518.
pmatos added a comment.
Address further concerns.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D122215/new/
https://reviews.llvm.org/D122215
Files:
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Type.h
clang/include/clang/AST/TypeProperties.td
clang/include/clang/Basic/AddressSpaces.h
clang/include/clang/Basic/BuiltinsWebAssembly.def
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/WebAssemblyReferenceTypes.def
clang/include/clang/Sema/Sema.h
clang/include/clang/Serialization/ASTBitCodes.h
clang/include/clang/module.modulemap
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/AST/NSAPI.cpp
clang/lib/AST/PrintfFormatString.cpp
clang/lib/AST/Type.cpp
clang/lib/AST/TypeLoc.cpp
clang/lib/Basic/Targets/DirectX.h
clang/lib/Basic/Targets/NVPTX.h
clang/lib/Basic/Targets/SPIR.h
clang/lib/Basic/Targets/TCE.h
clang/lib/Basic/Targets/X86.h
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/CodeGenTypes.cpp
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/CodeGen/TargetInfo.h
clang/lib/Index/USRGeneration.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaType.cpp
clang/lib/Serialization/ASTCommon.cpp
clang/lib/Serialization/ASTReader.cpp
clang/test/CodeGen/WebAssembly/wasm-externref.c
clang/test/CodeGen/builtins-wasm.c
clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
clang/test/Sema/wasm-refs-and-tables.c
clang/test/SemaCXX/wasm-refs.cpp
clang/test/SemaTemplate/address_space-dependent.cpp
clang/tools/libclang/CIndex.cpp
llvm/include/llvm/IR/Type.h
llvm/lib/CodeGen/ValueTypes.cpp
llvm/lib/IR/Type.cpp
Index: llvm/lib/IR/Type.cpp
===================================================================
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -304,6 +304,18 @@
return getInt64Ty(C)->getPointerTo(AS);
}
+Type *Type::getWasm_ExternrefTy(LLVMContext &C) {
+ // opaque pointer in addrspace(10)
+ static PointerType *Ty = PointerType::get(C, 10);
+ return Ty;
+}
+
+Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
+ // opaque pointer in addrspace(20)
+ static PointerType *Ty = PointerType::get(C, 20);
+ return Ty;
+}
+
//===----------------------------------------------------------------------===//
// IntegerType Implementation
//===----------------------------------------------------------------------===//
Index: llvm/lib/CodeGen/ValueTypes.cpp
===================================================================
--- llvm/lib/CodeGen/ValueTypes.cpp
+++ llvm/lib/CodeGen/ValueTypes.cpp
@@ -204,12 +204,8 @@
case MVT::x86mmx: return Type::getX86_MMXTy(Context);
case MVT::x86amx: return Type::getX86_AMXTy(Context);
case MVT::i64x8: return IntegerType::get(Context, 512);
- case MVT::externref:
- // pointer to opaque struct in addrspace(10)
- return PointerType::get(StructType::create(Context), 10);
- case MVT::funcref:
- // pointer to i8 addrspace(20)
- return PointerType::get(Type::getInt8Ty(Context), 20);
+ case MVT::externref: return Type::getWasm_ExternrefTy(Context);
+ case MVT::funcref: return Type::getWasm_FuncrefTy(Context);
case MVT::v1i1:
return FixedVectorType::get(Type::getInt1Ty(Context), 1);
case MVT::v2i1:
Index: llvm/include/llvm/IR/Type.h
===================================================================
--- llvm/include/llvm/IR/Type.h
+++ llvm/include/llvm/IR/Type.h
@@ -473,6 +473,8 @@
static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0);
+ static Type *getWasm_ExternrefTy(LLVMContext &C);
+ static Type *getWasm_FuncrefTy(LLVMContext &C);
/// Return a pointer to the current type. This is equivalent to
/// PointerType::get(Foo, AddrSpace).
Index: clang/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -1627,6 +1627,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define BUILTIN_TYPE(Id, SingletonId)
#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
Index: clang/test/SemaTemplate/address_space-dependent.cpp
===================================================================
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
template <long int I>
void tooBig() {
- __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388588)}}
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
}
template <long int I>
@@ -101,7 +101,7 @@
car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
HasASTemplateFields<1> HASTF;
neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
- correct<0x7FFFEB>();
+ correct<0x7FFFEA>();
tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
__attribute__((address_space(1))) char *x;
Index: clang/test/SemaCXX/wasm-refs.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/wasm-refs.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -std=gnu++11 -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
+
+// This file tests C++ specific constructs with WebAssembly references and
+// tables. See wasm-refs-and-tables.c for C constructs.
+
+__externref_t ref;
+__externref_t &ref_ref1 = ref; // expected-error {{references to WebAssembly reference types are illegal}}
+__externref_t &ref_ref2(ref); // expected-error {{references to WebAssembly reference types are illegal}}
+
+static __externref_t table[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+static __externref_t (&ref_to_table1)[0] = table; // expected-error {{array has sizeless element type '__externref_t'}}
+static __externref_t (&ref_to_table2)[0](table); // expected-error {{array has sizeless element type '__externref_t'}}
+
+void illegal_argument_1(__externref_t &r); // expected-error {{references to WebAssembly reference types are illegal}}
+void illegal_argument_2(__externref_t (&t)[0]); // expected-error {{array has sizeless element type '__externref_t'}}
+
+__externref_t &illegal_return_1(); // expected-error {{references to WebAssembly reference types are illegal}}
+__externref_t (&illegal_return_2())[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+
+void illegal_throw1() throw(__externref_t); // expected-error {{sizeless type '__externref_t' is not allowed in exception specification}}
+void illegal_throw2() throw(__externref_t *); // expected-error {{pointers to WebAssembly reference types are illegal}}
+void illegal_throw3() throw(__externref_t &); // expected-error {{references to WebAssembly reference types are illegal}}
+void illegal_throw4() throw(__externref_t[0]); // expected-error {{array has sizeless element type '__externref_t'}}
+
+class RefClass {
+ __externref_t f1; // expected-error {{field has sizeless type '__externref_t'}}
+ __externref_t f2[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t f3[]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t f4[0][0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t *f5; // expected-error {{pointers to WebAssembly reference types are illegal}}
+ __externref_t ****f6; // expected-error {{pointers to WebAssembly reference types are illegal}}
+ __externref_t (*f7)[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+};
+
+struct AStruct {};
+
+template <typename T>
+struct TemplatedStruct {
+ T f; // expected-error {{field has sizeless type '__externref_t'}}
+ void foo(T);
+ T bar(void);
+ T arr[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ T *ptr; // expected-error {{pointers to WebAssembly reference types are illegal}}
+};
+
+void func() {
+ int foo = 40;
+ static_cast<__externref_t>(foo); // expected-error {{static_cast from 'int' to '__externref_t' is not allowed}}
+ static_cast<__externref_t *>(&foo); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ static_cast<int>(ref); // expected-error {{static_cast from '__externref_t' to 'int' is not allowed}}
+ __externref_t(10); // expected-error {{functional-style cast from 'int' to '__externref_t' is not allowed}}
+ int i(ref); // expected-error {{cannot initialize a variable of type 'int' with an lvalue of type '__externref_t'}}
+ const_cast<__externref_t[0]>(table); // expected-error {{array has sizeless element type '__externref_t'}}
+ const_cast<__externref_t *>(table); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ reinterpret_cast<__externref_t>(foo); // expected-error {{reinterpret_cast from 'int' to '__externref_t' is not allowed}}
+ reinterpret_cast<int>(ref); // expected-error {{reinterpret_cast from '__externref_t' to 'int' is not allowed}}
+ int iarr[0];
+ reinterpret_cast<__externref_t[0]>(iarr); // expected-error {{array has sizeless element type '__externref_t'}}
+ reinterpret_cast<__externref_t *>(iarr); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ dynamic_cast<__externref_t>(foo); // expected-error {{invalid target type '__externref_t' for dynamic_cast; target type must be a reference or pointer type to a defined class}}
+ dynamic_cast<__externref_t *>(&foo); // expected-error {{pointers to WebAssembly reference types are illegal}}
+
+ TemplatedStruct<__externref_t> ts1; // expected-note {{in instantiation}}
+ TemplatedStruct<__externref_t *> ts2; // expected-error {{pointers to WebAssembly reference types are illegal}}
+ TemplatedStruct<__externref_t &> ts3; // expected-error {{references to WebAssembly reference types are illegal}}
+ TemplatedStruct<__externref_t[0]> ts4; // expected-error {{array has sizeless element type '__externref_t'}}
+
+ auto auto_ref = ref;
+
+ auto fn1 = [](__externref_t x) { return x; };
+ auto fn2 = [](__externref_t *x) { return x; }; // expected-error {{pointers to WebAssembly reference types are illegal}}
+ auto fn3 = [](__externref_t &x) { return x; }; // expected-error {{references to WebAssembly reference types are illegal}}
+ auto fn4 = [](__externref_t x[0]) { return x; }; // expected-error {{array has sizeless element type '__externref_t'}}
+ auto fn5 = [&auto_ref](void) { return true; }; // expected-error {{cannot capture WebAssembly reference}}
+ auto fn6 = [auto_ref](void) { return true; }; // expected-error {{cannot capture WebAssembly reference}}
+ auto fn7 = [&](void) { auto_ref; return true; }; // expected-error {{cannot capture WebAssembly reference}}
+ auto fn8 = [=](void) { auto_ref; return true; }; // expected-error {{cannot capture WebAssembly reference}}
+
+ alignof(__externref_t); // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
+ alignof(ref); // expected-warning {{'alignof' applied to an expression is a GNU extension}} expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
+ alignof(__externref_t[0]); // expected-error {{array has sizeless element type '__externref_t'}}
+
+ throw ref; // expected-error {{cannot throw object of sizeless type '__externref_t'}}
+ throw &ref; // expected-error {{cannot take address of WebAssembly reference}}
+
+ try {
+ } catch (__externref_t) { // expected-error {{cannot catch sizeless type '__externref_t'}}
+ }
+ try {
+ } catch (__externref_t *) { // expected-error {{pointers to WebAssembly reference types are illegal}}
+ }
+ try {
+ } catch (__externref_t &) { // expected-error {{references to WebAssembly reference types are illegal}}
+ }
+ try {
+ } catch (__externref_t[0]) { // expected-error {{array has sizeless element type '__externref_t'}}
+ }
+
+ new __externref_t; // expected-error {{allocation of sizeless type '__externref_t'}}
+ new __externref_t[0]; // expected-error {{allocation of sizeless type '__externref_t'}}
+
+ delete ref; // expected-error {{cannot delete expression of type '__externref_t'}}
+}
Index: clang/test/Sema/wasm-refs-and-tables.c
===================================================================
--- /dev/null
+++ clang/test/Sema/wasm-refs-and-tables.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple wasm32 -target-feature +reference-types %s
+
+// Note: As WebAssembly references are sizeless types, we don't exhaustively
+// test for cases covered by sizeless-1.c and similar tests.
+
+// Unlike standard sizeless types, reftype globals are supported.
+__externref_t r1;
+extern __externref_t r2;
+static __externref_t r3;
+
+__externref_t *t1; // expected-error {{pointers to WebAssembly reference types are illegal}}
+__externref_t **t2; // expected-error {{pointers to WebAssembly reference types are illegal}}
+__externref_t ******t3; // expected-error {{pointers to WebAssembly reference types are illegal}}
+static __externref_t t4[3]; // expected-error {{array has sizeless element type '__externref_t'}}
+static __externref_t t5[]; // expected-error {{array has sizeless element type '__externref_t'}}
+static __externref_t t6[] = {0}; // expected-error {{array has sizeless element type '__externref_t'}}
+__externref_t t7[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+static __externref_t t8[0][0]; // expected-error {{array has sizeless element type '__externref_t'}}
+
+static __externref_t table[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+
+struct s {
+ __externref_t f1; // expected-error {{field has sizeless type '__externref_t'}}
+ __externref_t f2[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t f3[]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t f4[0][0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t *f5; // expected-error {{pointers to WebAssembly reference types are illegal}}
+ __externref_t ****f6; // expected-error {{pointers to WebAssembly reference types are illegal}}
+};
+
+union u {
+ __externref_t f1; // expected-error {{field has sizeless type '__externref_t'}}
+ __externref_t f2[0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t f3[]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t f4[0][0]; // expected-error {{array has sizeless element type '__externref_t'}}
+ __externref_t *f5; // expected-error {{pointers to WebAssembly reference types are illegal}}
+ __externref_t ****f6; // expected-error {{pointers to WebAssembly reference types are illegal}}
+};
+
+void illegal_argument_1(__externref_t table[]); // expected-error {{array has sizeless element type '__externref_t'}}
+void illegal_argument_2(__externref_t table[0][0]); // expected-error {{array has sizeless element type '__externref_t'}}
+void illegal_argument_3(__externref_t *table); // expected-error {{pointers to WebAssembly reference types are illegal}}
+void illegal_argument_4(__externref_t ***table); // expected-error {{pointers to WebAssembly reference types are illegal}}
+
+__externref_t *illegal_return_1(); // expected-error {{pointers to WebAssembly reference types are illegal}}
+__externref_t ***illegal_return_2(); // expected-error {{pointers to WebAssembly reference types are illegal}}
+
+void varargs(int, ...);
+
+__externref_t func(__externref_t ref) {
+ &ref; // expected-error {{cannot take address of WebAssembly reference}}
+ int foo = 40;
+ (__externref_t *)(&foo); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ (__externref_t ****)(&foo); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ sizeof(ref); // expected-error {{invalid application of 'sizeof' to sizeless type '__externref_t'}}
+ sizeof(__externref_t); // expected-error {{invalid application of 'sizeof' to sizeless type '__externref_t'}}
+ sizeof(__externref_t[0]); // expected-error {{array has sizeless element type '__externref_t'}}
+ sizeof(__externref_t[0][0]); // expected-error {{array has sizeless element type '__externref_t'}}
+ sizeof(__externref_t *); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ sizeof(__externref_t ***); // expected-error {{pointers to WebAssembly reference types are illegal}};
+ // expected-warning@+1 {{'_Alignof' applied to an expression is a GNU extension}}
+ _Alignof(ref); // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
+ _Alignof(__externref_t); // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
+ _Alignof(__externref_t[]); // expected-error {{array has sizeless element type '__externref_t'}}
+ _Alignof(__externref_t[0][0]); // expected-error {{array has sizeless element type '__externref_t'}}
+ _Alignof(__externref_t *); // expected-error {{pointers to WebAssembly reference types are illegal}}
+ _Alignof(__externref_t ***); // expected-error {{pointers to WebAssembly reference types are illegal}};
+ varargs(1, ref); // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
+
+ return ref;
+}
Index: clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
@@ -0,0 +1,12 @@
+// REQUIRES: webassembly-registered-target
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -target-feature +reference-types -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -target-feature +reference-types -emit-llvm -o - -std=c++11 | FileCheck %s
+
+namespace std {
+class type_info;
+};
+
+auto &externref = typeid(__externref_t);
+
+// CHECK-DAG: @_ZTS11externref_t = {{.*}} c"11externref_t\00"
+// CHECK-DAG: @_ZTI11externref_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTS11externref_t
Index: clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
@@ -0,0 +1,6 @@
+// REQUIRES: webassembly-registered-target
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -target-feature +reference-types -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -target-feature +reference-types -emit-llvm -o - -std=c++11 | FileCheck %s
+
+// CHECK: _Z2f111externref_t
+void f1(__externref_t) {}
Index: clang/test/CodeGen/builtins-wasm.c
===================================================================
--- clang/test/CodeGen/builtins-wasm.c
+++ clang/test/CodeGen/builtins-wasm.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +simd128 -target-feature +relaxed-simd -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
-// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +simd128 -target-feature +relaxed-simd -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
-// RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +reference-types -target-feature +simd128 -target-feature +relaxed-simd -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +reference-types -target-feature +simd128 -target-feature +relaxed-simd -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
+// RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +reference-types -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
// SIMD convenience types
typedef signed char i8x16 __attribute((vector_size(16)));
@@ -801,3 +801,9 @@
// WEBASSEMBLY-SAME: <8 x i16> %a, <8 x i16> %b, <4 x float> %c)
// WEBASSEMBLY-NEXT: ret
}
+
+__externref_t externref_null() {
+ return __builtin_wasm_ref_null_extern();
+ // WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern()
+ // WEBASSEMBLY-NEXT: ret
+}
Index: clang/test/CodeGen/WebAssembly/wasm-externref.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-externref.c
@@ -0,0 +1,27 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef __externref_t externref_t;
+
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(10) @llvm.wasm.ref.null.extern()
+// CHECK-NEXT: ret ptr addrspace(10) [[TMP0]]
+//
+externref_t get_null() {
+ return __builtin_wasm_ref_null_extern();
+}
+
+void helper(externref_t);
+
+// CHECK-LABEL: @handle(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[OBJ_ADDR:%.*]] = alloca ptr addrspace(10), align 1
+// CHECK-NEXT: store ptr addrspace(10) [[OBJ:%.*]], ptr [[OBJ_ADDR]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(10), ptr [[OBJ_ADDR]], align 1
+// CHECK-NEXT: call void @helper(ptr addrspace(10) [[TMP0]])
+// CHECK-NEXT: ret void
+//
+void handle(externref_t obj) {
+ helper(obj);
+}
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -7106,6 +7106,11 @@
T = Context.SingletonId; \
break;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) \
+ case PREDEF_TYPE_##Id##_ID: \
+ T = Context.SingletonId; \
+ break;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
}
assert(!T.isNull() && "Unknown predefined type");
Index: clang/lib/Serialization/ASTCommon.cpp
===================================================================
--- clang/lib/Serialization/ASTCommon.cpp
+++ clang/lib/Serialization/ASTCommon.cpp
@@ -250,6 +250,11 @@
ID = PREDEF_TYPE_##Id##_ID; \
break;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ ID = PREDEF_TYPE_##Id##_ID; \
+ break;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::BuiltinFn:
ID = PREDEF_TYPE_BUILTIN_FN;
break;
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2191,6 +2191,13 @@
if (getLangOpts().OpenCL)
T = deduceOpenCLPointeeAddrSpace(*this, T);
+ // In WebAssembly, pointers to reference types are illegal.
+ if (getASTContext().getTargetInfo().getTriple().isWasm() &&
+ T->isWebAssemblyReferenceType()) {
+ Diag(Loc, diag::err_wasm_reference_pr) << 0;
+ return QualType();
+ }
+
// Build the pointer type.
return Context.getPointerType(T);
}
@@ -2266,6 +2273,13 @@
if (getLangOpts().OpenCL)
T = deduceOpenCLPointeeAddrSpace(*this, T);
+ // In WebAssembly, references to reference types are illegal.
+ if (getASTContext().getTargetInfo().getTriple().isWasm() &&
+ T->isWebAssemblyReferenceType()) {
+ Diag(Loc, diag::err_wasm_reference_pr) << 1;
+ return QualType();
+ }
+
// Handle restrict on references.
if (LValueRef)
return Context.getLValueReferenceType(T, SpelledAsLValue);
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -936,6 +936,11 @@
if (Ty.isDestructedType() == QualType::DK_nontrivial_c_struct)
return VAK_Invalid;
+ if (Context.getTargetInfo().getTriple().isWasm() &&
+ Ty->isWebAssemblyReferenceType()) {
+ return VAK_Invalid;
+ }
+
if (Ty.isCXX98PODType(Context))
return VAK_Valid;
@@ -6317,6 +6322,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define PLACEHOLDER_TYPE(ID, SINGLETON_ID)
#define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID:
#include "clang/AST/BuiltinTypes.def"
@@ -14460,6 +14467,13 @@
if (op->getType()->isObjCObjectType())
return Context.getObjCObjectPointerType(op->getType());
+ if (Context.getTargetInfo().getTriple().isWasm() &&
+ op->getType()->isWebAssemblyReferenceType()) {
+ Diag(OpLoc, diag::err_wasm_ca_reference)
+ << 1 << OrigOp.get()->getSourceRange();
+ return QualType();
+ }
+
CheckAddressOfPackedMember(op);
return Context.getPointerType(op->getType());
@@ -18556,6 +18570,12 @@
Invalid = true;
}
+ if (BuildAndDiagnose && S.Context.getTargetInfo().getTriple().isWasm() &&
+ CaptureType.getNonReferenceType()->isWebAssemblyReferenceType()) {
+ S.Diag(Loc, diag::err_wasm_ca_reference) << 0;
+ Invalid = true;
+ }
+
// Compute the type of the field that will capture this variable.
if (ByRef) {
// C++11 [expr.prim.lambda]p15:
@@ -20787,6 +20807,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id:
#define PLACEHOLDER_TYPE(Id, SingletonId)
#include "clang/AST/BuiltinTypes.def"
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -8550,7 +8550,8 @@
return;
}
- if (!NewVD->hasLocalStorage() && T->isSizelessType()) {
+ if (!NewVD->hasLocalStorage() && T->isSizelessType() &&
+ !T->isWebAssemblyReferenceType()) {
Diag(NewVD->getLocation(), diag::err_sizeless_nonlocal) << T;
NewVD->setInvalidDecl();
return;
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -2011,6 +2011,9 @@
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
return CheckRISCVBuiltinFunctionCall(TI, BuiltinID, TheCall);
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64:
+ return CheckWebAssemblyBuiltinFunctionCall(TI, BuiltinID, TheCall);
}
}
@@ -4521,6 +4524,17 @@
return SemaBuiltinConstantArgRange(TheCall, i, l, u);
}
+bool Sema::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
+ unsigned BuiltinID,
+ CallExpr *TheCall) {
+ switch (BuiltinID) {
+ case WebAssembly::BI__builtin_wasm_ref_null_extern:
+ return BuiltinWasmRefNullExtern(TheCall);
+ }
+
+ return false;
+}
+
/// SemaBuiltinCpuSupports - Handle __builtin_cpu_supports(char *).
/// This checks that the target supports __builtin_cpu_supports and
/// that the string argument is constant and valid.
@@ -6538,6 +6552,15 @@
return false;
}
+bool Sema::BuiltinWasmRefNullExtern(CallExpr *TheCall) {
+ if (TheCall->getNumArgs() != 0)
+ return true;
+
+ TheCall->setType(Context.getExternrefType());
+
+ return false;
+}
+
/// We have a call to a function like __sync_fetch_and_add, which is an
/// overloaded function based on the pointer type of its first argument.
/// The main BuildCallExpr routines have already promoted the types of
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -442,6 +442,13 @@
#include "clang/Basic/RISCVVTypes.def"
}
+ if (Context.getTargetInfo().getTriple().isWasm() &&
+ Context.getTargetInfo().hasFeature("reference-types")) {
+#define WASM_TYPE(Name, Id, SingletonId) \
+ addImplicitTypedef(Name, Context.SingletonId);
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ }
+
if (Context.getTargetInfo().hasBuiltinMSVaList()) {
DeclarationName MSVaList = &Context.Idents.get("__builtin_ms_va_list");
if (IdResolver.begin(MSVaList) == IdResolver.end())
Index: clang/lib/Index/USRGeneration.cpp
===================================================================
--- clang/lib/Index/USRGeneration.cpp
+++ clang/lib/Index/USRGeneration.cpp
@@ -736,6 +736,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::ShortAccum:
case BuiltinType::Accum:
case BuiltinType::LongAccum:
Index: clang/lib/CodeGen/TargetInfo.h
===================================================================
--- clang/lib/CodeGen/TargetInfo.h
+++ clang/lib/CodeGen/TargetInfo.h
@@ -362,6 +362,9 @@
return nullptr;
}
+ /// Return the WebAssembly externref reference type.
+ virtual llvm::Type *getWasmExternrefReferenceType() const { return nullptr; }
+
/// Emit the device-side copy of the builtin surface type.
virtual bool emitCUDADeviceBuiltinSurfaceDeviceCopy(CodeGenFunction &CGF,
LValue Dst,
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -891,6 +891,11 @@
Fn->addFnAttr("no-prototype");
}
}
+
+ /// Return the WebAssembly externref reference type.
+ virtual llvm::Type *getWasmExternrefReferenceType() const override {
+ return llvm::Type::getWasm_ExternrefTy(getABIInfo().getVMContext());
+ }
};
/// Classify argument of given type \p Ty.
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3268,6 +3268,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::ShortAccum:
case BuiltinType::Accum:
case BuiltinType::LongAccum:
Index: clang/lib/CodeGen/CodeGenTypes.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenTypes.cpp
+++ clang/lib/CodeGen/CodeGenTypes.cpp
@@ -633,7 +633,15 @@
Info.EC.getKnownMinValue() *
Info.NumVectors);
}
- case BuiltinType::Dependent:
+#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
+ case BuiltinType::Id: { \
+ if (BuiltinType::Id == BuiltinType::WasmExternRef) \
+ ResultType = CGM.getTargetCodeGenInfo().getWasmExternrefReferenceType(); \
+ else \
+ llvm_unreachable("Unexpected wasm reference builtin type!"); \
+ } break;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ case BuiltinType::Dependent:
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) \
case BuiltinType::Id:
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -80,6 +80,8 @@
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
llvm::DIType *Id##Ty = nullptr;
#include "clang/Basic/OpenCLExtensionTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) llvm::DIType *SingletonId = nullptr;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
/// Cache of previously constructed Types.
llvm::DenseMap<const void *, llvm::TrackingMDRef> TypeCache;
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -801,6 +801,17 @@
return DBuilder.createVectorType(/*Size=*/0, Align, ElemTy,
SubscriptArray);
}
+
+#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
+ case BuiltinType::Id: { \
+ if (!SingletonId) \
+ SingletonId = \
+ DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, \
+ MangledName, TheCU, TheCU->getFile(), 0); \
+ return SingletonId; \
+ }
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+
case BuiltinType::UChar:
case BuiltinType::Char_U:
Encoding = llvm::dwarf::DW_ATE_unsigned_char;
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -18529,6 +18529,10 @@
Function *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
return Builder.CreateCall(Callee, Value);
}
+ case WebAssembly::BI__builtin_wasm_ref_null_extern: {
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_extern);
+ return Builder.CreateCall(Callee);
+ }
case WebAssembly::BI__builtin_wasm_swizzle_i8x16: {
Value *Src = EmitScalarExpr(E->getArg(0));
Value *Indices = EmitScalarExpr(E->getArg(1));
@@ -18650,7 +18654,7 @@
IntNo = Intrinsic::wasm_extadd_pairwise_unsigned;
break;
default:
- llvm_unreachable("unexptected builtin ID");
+ llvm_unreachable("unexpected builtin ID");
}
Function *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
Index: clang/lib/Basic/Targets/X86.h
===================================================================
--- clang/lib/Basic/Targets/X86.h
+++ clang/lib/Basic/Targets/X86.h
@@ -43,7 +43,9 @@
0, // sycl_private
270, // ptr32_sptr
271, // ptr32_uptr
- 272 // ptr64
+ 272, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref,
};
// X86 target abstract base class; x86-32 and x86-64 are very close, so
Index: clang/lib/Basic/Targets/TCE.h
===================================================================
--- clang/lib/Basic/Targets/TCE.h
+++ clang/lib/Basic/Targets/TCE.h
@@ -50,6 +50,8 @@
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref
};
class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {
Index: clang/lib/Basic/Targets/SPIR.h
===================================================================
--- clang/lib/Basic/Targets/SPIR.h
+++ clang/lib/Basic/Targets/SPIR.h
@@ -42,7 +42,9 @@
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref
};
// Used by both the SPIR and SPIR-V targets.
@@ -71,7 +73,9 @@
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref
};
// Base class for SPIR and SPIR-V target info.
Index: clang/lib/Basic/Targets/NVPTX.h
===================================================================
--- clang/lib/Basic/Targets/NVPTX.h
+++ clang/lib/Basic/Targets/NVPTX.h
@@ -42,7 +42,9 @@
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref
};
/// The DWARF address class. Taken from
Index: clang/lib/Basic/Targets/DirectX.h
===================================================================
--- clang/lib/Basic/Targets/DirectX.h
+++ clang/lib/Basic/Targets/DirectX.h
@@ -40,7 +40,9 @@
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref
};
class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
Index: clang/lib/AST/TypeLoc.cpp
===================================================================
--- clang/lib/AST/TypeLoc.cpp
+++ clang/lib/AST/TypeLoc.cpp
@@ -424,6 +424,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::BuiltinFn:
case BuiltinType::IncompleteMatrixIdx:
case BuiltinType::OMPArraySection:
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -2311,6 +2311,10 @@
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
return true;
+ // WebAssembly reference types
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ return true;
default:
return false;
}
@@ -2318,6 +2322,16 @@
return false;
}
+bool Type::isWebAssemblyReferenceType() const {
+ return isWebAssemblyExternrefType();
+}
+
+bool Type::isWebAssemblyExternrefType() const {
+ if (const auto *BT = getAs<BuiltinType>())
+ return BT->getKind() == BuiltinType::WasmExternRef;
+ return false;
+}
+
bool Type::isSizelessType() const { return isSizelessBuiltinType(); }
bool Type::isVLSTBuiltinType() const {
@@ -3143,6 +3157,10 @@
case Id: \
return Name;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) \
+ case Id: \
+ return Name;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
}
llvm_unreachable("Invalid builtin type.");
@@ -4190,6 +4208,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::BuiltinFn:
case BuiltinType::NullPtr:
case BuiltinType::IncompleteMatrixIdx:
Index: clang/lib/AST/PrintfFormatString.cpp
===================================================================
--- clang/lib/AST/PrintfFormatString.cpp
+++ clang/lib/AST/PrintfFormatString.cpp
@@ -800,6 +800,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define SIGNED_TYPE(Id, SingletonId)
#define UNSIGNED_TYPE(Id, SingletonId)
#define FLOATING_TYPE(Id, SingletonId)
Index: clang/lib/AST/NSAPI.cpp
===================================================================
--- clang/lib/AST/NSAPI.cpp
+++ clang/lib/AST/NSAPI.cpp
@@ -480,6 +480,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::BoundMember:
case BuiltinType::Dependent:
case BuiltinType::Overload:
Index: clang/lib/AST/MicrosoftMangle.cpp
===================================================================
--- clang/lib/AST/MicrosoftMangle.cpp
+++ clang/lib/AST/MicrosoftMangle.cpp
@@ -2481,6 +2481,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::ShortAccum:
case BuiltinType::Accum:
case BuiltinType::LongAccum:
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -3141,6 +3141,13 @@
Out << 'u' << type_name.size() << type_name; \
break;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
+ case BuiltinType::Id: \
+ type_name = MangledName; \
+ Out << (type_name == InternalName ? "u" : "") << type_name.size() \
+ << type_name; \
+ break;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
}
}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -11304,6 +11304,8 @@
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
return GCCTypeClass::None;
case BuiltinType::Dependent:
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -1099,6 +1099,10 @@
case BuiltinType::Id: \
return Importer.getToContext().SingletonId;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ return Importer.getToContext().SingletonId;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define SHARED_SINGLETON_TYPE(Expansion)
#define BUILTIN_TYPE(Id, SingletonId) \
case BuiltinType::Id: return Importer.getToContext().SingletonId;
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -951,7 +951,9 @@
0, // sycl_private
10, // ptr32_sptr
11, // ptr32_uptr
- 12 // ptr64
+ 12, // ptr64
+ // Wasm address space values for this map are dummy
+ 10, // wasm_externref,
};
return &FakeAddrSpaceMap;
} else {
@@ -1463,6 +1465,12 @@
#include "clang/Basic/RISCVVTypes.def"
}
+ if (Target.getTriple().isWasm() && Target.hasFeature("reference-types")) {
+#define WASM_TYPE(Name, Id, SingletonId) \
+ InitBuiltinType(SingletonId, BuiltinType::Id);
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ }
+
// Builtin type for __objc_yes and __objc_no
ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?
SignedCharTy : BoolTy);
@@ -2247,6 +2255,12 @@
Align = 8; \
break;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ Width = 0; \
+ Align = 8; \
+ break;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
}
break;
case Type::ObjCObjectPointer:
@@ -3970,6 +3984,18 @@
}
}
+/// getExternrefType - Return a WebAssembly externref type, which represents an
+/// opaque reference to a host value.
+QualType ASTContext::getExternrefType() const {
+ if (Target->getTriple().isWasm() && Target->hasFeature("reference-types")) {
+#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
+ if (BuiltinType::Id == BuiltinType::WasmExternRef) \
+ return SingletonId;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ }
+ return QualType();
+}
+
/// getScalableVectorType - Return the unique reference to a scalable vector
/// type of the specified element type and size. VectorType must be a built-in
/// type.
@@ -7949,6 +7975,8 @@
#include "clang/Basic/AArch64SVEACLETypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
{
DiagnosticsEngine &Diags = C->getDiagnostics();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
Index: clang/include/clang/module.modulemap
===================================================================
--- clang/include/clang/module.modulemap
+++ clang/include/clang/module.modulemap
@@ -72,6 +72,8 @@
textual header "Basic/Sanitizers.def"
textual header "Basic/TargetCXXABI.def"
textual header "Basic/TransformTypeTraits.def"
+ textual header "Basic/TokenKinds.def"
+ textual header "Basic/WebAssemblyReferenceTypes.def"
module * { export * }
}
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -1093,6 +1093,9 @@
// \brief RISC-V V types with auto numeration
#define RVV_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/RISCVVTypes.def"
+// \brief WebAssembly reference types with auto numeration
+#define WASM_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
};
/// The number of predefined type IDs that are reserved for
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -13134,6 +13134,9 @@
bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);
+ bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
+ unsigned BuiltinID,
+ CallExpr *TheCall);
bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);
@@ -13197,6 +13200,9 @@
ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall,
ExprResult CallResult);
+ // WebAssembly builtin handling.
+ bool BuiltinWasmRefNullExtern(CallExpr *TheCall);
+
public:
enum FormatStringType {
FST_Scanf,
Index: clang/include/clang/Basic/WebAssemblyReferenceTypes.def
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/WebAssemblyReferenceTypes.def
@@ -0,0 +1,38 @@
+//===-- WebAssemblyReferenceTypes.def - Wasm reference 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 externref_t. The macros are:
+//
+// WASM_TYPE(Name, Id, SingletonId)
+// WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS)
+//
+// where:
+//
+// - Name is the name of the builtin type. MangledName is the mangled name.
+//
+// - BuiltinType::Id is the enumerator defining the type.
+//
+// - Context.SingletonId is the global singleton of this type.
+//
+// - AS indicates the address space for values of this type.
+//
+// To include this file, define either WASM_REF_TYPE or WASM_TYPE, depending on
+// how much information you want. The macros will be undefined after inclusion.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef WASM_REF_TYPE
+#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
+ WASM_TYPE(Name, Id, SingletonId)
+#endif
+
+WASM_REF_TYPE("__externref_t", "externref_t", WasmExternRef, WasmExternRefTy, 10)
+
+#undef WASM_TYPE
+#undef WASM_REF_TYPE
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11669,4 +11669,10 @@
"a randomized struct can only be initialized with a designated initializer">;
def err_cast_from_randomized_struct : Error<
"casting from randomized structure pointer type %0 to %1">;
+
+// WebAssembly reference type and table diagnostics.
+def err_wasm_reference_pr : Error<
+ "%select{pointers|references}0 to WebAssembly reference types are illegal">;
+def err_wasm_ca_reference : Error<
+ "cannot %select{capture|take address of}0 WebAssembly reference">;
} // end of sema component.
Index: clang/include/clang/Basic/BuiltinsWebAssembly.def
===================================================================
--- clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -190,5 +190,9 @@
TARGET_BUILTIN(__builtin_wasm_dot_i8x16_i7x16_add_s_i32x4, "V4iV16ScV16ScV4i", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f", "nc", "relaxed-simd")
+// Reference Types builtins
+
+TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "i", "nct", "reference-types")
+
#undef BUILTIN
#undef TARGET_BUILTIN
Index: clang/include/clang/Basic/AddressSpaces.h
===================================================================
--- clang/include/clang/Basic/AddressSpaces.h
+++ clang/include/clang/Basic/AddressSpaces.h
@@ -56,6 +56,7 @@
ptr32_uptr,
ptr64,
+ wasm_externref,
// This denotes the count of language-specific address spaces and also
// the offset added to the target-specific address spaces, which are usually
// specified by address space attributes __attribute__(address_space(n))).
Index: clang/include/clang/AST/TypeProperties.td
===================================================================
--- clang/include/clang/AST/TypeProperties.td
+++ clang/include/clang/AST/TypeProperties.td
@@ -799,6 +799,10 @@
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(NAME, ID, SINGLETON_ID) \
+ case BuiltinType::ID: return ctx.SINGLETON_ID;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+
#define BUILTIN_TYPE(ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/AST/BuiltinTypes.def"
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -1971,6 +1971,10 @@
bool isSizelessType() const;
bool isSizelessBuiltinType() const;
+ /// Check if this is a WebAssembly Reference Type.
+ bool isWebAssemblyReferenceType() const;
+ bool isWebAssemblyExternrefType() const;
+
/// Determines if this is a sizeless type supported by the
/// 'arm_sve_vector_bits' type attribute, which can be applied to a single
/// SVE vector or predicate, excluding tuple types such as svint32x4_t.
@@ -2581,6 +2585,9 @@
// RVV Types
#define RVV_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/RISCVVTypes.def"
+// WebAssembly reference types
+#define WASM_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1155,6 +1155,8 @@
#define RVV_TYPE(Name, Id, SingletonId) \
CanQualType SingletonId;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@@ -1500,6 +1502,9 @@
/// \pre \p EltTy must be a built-in type.
QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const;
+ /// Return a WebAssembly externref type.
+ QualType getExternrefType() const;
+
/// Return the unique reference to a vector type of the specified
/// element type and size.
///
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits