pmatos updated this revision to Diff 432876.
pmatos added a comment.
Rebased the work on D126535 <https://reviews.llvm.org/D126535>. Added support
for funcrefs as return values.
Still having problems with funcrefs as function arguments though. So, further
work is required.
Not ready for review.
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/Attr.td
clang/include/clang/Basic/Builtins.def
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/AST/TypePrinter.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/CGExprScalar.cpp
clang/lib/CodeGen/CodeGenModule.cpp
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/WebAssembly/wasm-funcref.c
clang/test/CodeGen/builtins-wasm.c
clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
clang/tools/libclang/CIndex.cpp
llvm/include/llvm/IR/Type.h
llvm/lib/CodeGen/ValueTypes.cpp
llvm/lib/IR/Type.cpp
llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -404,11 +404,17 @@
}
//===----------------------------------------------------------------------===//
-// The following functions are called from lib/CodeGen/Passes.cpp to modify
-// the CodeGen pass sequence.
+// The following functions are called from lib/CodeGen/TargetPassConfig.cpp
+// to modify the CodeGen pass sequence.
//===----------------------------------------------------------------------===//
void WebAssemblyPassConfig::addIRPasses() {
+ // Run mem2reg to remove alloca references - needed for reference types
+ // FIXME: this should only be added when the subtarget has reference types
+ // enabled but the subtarget is dependent on the function being compiled to
+ // which we don't have access atm.
+ addPass(createPromoteMemoryToRegisterPass());
+
// Add signatures to prototype-less function declarations
addPass(createWebAssemblyAddMissingPrototypes());
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) {
+ // pointer to opaque struct in addrspace(10)
+ static PointerType *Ty = PointerType::get(StructType::get(C), 10);
+ return Ty;
+}
+
+Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
+ // pointer to i8 addrspace(20)
+ static PointerType *Ty = PointerType::get(Type::getInt8Ty(C), 20);
+ return Ty;
+}
+
//===----------------------------------------------------------------------===//
// IntegerType Implementation
//===----------------------------------------------------------------------===//
Index: llvm/lib/CodeGen/ValueTypes.cpp
===================================================================
--- llvm/lib/CodeGen/ValueTypes.cpp
+++ llvm/lib/CodeGen/ValueTypes.cpp
@@ -201,12 +201,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
@@ -468,6 +468,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/CodeGenCXX/wasm-reftypes-typeinfo.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
@@ -0,0 +1,10 @@
+// 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,7 @@
+// 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 -no-opaque-pointers -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 -no-opaque-pointers -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 -no-opaque-pointers -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 -no-opaque-pointers -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 -no-opaque-pointers -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 -no-opaque-pointers -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)));
@@ -777,3 +777,9 @@
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.unsigned.zero(<2 x double> %x)
// WEBASSEMBLY-NEXT: ret
}
+
+__externref_t externref_null() {
+ return __builtin_wasm_ref_null_extern();
+ // WEBASSEMBLY: tail call {} addrspace(10)* @llvm.wasm.ref.null.extern()
+ // WEBASSEMBLY-NEXT: ret
+}
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*funcref_t)() __attribute__((__funcref));
+
+funcref_t get_null() {
+// CHECK: define i8 addrspace(20)* @get_null() #0 {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %0 = call i8 addrspace(20)* @llvm.wasm.ref.null.func()
+// CHECK-NEXT: ret i8 addrspace(20)* %0
+// CHECK-NEXT: }
+ return __builtin_wasm_ref_null_func();
+}
+
+void helper(funcref_t);
+
+void handle(funcref_t fn) {
+// CHECK: define void @handle(i8 addrspace(20)* %fn) #0 {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %fn.addr = alloca i8 addrspace(20)*, align 1
+// CHECK-NEXT: store i8 addrspace(20)* %fn, i8 addrspace(20)** %fn.addr, align 1
+// CHECK-NEXT: %0 = load i8 addrspace(20)*, i8 addrspace(20)** %fn.addr, align 1
+// CHECK-NEXT: call void @helper(i8 addrspace(20)* %0)
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+ helper(fn);
+}
+
+typedef int (*fn_t)(int);
+typedef fn_t __attribute__((__funcref)) fn_funcref_t;
+
+// What happens when we move a function pointer into a funcref and then call it?
+fn_funcref_t get_ref(fn_t fnptr) {
+ return fnptr;
+}
+
+int call_fn(fn_funcref_t ref, int x) {
+ return ref(x);
+}
Index: clang/test/CodeGen/WebAssembly/wasm-externref.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-externref.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef __externref_t externref_t;
+
+externref_t get_null() {
+// CHECK: define {} addrspace(10)* @get_null() #0 {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %0 = call {} addrspace(10)* @llvm.wasm.ref.null.extern()
+// CHECK-NEXT: ret {} addrspace(10)* %0
+// CHECK-NEXT: }
+ return __builtin_wasm_ref_null_extern();
+}
+
+void helper(externref_t);
+
+void handle(externref_t obj) {
+// CHECK: define void @handle({} addrspace(10)* %obj) #0 {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %obj.addr = alloca {} addrspace(10)*, align 1
+// CHECK-NEXT: store {} addrspace(10)* %obj, {} addrspace(10)** %obj.addr, align 1
+// CHECK-NEXT: %0 = load {} addrspace(10)*, {} addrspace(10)** %obj.addr, align 1
+// CHECK-NEXT: call void @helper({} addrspace(10)* %0)
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+ helper(obj);
+}
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -7103,6 +7103,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
@@ -8059,6 +8059,27 @@
CurType, CurType);
}
+static void HandleWebAssemblyFuncrefAttr(TypeProcessingState &State,
+ QualType &CurType,
+ ParsedAttr &Attr) {
+ if (!CurType->isFunctionPointerType()) {
+ State.getSema().Diag(Attr.getLoc(),
+ diag::err_attribute_webassembly_funcref);
+ Attr.setInvalid();
+ return;
+ }
+
+ // Add attribute
+ CurType =
+ State.getAttributedType(createSimpleAttr<WebAssemblyFuncrefAttr>(
+ State.getSema().Context, Attr),
+ CurType, CurType);
+
+ // Change address space to the funcref addrspace
+ Qualifiers Q = CurType.getQualifiers();
+ Q.setAddressSpace(LangAS::wasm_funcref);
+}
+
/// Handle OpenCL Access Qualifier Attribute.
static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr,
Sema &S) {
@@ -8305,6 +8326,12 @@
attr.setUsedAsTypeAttr();
break;
+ case ParsedAttr::AT_WebAssemblyFuncref: {
+ HandleWebAssemblyFuncrefAttr(state, type, attr);
+ attr.setUsedAsTypeAttr();
+ break;
+ }
+
MS_TYPE_ATTRS_CASELIST:
if (!handleMSPointerTypeQualifierAttr(state, attr, type))
attr.setUsedAsTypeAttr();
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -6326,6 +6326,9 @@
#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"
@@ -20591,6 +20594,9 @@
#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
@@ -14278,7 +14278,10 @@
// OpenCL allows function arguments declared to be an array of a type
// to be qualified with an address space.
!(getLangOpts().OpenCL &&
- (T->isArrayType() || T.getAddressSpace() == LangAS::opencl_private))) {
+ (T->isArrayType() || T.getAddressSpace() == LangAS::opencl_private)) &&
+ // WebAssembly allows reference types as parameters. Funcref in particular
+ // lives in a different address space
+ !T->isWebAssemblyFuncrefType()) {
Diag(NameLoc, diag::err_arg_with_address_space);
New->setInvalidDecl();
}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -2643,7 +2643,14 @@
diag::err_hip_invalid_args_builtin_mangled_name);
return ExprError();
}
+ break;
}
+
+ case WebAssembly::BI__builtin_wasm_ref_null_func:
+ if (SemaBuiltinWasmRefNullFunc(TheCall))
+ return ExprError();
+ break;
+
}
// Since the target specific builtins for each arch overlap, only check those
@@ -6502,6 +6509,20 @@
return false;
}
+bool
+Sema::SemaBuiltinWasmRefNullFunc(CallExpr *TheCall) {
+ if (TheCall->getNumArgs() != 0)
+ return true;
+
+ // Set return type to a function pointer with the funcref attribute attached
+ QualType FnType = Context.getFunctionType(Context.VoidTy, {}, {});
+ QualType FnPtrType = Context.getPointerType(FnType);
+
+ TheCall->setType(FnPtrType);
+
+ 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
@@ -455,6 +455,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,9 @@
#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
@@ -349,6 +349,15 @@
return nullptr;
}
+ /// Return the WebAssembly externref reference type.
+ virtual llvm::Type *getWasmExternrefReferenceType() const {
+ return nullptr;
+ }
+ /// Return the WebAssembly funcref reference type.
+ virtual llvm::Type *getWasmFuncrefReferenceType() 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
@@ -884,6 +884,15 @@
Fn->addFnAttr("no-prototype");
}
}
+
+ /// Return the WebAssembly externref reference type.
+ virtual llvm::Type *getWasmExternrefReferenceType() const override {
+ return llvm::Type::getWasm_ExternrefTy(getABIInfo().getVMContext());
+ }
+ /// Return the WebAssembly funcref reference type.
+ virtual llvm::Type *getWasmFuncrefReferenceType() const override {
+ return llvm::Type::getWasm_FuncrefTy(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
@@ -3257,6 +3257,9 @@
#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
@@ -399,6 +399,7 @@
/// ConvertType - Convert the specified type to its LLVM form.
llvm::Type *CodeGenTypes::ConvertType(QualType T) {
+ const bool isWebAssemblyFuncref = T.getTypePtr()->isWebAssemblyFuncrefType();
T = Context.getCanonicalType(T);
const Type *Ty = T.getTypePtr();
@@ -417,6 +418,19 @@
}
}
+ if (isWebAssemblyFuncref) {
+ // Copies what we do later for PointerType but takes Funcref attribute into
+ // consideration. We cannot this reach caching which doesn't take the
+ // funcref attribute into consideration.
+ const PointerType *PTy = cast<PointerType>(Ty);
+ QualType ETy = PTy->getPointeeType();
+ llvm::Type *PointeeType = ConvertTypeForMem(ETy);
+ if (PointeeType->isVoidTy())
+ PointeeType = llvm::Type::getInt8Ty(getLLVMContext());
+ llvm::Type *FuncTy = llvm::PointerType::get(PointeeType, 20 /*FixMe hardcoded AS*/);
+ return FuncTy;
+ }
+
// RecordTypes are cached and processed specially.
if (const RecordType *RT = dyn_cast<RecordType>(Ty))
return ConvertRecordDeclType(RT->getDecl());
@@ -633,6 +647,17 @@
Info.EC.getKnownMinValue() *
Info.NumVectors);
}
+#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) \
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5113,6 +5113,15 @@
const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
+ // If FI FunctionType is a WebAssembly funcref,
+ // then transform Ty so that it points to the funcref AS
+ if (D->getReturnType()->isWebAssemblyFuncrefType()) {
+ llvm::PointerType *PtrTy = dyn_cast<llvm::PointerType>(Ty->getReturnType());
+ assert(PtrTy);
+ Ty = llvm::FunctionType::get(llvm::PointerType::getWithSamePointeeType(PtrTy, 20),
+ Ty->params(), Ty->isVarArg());
+ }
+
// Get or create the prototype for the function.
if (!GV || (GV->getValueType() != Ty))
GV = cast<llvm::GlobalValue>(GetAddrOfFunction(GD, Ty, /*ForVTable=*/false,
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -2036,6 +2036,17 @@
Value *Src = Visit(const_cast<Expr*>(E));
llvm::Type *SrcTy = Src->getType();
llvm::Type *DstTy = ConvertType(DestTy);
+
+ // If the destination type is a WebAssembly Funcref then, we allow the
+ // types to have different address spaces and the one not in the
+ // funcref address space is converted at this point.
+ if (DestTy->isWebAssemblyFuncrefType()) {
+ llvm::PointerType *PtrTy = cast<llvm::PointerType>(DstTy);
+ // FIXME: hardcoded addrspace, should be
+ // llvm::WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF
+ DstTy = llvm::PointerType::getWithSamePointeeType(PtrTy, 20);
+ }
+
if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
llvm_unreachable("wrong cast for pointers in different address spaces"
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -80,6 +80,9 @@
#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
@@ -798,6 +798,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
@@ -18343,6 +18343,14 @@
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_ref_null_func: {
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func);
+ return Builder.CreateCall(Callee);
+ }
case WebAssembly::BI__builtin_wasm_swizzle_i8x16: {
Value *Src = EmitScalarExpr(E->getArg(0));
Value *Indices = EmitScalarExpr(E->getArg(1));
@@ -18464,7 +18472,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
@@ -42,7 +42,10 @@
0, // sycl_private
270, // ptr32_sptr
271, // ptr32_uptr
- 272 // ptr64
+ 272, // ptr64
+ 1, // wasm_var
+ 10, // wasm_externref,
+ 20, // wasm_funcref
};
// 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
@@ -38,18 +38,21 @@
1, // opencl_global_device
1, // opencl_global_host
// FIXME: generic has to be added to the target
- 0, // opencl_generic
- 0, // cuda_device
- 0, // cuda_constant
- 0, // cuda_shared
- 0, // sycl_global
- 0, // sycl_global_device
- 0, // sycl_global_host
- 0, // sycl_local
- 0, // sycl_private
- 0, // ptr32_sptr
- 0, // ptr32_uptr
- 0, // ptr64
+ 0, // opencl_generic
+ 0, // cuda_device
+ 0, // cuda_constant
+ 0, // cuda_shared
+ 0, // sycl_global
+ 0, // sycl_global_device
+ 0, // sycl_global_host
+ 0, // sycl_local
+ 0, // sycl_private
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0, // ptr64
+ 1, // wasm_var
+ 10, // wasm_externref,
+ 20, // wasm_funcref
};
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,10 @@
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 1, // wasm_var
+ 10,// wasm_externref
+ 20,// wasm_funcref
};
// Used by both the SPIR and SPIR-V targets.
@@ -71,7 +74,10 @@
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 1, // wasm_var
+ 10,// wasm_externref
+ 20,// wasm_funcref
};
// 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
@@ -29,20 +29,23 @@
4, // opencl_constant
0, // opencl_private
// FIXME: generic has to be added to the target
- 0, // opencl_generic
- 1, // opencl_global_device
- 1, // opencl_global_host
- 1, // cuda_device
- 4, // cuda_constant
- 3, // cuda_shared
- 1, // sycl_global
- 1, // sycl_global_device
- 1, // sycl_global_host
- 3, // sycl_local
- 0, // sycl_private
- 0, // ptr32_sptr
- 0, // ptr32_uptr
- 0 // ptr64
+ 0, // opencl_generic
+ 1, // opencl_global_device
+ 1, // opencl_global_host
+ 1, // cuda_device
+ 4, // cuda_constant
+ 3, // cuda_shared
+ 1, // sycl_global
+ 1, // sycl_global_device
+ 1, // sycl_global_host
+ 3, // sycl_local
+ 0, // sycl_private
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0, // ptr64
+ 1, // wasm_var
+ 10, // wasm_externref,
+ 20, // wasm_funcref
};
/// 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
@@ -33,14 +33,17 @@
0, // cuda_constant
0, // cuda_shared
// SYCL address space values for this map are dummy
- 0, // sycl_global
- 0, // sycl_global_device
- 0, // sycl_global_host
- 0, // sycl_local
- 0, // sycl_private
- 0, // ptr32_sptr
- 0, // ptr32_uptr
- 0 // ptr64
+ 0, // sycl_global
+ 0, // sycl_global_device
+ 0, // sycl_global_host
+ 0, // sycl_local
+ 0, // sycl_private
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0, // ptr64
+ 1, // wasm_var
+ 10, // wasm_externref
+ 20, // wasm_funcref
};
class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1710,6 +1710,8 @@
// AttributedType nodes for them.
break;
+ case attr::WebAssemblyFuncref: OS << "__funcref"; break;
+
case attr::LifetimeBound:
case attr::TypeNonNull:
case attr::TypeNullable:
Index: clang/lib/AST/TypeLoc.cpp
===================================================================
--- clang/lib/AST/TypeLoc.cpp
+++ clang/lib/AST/TypeLoc.cpp
@@ -418,6 +418,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,18 @@
return false;
}
+bool Type::isWebAssemblyReferenceType() const {
+ return isWebAssemblyFuncrefType() ||
+ isWebAssemblyExternrefType();
+}
+
+bool Type::isWebAssemblyExternrefType() const {
+ const BuiltinType *BT = getAs<BuiltinType>();
+ if (BT && BT->getKind() == BuiltinType::WasmExternRef)
+ return true;
+ return false;
+}
+
bool Type::isSizelessType() const { return isSizelessBuiltinType(); }
bool Type::isVLSTBuiltinType() const {
@@ -3143,6 +3159,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.");
@@ -4184,6 +4204,9 @@
#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
@@ -797,6 +797,9 @@
#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
@@ -2472,6 +2472,9 @@
#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
@@ -11288,6 +11288,9 @@
#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
@@ -948,7 +948,10 @@
0, // sycl_private
10, // ptr32_sptr
11, // ptr32_uptr
- 12 // ptr64
+ 12, // ptr64
+ 1, // wasm_var
+ 10, // wasm_externref,
+ 20, // wasm_funcref
};
return &FakeAddrSpaceMap;
} else {
@@ -1460,6 +1463,13 @@
#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);
@@ -2235,6 +2245,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:
@@ -3939,6 +3955,26 @@
}
}
+/// getExternrefType - Return a WebAssembly externref type, which represents an
+/// opaque reference to a host value.
+QualType ASTContext::getExternrefType() const {
+ if (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();
+}
+
+/// getFuncrefType - Return a WebAssembly funcref type, which represents an
+/// opaque reference to a function.
+QualType ASTContext::getFuncrefType() const {
+ // FIXME: this cannot be written because there's no single funcref type
+ // anymore
+ 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.
@@ -7840,6 +7876,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,
@@ -11065,6 +11103,10 @@
Type = Context.getScalableVectorType(ElementType, NumElements);
break;
}
+ case 'e': {
+ Type = Context.getExternrefType();
+ break;
+ }
case 'V': {
char *End;
unsigned NumElements = strtoul(Str, &End, 10);
Index: clang/include/clang/module.modulemap
===================================================================
--- clang/include/clang/module.modulemap
+++ clang/include/clang/module.modulemap
@@ -72,6 +72,7 @@
textual header "Basic/Sanitizers.def"
textual header "Basic/TargetCXXABI.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
@@ -13001,6 +13001,9 @@
ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall,
ExprResult CallResult);
+ // WebAssembly builtin handling
+ bool SemaBuiltinWasmRefNullFunc(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, funcref_t, and the like. 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
@@ -7306,6 +7306,8 @@
"'__clang_arm_builtin_alias' attribute can only be applied to an ARM builtin">;
def err_attribute_arm_mve_polymorphism : Error<
"'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an MVE/NEON vector type">;
+def err_attribute_webassembly_funcref : Error<
+ "'__clang_webassembly_funcref' attribute can only be applied to function pointer types">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
Index: clang/include/clang/Basic/BuiltinsWebAssembly.def
===================================================================
--- clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -184,5 +184,13 @@
TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2, "V4iV2d", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2, "V4UiV2d", "nc", "relaxed-simd")
+// Reference Types builtins
+// Some builtins are polymorphic - see 't' as part of the third argument,
+// in which case the argument spec (second argument) is unused.
+TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "e", "nc", "reference-types")
+// A funcref represented as a function pointer with the funcref attribute
+// attached to the type, therefore SemaChecking will check for the right
+// return type.
+TARGET_BUILTIN(__builtin_wasm_ref_null_func, "i", "nct", "reference-types")
#undef BUILTIN
#undef TARGET_BUILTIN
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -47,6 +47,7 @@
// SJ -> sigjmp_buf
// K -> ucontext_t
// p -> pid_t
+// e -> wasm externref
// . -> "...". This may only occur at the end of the function list.
//
// Types may be prefixed with the following modifiers:
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -4011,3 +4011,9 @@
let LangOpts = [COnly];
}
def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>;
+
+def WebAssemblyFuncref : TypeAttr, TargetSpecificAttr<TargetWebAssembly> {
+ let Spellings = [Clang<"__funcref">];
+ let Args = [];
+ let Documentation = [Undocumented];
+}
Index: clang/include/clang/Basic/AddressSpaces.h
===================================================================
--- clang/include/clang/Basic/AddressSpaces.h
+++ clang/include/clang/Basic/AddressSpaces.h
@@ -56,6 +56,10 @@
ptr32_uptr,
ptr64,
+ wasm_var,
+ wasm_externref,
+ wasm_funcref,
+
// 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
@@ -1426,8 +1426,12 @@
return Quals.getObjCLifetime();
}
- bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
- LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
+ bool hasAddressSpace() const {
+ return Quals.hasAddressSpace();
+ }
+ LangAS getAddressSpace() const {
+ return Quals.getAddressSpace();
+ }
const Type *getBaseType() const { return BaseType; }
@@ -1909,6 +1913,11 @@
bool isSizelessType() const;
bool isSizelessBuiltinType() const;
+ /// Check if this is a WebAssembly Reference Type.
+ bool isWebAssemblyReferenceType() const;
+ bool isWebAssemblyExternrefType() const;
+ bool isWebAssemblyFuncrefType() 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.
@@ -2519,6 +2528,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
@@ -6619,6 +6631,9 @@
/// Return the address space of this type.
inline LangAS QualType::getAddressSpace() const {
+ if (getTypePtr()->isWebAssemblyFuncrefType()) {
+ return LangAS::wasm_funcref;
+ }
return getQualifiers().getAddressSpace();
}
@@ -6786,6 +6801,11 @@
return false;
}
+inline bool Type::isWebAssemblyFuncrefType() const {
+ return isFunctionPointerType() &&
+ hasAttr(attr::WebAssemblyFuncref);
+}
+
inline bool Type::isFunctionReferenceType() const {
if (const auto *T = getAs<ReferenceType>())
return T->getPointeeType()->isFunctionType();
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1145,6 +1145,9 @@
#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'.
@@ -1490,6 +1493,12 @@
/// \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 a WebAssembly funcref type
+ QualType getFuncrefType() 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