mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This is a value operation that can work just fine on lowered types, so there's no need to carry along a formal type. Make the value/address duality clearer, and enforce it in the verifier.
1189 lines
53 KiB
C++
1189 lines
53 KiB
C++
//===--- Builtins.def - Builtins Macro Metaprogramming Database -*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the database of builtin functions.
|
|
//
|
|
// BUILTIN(Id, Name, Attrs)
|
|
// - Id is an identifier suitable for use in C++
|
|
// - Name is a string literal for the name to which the builtin should be
|
|
// bound in Swift
|
|
// - Attrs specifies information about attributes of the function:
|
|
// n -> readnone
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Cast operations have type T1 -> T2.
|
|
#ifndef BUILTIN_CAST_OPERATION
|
|
#define BUILTIN_CAST_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
BUILTIN_CAST_OPERATION(Trunc , "trunc", "n")
|
|
BUILTIN_CAST_OPERATION(ZExt , "zext", "n")
|
|
BUILTIN_CAST_OPERATION(SExt , "sext", "n")
|
|
BUILTIN_CAST_OPERATION(FPToUI , "fptoui", "n")
|
|
BUILTIN_CAST_OPERATION(FPToSI , "fptosi", "n")
|
|
BUILTIN_CAST_OPERATION(UIToFP , "uitofp", "n")
|
|
BUILTIN_CAST_OPERATION(SIToFP , "sitofp", "n")
|
|
BUILTIN_CAST_OPERATION(FPTrunc , "fptrunc", "n")
|
|
BUILTIN_CAST_OPERATION(FPExt , "fpext", "n")
|
|
BUILTIN_CAST_OPERATION(PtrToInt, "ptrtoint", "n")
|
|
BUILTIN_CAST_OPERATION(IntToPtr, "inttoptr", "n")
|
|
BUILTIN_CAST_OPERATION(BitCast , "bitcast", "n")
|
|
|
|
/// Cast-or-bitcast operations have type T1 -> T2.
|
|
/// T1 and T2 may be the same size, unlike the corresponding true casts.
|
|
#ifndef BUILTIN_CAST_OR_BITCAST_OPERATION
|
|
#define BUILTIN_CAST_OR_BITCAST_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
BUILTIN_CAST_OR_BITCAST_OPERATION(TruncOrBitCast, "truncOrBitCast", "n")
|
|
BUILTIN_CAST_OR_BITCAST_OPERATION(ZExtOrBitCast, "zextOrBitCast", "n")
|
|
BUILTIN_CAST_OR_BITCAST_OPERATION(SExtOrBitCast, "sextOrBitCast", "n")
|
|
|
|
/// Binary operations have type (T,T) -> T.
|
|
///
|
|
/// We define two different sorts of operations varying when T is static,
|
|
/// specifically:
|
|
///
|
|
/// 1. Overloaded statically typed operations. E.x:
|
|
///
|
|
/// builtin "add_Vec4xInt32"(Vec4xInt32, Vec4xInt32) : Vec4xInt32.
|
|
///
|
|
/// 2. Polymorphic typed operations that are valid only in raw SIL. By the time
|
|
/// diagnostic constant propagation runs, these must have as its operand a
|
|
/// fully specialized type. If the builtin has a type that is not one of its
|
|
/// overloaded types, diagnostic constant propagation will emit a diagnostic
|
|
/// saying the builtin's type has not been fully resolved. Otherwise,
|
|
/// diagnostic constant propagation will transform the builtin to the
|
|
/// relevant static overloaded builtin form. E.x.:
|
|
///
|
|
/// builtin "add"(Self, Self) : Self // *error*
|
|
///
|
|
/// OR
|
|
///
|
|
/// builtin "generic_add"(Vec4xInt32, Vec4xInt32) : Vec4xInt32
|
|
/// ->
|
|
/// builtin "add_Vec4xInt32"(Vec4xInt32, Vec4xInt32) : Vec4xInt32
|
|
///
|
|
/// NOTE: If a polymorphic typed operation is not static by the time guaranteed
|
|
/// constant propagation runs, we emit a diagnostic to inform the user (who is
|
|
/// assumed to be an expert user) to tell them the value was unspecialized. The
|
|
/// typical way this specialization occurs today is via transparent inlining
|
|
/// since the transparent inliner devirtualizes and specializes as it goes. Of
|
|
/// course this means mandatory inlining must /always/ occur before diagnostic
|
|
/// constant propagation.
|
|
///
|
|
/// NOTE: Often times the builtin infrastructure wants to treat all
|
|
/// binary operation builtins generic or not the same way. To ensure
|
|
/// we support all use cases in the compiler, we do not declare the
|
|
/// operations as part of this builtin since often times this macro is
|
|
/// used to generic code. Instead, we stamp this out using the
|
|
/// overloaded_static, polymorphic, and all suffixed operations.
|
|
#ifndef BUILTIN_BINARY_OPERATION
|
|
#define BUILTIN_BINARY_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
|
|
#ifdef BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR
|
|
#error "Do not define BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR before including this .def file"
|
|
#endif
|
|
|
|
#define BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR(NAME) #NAME
|
|
|
|
#ifndef BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC
|
|
#define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(Id, Name, Attrs, Overload) \
|
|
BUILTIN_BINARY_OPERATION(Id, Name, Attrs)
|
|
#endif
|
|
|
|
#ifndef BUILTIN_BINARY_OPERATION_POLYMORPHIC
|
|
#define BUILTIN_BINARY_OPERATION_POLYMORPHIC(Id, Name) \
|
|
BUILTIN_BINARY_OPERATION(Id, Name, "")
|
|
#endif
|
|
|
|
// TODO: This needs a better name. We stringify generic_ in *_{OVERLOADED_STATIC,POLYMORPHIC}
|
|
#ifndef BUILTIN_BINARY_OPERATION_ALL
|
|
#define BUILTIN_BINARY_OPERATION_ALL(Id, Name, Attrs, Overload) \
|
|
BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(Id, BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR(Name), Attrs, Overload) \
|
|
BUILTIN_BINARY_OPERATION_POLYMORPHIC(Generic##Id, BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR(generic_##Name))
|
|
#endif
|
|
|
|
// NOTE: Here we need our name field to be bare. We stringify them as
|
|
// appropriately in BUILTIN_BINARY_OPERATION_{OVERLOADED_STATIC,POLYMORPHIC}.
|
|
BUILTIN_BINARY_OPERATION_ALL(Add, add, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(FAdd, fadd, "n", FloatOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(And, and, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(AShr, ashr, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(LShr, lshr, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(Or, or, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(FDiv, fdiv, "n", FloatOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(Mul, mul, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(FMul, fmul, "n", FloatOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(SDiv, sdiv, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(ExactSDiv, sdiv_exact, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(Shl, shl, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(SRem, srem, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(Sub, sub, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(FSub, fsub, "n", FloatOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(UDiv, udiv, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(ExactUDiv, udiv_exact, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(URem, urem, "n", Integer)
|
|
BUILTIN_BINARY_OPERATION_ALL(FRem, frem, "n", FloatOrVector)
|
|
BUILTIN_BINARY_OPERATION_ALL(Xor, xor, "n", IntegerOrVector)
|
|
BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(Expect, "int_expect", "n", Integer)
|
|
|
|
/// These builtins are analogous the similarly named llvm intrinsics. The
|
|
/// difference between the two is that these are not expected to overflow,
|
|
/// so we should produce a compile time error if we can statically prove
|
|
/// that they do.
|
|
#ifndef BUILTIN_BINARY_OPERATION_WITH_OVERFLOW
|
|
#define BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(Id, Name, UncheckedID, Attrs, Overload) \
|
|
BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(SAddOver,
|
|
"sadd_with_overflow", Add, "n", Integer)
|
|
BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(UAddOver,
|
|
"uadd_with_overflow", Add, "n", Integer)
|
|
BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(SSubOver,
|
|
"ssub_with_overflow", Sub, "n", Integer)
|
|
BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(USubOver,
|
|
"usub_with_overflow", Sub, "n", Integer)
|
|
BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(SMulOver,
|
|
"smul_with_overflow", Mul, "n", Integer)
|
|
BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(UMulOver,
|
|
"umul_with_overflow", Mul, "n", Integer)
|
|
|
|
/// Unary operations have type (T) -> T.
|
|
#ifndef BUILTIN_UNARY_OPERATION
|
|
#define BUILTIN_UNARY_OPERATION(Id, Name, Attrs, Overload) \
|
|
BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
|
|
// "fneg" is a separate builtin because its LLVM representation is
|
|
// 'fsub -0.0, %x', but defining it in swift as
|
|
// 'func [prefix] -(x) { -0.0 - x }' would be infinitely recursive.
|
|
BUILTIN_UNARY_OPERATION(FNeg, "fneg", "n", FloatOrVector)
|
|
|
|
// Returns the argument and specifies that the value is not negative.
|
|
// It has only an effect if the argument is a load or call.
|
|
// TODO: consider printing a warning if it is not used on a load or call.
|
|
BUILTIN_UNARY_OPERATION(AssumeNonNegative, "assumeNonNegative", "n", Integer)
|
|
// It only works on i1.
|
|
BUILTIN_UNARY_OPERATION(AssumeTrue, "assume", "", Integer)
|
|
// Converts poison/undef to an indeterminate but valid value.
|
|
BUILTIN_UNARY_OPERATION(Freeze, "freeze", "n", IntegerOrVector)
|
|
|
|
// Binary predicates have type (T,T) -> i1 or (T, T) -> Vector<i1> for scalars
|
|
// and vectors, respectively.
|
|
#ifndef BUILTIN_BINARY_PREDICATE
|
|
#define BUILTIN_BINARY_PREDICATE(Id, Name, Attrs, Overload) \
|
|
BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
BUILTIN_BINARY_PREDICATE(ICMP_EQ, "cmp_eq", "n", IntegerOrRawPointerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_NE, "cmp_ne", "n", IntegerOrRawPointerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_SLE, "cmp_sle", "n", IntegerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_SLT, "cmp_slt", "n", IntegerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_SGE, "cmp_sge", "n", IntegerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_SGT, "cmp_sgt", "n", IntegerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_ULE, "cmp_ule", "n", IntegerOrRawPointerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_ULT, "cmp_ult", "n", IntegerOrRawPointerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_UGE, "cmp_uge", "n", IntegerOrRawPointerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(ICMP_UGT, "cmp_ugt", "n", IntegerOrRawPointerOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_OEQ, "fcmp_oeq", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_OGT, "fcmp_ogt", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_OGE, "fcmp_oge", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_OLT, "fcmp_olt", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_OLE, "fcmp_ole", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_ONE, "fcmp_one", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_ORD, "fcmp_ord", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_UEQ, "fcmp_ueq", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_UGT, "fcmp_ugt", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_UGE, "fcmp_uge", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_ULT, "fcmp_ult", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_ULE, "fcmp_ule", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_UNE, "fcmp_une", "n", FloatOrVector)
|
|
BUILTIN_BINARY_PREDICATE(FCMP_UNO, "fcmp_uno", "n", FloatOrVector)
|
|
|
|
// BUILTIN_SIL_OPERATION - Operations that can be lowered to SIL instructions.
|
|
// These have various types.
|
|
// Since these operations will be lowered to SIL Instructions, we do not
|
|
// assign any attributes on them.
|
|
#ifndef BUILTIN_SIL_OPERATION
|
|
#define BUILTIN_SIL_OPERATION(Id, Name, Overload) BUILTIN(Id, Name, "")
|
|
#endif
|
|
|
|
/// retain: T -> ()
|
|
BUILTIN_SIL_OPERATION(Retain, "retain", Special)
|
|
|
|
/// release: T -> ()
|
|
BUILTIN_SIL_OPERATION(Release, "release", Special)
|
|
|
|
/// autorelease: T -> ()
|
|
BUILTIN_SIL_OPERATION(Autorelease, "autorelease", Special)
|
|
|
|
/// Load has type (Builtin.RawPointer) -> T
|
|
BUILTIN_SIL_OPERATION(Load, "load", Special)
|
|
|
|
/// LoadRaw has type (Builtin.RawPointer) -> T
|
|
/// This is a load of T from raw memory.
|
|
/// Its address does not adhere to strict aliasing.
|
|
BUILTIN_SIL_OPERATION(LoadRaw, "loadRaw", Special)
|
|
|
|
/// LoadInvariant has type (Builtin.RawPointer) -> T
|
|
/// This is a load of T from raw memory.
|
|
/// The load is marked as invariant.
|
|
BUILTIN_SIL_OPERATION(LoadInvariant, "loadInvariant", Special)
|
|
|
|
/// Take has type (Builtin.RawPointer) -> T
|
|
BUILTIN_SIL_OPERATION(Take, "take", Special)
|
|
|
|
/// Destroy has type (T.Type, Builtin.RawPointer) -> ()
|
|
BUILTIN_SIL_OPERATION(Destroy, "destroy", Special)
|
|
|
|
/// Assign has type (T, Builtin.RawPointer) -> ()
|
|
BUILTIN_SIL_OPERATION(Assign, "assign", Special)
|
|
|
|
/// Init has type (T, Builtin.RawPointer) -> ()
|
|
BUILTIN_SIL_OPERATION(Init, "initialize", Special)
|
|
|
|
/// StoreRaw has type (T, Builtin.RawPointer) -> ()
|
|
/// Stores a T to raw memory.
|
|
/// Its address does not adhere to strict aliasing.
|
|
/// See also LoadRaw.
|
|
BUILTIN_SIL_OPERATION(StoreRaw, "storeRaw", Special)
|
|
|
|
/// CastToNativeObject has type (T) -> Builtin.NativeObject.
|
|
///
|
|
/// This builtin asserts if the underlying type /could/ be objc.
|
|
BUILTIN_SIL_OPERATION(CastToNativeObject, "castToNativeObject", Special)
|
|
|
|
/// UnsafeCastToNativeObject has type (T) -> Builtin.NativeObject.
|
|
///
|
|
/// This builtin does not check if the underlying type /could/ be objc.
|
|
BUILTIN_SIL_OPERATION(UnsafeCastToNativeObject, "unsafeCastToNativeObject", Special)
|
|
|
|
/// CastFromNativeObject has type (Builtin.NativeObject) -> T
|
|
BUILTIN_SIL_OPERATION(CastFromNativeObject, "castFromNativeObject", Special)
|
|
|
|
/// CastToBridgeObject has type (T, Builtin.Word) -> Builtin.BridgeObject.
|
|
/// It sets the BridgeObject to the bitwise OR of its operands.
|
|
/// It is assumed that
|
|
///
|
|
/// castReferenceFromBridgeObject(castToBridgeObject(ref, x)) === ref
|
|
///
|
|
/// regardless of what x is.
|
|
/// x thus must not have any bits set that would change the heap
|
|
/// object pointer value, nor may it have the native/ObjC discriminator bit set,
|
|
/// nor may it have any bits set if the first operand is an ObjC tagged pointer,
|
|
/// or else undefined behavior will ensue.
|
|
BUILTIN_SIL_OPERATION(CastToBridgeObject, "castToBridgeObject", Special)
|
|
|
|
/// ValueToBridgeObject has type (T) -> Builtin.BridgeObject.
|
|
/// It sets the BridgeObject to a tagged pointer representation holding its
|
|
// operands by tagging and shifting the operand if needed.
|
|
///
|
|
/// valueToBridgeObject(x) === (x << _swift_abi_ObjCReservedLowBits) |
|
|
/// _swift_BridgeObject_TaggedPointerBits
|
|
///
|
|
/// x thus must not be using any high bits shifted away (via _swift_abi_ObjCReservedLowBits)
|
|
/// or the tag bits post-shift.
|
|
/// ARC operations on such tagged values are NOPs.
|
|
BUILTIN_SIL_OPERATION(ValueToBridgeObject, "valueToBridgeObject", Special)
|
|
|
|
/// CastReferenceFromBridgeObject has type (Builtin.BridgeObject) -> T.
|
|
/// It recovers the heap object reference by masking spare bits from the
|
|
/// BridgeObject.
|
|
BUILTIN_SIL_OPERATION(CastReferenceFromBridgeObject,
|
|
"castReferenceFromBridgeObject",
|
|
Special)
|
|
|
|
/// CastBitPatternFromBridgeObject has type (Builtin.BridgeObject) -> Builtin.Word.
|
|
/// It presents the raw bit pattern of the BridgeObject as
|
|
BUILTIN_SIL_OPERATION(CastBitPatternFromBridgeObject,
|
|
"castBitPatternFromBridgeObject",
|
|
Special)
|
|
|
|
/// ClassifyBridgeObject has type:
|
|
/// (Builtin.BridgeObject) -> (Builtin.Int1, Builtin.Int1).
|
|
/// It interprets the bits mangled into a bridge object, returning whether it is
|
|
/// an Objective-C object or tagged pointer representation.
|
|
BUILTIN_SIL_OPERATION(ClassifyBridgeObject, "classifyBridgeObject", Special)
|
|
|
|
|
|
/// BridgeToRawPointer has type (T) -> Builtin.RawPointer
|
|
BUILTIN_SIL_OPERATION(BridgeToRawPointer, "bridgeToRawPointer", Special)
|
|
|
|
/// BridgeFromRawPointer (Builtin.RawPointer) -> T
|
|
/// SILGen requires that T is a single retainable pointer.
|
|
/// Bridging to/from a raw pointer does not imply a retain.
|
|
BUILTIN_SIL_OPERATION(BridgeFromRawPointer, "bridgeFromRawPointer", Special)
|
|
|
|
/// castReference has type T -> U.
|
|
/// T and U must be convertible to AnyObject.
|
|
BUILTIN_SIL_OPERATION(CastReference, "castReference", Special)
|
|
|
|
/// reinterpretCast has type T -> U.
|
|
BUILTIN_SIL_OPERATION(ReinterpretCast, "reinterpretCast", Special)
|
|
|
|
/// addressof (inout T) -> Builtin.RawPointer
|
|
/// Returns a RawPointer pointing to a physical lvalue. The returned pointer is
|
|
/// only valid for the duration of the original binding.
|
|
BUILTIN_SIL_OPERATION(AddressOf, "addressof", Special)
|
|
|
|
/// unprotectedAddressOf (inout T) -> Builtin.RawPointer
|
|
/// Returns a RawPointer pointing to a physical lvalue. The returned pointer is
|
|
/// only valid for the duration of the original binding.
|
|
/// In contrast to `addressof`, this builtin doesn't trigger an insertion of
|
|
/// stack protectors.
|
|
BUILTIN_SIL_OPERATION(UnprotectedAddressOf, "unprotectedAddressOf", Special)
|
|
|
|
/// addressOfBorrow (__shared T) -> Builtin.RawPointer
|
|
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
|
|
/// valid within the scope of the borrow.
|
|
BUILTIN_SIL_OPERATION(AddressOfBorrow, "addressOfBorrow", Special)
|
|
|
|
/// unprotectedAddressOfBorrow (__shared T) -> Builtin.RawPointer
|
|
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
|
|
/// valid within the scope of the borrow.
|
|
/// In contrast to `addressOfBorrow`, this builtin doesn't trigger an insertion of
|
|
/// stack protectors.
|
|
BUILTIN_SIL_OPERATION(UnprotectedAddressOfBorrow, "unprotectedAddressOfBorrow", Special)
|
|
|
|
/// GepRaw(Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer
|
|
///
|
|
/// Adds index bytes to a base pointer.
|
|
BUILTIN_SIL_OPERATION(GepRaw, "gepRaw", Integer)
|
|
|
|
/// Gep (Builtin.RawPointer, Builtin.Word, T.Type) -> Builtin.RawPointer
|
|
///
|
|
/// Like the GepRaw-builtin, but multiplies the index by stride-of type 'T'.
|
|
BUILTIN_SIL_OPERATION(Gep, "gep", Integer)
|
|
|
|
/// getTailAddr(Builtin.RawPointer,
|
|
/// Builtin.Word, T.Type, E.Type) -> Builtin.RawPointer
|
|
///
|
|
/// Like the Gep-builtin, but rounds up the resulting address to a tail-
|
|
/// allocated element type 'E'.
|
|
BUILTIN_SIL_OPERATION(GetTailAddr, "getTailAddr", Integer)
|
|
|
|
/// performInstantaneousReadAccess(Builtin.RawPointer, T.Type) -> ()
|
|
/// Begin and then immediately end a read access to the given raw pointer,
|
|
/// which will be treated as an address of type 'T'.
|
|
BUILTIN_SIL_OPERATION(PerformInstantaneousReadAccess,
|
|
"performInstantaneousReadAccess", Special)
|
|
|
|
/// beginUnpairedModifyAccess(Builtin.RawPointer, Builtin.RawPointer,
|
|
/// T.Type) -> ()
|
|
/// Begins but does not end a 'modify' access to the first raw pointer argument.
|
|
/// The second raw pointer must be a pointer to an UnsafeValueBuffer, which
|
|
/// will be used by the runtime to record the access. The lifetime of the
|
|
/// value buffer must be longer than that of the access itself. The accessed
|
|
/// address will be treated as having type 'T'.
|
|
BUILTIN_SIL_OPERATION(BeginUnpairedModifyAccess, "beginUnpairedModifyAccess",
|
|
Special)
|
|
|
|
/// endUnpairedAccess(Builtin.RawPointer) -> ()
|
|
/// Ends an in-progress unpaired access. The raw pointer argument must be
|
|
/// be a pointer to an UnsafeValueBuffer that records an in progress access.
|
|
BUILTIN_SIL_OPERATION(EndUnpairedAccess, "endUnpairedAccess", Special)
|
|
|
|
/// condfail(Int1) -> ()
|
|
/// Triggers a runtime failure if the condition is true.
|
|
/// This builtin is deprecated. Use condfail_message instead.
|
|
BUILTIN_SIL_OPERATION(LegacyCondFail, "condfail", Special)
|
|
|
|
/// fixLifetime(T) -> ()
|
|
/// Fixes the lifetime of any heap references in a value.
|
|
BUILTIN_SIL_OPERATION(FixLifetime, "fixLifetime", Special)
|
|
|
|
/// isUnique : <T> (inout T[?]) -> Int1
|
|
///
|
|
/// This builtin takes an inout object reference and returns a boolean. Passing
|
|
/// the reference inout forces the optimizer to preserve a retain distinct from
|
|
/// what's required to maintain lifetime for any of the reference's source-level
|
|
/// copies, because the called function is allowed to replace the reference,
|
|
/// thereby releasing the referent.
|
|
///
|
|
/// The kind of reference count checking that Builtin.isUnique performs depends
|
|
/// on the argument type:
|
|
///
|
|
/// - Native object types are directly checked by reading the
|
|
/// strong reference count:
|
|
/// (Builtin.NativeObject, known native class reference)
|
|
///
|
|
/// - Objective-C object types require an additional check that the
|
|
/// dynamic object type uses native swift reference counting:
|
|
/// (AnyObject, unknown class reference, class existential)
|
|
///
|
|
/// - Bridged object types allow the dynamic object type check to be
|
|
/// passed based on their pointer encoding:
|
|
/// (Builtin.BridgeObject)
|
|
///
|
|
/// Any of the above types may also be wrapped in an optional.
|
|
/// If the static argument type is optional, then a null check is also
|
|
/// performed.
|
|
///
|
|
/// Thus, isUnique only returns true for non-null, native swift object
|
|
/// references with a strong reference count of one.
|
|
BUILTIN_SIL_OPERATION(IsUnique, "isUnique", Special)
|
|
|
|
/// IsUnique_native : <T> (inout T[?]) -> Int1
|
|
///
|
|
/// These variants of isUnique implicitly cast to a non-null NativeObject before
|
|
/// checking uniqueness. This allows an object reference statically typed as
|
|
/// BridgeObject to be treated as a native object by the runtime.
|
|
BUILTIN_SIL_OPERATION(IsUnique_native, "isUnique_native", Special)
|
|
|
|
/// beginCOWMutation<T : AnyObject>(inout T) -> Int1
|
|
///
|
|
/// Begins a copy-on-write mutation for a buffer reference which is passed as
|
|
/// inout argument. It returns a true if the buffer is uniquely referenced.
|
|
/// In this case the buffer may be mutated after calling this builtin.
|
|
///
|
|
/// The beginCOWMutation builtin is very similar to isUnique. It just translates
|
|
/// to a different SIL instruction (begin_cow_mutation), which is the preferred
|
|
/// representation of COW in SIL.
|
|
BUILTIN_SIL_OPERATION(BeginCOWMutation, "beginCOWMutation", Special)
|
|
|
|
/// beginCOWMutation_native<T : AnyObject>(inout T) -> Int1
|
|
///
|
|
/// Like beginCOWMutation, but it's assumed that T has native Swift reference
|
|
/// counting.
|
|
BUILTIN_SIL_OPERATION(BeginCOWMutation_native, "beginCOWMutation_native", Special)
|
|
|
|
/// endCOWMutation<T : AnyObject>(inout T)
|
|
///
|
|
/// Ends a copy-on-write mutation for a buffer reference which is passed as
|
|
/// inout argument. After calling this builtin, the buffer must not be mutated.
|
|
BUILTIN_SIL_OPERATION(EndCOWMutation, "endCOWMutation", Special)
|
|
|
|
/// bindMemory : <T> (Builtin.RawPointer, Builtin.Word, T.Type) -> Builtin.Word
|
|
///
|
|
/// Binds memory to a statically known type. Returns an opaque token
|
|
/// representing the memory region's previously bound types.
|
|
BUILTIN_SIL_OPERATION(BindMemory, "bindMemory", Special)
|
|
|
|
/// rebindMemory : (Builtin.RawPointer, Builtin.Word) -> Builtin.Word
|
|
///
|
|
/// Binds memory to the types represented by an opaque token operand. Returns an
|
|
/// opaque token representing the memory region's previously bound types.
|
|
BUILTIN_SIL_OPERATION(RebindMemory, "rebindMemory", Special)
|
|
|
|
/// allocWithTailElems_<n>(C.Type,
|
|
/// Builtin.Word, E1.Type, ... , Builtin.Word, En.Type) -> C\
|
|
///
|
|
/// The integer suffix <n> specifies the number of tail-allocated arrays.
|
|
/// Each tail-allocated array adds a counter and an element meta-type parameter.
|
|
BUILTIN_SIL_OPERATION(AllocWithTailElems, "allocWithTailElems", Special)
|
|
|
|
/// projectTailElems : <C,E> (C) -> Builtin.RawPointer
|
|
///
|
|
/// Projects the first tail-allocated element of type E from a class C.
|
|
BUILTIN_SIL_OPERATION(ProjectTailElems, "projectTailElems", Special)
|
|
|
|
/// Unsafely convert a value of type T to an unowned value.
|
|
///
|
|
/// It has type (T, @inout @unowned(unsafe) T) -> (). The reason for the weird
|
|
/// signature is to work around issues with results in SILGen builtin emission.
|
|
BUILTIN_SIL_OPERATION(ConvertStrongToUnownedUnsafe, "convertStrongToUnownedUnsafe", Special)
|
|
|
|
/// Unsafely convert a value of type @inout @unowned(unsafe) T to a loaded
|
|
/// guaranteed T value that has a lifetime guaranteed by the passed in base
|
|
/// value of type BaseTy.
|
|
///
|
|
/// It has type (@in_guaranteed BaseTy, @in_guaranteed @unowned (unsafe) T) -> @guaranteed T.
|
|
///
|
|
/// NOTE: Saying the result is a guaranteed T is a bit of a misnomer. We aren't
|
|
/// emitting a builtin call, but are just emitting SIL directly.
|
|
///
|
|
/// NOTE: Even though the signature is as mentioned above, we actually tell the
|
|
/// AST we have the signature:
|
|
///
|
|
/// <BaseT, T, U> (BaseT, T) -> U
|
|
///
|
|
/// We then perform the actual type checking in SILGen and assert on
|
|
/// failure. This is an early, unsupported feature so this is sufficient for
|
|
/// now.
|
|
BUILTIN_SIL_OPERATION(ConvertUnownedUnsafeToGuaranteed, "convertUnownedUnsafeToGuaranteed", Special)
|
|
|
|
/// applyDerivative
|
|
BUILTIN_SIL_OPERATION(ApplyDerivative, "applyDerivative", Special)
|
|
|
|
/// applyTranspose
|
|
BUILTIN_SIL_OPERATION(ApplyTranspose, "applyTranspose", Special)
|
|
|
|
/// withUnsafeContinuation<T> : (Builtin.RawUnsafeContinuation -> ()) async -> sending T
|
|
///
|
|
/// Unsafely capture the current continuation and pass it to the given
|
|
/// function value. Returns a value of type T when the continuation is
|
|
/// resumed.
|
|
BUILTIN_SIL_OPERATION(WithUnsafeContinuation, "withUnsafeContinuation", Special)
|
|
|
|
/// withUnsafeThrowingContinuation<T> : (Builtin.RawUnsafeContinuation -> ()) async throws -> sending T
|
|
///
|
|
/// Unsafely capture the current continuation and pass it to the given
|
|
/// function value. Returns a value of type T or throws an error when
|
|
/// the continuation is resumed.
|
|
BUILTIN_SIL_OPERATION(WithUnsafeThrowingContinuation, "withUnsafeThrowingContinuation", Special)
|
|
|
|
/// Force the current task to be rescheduled on the specified actor.
|
|
BUILTIN_SIL_OPERATION(HopToActor, "hopToActor", None)
|
|
|
|
/// packLength: <each T>(_: repeat each T) -> Int
|
|
///
|
|
/// Returns the number of items in a pack.
|
|
BUILTIN_SIL_OPERATION(PackLength, "packLength", Special)
|
|
|
|
// BUILTIN_RUNTIME_CALL - A call into a runtime function.
|
|
// These functions accept a single argument of any type.
|
|
#ifndef BUILTIN_RUNTIME_CALL
|
|
#define BUILTIN_RUNTIME_CALL(Id, Name, Attrs) \
|
|
BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
|
|
/// unexpectedError: Error -> ()
|
|
BUILTIN_RUNTIME_CALL(UnexpectedError, "unexpectedError", "")
|
|
|
|
/// errorInMain: Error -> ()
|
|
BUILTIN_RUNTIME_CALL(ErrorInMain, "errorInMain", "")
|
|
|
|
/// IsOptionalType : T.Type -> Bool
|
|
/// This builtin takes a metatype and returns true if the metatype's
|
|
/// nominal type is Optional.
|
|
BUILTIN_RUNTIME_CALL(IsOptionalType, "isOptional", "")
|
|
|
|
// BUILTIN_MISC_OPERATION - Miscellaneous operations without a unifying class.
|
|
// These have various types.
|
|
#ifndef BUILTIN_MISC_OPERATION
|
|
#define BUILTIN_MISC_OPERATION(Id, Name, Attrs, Overload) \
|
|
BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
|
|
/// condfail_message(Int1, RawPointer) -> ()
|
|
/// Triggers a runtime failure if the condition is true.
|
|
BUILTIN_MISC_OPERATION(CondFailMessage, "condfail_message", "", Special)
|
|
|
|
/// IsPOD has type T.Type -> Bool
|
|
BUILTIN_MISC_OPERATION(IsPOD, "ispod", "n", Special)
|
|
|
|
/// IsConcrete has type (T.Type) -> Bool
|
|
///
|
|
/// If the meta type T is concrete, we can always transform this to `true` at
|
|
/// any time in SIL. If it's generic, then we lower it to `false` right before
|
|
/// IRGen in IRGenPrepare. This allows for the optimizer to specialize this at
|
|
/// -O and eliminate conditional code.
|
|
BUILTIN_MISC_OPERATION(IsConcrete, "isConcrete", "n", Special)
|
|
|
|
/// IsBitwiseTakable has type T.Type -> Bool
|
|
BUILTIN_MISC_OPERATION(IsBitwiseTakable, "isbitwisetakable", "n", Special)
|
|
|
|
/// IsSameMetatype has type (Any.Type, Any.Type) -> Bool
|
|
BUILTIN_MISC_OPERATION(IsSameMetatype, "is_same_metatype", "n", Special)
|
|
|
|
/// AllocRaw has type (Int, Int) -> Builtin.RawPointer
|
|
///
|
|
/// Parameters: object size, object alignment.
|
|
///
|
|
/// This alignment is not a mask; the compiler decrements by one to provide
|
|
/// a mask to the runtime.
|
|
///
|
|
/// If alignment == 0, then the runtime will use "aligned" allocation,
|
|
/// and the memory will be aligned to _swift_MinAllocationAlignment.
|
|
BUILTIN_MISC_OPERATION(AllocRaw, "allocRaw", "", Special)
|
|
|
|
/// DeallocRaw has type (Builtin.RawPointer, Int, Int) -> ()
|
|
///
|
|
/// Parameters: object address, object size, object alignment.
|
|
///
|
|
/// This alignment is not a mask; the compiler decrements by one to provide
|
|
/// a mask to the runtime.
|
|
///
|
|
/// If alignment == 0, then the runtime will use the "aligned" deallocation
|
|
/// path, which assumes that "aligned" allocation was used.
|
|
///
|
|
/// Note that the alignment value provided to `deallocRaw` must be identical to
|
|
/// the alignment value provided to `allocRaw` when the memory at this address
|
|
/// was allocated.
|
|
BUILTIN_MISC_OPERATION(DeallocRaw, "deallocRaw", "", Special)
|
|
|
|
/// StackAlloc has type (Int, Int, Int) -> Builtin.RawPointer
|
|
///
|
|
/// Parameters: capacity, stride, alignment
|
|
///
|
|
/// The resulting pointer comes from the stack (as in the non-standard C
|
|
/// extension `alloca()`.) It is at least as aligned as specified and is valid
|
|
/// until the end of the calling scope.
|
|
///
|
|
/// The count and stride are multiplied together to get the byte count to use
|
|
/// for the allocation.
|
|
///
|
|
/// The passed alignment must be a positive power of two. If the alignment value
|
|
/// is not known at compile time, MaximumAlignment is assumed.
|
|
BUILTIN_MISC_OPERATION(StackAlloc, "stackAlloc", "", Special)
|
|
|
|
/// Like `stackAlloc`, but doesn't set the `[stack_protection]` flag on its
|
|
/// containing function.
|
|
BUILTIN_MISC_OPERATION(UnprotectedStackAlloc, "unprotectedStackAlloc", "", Special)
|
|
|
|
/// StackDealloc has type (Builtin.RawPointer) -> ()
|
|
///
|
|
/// Parameters: address.
|
|
///
|
|
/// The range starting at `address`, previously allocated with
|
|
/// Builtin.stackAlloc(), is deallocated from the stack.
|
|
BUILTIN_MISC_OPERATION(StackDealloc, "stackDealloc", "", Special)
|
|
|
|
// Obsolete: only there to be able to read old Swift.interface files which still
|
|
// contain the builtin.
|
|
/// allocVector<Element>(Element.Type, Builtin.Word) -> Builtin.RawPointer
|
|
BUILTIN_MISC_OPERATION(AllocVector, "allocVector", "", Special)
|
|
|
|
/// Fence has type () -> ().
|
|
BUILTIN_MISC_OPERATION(Fence, "fence", "", None)
|
|
|
|
/// onFastPath has type () -> ().
|
|
BUILTIN_MISC_OPERATION(OnFastPath, "onFastPath", "n", None)
|
|
|
|
/// CmpXChg has type (Builtin.RawPointer, T, T) -> (T, Bool).
|
|
BUILTIN_MISC_OPERATION(CmpXChg, "cmpxchg", "", Special)
|
|
|
|
/// AtomicLoad has type (Builtin.RawPointer) -> T.
|
|
BUILTIN_MISC_OPERATION(AtomicLoad, "atomicload", "", Special)
|
|
|
|
/// AtomicStore has type (Builtin.RawPointer, T) -> ().
|
|
BUILTIN_MISC_OPERATION(AtomicStore, "atomicstore", "", Special)
|
|
|
|
/// AtomicRMW has type (Builtin.RawPointer, T) -> T.
|
|
BUILTIN_MISC_OPERATION(AtomicRMW, "atomicrmw", "", IntegerOrRawPointer)
|
|
|
|
/// convertTaskToJob : (Builtin.NativePointer) -> Builtin.Job
|
|
///
|
|
/// Convert a task pointer into a job pointer.
|
|
BUILTIN_MISC_OPERATION(ConvertTaskToJob, "convertTaskToJob", "n", Special)
|
|
|
|
/// ExtractElement has type (Vector<N, T>, Int32) -> T
|
|
BUILTIN_MISC_OPERATION(ExtractElement, "extractelement", "n", Special)
|
|
|
|
/// InsertElement has type (Vector<N, T>, T, Int32) -> Vector<N, T>.
|
|
BUILTIN_MISC_OPERATION(InsertElement, "insertelement", "n", Special)
|
|
|
|
// Shufflevector has type (VecN<T>, VecN<T>, VecM<Int32>) -> VecM<T>
|
|
BUILTIN_MISC_OPERATION(ShuffleVector, "shufflevector", "n", Special)
|
|
|
|
/// StaticReport has type (Builtin.Int1, Builtin.Int1, Builtin.RawPointer) -> ()
|
|
BUILTIN_MISC_OPERATION(StaticReport, "staticReport", "", Special)
|
|
|
|
/// assert_configuration has type () -> Builtin.Int32
|
|
/// Returns the selected assertion configuration.
|
|
BUILTIN_MISC_OPERATION(AssertConf, "assert_configuration", "n", Special)
|
|
|
|
/// Ifdef has type () -> Bool.
|
|
BUILTIN_MISC_OPERATION(Ifdef, "ifdef", "n", Special)
|
|
|
|
/// StringObjectOr has type (T,T) -> T.
|
|
/// Sets bits in a string object. The first operand is bit-cast string literal
|
|
/// pointer to an integer. The second operand is the bit mask to be or'd into
|
|
/// the high bits of the pointer.
|
|
/// It is required that the or'd bits are all 0 in the first operand. So this
|
|
/// or-operation is actually equivalent to an addition.
|
|
BUILTIN_MISC_OPERATION(StringObjectOr, "stringObjectOr", "n", Integer)
|
|
|
|
/// Special truncation builtins that check for sign and overflow errors. These
|
|
/// take an integer as an input and return a tuple of the truncated result and
|
|
/// an error bit. The name of each builtin is extended with the "from"
|
|
/// (sign-agnostic) builtin integer type and the "to" integer type.
|
|
/// We require the source type size to be larger than the destination type size
|
|
/// (number of bits).
|
|
BUILTIN_MISC_OPERATION(UToSCheckedTrunc, "u_to_s_checked_trunc", "n", Special)
|
|
BUILTIN_MISC_OPERATION(SToSCheckedTrunc, "s_to_s_checked_trunc", "n", Special)
|
|
BUILTIN_MISC_OPERATION(SToUCheckedTrunc, "s_to_u_checked_trunc", "n", Special)
|
|
BUILTIN_MISC_OPERATION(UToUCheckedTrunc, "u_to_u_checked_trunc", "n", Special)
|
|
|
|
/// IntToFPWithOverflow has type (Integer) -> Float
|
|
BUILTIN_MISC_OPERATION(IntToFPWithOverflow, "itofp_with_overflow", "n", Special)
|
|
|
|
/// Builtin.bitWidth_IntLiteral has type
|
|
/// (_ value: Builtin.IntLiteral) -> Builtin.Word
|
|
BUILTIN_MISC_OPERATION(BitWidth, "bitWidth", "n", Special)
|
|
|
|
/// Builtin.isNegative_IntLiteral has type
|
|
/// (_ value: Builtin.IntLiteral) -> Builtin.Int1
|
|
BUILTIN_MISC_OPERATION(IsNegative, "isNegative", "n", Special)
|
|
|
|
/// Builtin.wordAtIndex_IntLiteral has type
|
|
/// (_ value: Builtin.IntLiteral, _ index: Builtin.Word) -> Builtin.Word
|
|
BUILTIN_MISC_OPERATION(WordAtIndex, "wordAtIndex", "n", Special)
|
|
|
|
/// once has type (Builtin.RawPointer, (Builtin.RawPointer) -> ())
|
|
BUILTIN_MISC_OPERATION(Once, "once", "", Special)
|
|
/// onceWithContext has type (Builtin.RawPointer, (Builtin.RawPointer) -> (), Builtin.RawPointer)
|
|
BUILTIN_MISC_OPERATION(OnceWithContext, "onceWithContext", "", Special)
|
|
|
|
/// unreachable has type () -> Never
|
|
BUILTIN_MISC_OPERATION(Unreachable, "unreachable", "", Special)
|
|
|
|
/// conditionallyUnreachable has type () -> Never
|
|
BUILTIN_MISC_OPERATION(CondUnreachable, "conditionallyUnreachable", "", Special)
|
|
|
|
/// DestroyArray has type (T.Type, Builtin.RawPointer, Builtin.Word) -> ()
|
|
BUILTIN_MISC_OPERATION(DestroyArray, "destroyArray", "", Special)
|
|
|
|
/// CopyArray, TakeArrayNoAlias, TakeArrayFrontToBack, and TakeArrayBackToFront
|
|
/// AssignCopyArrayNoAlias, AssignCopyArrayFrontToBack,
|
|
/// AssignCopyArrayBackToFront, AssignTakeArray all have type
|
|
/// (T.Type, Builtin.RawPointer, Builtin.RawPointer, Builtin.Word) -> ()
|
|
BUILTIN_MISC_OPERATION(CopyArray, "copyArray", "", Special)
|
|
BUILTIN_MISC_OPERATION(TakeArrayNoAlias, "takeArrayNoAlias", "", Special)
|
|
BUILTIN_MISC_OPERATION(TakeArrayFrontToBack, "takeArrayFrontToBack", "", Special)
|
|
BUILTIN_MISC_OPERATION(TakeArrayBackToFront, "takeArrayBackToFront", "", Special)
|
|
BUILTIN_MISC_OPERATION(AssignCopyArrayNoAlias, "assignCopyArrayNoAlias", "", Special)
|
|
BUILTIN_MISC_OPERATION(AssignCopyArrayFrontToBack, "assignCopyArrayFrontToBack", "", Special)
|
|
BUILTIN_MISC_OPERATION(AssignCopyArrayBackToFront, "assignCopyArrayBackToFront", "", Special)
|
|
BUILTIN_MISC_OPERATION(AssignTakeArray, "assignTakeArray", "", Special)
|
|
|
|
/// COWBufferForReading has type <T: AnyObject> T -> T
|
|
///
|
|
/// Returns the buffer reference which is passed as argument.
|
|
/// This builtin indicates to the optimizer that the buffer is not mutable.
|
|
BUILTIN_MISC_OPERATION(COWBufferForReading, "COWBufferForReading", "n", Special)
|
|
|
|
// getObjCTypeEncoding has type <T> T.Type -> RawPointer
|
|
BUILTIN_MISC_OPERATION(GetObjCTypeEncoding, "getObjCTypeEncoding", "n", Special)
|
|
|
|
/// willThrow: Error -> ()
|
|
BUILTIN_MISC_OPERATION(WillThrow, "willThrow", "", Special)
|
|
|
|
/// poundAssert has type (Builtin.Int1, Builtin.RawPointer) -> ().
|
|
BUILTIN_MISC_OPERATION(PoundAssert, "poundAssert", "", Special)
|
|
|
|
// TypePtrAuthDiscriminator has type <T> (T.Type) -> Int64
|
|
BUILTIN_MISC_OPERATION(TypePtrAuthDiscriminator, "typePtrAuthDiscriminator", "n", Special)
|
|
|
|
/// Initialize the default-actor instance in a default actor object.
|
|
BUILTIN_MISC_OPERATION(InitializeDefaultActor, "initializeDefaultActor", "", Special)
|
|
|
|
/// Destroy the default-actor instance in a default actor object.
|
|
BUILTIN_MISC_OPERATION(DestroyDefaultActor, "destroyDefaultActor", "", Special)
|
|
|
|
/// Initialize the extra storage state of a non-default distributed actor object.
|
|
BUILTIN_MISC_OPERATION(InitializeNonDefaultDistributedActor,
|
|
"initializeNonDefaultDistributedActor", "", Special)
|
|
|
|
/// Allocate a "proxy" for a distributed remote actor.
|
|
BUILTIN_MISC_OPERATION(InitializeDistributedRemoteActor,
|
|
"initializeDistributedRemoteActor", "", Special)
|
|
|
|
/// Resume a non-throwing continuation normally with the given result.
|
|
BUILTIN_MISC_OPERATION(ResumeNonThrowingContinuationReturning,
|
|
"resumeNonThrowingContinuationReturning", "", Special)
|
|
|
|
/// targetOSVersionAtLeast has type (Builtin.Int32, Builtin.Int32, Builtin.Int32) -> Builtin.Int32
|
|
BUILTIN_MISC_OPERATION(TargetOSVersionAtLeast, "targetOSVersionAtLeast", "n", Special)
|
|
|
|
/// targetVariantOSVersionAtLeast has type (Builtin.Int32, Builtin.Int32, Builtin.Int32) -> Builtin.Int32
|
|
BUILTIN_MISC_OPERATION(TargetVariantOSVersionAtLeast, "targetVariantOSVersionAtLeast", "n", Special)
|
|
|
|
/// targetOSVersionOrVariantOSVersionAtLeast has type (Builtin.UInt32, Builtin.UInt32, Builtin.UInt32, Builtin.UInt32, Builtin.UInt32, Builtin.UInt32) -> Builtin.UInt32
|
|
BUILTIN_MISC_OPERATION(TargetOSVersionOrVariantOSVersionAtLeast, "targetOSVersionOrVariantOSVersionAtLeast", "n", Special)
|
|
|
|
/// Resume a throwing continuation normally with the given result.
|
|
BUILTIN_MISC_OPERATION(ResumeThrowingContinuationReturning,
|
|
"resumeThrowingContinuationReturning", "", Special)
|
|
|
|
/// Resume a throwing continuation abnormally with the given error.
|
|
BUILTIN_MISC_OPERATION(ResumeThrowingContinuationThrowing,
|
|
"resumeThrowingContinuationThrowing", "", Special)
|
|
|
|
/// Unchecked pointer alignment assertion. Allows the compiler to assume
|
|
/// alignment of the pointer to emit more efficient code.
|
|
///
|
|
/// %alignedPtr = builtin "assumeAlignment" (%ptr : $Builtin.RawPointer,
|
|
/// %alignment : $Builtin.Int)
|
|
/// : $Builtin.RawPointer
|
|
/// %address = pointer_to_address %alignedPtr
|
|
/// : $Builtin.RawPointer to [align=1] $*Int
|
|
/// %val = load %address : $*Int
|
|
///
|
|
/// With compile-time knowledge of the value of `%alignment` the compiler can
|
|
/// optimize any downstream 'pointer_to_address' instruction by refining its
|
|
/// '[align=]' flag . That `[align=]` flag can be used by IRGen to refine the
|
|
/// alignment on LLVM load instructions that use the resulting address.
|
|
///
|
|
/// (Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer
|
|
BUILTIN_MISC_OPERATION(AssumeAlignment, "assumeAlignment", "n", Special)
|
|
|
|
// BUILTIN_MISC_OPERATION_WITH_SILGEN - Miscellaneous operations that are
|
|
// specially emitted during SIL generation.
|
|
//
|
|
// The intention is that this is meant for builtins that need a named
|
|
// builtin representation so one can create a builtin instruction in
|
|
// SIL, but that also need special SILGen behavior. If an operation
|
|
// just emits custom SIL and does not need to be able to form a
|
|
// builtin instruction, please use BUILTIN_SIL_OPERATION.
|
|
#ifndef BUILTIN_MISC_OPERATION_WITH_SILGEN
|
|
#define BUILTIN_MISC_OPERATION_WITH_SILGEN(Id, Name, Attrs, Overload) \
|
|
BUILTIN_MISC_OPERATION(Id, Name, Attrs, Overload)
|
|
#endif
|
|
|
|
/// Sizeof has type T.Type -> Int
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(Sizeof, "sizeof", "n", Special)
|
|
|
|
/// Strideof has type T.Type -> Int
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(Strideof, "strideof", "n", Special)
|
|
|
|
/// Alignof has type T.Type -> Int
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(Alignof, "alignof", "n", Special)
|
|
|
|
/// zeroInitializer has type <T> () -> T, but the SIL builtin has its
|
|
/// own rules.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(ZeroInitializer, "zeroInitializer", "n", Special)
|
|
|
|
// getCurrentExecutor: () async -> Builtin.Executor?
|
|
//
|
|
// Retrieve the SerialExecutorRef on which the current asynchronous
|
|
// function is executing, or nil if the function isn't running
|
|
// anywhere in particular.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(GetCurrentExecutor, "getCurrentExecutor", "", Special)
|
|
|
|
// getCurrentAsyncTask: () -> Builtin.NativeObject
|
|
//
|
|
// Retrieve the pointer to the task in which the current asynchronous
|
|
// function is executing.
|
|
//
|
|
// This is readnone because, within the world modeled by SIL, the
|
|
// current async task of a thread never changes.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(GetCurrentAsyncTask, "getCurrentAsyncTask", "n", Special)
|
|
|
|
/// cancelAsyncTask(): (Builtin.NativeObject) -> Void
|
|
///
|
|
/// Cancel the given asynchronous task.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(CancelAsyncTask, "cancelAsyncTask", "", Special)
|
|
|
|
/// startAsyncLet()<T>: (
|
|
/// __owned @escaping () async throws -> sending T
|
|
/// ) -> Builtin.RawPointer
|
|
///
|
|
/// DEPRECATED. startAsyncLetWithLocalBuffer is used instead.
|
|
///
|
|
/// Create, initialize and start a new async-let and associated task.
|
|
/// Returns an AsyncLet* that must be passed to endAsyncLet for destruction.
|
|
BUILTIN_MISC_OPERATION(StartAsyncLet, "startAsyncLet", "", Special)
|
|
|
|
/// startAsyncLetWithLocalBuffer()<T>: (
|
|
/// __owned @escaping () async throws -> sending T,
|
|
/// _ resultBuf: Builtin.RawPointer
|
|
/// ) -> Builtin.RawPointer
|
|
///
|
|
/// Create, initialize and start a new async-let and associated task, with a
|
|
/// locally-allocated buffer assigned to receive the result if the task
|
|
/// completes.
|
|
/// Returns an AsyncLet* that must be passed to endAsyncLetLifetime for
|
|
/// destruction.
|
|
BUILTIN_MISC_OPERATION(StartAsyncLetWithLocalBuffer, "startAsyncLetWithLocalBuffer", "", Special)
|
|
|
|
/// taskRunInline()<T>: (
|
|
/// () async -> T
|
|
/// ) -> T
|
|
///
|
|
/// Create an async context inline in the current synchronous context and run
|
|
/// the specified closure.
|
|
///
|
|
/// This is only supported under the task-to-thread concurrency model.
|
|
BUILTIN_MISC_OPERATION(TaskRunInline, "taskRunInline", "", Special)
|
|
|
|
/// flowSensitiveSelfIsolation<T: Actor>(_ actor: T) -> (any Actor)?
|
|
///
|
|
/// Used only in actor initializers, this builtin lowers to either 'actor'
|
|
/// (wrapped in an optional) or 'nil' depending on whether 'self' has been
|
|
/// initialized at this point. 'actor' is always an alias for the 'self'
|
|
/// being initialized.
|
|
BUILTIN_MISC_OPERATION(FlowSensitiveSelfIsolation, "flowSensitiveSelfIsolation", "", Special)
|
|
|
|
/// flowSensitiveDistributedSelfIsolation<T: DistributedActor>(
|
|
/// _ actor: T
|
|
/// ) -> (any Actor)?
|
|
///
|
|
/// Used only in distributed actor initializers, this builtin lowers to either
|
|
/// 'actor.asLocalActor' or 'nil' depending on whether 'self' has been
|
|
/// initialized at this point. 'actor' is always an alias for the 'self'
|
|
/// being initialized.
|
|
BUILTIN_MISC_OPERATION(FlowSensitiveDistributedSelfIsolation,
|
|
"flowSensitiveDistributedSelfIsolation", "", Special)
|
|
|
|
/// endAsyncLet(): (Builtin.RawPointer) -> Void
|
|
///
|
|
/// DEPRECATED. The swift_asyncLet_finish intrinsic and endAsyncLetLifetime
|
|
/// builtin are used instead.
|
|
///
|
|
/// Ends and destroys an async-let.
|
|
/// The ClosureLifetimeFixup pass adds a second operand to the builtin to
|
|
/// ensure that optimizations keep the stack-allocated closure arguments alive
|
|
/// until the endAsyncLet.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
|
|
|
|
/// endAsyncLetLifetime(): (Builtin.RawPointer) -> Void
|
|
///
|
|
/// Marks the end of an async-let's lifetime.
|
|
/// The ClosureLifetimeFixup pass adds a second operand to the builtin to
|
|
/// ensure that optimizations keep the stack-allocated closure arguments alive
|
|
/// until the endAsyncLet.
|
|
BUILTIN_MISC_OPERATION(EndAsyncLetLifetime, "endAsyncLetLifetime", "", Special)
|
|
|
|
/// addressOfBorrowOpaque (__shared T) -> Builtin.RawPointer
|
|
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is
|
|
/// only valid within the scope of the borrow.
|
|
///
|
|
/// Differs from addressOfBorrow only in that it is not lowered until
|
|
/// AddressLowering.
|
|
BUILTIN_MISC_OPERATION(AddressOfBorrowOpaque, "addressOfBorrowOpaque", "", Special)
|
|
|
|
/// unprotectedAddressOfBorrowOpaque (__shared T) -> Builtin.RawPointer
|
|
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
|
|
/// valid within the scope of the borrow.
|
|
/// In contrast to `addressOfBorrowOpaque`, this builtin doesn't trigger an
|
|
/// insertion of stack protectors.
|
|
///
|
|
/// Differs from unprotectedAddressOfBorrow only in that it is not lowered until
|
|
/// AddressLowering.
|
|
BUILTIN_MISC_OPERATION(UnprotectedAddressOfBorrowOpaque, "unprotectedAddressOfBorrowOpaque", "", Special)
|
|
|
|
/// createTask<T>(flags: Int,
|
|
/// initialSerialExecutor: (Builtin.Executor)? = nil,
|
|
/// taskGroup: Builtin.RawPointer? = nil,
|
|
/// initialTaskExecutorDeprecated: (Builtin.Executor)? = nil,
|
|
/// initialTaskExecutorOwned: (any TaskExecutor)? = nil,
|
|
/// operation: sending @escaping () async throws -> T)
|
|
/// -> Builtin.NativeObject, Builtin.RawPointer)
|
|
///
|
|
/// Create a new task.
|
|
BUILTIN_SIL_OPERATION(CreateTask, "createTask", Special)
|
|
|
|
/// createDiscardingTask(flags: Int,
|
|
/// initialSerialExecutor: (Builtin.Executor)? = nil,
|
|
/// taskGroup: Builtin.RawPointer? = nil,
|
|
/// initialTaskExecutor: (Builtin.Executor)? = nil,
|
|
/// operation: sending @escaping () async throws -> ())
|
|
/// -> (Builtin.NativeObject, Builtin.RawPointer)
|
|
///
|
|
/// Create a new discarding task.
|
|
BUILTIN_SIL_OPERATION(CreateDiscardingTask, "createDiscardingTask", Special)
|
|
|
|
/// createAsyncTask(): (
|
|
/// Int, // task-creation flags
|
|
/// sending @escaping () async throws -> T // function
|
|
/// ) -> Builtin.NativeObject
|
|
///
|
|
/// Legacy spelling of:
|
|
/// createTask(flags: $0, operation: $1)
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask,
|
|
"createAsyncTask", "", Special)
|
|
|
|
/// createAsyncTaskInGroup(): (
|
|
/// Int, // flags
|
|
/// Builtin.RawPointer, // group
|
|
/// sending @escaping () async throws -> T // function
|
|
/// ) -> Builtin.NativeObject
|
|
///
|
|
/// Legacy spelling of:
|
|
/// createTask(flags: $0, taskGroup: $1, operation: $2)
|
|
BUILTIN_SIL_OPERATION(CreateAsyncTaskInGroup,
|
|
"createAsyncTaskInGroup", Special)
|
|
|
|
/// createAsyncDiscardingTaskInGroup(): (
|
|
/// Int, // flags
|
|
/// Builtin.RawPointer, // group
|
|
/// sending @escaping () async throws -> Void // function
|
|
/// ) -> Builtin.NativeObject
|
|
///
|
|
/// Legacy spelling of:
|
|
/// createDiscardingTask(flags: $0, taskGroup: $1, operation: $2)
|
|
BUILTIN_SIL_OPERATION(CreateAsyncDiscardingTaskInGroup,
|
|
"createAsyncDiscardingTaskInGroup", Special)
|
|
|
|
/// createAsyncTaskWithExecutor(): (
|
|
/// Int, // flags
|
|
/// Builtin.Executor, // executor
|
|
/// sending @escaping () async throws -> T // function
|
|
/// ) -> Builtin.NativeObject
|
|
///
|
|
/// Legacy spelling of:
|
|
/// createTask(flags: $0, initialTaskExecutor: $1, operation: $2)
|
|
BUILTIN_SIL_OPERATION(CreateAsyncTaskWithExecutor,
|
|
"createAsyncTaskWithExecutor", Special)
|
|
|
|
/// createAsyncTaskInGroupWithExecutor(): (
|
|
/// Int, // flags
|
|
/// Builtin.RawPointer, // group
|
|
/// Builtin.Executor, // executor
|
|
/// sending @escaping () async throws -> T // function
|
|
/// ) -> Builtin.NativeObject
|
|
///
|
|
/// Legacy spelling of:
|
|
/// createTask(flags: $0, taskGroup: $1, initialTaskExecutor: $2, operation: $3)
|
|
BUILTIN_SIL_OPERATION(CreateAsyncTaskInGroupWithExecutor,
|
|
"createAsyncTaskInGroupWithExecutor", Special)
|
|
|
|
/// createAsyncDiscardingTaskInGroupWithExecutor(): (
|
|
/// Int, // flags
|
|
/// Builtin.RawPointer, // group
|
|
/// Builtin.Executor, // executor
|
|
/// sending @escaping () async throws -> Void // function
|
|
/// ) -> Builtin.NativeObject
|
|
///
|
|
/// Legacy spelling of:
|
|
/// createDiscardingTask(flags: $0, taskGroup: $1, initialTaskExecutor: $2,
|
|
/// operation: $3)
|
|
BUILTIN_SIL_OPERATION(CreateAsyncDiscardingTaskInGroupWithExecutor,
|
|
"createAsyncDiscardingTaskInGroupWithExecutor", Special)
|
|
|
|
/// Build a Builtin.Executor value from an "ordinary" task executor
|
|
/// reference.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildOrdinaryTaskExecutorRef,
|
|
"buildOrdinaryTaskExecutorRef", "n", Special)
|
|
|
|
/// Create a task group.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateTaskGroup, "createTaskGroup", "", Special)
|
|
|
|
/// Create a task group, with options.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateTaskGroupWithFlags, "createTaskGroupWithFlags", "", Special)
|
|
|
|
/// Destroy a task group.
|
|
BUILTIN_MISC_OPERATION(DestroyTaskGroup, "destroyTaskGroup", "", Special)
|
|
|
|
/// globalStringTablePointer has type String -> Builtin.RawPointer.
|
|
/// It returns an immortal, global string table pointer for strings constructed
|
|
/// from string literals. We consider it effects as readnone meaning that it
|
|
/// does not read any memory (note that even though it reads from a string, it
|
|
/// is a pure value and therefore we can consider it as readnone).
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(GlobalStringTablePointer, "globalStringTablePointer", "n", Special)
|
|
|
|
// autoDiffCreateLinearMapContextWithType: (T.Type) -> Builtin.NativeObject
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffCreateLinearMapContextWithType, "autoDiffCreateLinearMapContextWithType", "", Special)
|
|
|
|
// autoDiffProjectTopLevelSubcontext: (Builtin.NativeObject) -> Builtin.RawPointer
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffProjectTopLevelSubcontext, "autoDiffProjectTopLevelSubcontext", "n", Special)
|
|
|
|
// autoDiffAllocateSubcontextWithType: (Builtin.NativeObject, T.Type) -> Builtin.RawPointer
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffAllocateSubcontextWithType, "autoDiffAllocateSubcontextWithType", "", Special)
|
|
|
|
/// Build a Builtin.Executor value from an "ordinary" serial executor
|
|
/// reference.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildOrdinarySerialExecutorRef,
|
|
"buildOrdinarySerialExecutorRef", "n", Special)
|
|
|
|
/// Build a Builtin.Executor value from an "complex equality" serial executor
|
|
/// reference.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildComplexEqualitySerialExecutorRef,
|
|
"buildComplexEqualitySerialExecutorRef", "n", Special)
|
|
|
|
/// Build a Builtin.Executor value from a default actor reference.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildDefaultActorExecutorRef,
|
|
"buildDefaultActorExecutorRef", "n", Special)
|
|
|
|
/// Build a Builtin.Executor value for the main actor.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildMainActorExecutorRef,
|
|
"buildMainActorExecutorRef", "n", Special)
|
|
|
|
/// extractFunctionIsolation: <T>(_: T) -> (any Actor)?
|
|
///
|
|
/// Returns the isolation of a value, which must be an @isolated(any)
|
|
/// function type.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(ExtractFunctionIsolation,
|
|
"extractFunctionIsolation", "", Special)
|
|
|
|
/// getEnumTag: <T>(_: T) -> Builtin.Int32
|
|
///
|
|
/// Given a dynamic generic value, unsafely assume it is an enum type and call
|
|
/// the getEnumTag vwt function.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(GetEnumTag, "getEnumTag", "", Special)
|
|
|
|
/// injectEnumTag: <T>(_: inout T, _: Builtin.Int32) -> ()
|
|
///
|
|
/// Given a dynamic inout generic value, unsafely assume it is an enum type and
|
|
/// inject the given tag into it.
|
|
///
|
|
/// Note: This assume that either 1. the given tag has no payload or 2. the
|
|
/// tag's payload is already initialized with the given source.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(InjectEnumTag, "injectEnumTag", "", Special)
|
|
|
|
/// distributedActorAsAnyActor: <DA: DistributedActor>(_: DA) -> any Actor
|
|
///
|
|
/// For a given distributed actor that is known to be local, extract an
|
|
/// `any Actor` existential that refers to the local actor.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(DistributedActorAsAnyActor, "distributedActorAsAnyActor", "n", Special)
|
|
|
|
/// addressOfRawLayout: <T: ~Copyable>(_: borrowing T) -> Builtin.RawPointer
|
|
///
|
|
/// Returns a raw pointer to the address of the raw layout type. This address is
|
|
/// only valid during a borrow access of the raw layout type or until the value
|
|
/// is either moved or consumed.
|
|
///
|
|
/// Note: The purpose of this builtin is to get an opaque pointer to the address
|
|
/// of the raw layout type. We explicitly do not want the optimizer looking into
|
|
/// this pointer or address thereof to start assuming things about mutability or
|
|
/// immutability. This builtin _must_ persist throughout all of SIL and must be
|
|
/// lowered away at IRGen, no sooner.
|
|
BUILTIN_MISC_OPERATION_WITH_SILGEN(AddressOfRawLayout, "addressOfRawLayout", "n", Special)
|
|
|
|
/// emplace<T>((Builtin.RawPointer) -> Void) -> T
|
|
///
|
|
/// Passes a pointer to an uninitialized result value to the given function,
|
|
/// which must initialize the memory before finishing execution. The value in
|
|
/// memory becomes the result of the call.
|
|
BUILTIN_SIL_OPERATION(Emplace, "emplace", Special)
|
|
|
|
/// Builtins for instrumentation added by sanitizers during SILGen.
|
|
#ifndef BUILTIN_SANITIZER_OPERATION
|
|
#define BUILTIN_SANITIZER_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs)
|
|
#endif
|
|
|
|
/// Builtin representing a call to Thread Sanitizer instrumentation.
|
|
/// TSanInoutAccess has type (T) -> ()
|
|
BUILTIN_SANITIZER_OPERATION(TSanInoutAccess, "tsanInoutAccess", "")
|
|
|
|
/// Builtins for compile-time type-checking operations used for unit testing.
|
|
#ifndef BUILTIN_TYPE_CHECKER_OPERATION
|
|
#define BUILTIN_TYPE_CHECKER_OPERATION(Id, Name) BUILTIN(Id, #Name, "n")
|
|
#endif
|
|
|
|
BUILTIN_TYPE_CHECKER_OPERATION(TypeJoin, type_join)
|
|
BUILTIN_TYPE_CHECKER_OPERATION(TypeJoinInout, type_join_inout)
|
|
BUILTIN_TYPE_CHECKER_OPERATION(TypeJoinMeta, type_join_meta)
|
|
BUILTIN_TYPE_CHECKER_OPERATION(TriggerFallbackDiagnostic, trigger_fallback_diagnostic)
|
|
|
|
// BUILTIN_TYPE_TRAIT_OPERATION - Compile-time type trait operations.
|
|
#ifndef BUILTIN_TYPE_TRAIT_OPERATION
|
|
#define BUILTIN_TYPE_TRAIT_OPERATION(Id, Name) \
|
|
BUILTIN(Id, #Name, "n")
|
|
#endif
|
|
|
|
/// canBeClass(T.Type) -> Builtin.Int8
|
|
/// At compile time, evaluate whether T is or can be bound to a class or
|
|
/// @objc protocol type. The answer is a tri-state of 0 = No, 1 = Yes, 2 =
|
|
/// Maybe.
|
|
BUILTIN_TYPE_TRAIT_OPERATION(CanBeObjCClass, canBeClass)
|
|
|
|
#undef BUILTIN_TYPE_TRAIT_OPERATION
|
|
#undef BUILTIN_UNARY_OPERATION
|
|
#undef BUILTIN_BINARY_PREDICATE
|
|
#undef BUILTIN_RUNTIME_CALL
|
|
#undef BUILTIN_MISC_OPERATION_WITH_SILGEN
|
|
#undef BUILTIN_MISC_OPERATION
|
|
#undef BUILTIN_SANITIZER_OPERATION
|
|
#undef BUILTIN_TYPE_CHECKER_OPERATION
|
|
#undef BUILTIN_BINARY_OPERATION_WITH_OVERFLOW
|
|
#undef BUILTIN_BINARY_OPERATION_ALL
|
|
#undef BUILTIN_BINARY_OPERATION_POLYMORPHIC
|
|
#undef BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC
|
|
#undef BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR
|
|
#undef BUILTIN_BINARY_OPERATION
|
|
#undef BUILTIN_CAST_OPERATION
|
|
#undef BUILTIN_CAST_OR_BITCAST_OPERATION
|
|
#undef BUILTIN_SIL_OPERATION
|
|
#undef BUILTIN
|