blob: d07eca212993cd9fe360c7dc72128d003714ef7d [file] [log] [blame]
//===--- ValueWitness.def - Value witness x-macros --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
//
//===----------------------------------------------------------------------===//
//
// X-macro definition file for value witness tables.
//
//===----------------------------------------------------------------------===//
// This file is "parameterized" in the sense that exactly one of the
// following macros *must* be defined:
/// WANT_ALL_VALUE_WITNESSES
/// Define this to expand all value witnesses, not just the ones from
/// a specific category.
#if defined(WANT_ALL_VALUE_WITNESSES)
#undef WANT_ALL_VALUE_WITNESSES
#define WANT_REQUIRED_VALUE_WITNESSES 1
#define WANT_ENUM_VALUE_WITNESSES 1
/// WANT_ONLY_REQUIRED_VALUE_WITNESSES
/// Define this to expand only the required value witnesses.
#elif defined(WANT_ONLY_REQUIRED_VALUE_WITNESSES)
#undef WANT_ONLY_REQUIRED_VALUE_WITNESSES
#define WANT_REQUIRED_VALUE_WITNESSES 1
#define WANT_ENUM_VALUE_WITNESSES 0
/// WANT_ONLY_ENUM_VALUE_WITNESSES
/// Define this to expand only the enum value witnesses.
#elif defined(WANT_ONLY_ENUM_VALUE_WITNESSES)
#undef WANT_ONLY_ENUM_VALUE_WITNESSES
#define WANT_REQUIRED_VALUE_WITNESSES 0
#define WANT_ENUM_VALUE_WITNESSES 1
/// WANT_REQUIRED_VALUE_WITNESSES
/// WANT_ENUM_VALUE_WITNESSES
/// Define all of these to control exactly what to expand.
#else
#if !defined(WANT_REQUIRED_VALUE_WITNESSES) || !defined(WANT_ENUM_VALUE_WITNESSES)
#error failed to define a WANT macro; possible typo?
#endif
#endif
/// VALUE_WITNESS(lowerId, upperId)
/// A fallback called for value witnesses if either of DATA_VALUE_WITNESS or
/// FUNCTION_VALUE_WITNESS is not defined.
/// FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypeList)
/// A function value witness. Types will be defined in terms of the
/// following macros:
/// MUTABLE_VALUE_TYPE - a pointer to a mutable opaque value
/// IMMUTABLE_VALUE_TYPE - a pointer to an immutable opaque value
/// MUTABLE_BUFFER_TYPE - a pointer to a fixed-size value buffer
/// IMMUTABLE_BUFFER_TYPE - a pointer to an immutable fixed-size buffer
/// TYPE_TYPE - a pointer to type metadata
/// SIZE_TYPE - StoredSize
/// INT_TYPE - int
/// UINT_TYPE - unsigned int
/// VOID_TYPE - void
/// Defaults to VALUE_WITNESS.
/// FIXME: The 'copy' witnesses should be using immutable types but aren't.
#ifndef FUNCTION_VALUE_WITNESS
#define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \
VALUE_WITNESS(lowerId, upperId)
#endif
/// DATA_VALUE_WITNESS(lowerId, upperId, type)
/// A non-function value witness. Types are specified as for
/// FUNCTION_VALUE_WITNESS
/// Defaults to VALUE_WITNESS.
#ifndef DATA_VALUE_WITNESS
#define DATA_VALUE_WITNESS(lowerId, upperId, type) \
VALUE_WITNESS(lowerId, upperId)
#endif
/// Begin a range of value witnesses. This will be expanded immediately
/// after the first value in the range, whose ID will be upperId.
/// Range expansions do not interact well with the use of WANT_ONLY_*.
#ifndef BEGIN_VALUE_WITNESS_RANGE
#define BEGIN_VALUE_WITNESS_RANGE(rangeId, upperId)
#endif
/// End a range of value witnesses. This will be expanded immediately
/// after the last value in the range, whose ID will be upperId.
/// Range expansions do not interact well with the use of WANT_ONLY_*.
#ifndef END_VALUE_WITNESS_RANGE
#define END_VALUE_WITNESS_RANGE(rangeId, upperId)
#endif
#if WANT_REQUIRED_VALUE_WITNESSES
/// T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self);
/// Given an invalid buffer, initialize it as a copy of the
/// object in the source buffer.
FUNCTION_VALUE_WITNESS(initializeBufferWithCopyOfBuffer,
InitializeBufferWithCopyOfBuffer,
MUTABLE_VALUE_TYPE,
(MUTABLE_BUFFER_TYPE, MUTABLE_BUFFER_TYPE, TYPE_TYPE))
BEGIN_VALUE_WITNESS_RANGE(ValueWitness,
InitializeBufferWithCopyOfBuffer)
BEGIN_VALUE_WITNESS_RANGE(RequiredValueWitness,
InitializeBufferWithCopyOfBuffer)
BEGIN_VALUE_WITNESS_RANGE(RequiredValueWitnessFunction,
InitializeBufferWithCopyOfBuffer)
/// void (*destroy)(T *object, witness_t *self);
///
/// Given a valid object of this type, destroy it, leaving it as an
/// invalid object. This is useful when generically destroying
/// an object which has been allocated in-line, such as an array,
/// struct, or tuple element.
FUNCTION_VALUE_WITNESS(destroy,
Destroy,
VOID_TYPE,
(MUTABLE_VALUE_TYPE, TYPE_TYPE))
/// T *(*initializeWithCopy)(T *dest, T *src, M *self);
///
/// Given an invalid object of this type, initialize it as a copy of
/// the source object. Returns the dest object.
FUNCTION_VALUE_WITNESS(initializeWithCopy,
InitializeWithCopy,
MUTABLE_VALUE_TYPE,
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
/// T *(*assignWithCopy)(T *dest, T *src, M *self);
///
/// Given a valid object of this type, change it to be a copy of the
/// source object. Returns the dest object.
FUNCTION_VALUE_WITNESS(assignWithCopy,
AssignWithCopy,
MUTABLE_VALUE_TYPE,
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
/// T *(*initializeWithTake)(T *dest, T *src, M *self);
///
/// Given an invalid object of this type, initialize it by taking
/// the value of the source object. The source object becomes
/// invalid. Returns the dest object.
FUNCTION_VALUE_WITNESS(initializeWithTake,
InitializeWithTake,
MUTABLE_VALUE_TYPE,
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
/// T *(*assignWithTake)(T *dest, T *src, M *self);
///
/// Given a valid object of this type, change it to be a copy of the
/// source object. The source object becomes invalid. Returns the
/// dest object.
FUNCTION_VALUE_WITNESS(assignWithTake,
AssignWithTake,
MUTABLE_VALUE_TYPE,
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
/// unsigned (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases)
/// Given an instance of valid single payload enum with a payload of this
/// witness table's type (e.g Optional<ThisType>) , get the tag of the enum.
FUNCTION_VALUE_WITNESS(getEnumTagSinglePayload,
GetEnumTagSinglePayload,
UINT_TYPE,
(IMMUTABLE_VALUE_TYPE, UINT_TYPE, TYPE_TYPE))
/// void (*storeEnumTagSinglePayload)(T* enum, UINT_TYPE whichCase,
/// UINT_TYPE emptyCases)
/// Given uninitialized memory for an instance of a single payload enum with a
/// payload of this witness table's type (e.g Optional<ThisType>), store the
/// tag.
FUNCTION_VALUE_WITNESS(storeEnumTagSinglePayload,
StoreEnumTagSinglePayload,
VOID_TYPE,
(MUTABLE_VALUE_TYPE, UINT_TYPE, UINT_TYPE, TYPE_TYPE))
END_VALUE_WITNESS_RANGE(RequiredValueWitnessFunction,
StoreEnumTagSinglePayload)
/// SIZE_TYPE size;
///
/// The required storage size of a single object of this type.
DATA_VALUE_WITNESS(size,
Size,
SIZE_TYPE)
BEGIN_VALUE_WITNESS_RANGE(TypeLayoutWitness,
Size)
BEGIN_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness,
Size)
/// SIZE_TYPE stride;
///
/// The required size per element of an array of this type. It is at least
/// one, even for zero-sized types, like the empty tuple.
DATA_VALUE_WITNESS(stride,
Stride,
SIZE_TYPE)
/// UINT_TYPE flags;
///
/// The ValueWitnessAlignmentMask bits represent the required
/// alignment of the first byte of an object of this type, expressed
/// as a mask of the low bits that must not be set in the pointer.
/// This representation can be easily converted to the 'alignof'
/// result by merely adding 1, but it is more directly useful for
/// performing dynamic structure layouts, and it grants an
/// additional bit of precision in a compact field without needing
/// to switch to an exponent representation.
///
/// The ValueWitnessIsNonPOD bit is set if the type is not POD.
///
/// The ValueWitnessIsNonInline bit is set if the type cannot be
/// represented in a fixed-size buffer or if it is not bitwise takable.
///
/// The ExtraInhabitantsMask bits represent the number of "extra inhabitants"
/// of the bit representation of the value that do not form valid values of
/// the type.
///
/// The Enum_HasSpareBits bit is set if the type's binary representation
/// has unused bits.
///
/// The HasEnumWitnesses bit is set if the type is an enum type.
DATA_VALUE_WITNESS(flags,
Flags,
UINT_TYPE)
/// UINT_TYPE extraInhabitantCount;
///
/// The number of extra inhabitants in the type.
DATA_VALUE_WITNESS(extraInhabitantCount,
ExtraInhabitantCount,
UINT_TYPE)
END_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness,
ExtraInhabitantCount)
END_VALUE_WITNESS_RANGE(RequiredValueWitness,
ExtraInhabitantCount)
END_VALUE_WITNESS_RANGE(TypeLayoutWitness,
ExtraInhabitantCount)
#endif /* WANT_REQUIRED_VALUE_WITNESSES */
#if WANT_ENUM_VALUE_WITNESSES
// The following value witnesses are conditionally present if the witnessed
// type is an enum.
/// unsigned (*getEnumTag)(T *obj, M *self);
///
/// Given a valid object of this enum type, extracts the tag value indicating
/// which case of the enum is inhabited. Returned values are in the range
/// [0..NumElements-1].
FUNCTION_VALUE_WITNESS(getEnumTag,
GetEnumTag,
INT_TYPE,
(IMMUTABLE_VALUE_TYPE, TYPE_TYPE))
BEGIN_VALUE_WITNESS_RANGE(EnumValueWitness,
GetEnumTag)
/// void (*destructiveProjectEnumData)(T *obj, M *self);
/// Given a valid object of this enum type, destructively extracts the
/// associated payload.
FUNCTION_VALUE_WITNESS(destructiveProjectEnumData,
DestructiveProjectEnumData,
VOID_TYPE,
(MUTABLE_VALUE_TYPE, TYPE_TYPE))
/// void (*destructiveInjectEnumTag)(T *obj, unsigned tag, M *self);
/// Given an enum case tag and a valid object of case's payload type,
/// destructively inserts the tag into the payload. The given tag value
/// must be in the range [-ElementsWithPayload..ElementsWithNoPayload-1].
FUNCTION_VALUE_WITNESS(destructiveInjectEnumTag,
DestructiveInjectEnumTag,
VOID_TYPE,
(MUTABLE_VALUE_TYPE, UINT_TYPE, TYPE_TYPE))
END_VALUE_WITNESS_RANGE(EnumValueWitness,
DestructiveInjectEnumTag)
END_VALUE_WITNESS_RANGE(ValueWitness,
DestructiveInjectEnumTag)
#endif /* WANT_ENUM_VALUE_WITNESSES */
#undef MUTABLE_VALUE_TYPE
#undef IMMUTABLE_VALUE_TYPE
#undef MUTABLE_BUFFER_TYPE
#undef IMMUTABLE_BUFFER_TYPE
#undef TYPE_TYPE
#undef SIZE_TYPE
#undef INT_TYPE
#undef VOID_TYPE
#undef END_VALUE_WITNESS_RANGE
#undef BEGIN_VALUE_WITNESS_RANGE
#undef DATA_VALUE_WITNESS
#undef FUNCTION_VALUE_WITNESS
#undef VALUE_WITNESS
#undef ENUM_VALUE_WITNESS
#undef NON_REQUIRED_VALUE_WITNESS
#undef REQUIRED_VALUE_WITNESS
#undef WANT_ENUM_VALUE_WITNESSES
#undef WANT_REQUIRED_VALUE_WITNESSES