$ g++ -E ValueWitness.hpp | sed -e '/^$/d -e '/^#/d' > _out.hpp
Last active
June 10, 2018 06:48
-
-
Save koron/96405064efe2ac47a649eb4c3f2572f2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum class ValueWitness : unsigned { | |
InitializeBufferWithCopyOfBuffer, | |
First_ValueWitness = InitializeBufferWithCopyOfBuffer, | |
First_RequiredValueWitness = InitializeBufferWithCopyOfBuffer, | |
First_RequiredValueWitnessFunction = InitializeBufferWithCopyOfBuffer, | |
Destroy, | |
InitializeWithCopy, | |
AssignWithCopy, | |
InitializeWithTake, | |
AssignWithTake, | |
GetEnumTagSinglePayload, | |
StoreEnumTagSinglePayload, | |
Last_RequiredValueWitnessFunction = StoreEnumTagSinglePayload, | |
Size, | |
First_TypeLayoutWitness = Size, | |
First_RequiredTypeLayoutWitness = Size, | |
Flags, | |
Stride, | |
Last_RequiredTypeLayoutWitness = Stride, | |
Last_RequiredValueWitness = Stride, | |
ExtraInhabitantFlags, | |
First_ExtraInhabitantValueWitness = ExtraInhabitantFlags, | |
Last_TypeLayoutWitness = ExtraInhabitantFlags, | |
StoreExtraInhabitant, | |
First_ExtraInhabitantValueWitnessFunction = StoreExtraInhabitant, | |
GetExtraInhabitantIndex, | |
Last_ExtraInhabitantValueWitnessFunction = GetExtraInhabitantIndex, | |
Last_ExtraInhabitantValueWitness = GetExtraInhabitantIndex, | |
GetEnumTag, | |
First_EnumValueWitness = GetEnumTag, | |
DestructiveProjectEnumData, | |
DestructiveInjectEnumTag, | |
Last_EnumValueWitness = DestructiveInjectEnumTag, | |
Last_ValueWitness = DestructiveInjectEnumTag, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copy from https://github.com/apple/swift/blob/0ba027f04ba553c87d99bdfacdb82c468b7119c9/include/swift/ABI/ValueWitness.def | |
//===--- 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_EXTRA_INHABITANT_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_EXTRA_INHABITANT_VALUE_WITNESSES 0 | |
#define WANT_ENUM_VALUE_WITNESSES 0 | |
/// WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES | |
/// Define this to expand only the extra-inhabitant value witnesses. | |
#elif defined(WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES) | |
#undef WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES | |
#define WANT_REQUIRED_VALUE_WITNESSES 0 | |
#define WANT_EXTRA_INHABITANT_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_EXTRA_INHABITANT_VALUE_WITNESSES 0 | |
#define WANT_ENUM_VALUE_WITNESSES 1 | |
/// WANT_REQUIRED_VALUE_WITNESSES | |
/// WANT_EXTRA_INHABITANT_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_EXTRA_INHABITANT_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 - size_t | |
/// 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_t 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_t 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 Enum_HasExtraInhabitants bit is set if the type's binary | |
/// representation has "extra inhabitants" that do not form valid values of | |
/// the type, and the value witness table contains the ExtraInhabitantWitness | |
/// entries. | |
/// | |
/// 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, | |
SIZE_TYPE) | |
/// size_t 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) | |
END_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness, | |
Stride) | |
END_VALUE_WITNESS_RANGE(RequiredValueWitness, | |
Stride) | |
#endif /* WANT_REQUIRED_VALUE_WITNESSES */ | |
#if WANT_EXTRA_INHABITANT_VALUE_WITNESSES | |
// The following value witnesses are conditionally present based on | |
// the Enum_HasExtraInhabitants bit of the flags. | |
/// size_t extraInhabitantFlags; | |
/// | |
/// These bits are always present if the extra inhabitants witnesses are: | |
/// | |
/// - The NumExtraInhabitantsMask bits contain the number of extra | |
/// inhabitants of the type representation. | |
/// | |
/// If the Enum_HasSpareBits flag is set in the value witness flags, these | |
/// additional flags are available: | |
/// | |
/// - The NumSpareBitsMask bits contain the number of (host-endian) contiguous | |
/// spare bits in the type representation. | |
/// - The SpareBitsShiftMask bits contain the (host-endian) bit offset of the | |
/// lowest spare bit. | |
DATA_VALUE_WITNESS(extraInhabitantFlags, | |
ExtraInhabitantFlags, | |
SIZE_TYPE) | |
BEGIN_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitness, | |
ExtraInhabitantFlags) | |
END_VALUE_WITNESS_RANGE(TypeLayoutWitness, | |
ExtraInhabitantFlags) | |
/// void (*storeExtraInhabitant)(T *obj, int index, M *self); | |
/// | |
/// Given an invalid object of this type, store the representation of an | |
/// extra inhabitant of the type. The object will remain invalid, because | |
/// an extra inhabitant is by definition an invalid representation of the | |
/// type. index must be less than numExtraInhabitants. | |
FUNCTION_VALUE_WITNESS(storeExtraInhabitant, | |
StoreExtraInhabitant, | |
VOID_TYPE, | |
(MUTABLE_VALUE_TYPE, INT_TYPE, TYPE_TYPE)) | |
BEGIN_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitnessFunction, | |
StoreExtraInhabitant) | |
/// int (*getExtraInhabitantIndex)(T *obj, M *self); | |
/// | |
/// Given an invalid object of this type with an extra inhabitant | |
/// representation, returns the index of the extra inhabitant representation. | |
/// Returns -1 if the object is a valid value of the type. If non-negative, | |
/// the return value is the same index that can be passed to | |
/// storeExtraInhabitant to reproduce the representation. | |
FUNCTION_VALUE_WITNESS(getExtraInhabitantIndex, | |
GetExtraInhabitantIndex, | |
INT_TYPE, | |
(IMMUTABLE_VALUE_TYPE, TYPE_TYPE)) | |
END_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitnessFunction, | |
GetExtraInhabitantIndex) | |
END_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitness, | |
GetExtraInhabitantIndex) | |
#endif /* WANT_EXTRA_INHABITANT_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 EXTRA_INHABITANT_VALUE_WITNESS | |
#undef NON_REQUIRED_VALUE_WITNESS | |
#undef REQUIRED_VALUE_WITNESS | |
#undef WANT_ENUM_VALUE_WITNESSES | |
#undef WANT_EXTRA_INHABITANT_VALUE_WITNESSES | |
#undef WANT_REQUIRED_VALUE_WITNESSES |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copy from https://github.com/apple/swift/blob/0ba027f04ba553c87d99bdfacdb82c468b7119c9/include/swift/IRGen/ValueWitness.h#L66-L72 | |
enum class ValueWitness : unsigned { | |
#define WANT_ALL_VALUE_WITNESSES | |
#define VALUE_WITNESS(lowerId, upperId) upperId, | |
#define BEGIN_VALUE_WITNESS_RANGE(rangeId, upperId) First_##rangeId = upperId, | |
#define END_VALUE_WITNESS_RANGE(rangeId, upperId) Last_##rangeId = upperId, | |
#include "./ValueWitness.def" | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment