Skip to content

Commit 11ff5b4

Browse files
authored
Merge pull request #78576 from rjmccall/demangle-sending-result-with-function-isolation
Fix the demangling of sending result types when combined with isolation
2 parents 727fb8c + fa932e7 commit 11ff5b4

File tree

7 files changed

+82
-28
lines changed

7 files changed

+82
-28
lines changed

docs/ABI/Mangling.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,10 +733,12 @@ Types
733733
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
734734
FUNCTION-KIND ::= 'E' // function type (noescape)
735735

736-
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
737-
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
736+
C-TYPE ::= NATURAL CHAR* // raw Itanium mangling
738737

739-
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? // results and parameters
738+
function-signature ::= result-type params-type async? sendable? throws? differentiable? function-isolation? sending-result? // results and parameters
739+
740+
result-type ::= type
741+
result-type ::= empty-list // shortcut for ()
740742

741743
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
742744
// with optional inout convention, shared convention. parameters don't have labels,
@@ -752,6 +754,7 @@ Types
752754
#if SWIFT_RUNTIME_VERSION >= 6.0
753755
throws ::= type 'YK' // 'throws(type)' annotation on function types
754756
function-isolation ::= type 'YA' // @isolated(any) on function type
757+
sending-result ::= 'YT' // -> sending T
755758
#endif
756759
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
757760
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
@@ -763,6 +766,12 @@ Types
763766
// FIXME: Consider replacing 'h' with a two-char code
764767
list-type ::= type identifier? 'Yk'? 'z'? 'h'? 'n'? 'Yi'? 'd'? 'Yt'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, actor 'isolated', variadic specifier, and compile-time constant
765768

769+
In the mangling of C function types,``C-TYPE`` is mangled according to the Itanium ABI, prefixed with its length. This resembles the mangling of ``identifier``, but it does not honor substitutions or Punycode.
770+
771+
The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when it's combined with ``function-isolation``.
772+
773+
::
774+
766775
METATYPE-REPR ::= 't' // Thin metatype representation
767776
METATYPE-REPR ::= 'T' // Thick metatype representation
768777
METATYPE-REPR ::= 'o' // ObjC metatype representation

include/swift/Demangling/TypeDecoder.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,12 @@ class TypeDecoder {
915915
++firstChildIdx;
916916
}
917917

918+
if (Node->getChild(firstChildIdx)->getKind() ==
919+
NodeKind::SendingResultFunctionType) {
920+
extFlags = extFlags.withSendingResult();
921+
++firstChildIdx;
922+
}
923+
918924
BuiltType globalActorType = BuiltType();
919925
if (Node->getChild(firstChildIdx)->getKind() ==
920926
NodeKind::GlobalActorFunctionType) {
@@ -937,12 +943,6 @@ class TypeDecoder {
937943
++firstChildIdx;
938944
}
939945

940-
if (Node->getChild(firstChildIdx)->getKind() ==
941-
NodeKind::SendingResultFunctionType) {
942-
extFlags = extFlags.withSendingResult();
943-
++firstChildIdx;
944-
}
945-
946946
FunctionMetadataDifferentiabilityKind diffKind;
947947
if (Node->getChild(firstChildIdx)->getKind() ==
948948
NodeKind::DifferentiableFunctionType) {

lib/Demangling/Demangler.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,24 +1634,51 @@ NodePointer Demangler::demanglePlainFunction() {
16341634

16351635
NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
16361636
NodePointer FuncType = createNode(kind);
1637+
1638+
// Demangle a C function type if the function node kind says that
1639+
// one follows.
16371640
NodePointer ClangType = nullptr;
16381641
if (hasClangType) {
16391642
ClangType = demangleClangType();
16401643
}
16411644
addChild(FuncType, ClangType);
1642-
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
1643-
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
1645+
1646+
// The components of function-signature. Note that these need to be
1647+
// popped in the reverse of the order they're mangled. If you add a
1648+
// new component, be sure to add a demangling test case for combinations
1649+
// of specifiers.
1650+
1651+
// sending-result?
16441652
addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType));
1653+
1654+
// function-isolation?
1655+
auto isFunctionIsolation = [](Node::Kind kind) {
1656+
return kind == Node::Kind::GlobalActorFunctionType ||
1657+
kind == Node::Kind::IsolatedAnyFunctionType;
1658+
};
1659+
addChild(FuncType, popNode(isFunctionIsolation));
1660+
1661+
// differentiable?
16451662
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
1663+
1664+
// throws?
16461665
addChild(FuncType, popNode([](Node::Kind kind) {
16471666
return kind == Node::Kind::ThrowsAnnotation ||
16481667
kind == Node::Kind::TypedThrowsAnnotation;
16491668
}));
1669+
1670+
// sendable?
16501671
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
1672+
1673+
// async?
16511674
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
16521675

1676+
// params-type
16531677
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
1678+
1679+
// result-type
16541680
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
1681+
16551682
return createType(FuncType);
16561683
}
16571684

