Skip to content

Commit 714ecbd

Browse files
authored
Merge pull request #78641 from rjmccall/demangle-sending-result-with-function-isolation-6.1
[6.1] Fix the demangling of sending result types when combined with isolation
2 parents f68e93b + 42a36ac commit 714ecbd

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
@@ -732,10 +732,12 @@ Types
732732
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
733733
FUNCTION-KIND ::= 'E' // function type (noescape)
734734

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

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

740742
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
741743
// with optional inout convention, shared convention. parameters don't have labels,
@@ -751,6 +753,7 @@ Types
751753
#if SWIFT_RUNTIME_VERSION >= 6.0
752754
throws ::= type 'YK' // 'throws(type)' annotation on function types
753755
function-isolation ::= type 'YA' // @isolated(any) on function type
756+
sending-result ::= 'YT' // -> sending T
754757
#endif
755758
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
756759
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
@@ -762,6 +765,12 @@ Types
762765
// FIXME: Consider replacing 'h' with a two-char code
763766
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
764767

768+
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.
769+
770+
The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when it's combined with ``function-isolation``.
771+
772+
::
773+
765774
METATYPE-REPR ::= 't' // Thin metatype representation
766775
METATYPE-REPR ::= 'T' // Thick metatype representation
767776
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
@@ -1628,24 +1628,51 @@ NodePointer Demangler::demanglePlainFunction() {
16281628

16291629
NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
16301630
NodePointer FuncType = createNode(kind);
1631+
1632+
// Demangle a C function type if the function node kind says that
1633+
// one follows.
16311634
NodePointer ClangType = nullptr;
16321635
if (hasClangType) {
16331636
ClangType = demangleClangType();
16341637
}
16351638
addChild(FuncType, ClangType);
1636-
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
1637-
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
1639+
1640+
// The components of function-signature. Note that these need to be
1641+
// popped in the reverse of the order they're mangled. If you add a
1642+
// new component, be sure to add a demangling test case for combinations
1643+
// of specifiers.
1644+
1645+
// sending-result?
16381646
addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType));
1647+
1648+
// function-isolation?
1649+
auto isFunctionIsolation = [](Node::Kind kind) {
1650+
return kind == Node::Kind::GlobalActorFunctionType ||
1651+
kind == Node::Kind::IsolatedAnyFunctionType;
1652+
};
1653+
addChild(FuncType, popNode(isFunctionIsolation));
1654+
1655+
// differentiable?
16391656
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
1657+
1658+
// throws?
16401659
addChild(FuncType, popNode([](Node::Kind kind) {
16411660
return kind == Node::Kind::ThrowsAnnotation ||
16421661
kind == Node::Kind::TypedThrowsAnnotation;
16431662
}));
1663+
1664+
// sendable?
16441665
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
1666+
1667+
// async?
16451668
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
16461669

1670+
// params-type
16471671
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
1672+
1673+
// result-type
16481674
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
1675+
16491676
return createType(FuncType);
16501677
}
16511678

@@ -1675,15 +1702,15 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16751702
return nullptr;
16761703

16771704
unsigned FirstChildIdx = 0;
1705+
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1706+
Node::Kind::SendingResultFunctionType)
1707+
++FirstChildIdx;
16781708
if (FuncType->getChild(FirstChildIdx)->getKind()
16791709
== Node::Kind::GlobalActorFunctionType)
16801710
++FirstChildIdx;
16811711
if (FuncType->getChild(FirstChildIdx)->getKind()
16821712
== Node::Kind::IsolatedAnyFunctionType)
16831713
++FirstChildIdx;
1684-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1685-
Node::Kind::SendingResultFunctionType)
1686-
++FirstChildIdx;
16871714
if (FuncType->getChild(FirstChildIdx)->getKind()
16881715
== Node::Kind::DifferentiableFunctionType)
16891716
++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)