Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,9 @@ Types
global-actor :: = type 'Yc' // Global actor on function type
#endif
throws ::= 'K' // 'throws' annotation on function types
#if SWIFT_RUNTIME_VERSION >= 5.11
throws ::= type 'YK' // 'throws(type)' annotation on function types
#endif
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
differentiable ::= 'Yjd' // @differentiable on function type
Expand Down
153 changes: 121 additions & 32 deletions include/swift/ABI/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -1459,21 +1459,91 @@ struct TargetEnumMetadata : public TargetValueMetadata<Runtime> {
};
using EnumMetadata = TargetEnumMetadata<InProcess>;

template <typename Runtime>
struct TargetFunctionGlobalActorMetadata {
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> GlobalActorType;
};
using FunctionGlobalActorMetadata = TargetFunctionGlobalActorMetadata<InProcess>;

template <typename Runtime>
struct TargetFunctionThrownErrorMetadata {
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> ThrownErrorType;
};
using FunctionThrownErrorMetadata = TargetFunctionThrownErrorMetadata<InProcess>;

/// The structure of function type metadata.
template <typename Runtime>
struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime>,
swift::ABI::TrailingObjects<
TargetFunctionTypeMetadata<Runtime>,
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>,
ParameterFlags,
TargetFunctionMetadataDifferentiabilityKind<typename Runtime::StoredSize>,
TargetFunctionGlobalActorMetadata<Runtime>,
ExtendedFunctionTypeFlags,
TargetFunctionThrownErrorMetadata<Runtime>> {
using StoredSize = typename Runtime::StoredSize;
using Parameter = ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>;

private:
using TrailingObjects =
swift::ABI::TrailingObjects<
TargetFunctionTypeMetadata<Runtime>,
Parameter,
ParameterFlags,
TargetFunctionMetadataDifferentiabilityKind<StoredSize>,
TargetFunctionGlobalActorMetadata<Runtime>,
ExtendedFunctionTypeFlags,
TargetFunctionThrownErrorMetadata<Runtime>>;
friend TrailingObjects;

template<typename T>
using OverloadToken = typename TrailingObjects::template OverloadToken<T>;

public:
TargetFunctionTypeFlags<StoredSize> Flags;

/// The type metadata for the result type.
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> ResultType;

Parameter *getParameters() { return reinterpret_cast<Parameter *>(this + 1); }
private:
size_t numTrailingObjects(OverloadToken<Parameter>) const {
return getNumParameters();
}

size_t numTrailingObjects(OverloadToken<ParameterFlags>) const {
return hasParameterFlags() ? getNumParameters() : 0;
}

size_t numTrailingObjects(
OverloadToken<TargetFunctionMetadataDifferentiabilityKind<StoredSize>>
) const {
return isDifferentiable() ? 1 : 0;
}

size_t numTrailingObjects(
OverloadToken<TargetFunctionGlobalActorMetadata<Runtime>>
) const {
return hasGlobalActor() ? 1 : 0;
}

size_t numTrailingObjects(OverloadToken<ExtendedFunctionTypeFlags>) const {
return hasExtendedFlags() ? 1 : 0;
}

size_t numTrailingObjects(
OverloadToken<TargetFunctionThrownErrorMetadata<Runtime>>
) const {
return hasThrownError() ? 1 : 0;
}

public:
Parameter *getParameters() {
return this->template getTrailingObjects<Parameter>();
}

const Parameter *getParameters() const {
return reinterpret_cast<const Parameter *>(this + 1);
return this->template getTrailingObjects<Parameter>();
}

Parameter getParameter(unsigned index) const {
Expand All @@ -1483,8 +1553,7 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {

ParameterFlags getParameterFlags(unsigned index) const {
assert(index < getNumParameters());
auto flags = hasParameterFlags() ? getParameterFlags()[index] : 0;
return ParameterFlags::fromIntValue(flags);
return hasParameterFlags() ? getParameterFlags()[index] : ParameterFlags();
}

StoredSize getNumParameters() const {
Expand All @@ -1500,39 +1569,38 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
bool isEscaping() const { return Flags.isEscaping(); }
bool hasGlobalActor() const { return Flags.hasGlobalActor(); }
bool hasExtendedFlags() const { return Flags.hasExtendedFlags(); }
bool hasThrownError() const {
if (!Flags.hasExtendedFlags())
return false;

return getExtendedFlags().isTypedThrows();
}

static constexpr StoredSize OffsetToFlags = sizeof(TargetMetadata<Runtime>);

static bool classof(const TargetMetadata<Runtime> *metadata) {
return metadata->getKind() == MetadataKind::Function;
}

uint32_t *getParameterFlags() {
return reinterpret_cast<uint32_t *>(getParameters() + getNumParameters());
ParameterFlags *getParameterFlags() {
return this->template getTrailingObjects<ParameterFlags>();
}

const uint32_t *getParameterFlags() const {
return reinterpret_cast<const uint32_t *>(getParameters() +
getNumParameters());
const ParameterFlags *getParameterFlags() const {
return this->template getTrailingObjects<ParameterFlags>();
}

TargetFunctionMetadataDifferentiabilityKind<StoredSize> *
getDifferentiabilityKindAddress() {
assert(isDifferentiable());
void *previousEndAddr = hasParameterFlags()
? reinterpret_cast<void *>(getParameterFlags() + getNumParameters())
: reinterpret_cast<void *>(getParameters() + getNumParameters());
return reinterpret_cast<
TargetFunctionMetadataDifferentiabilityKind<StoredSize> *>(
llvm::alignAddr(previousEndAddr,
llvm::Align(alignof(typename Runtime::StoredPointer))));
return this->template getTrailingObjects<TargetFunctionMetadataDifferentiabilityKind<StoredSize>>();
}

TargetFunctionMetadataDifferentiabilityKind<StoredSize>
getDifferentiabilityKind() const {
if (isDifferentiable()) {
return *const_cast<TargetFunctionTypeMetadata<Runtime> *>(this)
->getDifferentiabilityKindAddress();
return *(this->template getTrailingObjects<TargetFunctionMetadataDifferentiabilityKind<StoredSize>>());
}
return TargetFunctionMetadataDifferentiabilityKind<StoredSize>
::NonDifferentiable;
Expand All @@ -1541,26 +1609,47 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *
getGlobalActorAddr() {
assert(hasGlobalActor());

void *endAddr =
isDifferentiable()
? reinterpret_cast<void *>(getDifferentiabilityKindAddress() + 1) :
hasParameterFlags()
? reinterpret_cast<void *>(getParameterFlags() + getNumParameters()) :
reinterpret_cast<void *>(getParameters() + getNumParameters());
return reinterpret_cast<
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *>(
llvm::alignAddr(
endAddr, llvm::Align(alignof(typename Runtime::StoredPointer))));
auto globalActorAddr =
this->template getTrailingObjects<TargetFunctionGlobalActorMetadata<Runtime>>();
return &globalActorAddr->GlobalActorType;
}

ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>
getGlobalActor() const {
if (!hasGlobalActor())
return ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>();
auto globalActorAddr =
this->template getTrailingObjects<TargetFunctionGlobalActorMetadata<Runtime>>();
return globalActorAddr->GlobalActorType;
}

ExtendedFunctionTypeFlags *getExtendedFlagsAddr() {
assert(hasExtendedFlags());
return this->template getTrailingObjects<ExtendedFunctionTypeFlags>();
}

ExtendedFunctionTypeFlags getExtendedFlags() const {
if (!hasExtendedFlags())
return ExtendedFunctionTypeFlags();

return this->template getTrailingObjects<ExtendedFunctionTypeFlags>()[0];
}

ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *
getThrownErrorAddr() {
assert(hasThrownError());
auto thrownErrorAddr =
this->template getTrailingObjects<TargetFunctionThrownErrorMetadata<Runtime>>();
return &thrownErrorAddr->ThrownErrorType;
}

return *const_cast<TargetFunctionTypeMetadata<Runtime> *>(this)
->getGlobalActorAddr();
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>
getThrownError() const {
if (!hasThrownError())
return ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>();
auto thrownErrorAddr =
this->template getTrailingObjects<TargetFunctionThrownErrorMetadata<Runtime>>();
return thrownErrorAddr->ThrownErrorType;
}
};
using FunctionTypeMetadata = TargetFunctionTypeMetadata<InProcess>;
Expand Down
50 changes: 49 additions & 1 deletion include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,8 @@ class TargetFunctionTypeFlags {
GlobalActorMask = 0x10000000U,
AsyncMask = 0x20000000U,
SendableMask = 0x40000000U,
// NOTE: The next bit will need to introduce a separate flags word.
ExtendedFlagsMask = 0x80000000U,
// NOTE: No more room for flags here. Use TargetExtendedFunctionTypeFlags.
};
int_type Data;

Expand Down Expand Up @@ -1099,6 +1100,12 @@ class TargetFunctionTypeFlags {
(Data & ~GlobalActorMask) | (globalActor ? GlobalActorMask : 0));
}

constexpr TargetFunctionTypeFlags<int_type>
withExtendedFlags(bool extendedFlags) const {
return TargetFunctionTypeFlags<int_type>(
(Data & ~ExtendedFlagsMask) | (extendedFlags ? ExtendedFlagsMask : 0));
}

unsigned getNumParameters() const { return Data & NumParametersMask; }

FunctionMetadataConvention getConvention() const {
Expand Down Expand Up @@ -1127,6 +1134,10 @@ class TargetFunctionTypeFlags {
return bool (Data & GlobalActorMask);
}

bool hasExtendedFlags() const {
return bool (Data & ExtendedFlagsMask);
}

int_type getIntValue() const {
return Data;
}
Expand All @@ -1144,6 +1155,43 @@ class TargetFunctionTypeFlags {
};
using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;

/// Extended flags in a function type metadata record.
template <typename int_type>
class TargetExtendedFunctionTypeFlags {
enum : int_type {
TypedThrowsMask = 0x00000001U,
};
int_type Data;

constexpr TargetExtendedFunctionTypeFlags(int_type Data) : Data(Data) {}
public:
constexpr TargetExtendedFunctionTypeFlags() : Data(0) {}

constexpr TargetExtendedFunctionTypeFlags<int_type>
withTypedThrows(bool typedThrows) const {
return TargetExtendedFunctionTypeFlags<int_type>(
(Data & ~TypedThrowsMask) | (typedThrows ? TypedThrowsMask : 0));
}

bool isTypedThrows() const { return bool(Data & TypedThrowsMask); }

int_type getIntValue() const {
return Data;
}

static TargetExtendedFunctionTypeFlags<int_type> fromIntValue(int_type Data) {
return TargetExtendedFunctionTypeFlags(Data);
}

bool operator==(TargetExtendedFunctionTypeFlags<int_type> other) const {
return Data == other.Data;
}
bool operator!=(TargetExtendedFunctionTypeFlags<int_type> other) const {
return Data != other.Data;
}
};
using ExtendedFunctionTypeFlags = TargetExtendedFunctionTypeFlags<uint32_t>;

template <typename int_type>
class TargetParameterTypeFlags {
enum : int_type {
Expand Down
7 changes: 7 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,9 @@ class ASTContext final {
/// Get the runtime availability of support for differentiation.
AvailabilityContext getDifferentiationAvailability();

/// Get the runtime availability of support for typed throws.
AvailabilityContext getTypedThrowsAvailability();

/// Get the runtime availability of getters and setters of multi payload enum
/// tag single payloads.
AvailabilityContext getMultiPayloadEnumTagSinglePayload();
Expand Down Expand Up @@ -982,6 +985,10 @@ class ASTContext final {
/// compiler for the target platform.
AvailabilityContext getSwift59Availability();

/// Get the runtime availability of features introduced in the Swift 5.9
/// compiler for the target platform.
AvailabilityContext getSwift511Availability();

// Note: Update this function if you add a new getSwiftXYAvailability above.
/// Get the runtime availability for a particular version of Swift (5.0+).
AvailabilityContext
Expand Down
3 changes: 2 additions & 1 deletion include/swift/AST/ASTDemangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ class ASTBuilder {
Type createFunctionType(
ArrayRef<Demangle::FunctionParam<Type>> params,
Type output, FunctionTypeFlags flags,
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor);
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor,
Type thrownError);

Type createImplFunctionType(
Demangle::ImplParameterConvention calleeConvention,
Expand Down
1 change: 1 addition & 0 deletions include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ NODE(BaseConformanceDescriptor)
NODE(AssociatedTypeDescriptor)
NODE(AsyncAnnotation)
NODE(ThrowsAnnotation)
NODE(TypedThrowsAnnotation)
NODE(EmptyList)
NODE(FirstElementMarker)
NODE(VariadicMarker)
Expand Down
22 changes: 21 additions & 1 deletion include/swift/Demangling/TypeDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -855,11 +855,29 @@ class TypeDecoder {
++firstChildIdx;
}

BuiltType thrownErrorType = BuiltType();
bool isThrow = false;
if (Node->getChild(firstChildIdx)->getKind()
== NodeKind::ThrowsAnnotation) {
isThrow = true;
++firstChildIdx;
} else if (Node->getChild(firstChildIdx)->getKind()
== NodeKind::TypedThrowsAnnotation) {
isThrow = true;

auto child = Node->getChild(firstChildIdx);
if (child->getNumChildren() < 1) {
return MAKE_NODE_TYPE_ERROR0(child,
"Thrown error node is missing child");
}

auto thrownErrorResult =
decodeMangledType(child->getChild(0), depth + 1);
if (thrownErrorResult.isError())
return thrownErrorResult;

thrownErrorType = thrownErrorResult.getType();
++firstChildIdx;
}

bool isSendable = false;
Expand Down Expand Up @@ -905,8 +923,10 @@ class TypeDecoder {
/*forRequirement=*/false);
if (result.isError())
return result;

return Builder.createFunctionType(
parameters, result.getType(), flags, diffKind, globalActorType);
parameters, result.getType(), flags, diffKind, globalActorType,
thrownErrorType);
}
case NodeKind::ImplFunctionType: {
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
Expand Down
Loading