@@ -1681,15 +1708,15 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16811708
return nullptr;
16821709

16831710
unsigned FirstChildIdx = 0;
1711+
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1712+
Node::Kind::SendingResultFunctionType)
1713+
++FirstChildIdx;
16841714
if (FuncType->getChild(FirstChildIdx)->getKind()
16851715
== Node::Kind::GlobalActorFunctionType)
16861716
++FirstChildIdx;
16871717
if (FuncType->getChild(FirstChildIdx)->getKind()
16881718
== Node::Kind::IsolatedAnyFunctionType)
16891719
++FirstChildIdx;
1690-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1691-
Node::Kind::SendingResultFunctionType)
1692-
++FirstChildIdx;
16931720
if (FuncType->getChild(FirstChildIdx)->getKind()
16941721
== Node::Kind::DifferentiableFunctionType)
16951722
++FirstChildIdx;

lib/Demangling/NodePrinter.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,18 @@ class NodePrinter {
898898
// handled earlier
899899
++startIndex;
900900
}
901+
902+
// Be sure to check for function signature components in the same
903+
// order that they're added by the demangler, which is the reverse
904+
// of the order that they appear in the mangling grammar.
905+
906+
if (node->getChild(startIndex)->getKind() ==
907+
Node::Kind::SendingResultFunctionType) {
908+
++startIndex;
909+
hasSendingResult = true;
910+
}
911+
912+
// function-isolation; note that these can't actually both appear.
901913
if (node->getChild(startIndex)->getKind()
902914
== Node::Kind::IsolatedAnyFunctionType) {
903915
print(node->getChild(startIndex), depth + 1);
@@ -908,6 +920,7 @@ class NodePrinter {
908920
print(node->getChild(startIndex), depth + 1);
909921
++startIndex;
910922
}
923+
911924
if (node->getChild(startIndex)->getKind() ==
912925
Node::Kind::DifferentiableFunctionType) {
913926
diffKind =
@@ -932,11 +945,6 @@ class NodePrinter {
932945
++startIndex;
933946
isAsync = true;
934947
}
935-
if (node->getChild(startIndex)->getKind() ==
936-
Node::Kind::SendingResultFunctionType) {
937-
++startIndex;
938-
hasSendingResult = true;
939-
}
940948

941949
switch (diffKind) {
942950
case MangledDifferentiabilityKind::Forward:

stdlib/public/RemoteInspection/TypeRef.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,15 @@ class DemanglingForTypeRef
766766

767767
auto funcNode = Dem.createNode(kind);
768768

769+
// This needs to use the same order as the demangler.
770+
771+
// TODO: the C function type would go here
772+
773+
if (F->getExtFlags().hasSendingResult()) {
774+
auto node = Dem.createNode(Node::Kind::SendingResultFunctionType);
775+
funcNode->addChild(node, Dem);
776+
}
777+
769778
if (auto globalActor = F->getGlobalActor()) {
770779
auto node = Dem.createNode(Node::Kind::GlobalActorFunctionType);
771780
auto globalActorNode = visit(globalActor);
@@ -774,9 +783,6 @@ class DemanglingForTypeRef
774783
} else if (F->getExtFlags().isIsolatedAny()) {
775784
auto node = Dem.createNode(Node::Kind::IsolatedAnyFunctionType);
776785
funcNode->addChild(node, Dem);
777-
} else if (F->getExtFlags().hasSendingResult()) {
778-
auto node = Dem.createNode(Node::Kind::SendingResultFunctionType);
779-
funcNode->addChild(node, Dem);
780786
}
781787

782788
if (F->getFlags().isDifferentiable()) {

stdlib/public/runtime/Demangle.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -741,8 +741,14 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
741741

742742
NodePointer result = Dem.createNode(Node::Kind::ReturnType);
743743
result->addChild(resultTy, Dem);
744-
744+
745745
auto funcNode = Dem.createNode(kind);
746+
// Add the components of the function-signature production in the same
747+
// order that the demangler would.
748+
// TODO: C function type would go here
749+
if (func->getExtendedFlags().hasSendingResult())
750+
funcNode->addChild(Dem.createNode(Node::Kind::SendingResultFunctionType),
751+
Dem);
746752
if (func->hasGlobalActor()) {
747753
auto globalActorTypeNode =
748754
_swift_buildDemanglingForMetadata(func->getGlobalActor(), Dem);
@@ -798,10 +804,6 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
798804
if (func->isAsync())
799805
funcNode->addChild(Dem.createNode(Node::Kind::AsyncAnnotation), Dem);
800806

801-
if (func->getExtendedFlags().hasSendingResult())
802-
funcNode->addChild(Dem.createNode(Node::Kind::SendingResultFunctionType),
803-
Dem);
804-
805807
funcNode->addChild(parameters, Dem);
806808
funcNode->addChild(result, Dem);
807809
return funcNode;

test/Demangle/Inputs/manglings.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ $sS3fIedgyywTd_D ---> @escaping @differentiable @callee_guaranteed (@unowned Swi
465465
$sS3fIedgyyTd_D ---> @escaping @differentiable @callee_guaranteed (@unowned Swift.Float, @unowned sending Swift.Float) -> (@unowned Swift.Float)
466466
$s4testA2A5KlassCyYTF ---> test.test() -> sending test.Klass
467467
$s4main5KlassCACYTcMD ---> demangling cache variable for type metadata for (main.Klass) -> sending main.Klass
468-
$s4null19transferAsyncResultAA16NonSendableKlassCyYaYTF ---> null.transferAsyncResult() -> sending null.NonSendableKlass
468+
$s4null19transferAsyncResultAA16NonSendableKlassCyYaYTF ---> null.transferAsyncResult() async -> sending null.NonSendableKlass
469469
$s4null16NonSendableKlassCIegHo_ACs5Error_pIegHTrzo_TR ---> {T:} reabstraction thunk helper from @escaping @callee_guaranteed @async () -> (@owned null.NonSendableKlass) to @escaping @callee_guaranteed @async () -> sending (@out null.NonSendableKlass, @error @owned Swift.Error)
470470
$sSRyxG15Synchronization19AtomicRepresentableABRi_zrlMc ---> protocol conformance descriptor for < where A: ~Swift.Copyable> Swift.UnsafeBufferPointer<A> : Synchronization.AtomicRepresentable in Synchronization
471471
$sSRyxG15Synchronization19AtomicRepresentableABRi0_zrlMc ---> protocol conformance descriptor for < where A: ~Swift.Escapable> Swift.UnsafeBufferPointer<A> : Synchronization.AtomicRepresentable in Synchronization
@@ -483,3 +483,5 @@ $s4mainAAyyycAA1CCFTTH ---> hop to main actor thunk of main.main(main.C) -> () -
483483

484484
$s4main6VectorVy$1_SiG ---> main.Vector<2, Swift.Int>
485485
$s$n3_SSBV ---> Builtin.FixedArray<-4, Swift.String>
486+
$s3red7MyActorC3runyxxyYaKACYcYTXEYaKlFZ ---> static red.MyActor.run<A>(@red.MyActor () async throws -> sending A) async throws -> A
487+
$s3red7MyActorC3runyxxyYaKYAYTXEYaKlFZ ---> static red.MyActor.run<A>(@isolated(any) () async throws -> sending A) async throws -> A

0 commit comments

Comments
 (0)