Skip to content

Commit 29b04b9

Browse files
committed
Add support for coroutines to AST builder & demangler
1 parent 866a7c9 commit 29b04b9

File tree

11 files changed

+103
-15
lines changed

11 files changed

+103
-15
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ class ASTBuilder {
150150

151151
Type createImplFunctionType(
152152
Demangle::ImplParameterConvention calleeConvention,
153+
Demangle::ImplCoroutineKind coroutineKind,
153154
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
155+
ArrayRef<Demangle::ImplFunctionYield<Type>> yields,
154156
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
155157
std::optional<Demangle::ImplFunctionResult<Type>> errorResult,
156158
ImplFunctionTypeFlags flags);

include/swift/Demangling/Demangle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ struct [[nodiscard]] ManglingError {
553553
UnknownEncoding,
554554
InvalidImplCalleeConvention,
555555
InvalidImplDifferentiability,
556+
InvalidImplCoroutineKind,
556557
InvalidImplFunctionAttribute,
557558
InvalidImplParameterConvention,
558559
InvalidImplParameterTransferring,

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ NODE(ImplFunctionAttribute)
139139
NODE(ImplFunctionConvention)
140140
NODE(ImplFunctionConventionName)
141141
NODE(ImplFunctionType)
142+
NODE(ImplCoroutineKind)
142143
NODE(ImplInvocationSubstitutions)
143144
CONTEXT_NODE(ImplicitClosure)
144145
NODE(ImplParameter)

include/swift/Demangling/TypeDecoder.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ enum class ImplMetatypeRepresentation {
4848
ObjC,
4949
};
5050

51+
enum class ImplCoroutineKind {
52+
None,
53+
YieldOnce,
54+
YieldMany,
55+
};
56+
5157
/// Describe a function parameter, parameterized on the type
5258
/// representation.
5359
template <typename BuiltType>
@@ -188,6 +194,9 @@ class ImplFunctionParam {
188194
BuiltType getType() const { return Type; }
189195
};
190196

197+
template<typename Type>
198+
using ImplFunctionYield = ImplFunctionParam<Type>;
199+
191200
enum class ImplResultConvention {
192201
Indirect,
193202
Owned,
@@ -1023,9 +1032,11 @@ class TypeDecoder {
10231032
case NodeKind::ImplFunctionType: {
10241033
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
10251034
llvm::SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
1035+
llvm::SmallVector<ImplFunctionYield<BuiltType>, 8> yields;
10261036
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> results;
10271037
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
10281038
ImplFunctionTypeFlags flags;
1039+
ImplCoroutineKind coroutineKind = ImplCoroutineKind::None;
10291040

10301041
for (unsigned i = 0; i < Node->getNumChildren(); i++) {
10311042
auto child = Node->getChild(i);
@@ -1066,6 +1077,15 @@ class TypeDecoder {
10661077
} else if (child->getText() == "@async") {
10671078
flags = flags.withAsync();
10681079
}
1080+
} else if (child->getKind() == NodeKind::ImplCoroutineKind) {
1081+
if (!child->hasText())
1082+
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
1083+
if (child->getText() == "yield_once") {
1084+
coroutineKind = ImplCoroutineKind::YieldOnce;
1085+
} else if (child->getText() == "yield_many") {
1086+
coroutineKind = ImplCoroutineKind::YieldMany;
1087+
} else
1088+
return MAKE_NODE_TYPE_ERROR0(child, "failed to decode coroutine kind");
10691089
} else if (child->getKind() == NodeKind::ImplDifferentiabilityKind) {
10701090
ImplFunctionDifferentiabilityKind implDiffKind;
10711091
switch ((MangledDifferentiabilityKind)child->getIndex()) {
@@ -1088,10 +1108,14 @@ class TypeDecoder {
10881108
if (decodeImplFunctionParam(child, depth + 1, parameters))
10891109
return MAKE_NODE_TYPE_ERROR0(child,
10901110
"failed to decode function parameter");
1111+
} else if (child->getKind() == NodeKind::ImplYield) {
1112+
if (decodeImplFunctionParam(child, depth + 1, yields))
1113+
return MAKE_NODE_TYPE_ERROR0(child,
1114+
"failed to decode function yields");
10911115
} else if (child->getKind() == NodeKind::ImplResult) {
10921116
if (decodeImplFunctionParam(child, depth + 1, results))
10931117
return MAKE_NODE_TYPE_ERROR0(child,
1094-
"failed to decode function parameter");
1118+
"failed to decode function results");
10951119
} else if (child->getKind() == NodeKind::ImplErrorResult) {
10961120
if (decodeImplFunctionPart(child, depth + 1, errorResults))
10971121
return MAKE_NODE_TYPE_ERROR0(child,
@@ -1115,11 +1139,10 @@ class TypeDecoder {
11151139

11161140
// TODO: Some cases not handled above, but *probably* they cannot
11171141
// appear as the types of values in SIL (yet?):
1118-
// - functions with yield returns
11191142
// - functions with generic signatures
11201143
// - foreign error conventions
1121-
return Builder.createImplFunctionType(calleeConvention,
1122-
parameters, results,
1144+
return Builder.createImplFunctionType(calleeConvention, coroutineKind,
1145+
parameters, yields, results,
11231146
errorResult, flags);
11241147
}
11251148

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,9 @@ class TypeRefBuilder {
11341134

11351135
const FunctionTypeRef *createImplFunctionType(
11361136
Demangle::ImplParameterConvention calleeConvention,
1137+
Demangle::ImplCoroutineKind coroutineKind,
11371138
llvm::ArrayRef<Demangle::ImplFunctionParam<const TypeRef *>> params,
1139+
llvm::ArrayRef<Demangle::ImplFunctionYield<const TypeRef *>> yields,
11381140
llvm::ArrayRef<Demangle::ImplFunctionResult<const TypeRef *>> results,
11391141
std::optional<Demangle::ImplFunctionResult<const TypeRef *>> errorResult,
11401142
ImplFunctionTypeFlags flags) {

lib/AST/ASTDemangler.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,17 +571,33 @@ getResultOptions(ImplResultInfoOptions implOptions) {
571571
return result;
572572
}
573573

574+
static SILCoroutineKind
575+
getCoroutineKind(ImplCoroutineKind kind) {
576+
switch (kind) {
577+
case ImplCoroutineKind::None:
578+
return SILCoroutineKind::None;
579+
case ImplCoroutineKind::YieldOnce:
580+
return SILCoroutineKind::YieldOnce;
581+
case ImplCoroutineKind::YieldMany:
582+
return SILCoroutineKind::YieldMany;
583+
}
584+
llvm_unreachable("unknown coroutine kind");
585+
}
586+
574587
Type ASTBuilder::createImplFunctionType(
575588
Demangle::ImplParameterConvention calleeConvention,
589+
Demangle::ImplCoroutineKind coroutineKind,
576590
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
591+
ArrayRef<Demangle::ImplFunctionYield<Type>> yields,
577592
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
578593
std::optional<Demangle::ImplFunctionResult<Type>> errorResult,
579594
ImplFunctionTypeFlags flags) {
580595
GenericSignature genericSig;
581596

582-
SILCoroutineKind funcCoroutineKind = SILCoroutineKind::None;
583597
ParameterConvention funcCalleeConvention =
584598
getParameterConvention(calleeConvention);
599+
SILCoroutineKind funcCoroutineKind =
600+
getCoroutineKind(coroutineKind);
585601

586602
SILFunctionTypeRepresentation representation;
587603
switch (flags.getRepresentation()) {
@@ -644,6 +660,13 @@ Type ASTBuilder::createImplFunctionType(
644660
funcParams.emplace_back(type, conv, options);
645661
}
646662

663+
for (const auto &yield : yields) {
664+
auto type = yield.getType()->getCanonicalType();
665+
auto conv = getParameterConvention(yield.getConvention());
666+
auto options = *getParameterOptions(yield.getOptions());
667+
funcParams.emplace_back(type, conv, options);
668+
}
669+
647670
for (const auto &result : results) {
648671
auto type = result.getType()->getCanonicalType();
649672
auto conv = getResultConvention(result.getConvention());

lib/Demangling/Demangler.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,11 +2292,11 @@ NodePointer Demangler::demangleImplFunctionType() {
22922292

22932293
const char *CoroAttr = nullptr;
22942294
if (nextIf('A'))
2295-
CoroAttr = "@yield_once";
2295+
CoroAttr = "yield_once";
22962296
else if (nextIf('G'))
2297-
CoroAttr = "@yield_many";
2297+
CoroAttr = "yield_many";
22982298
if (CoroAttr)
2299-
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this);
2299+
type->addChild(createNode(Node::Kind::ImplCoroutineKind, CoroAttr), *this);
23002300

23012301
if (nextIf('h')) {
23022302
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, "@Sendable"),

lib/Demangling/NodePrinter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ class NodePrinter {
433433
case Node::Kind::ImplFunctionConvention:
434434
case Node::Kind::ImplFunctionConventionName:
435435
case Node::Kind::ImplFunctionType:
436+
case Node::Kind::ImplCoroutineKind:
436437
case Node::Kind::ImplInvocationSubstitutions:
437438
case Node::Kind::ImplPatternSubstitutions:
438439
case Node::Kind::ImplicitClosure:
@@ -2759,6 +2760,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
27592760
return nullptr;
27602761
case Node::Kind::ImplErasedIsolation:
27612762
Printer << "@isolated(any)";
2763+
return nullptr;
2764+
case Node::Kind::ImplCoroutineKind:
2765+
// Skip if text is empty.
2766+
if (Node->getText().empty())
2767+
return nullptr;
2768+
// Otherwise, print with leading @.
2769+
Printer << '@' << Node->getText();
27622770
return nullptr;
27632771
case Node::Kind::ImplTransferringResult:
27642772
Printer << "transferring";

lib/Demangling/OldRemangler.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,14 +1652,23 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
16521652
return ManglingError::Success;
16531653
}
16541654

1655-
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
1656-
unsigned depth) {
1655+
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
1656+
unsigned depth) {
16571657
StringRef text = node->getText();
1658-
if (text == "@yield_once") {
1658+
if (text == "yield_once") {
16591659
Buffer << "A";
1660-
} else if (text == "@yield_many") {
1660+
} else if (text == "yield_many") {
16611661
Buffer << "G";
1662-
} else if (text == "@Sendable") {
1662+
} else {
1663+
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind, node);
1664+
}
1665+
return ManglingError::Success;
1666+
}
1667+
1668+
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
1669+
unsigned depth) {
1670+
StringRef text = node->getText();
1671+
if (text == "@Sendable") {
16631672
Buffer << "h";
16641673
} else if (text == "@async") {
16651674
Buffer << "H";

lib/Demangling/Remangler.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,12 @@ ManglingError Remangler::mangleImplPatternSubstitutions(Node *node,
19171917
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
19181918
}
19191919

1920+
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
1921+
unsigned depth) {
1922+
// handled inline
1923+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1924+
}
1925+
19201926
ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
19211927
const char *PseudoGeneric = "";
19221928
Node *GenSig = nullptr;
@@ -2015,10 +2021,21 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
20152021
RETURN_IF_ERROR(mangleImplFunctionConvention(Child, depth + 1));
20162022
break;
20172023
}
2024+
case Node::Kind::ImplCoroutineKind: {
2025+
char CoroAttr = llvm::StringSwitch<char>(Child->getText())
2026+
.Case("yield_once", 'A')
2027+
.Case("yield_many", 'G')
2028+
.Default(0);
2029+
2030+
if (!CoroAttr) {
2031+
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind,
2032+
Child);
2033+
}
2034+
Buffer << CoroAttr;
2035+
break;
2036+
}
20182037
case Node::Kind::ImplFunctionAttribute: {
20192038
char FuncAttr = llvm::StringSwitch<char>(Child->getText())
2020-
.Case("@yield_once", 'A')
2021-
.Case("@yield_many", 'G')
20222039
.Case("@Sendable", 'h')
20232040
.Case("@async", 'H')
20242041
.Default(0);

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,9 @@ class DecodedMetadataBuilder {
20232023

20242024
TypeLookupErrorOr<BuiltType> createImplFunctionType(
20252025
Demangle::ImplParameterConvention calleeConvention,
2026+
Demangle::ImplCoroutineKind coroutineKind,
20262027
llvm::ArrayRef<Demangle::ImplFunctionParam<BuiltType>> params,
2028+
llvm::ArrayRef<Demangle::ImplFunctionYield<BuiltType>> yields,
20272029
llvm::ArrayRef<Demangle::ImplFunctionResult<BuiltType>> results,
20282030
std::optional<Demangle::ImplFunctionResult<BuiltType>> errorResult,
20292031
ImplFunctionTypeFlags flags) {

0 commit comments

Comments
 (0)