Skip to content

Commit 3c960a4

Browse files
committed
Add support for coroutines to AST builder & demangler
1 parent 9aff027 commit 3c960a4

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,
@@ -1046,9 +1055,11 @@ class TypeDecoder {
10461055
case NodeKind::ImplFunctionType: {
10471056
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
10481057
llvm::SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
1058+
llvm::SmallVector<ImplFunctionYield<BuiltType>, 8> yields;
10491059
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> results;
10501060
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
10511061
ImplFunctionTypeFlags flags;
1062+
ImplCoroutineKind coroutineKind = ImplCoroutineKind::None;
10521063

10531064
for (unsigned i = 0; i < Node->getNumChildren(); i++) {
10541065
auto child = Node->getChild(i);
@@ -1089,6 +1100,15 @@ class TypeDecoder {
10891100
} else if (child->getText() == "@async") {
10901101
flags = flags.withAsync();
10911102
}
1103+
} else if (child->getKind() == NodeKind::ImplCoroutineKind) {
1104+
if (!child->hasText())
1105+
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
1106+
if (child->getText() == "yield_once") {
1107+
coroutineKind = ImplCoroutineKind::YieldOnce;
1108+
} else if (child->getText() == "yield_many") {
1109+
coroutineKind = ImplCoroutineKind::YieldMany;
1110+
} else
1111+
return MAKE_NODE_TYPE_ERROR0(child, "failed to decode coroutine kind");
10921112
} else if (child->getKind() == NodeKind::ImplDifferentiabilityKind) {
10931113
ImplFunctionDifferentiabilityKind implDiffKind;
10941114
switch ((MangledDifferentiabilityKind)child->getIndex()) {
@@ -1111,10 +1131,14 @@ class TypeDecoder {
11111131
if (decodeImplFunctionParam(child, depth + 1, parameters))
11121132
return MAKE_NODE_TYPE_ERROR0(child,
11131133
"failed to decode function parameter");
1134+
} else if (child->getKind() == NodeKind::ImplYield) {
1135+
if (decodeImplFunctionParam(child, depth + 1, yields))
1136+
return MAKE_NODE_TYPE_ERROR0(child,
1137+
"failed to decode function yields");
11141138
} else if (child->getKind() == NodeKind::ImplResult) {
11151139
if (decodeImplFunctionParam(child, depth + 1, results))
11161140
return MAKE_NODE_TYPE_ERROR0(child,
1117-
"failed to decode function parameter");
1141+
"failed to decode function results");
11181142
} else if (child->getKind() == NodeKind::ImplErrorResult) {
11191143
if (decodeImplFunctionPart(child, depth + 1, errorResults))
11201144
return MAKE_NODE_TYPE_ERROR0(child,
@@ -1138,11 +1162,10 @@ class TypeDecoder {
11381162

11391163
// TODO: Some cases not handled above, but *probably* they cannot
11401164
// appear as the types of values in SIL (yet?):
1141-
// - functions with yield returns
11421165
// - functions with generic signatures
11431166
// - foreign error conventions
1144-
return Builder.createImplFunctionType(calleeConvention,
1145-
parameters, results,
1167+
return Builder.createImplFunctionType(calleeConvention, coroutineKind,
1168+
parameters, yields, results,
11461169
errorResult, flags);
11471170
}
11481171

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
@@ -1918,6 +1918,12 @@ ManglingError Remangler::mangleImplPatternSubstitutions(Node *node,
19181918
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
19191919
}
19201920

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