Skip to content

Add name mangling support for functions with a thrown error type #69471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
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
5 changes: 4 additions & 1 deletion include/swift/Remote/MetadataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1001,8 +1001,11 @@ class MetadataReader {
#undef CASE
}

BuiltType thrownError = BuiltType();
// FIXME: Read from metadata.

auto BuiltFunction = Builder.createFunctionType(
Parameters, Result, flags, diffKind, globalActor);
Parameters, Result, flags, diffKind, globalActor, thrownError);
TypeCache[TypeCacheKey] = BuiltFunction;
return BuiltFunction;
}
Expand Down
19 changes: 14 additions & 5 deletions include/swift/RemoteInspection/TypeRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,11 +485,13 @@ class FunctionTypeRef final : public TypeRef {
FunctionTypeFlags Flags;
FunctionMetadataDifferentiabilityKind DifferentiabilityKind;
const TypeRef *GlobalActor;
const TypeRef *ThrownError;

static TypeRefID Profile(const std::vector<Param> &Parameters,
const TypeRef *Result, FunctionTypeFlags Flags,
FunctionMetadataDifferentiabilityKind DiffKind,
const TypeRef *GlobalActor) {
const TypeRef *GlobalActor,
const TypeRef *ThrownError) {
TypeRefID ID;
for (const auto &Param : Parameters) {
ID.addString(Param.getLabel().str());
Expand All @@ -500,6 +502,7 @@ class FunctionTypeRef final : public TypeRef {
ID.addInteger(static_cast<uint64_t>(Flags.getIntValue()));
ID.addInteger(static_cast<uint64_t>(DiffKind.getIntValue()));
ID.addPointer(GlobalActor);
ID.addPointer(ThrownError);

return ID;
}
Expand All @@ -508,18 +511,20 @@ class FunctionTypeRef final : public TypeRef {
FunctionTypeRef(std::vector<Param> Params, const TypeRef *Result,
FunctionTypeFlags Flags,
FunctionMetadataDifferentiabilityKind DiffKind,
const TypeRef *GlobalActor)
const TypeRef *GlobalActor,
const TypeRef *ThrownError)
: TypeRef(TypeRefKind::Function), Parameters(Params), Result(Result),
Flags(Flags), DifferentiabilityKind(DiffKind),
GlobalActor(GlobalActor) {}
GlobalActor(GlobalActor), ThrownError(ThrownError) {}

template <typename Allocator>
static const FunctionTypeRef *create(
Allocator &A, std::vector<Param> Params, const TypeRef *Result,
FunctionTypeFlags Flags, FunctionMetadataDifferentiabilityKind DiffKind,
const TypeRef *GlobalActor) {
const TypeRef *GlobalActor, const TypeRef *ThrownError) {
FIND_OR_CREATE_TYPEREF(
A, FunctionTypeRef, Params, Result, Flags, DiffKind, GlobalActor);
A, FunctionTypeRef, Params, Result, Flags, DiffKind, GlobalActor,
ThrownError);
}

const std::vector<Param> &getParameters() const { return Parameters; };
Expand All @@ -540,6 +545,10 @@ class FunctionTypeRef final : public TypeRef {
return GlobalActor;
}

const TypeRef *getThrownError() const {
return ThrownError;
}

static bool classof(const TypeRef *TR) {
return TR->getKind() == TypeRefKind::Function;
}
Expand Down
6 changes: 3 additions & 3 deletions include/swift/RemoteInspection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,9 +793,9 @@ class TypeRefBuilder {
llvm::ArrayRef<remote::FunctionParam<const TypeRef *>> params,
const TypeRef *result, FunctionTypeFlags flags,
FunctionMetadataDifferentiabilityKind diffKind,
const TypeRef *globalActor) {
const TypeRef *globalActor, const TypeRef *thrownError) {
return FunctionTypeRef::create(
*this, params, result, flags, diffKind, globalActor);
*this, params, result, flags, diffKind, globalActor, thrownError);
}

const FunctionTypeRef *createImplFunctionType(
Expand Down Expand Up @@ -852,7 +852,7 @@ class TypeRefBuilder {

auto result = createTupleType({}, llvm::ArrayRef<llvm::StringRef>());
return FunctionTypeRef::create(
*this, {}, result, funcFlags, diffKind, nullptr);
*this, {}, result, funcFlags, diffKind, nullptr, nullptr);
}

BuiltType createProtocolTypeFromDecl(BuiltProtocolDecl protocol) {
Expand Down
6 changes: 2 additions & 4 deletions lib/AST/ASTDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ void ASTBuilder::endPackExpansion() {
Type ASTBuilder::createFunctionType(
ArrayRef<Demangle::FunctionParam<Type>> params,
Type output, FunctionTypeFlags flags,
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor) {
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor,
Type thrownError) {
// The result type must be materializable.
if (!output->isMaterializable()) return Type();

Expand Down Expand Up @@ -454,9 +455,6 @@ Type ASTBuilder::createFunctionType(
clangFunctionType = Ctx.getClangFunctionType(funcParams, output,
representation);

// FIXME: Populate thrownError
Type thrownError;

auto einfo =
FunctionType::ExtInfoBuilder(representation, noescape, flags.isThrowing(),
thrownError, resultDiffKind,
Expand Down
10 changes: 8 additions & 2 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2825,8 +2825,14 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
appendOperator("Ya");
if (fn->isSendable())
appendOperator("Yb");
if (fn->isThrowing())
appendOperator("K");
if (auto thrownError = fn->getEffectiveThrownErrorType()) {
if ((*thrownError)->isEqual(fn->getASTContext().getErrorExistentialType())){
appendOperator("K");
} else {
appendType(*thrownError, sig);
appendOperator("YK");
}
}
switch (auto diffKind = fn->getDifferentiabilityKind()) {
case DifferentiabilityKind::NonDifferentiable:
break;
Expand Down
11 changes: 9 additions & 2 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,8 @@ NodePointer Demangler::demangleTypeAnnotation() {
case 'k':
return createType(
createWithChild(Node::Kind::NoDerivative, popTypeAndGetChild()));
case 'K':
return createWithChild(Node::Kind::TypedThrowsAnnotation, popTypeAndGetChild());
case 't':
return createType(
createWithChild(Node::Kind::CompileTimeConst, popTypeAndGetChild()));
Expand Down Expand Up @@ -1530,7 +1532,10 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
addChild(FuncType, ClangType);
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
addChild(FuncType, popNode(Node::Kind::ThrowsAnnotation));
addChild(FuncType, popNode([](Node::Kind kind) {
return kind == Node::Kind::ThrowsAnnotation ||
kind == Node::Kind::TypedThrowsAnnotation;
}));
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));

Expand Down Expand Up @@ -1572,7 +1577,9 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
== Node::Kind::DifferentiableFunctionType)
++FirstChildIdx;
if (FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::ThrowsAnnotation)
== Node::Kind::ThrowsAnnotation ||
FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::TypedThrowsAnnotation)
++FirstChildIdx;
if (FuncType->getChild(FirstChildIdx)->getKind()
== Node::Kind::ConcurrentFunctionType)
Expand Down
27 changes: 20 additions & 7 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ class NodePrinter {
case Node::Kind::GlobalActorFunctionType:
case Node::Kind::AsyncAnnotation:
case Node::Kind::ThrowsAnnotation:
case Node::Kind::TypedThrowsAnnotation:
case Node::Kind::EmptyList:
case Node::Kind::FirstElementMarker:
case Node::Kind::VariadicMarker:
Expand Down Expand Up @@ -863,7 +864,7 @@ class NodePrinter {

unsigned argIndex = node->getNumChildren() - 2;
unsigned startIndex = 0;
bool isSendable = false, isAsync = false, isThrows = false;
bool isSendable = false, isAsync = false;
auto diffKind = MangledDifferentiabilityKind::NonDifferentiable;
if (node->getChild(startIndex)->getKind() == Node::Kind::ClangType) {
// handled earlier
Expand All @@ -880,10 +881,15 @@ class NodePrinter {
(MangledDifferentiabilityKind)node->getChild(startIndex)->getIndex();
++startIndex;
}
if (node->getChild(startIndex)->getKind() == Node::Kind::ThrowsAnnotation) {

Node *thrownErrorNode = nullptr;
if (node->getChild(startIndex)->getKind() == Node::Kind::ThrowsAnnotation ||
node->getChild(startIndex)->getKind()
== Node::Kind::TypedThrowsAnnotation) {
thrownErrorNode = node->getChild(startIndex);
++startIndex;
isThrows = true;
}

if (node->getChild(startIndex)->getKind()
== Node::Kind::ConcurrentFunctionType) {
++startIndex;
Expand Down Expand Up @@ -923,8 +929,9 @@ class NodePrinter {
if (isAsync)
Printer << " async";

if (isThrows)
Printer << " throws";
if (thrownErrorNode) {
print(thrownErrorNode, depth + 1);
}

print(node->getChild(argIndex + 1), depth + 1);
}
Expand Down Expand Up @@ -2909,10 +2916,16 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
return nullptr;
}
case Node::Kind::AsyncAnnotation:
Printer << " async ";
Printer << " async";
return nullptr;
case Node::Kind::ThrowsAnnotation:
Printer << " throws ";
Printer << " throws";
return nullptr;
case Node::Kind::TypedThrowsAnnotation:
Printer << " throws(";
if (Node->getNumChildren() == 1)
print(Node->getChild(0), depth + 1);
Printer << ")";
return nullptr;
case Node::Kind::EmptyList:
Printer << " empty-list ";
Expand Down
5 changes: 5 additions & 0 deletions lib/Demangling/OldRemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,11 @@ ManglingError Remangler::mangleThrowsAnnotation(Node *node, unsigned depth) {
return ManglingError::Success;
}

ManglingError Remangler::mangleTypedThrowsAnnotation(Node *node, unsigned depth) {
Buffer << "z";
return ManglingError::Success;
}

ManglingError Remangler::mangleDifferentiableFunctionType(Node *node,
unsigned depth) {
Buffer << "D";
Expand Down
6 changes: 6 additions & 0 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3273,6 +3273,12 @@ ManglingError Remangler::mangleThrowsAnnotation(Node *node, unsigned depth) {
return ManglingError::Success;
}

ManglingError Remangler::mangleTypedThrowsAnnotation(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
Buffer << "YK";
return ManglingError::Success;
}

ManglingError Remangler::mangleEmptyList(Node *node, unsigned depth) {
Buffer << 'y';
return ManglingError::Success;
Expand Down
13 changes: 11 additions & 2 deletions stdlib/public/RemoteInspection/TypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ class DemanglingForTypeRef

if (F->getFlags().isThrowing())
funcNode->addChild(Dem.createNode(Node::Kind::ThrowsAnnotation), Dem);
// FIXME: TypedThrowsAnnotation
if (F->getFlags().isSendable()) {
funcNode->addChild(
Dem.createNode(Node::Kind::ConcurrentFunctionType), Dem);
Expand Down Expand Up @@ -1166,12 +1167,16 @@ class ThickenMetatype
if (F->getGlobalActor())
globalActorType = visit(F->getGlobalActor());

const TypeRef *thrownErrorType = nullptr;
if (F->getThrownError())
thrownErrorType = visit(F->getThrownError());

auto SubstitutedResult = visit(F->getResult());

return FunctionTypeRef::create(Builder, SubstitutedParams,
SubstitutedResult, F->getFlags(),
F->getDifferentiabilityKind(),
globalActorType);
globalActorType, thrownErrorType);
}

const TypeRef *
Expand Down Expand Up @@ -1303,10 +1308,14 @@ class TypeRefSubstitution
if (F->getGlobalActor())
globalActorType = visit(F->getGlobalActor());

const TypeRef *thrownErrorType = nullptr;
if (F->getThrownError())
thrownErrorType = visit(F->getThrownError());

return FunctionTypeRef::create(Builder, SubstitutedParams,
SubstitutedResult, F->getFlags(),
F->getDifferentiabilityKind(),
globalActorType);
globalActorType, thrownErrorType);
}

const TypeRef *
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/runtime/Demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
}
if (func->isThrowing())
funcNode->addChild(Dem.createNode(Node::Kind::ThrowsAnnotation), Dem);
// FIXME: TypedThrowsAnnotation
if (func->isSendable()) {
funcNode->addChild(
Dem.createNode(Node::Kind::ConcurrentFunctionType), Dem);
Expand Down
4 changes: 3 additions & 1 deletion stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1934,7 +1934,7 @@ class DecodedMetadataBuilder {
llvm::ArrayRef<Demangle::FunctionParam<BuiltType>> params,
BuiltType result, FunctionTypeFlags flags,
FunctionMetadataDifferentiabilityKind diffKind,
BuiltType globalActorType) const {
BuiltType globalActorType, BuiltType thrownError) const {
assert(
(flags.isDifferentiable() && diffKind.isDifferentiable()) ||
(!flags.isDifferentiable() && !diffKind.isDifferentiable()));
Expand Down Expand Up @@ -1969,6 +1969,8 @@ class DecodedMetadataBuilder {
flags = flags.withGlobalActor(true);
}

// FIXME: thrownError

return BuiltType(
flags.hasGlobalActor()
? swift_getFunctionTypeMetadataGlobalActor(flags, diffKind, paramTypes.data(),
Expand Down
1 change: 1 addition & 0 deletions test/Demangle/Inputs/manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,4 @@ $s9MacroUser016testFreestandingA9ExpansionyyF4Foo3L_V23bitwidthNumberedStructsfM
@__swiftmacro_9MacroUser16MemberNotCoveredV33_4361AD9339943F52AE6186DD51E04E91Ll0dE0fMf0_ ---> freestanding macro expansion #2 of NotCovered(in _4361AD9339943F52AE6186DD51E04E91) in MacroUser.MemberNotCovered
$sxSo8_NSRangeVRlzCRl_Cr0_llySo12ModelRequestCyxq_GIsPetWAlYl_TC ---> coroutine continuation prototype for @escaping @convention(thin) @convention(witness_method) @yield_once <A, B where A: AnyObject, B: AnyObject> @substituted <A> (@inout A) -> (@yields @inout __C._NSRange) for <__C.ModelRequest<A, B>>
$SyyySGSS_IIxxxxx____xsIyFSySIxx_@xIxx____xxI ---> $SyyySGSS_IIxxxxx____xsIyFSySIxx_@xIxx____xxI
$s12typed_throws15rethrowConcreteyyAA7MyErrorOYKF --> typed_throws.rethrowConcrete() throws(typed_throws.MyError) -> ()
Loading