Skip to content

Commit 2f9b864

Browse files
aslasavonic
authored andcommitted
Add support for coroutines to AST builder & demangler
1 parent 05711ff commit 2f9b864

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
@@ -149,7 +149,9 @@ class ASTBuilder {
149149

150150
Type createImplFunctionType(
151151
Demangle::ImplParameterConvention calleeConvention,
152+
Demangle::ImplCoroutineKind coroutineKind,
152153
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
154+
ArrayRef<Demangle::ImplFunctionYield<Type>> yields,
153155
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
154156
llvm::Optional<Demangle::ImplFunctionResult<Type>> errorResult,
155157
ImplFunctionTypeFlags flags);

include/swift/Demangling/Demangle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ struct [[nodiscard]] ManglingError {
551551
UnknownEncoding,
552552
InvalidImplCalleeConvention,
553553
InvalidImplDifferentiability,
554+
InvalidImplCoroutineKind,
554555
InvalidImplFunctionAttribute,
555556
InvalidImplParameterConvention,
556557
InvalidMetatypeRepresentation,

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ NODE(ImplFunctionAttribute)
136136
NODE(ImplFunctionConvention)
137137
NODE(ImplFunctionConventionName)
138138
NODE(ImplFunctionType)
139+
NODE(ImplCoroutineKind)
139140
NODE(ImplInvocationSubstitutions)
140141
CONTEXT_NODE(ImplicitClosure)
141142
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>
@@ -185,6 +191,9 @@ class ImplFunctionParam {
185191
BuiltType getType() const { return Type; }
186192
};
187193

194+
template<typename Type>
195+
using ImplFunctionYield = ImplFunctionParam<Type>;
196+
188197
enum class ImplResultConvention {
189198
Indirect,
190199
Owned,
@@ -956,9 +965,11 @@ class TypeDecoder {
956965
case NodeKind::ImplFunctionType: {
957966
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
958967
llvm::SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
968+
llvm::SmallVector<ImplFunctionYield<BuiltType>, 8> yields;
959969
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> results;
960970
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
961971
ImplFunctionTypeFlags flags;
972+
ImplCoroutineKind coroutineKind = ImplCoroutineKind::None;
962973

963974
for (unsigned i = 0; i < Node->getNumChildren(); i++) {
964975
auto child = Node->getChild(i);
@@ -999,6 +1010,15 @@ class TypeDecoder {
9991010
} else if (child->getText() == "@async") {
10001011
flags = flags.withAsync();
10011012
}
1013+
} else if (child->getKind() == NodeKind::ImplCoroutineKind) {
1014+
if (!child->hasText())
1015+
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
1016+
if (child->getText() == "yield_once") {
1017+
coroutineKind = ImplCoroutineKind::YieldOnce;
1018+
} else if (child->getText() == "yield_many") {
1019+
coroutineKind = ImplCoroutineKind::YieldMany;
1020+
} else
1021+
return MAKE_NODE_TYPE_ERROR0(child, "failed to decode coroutine kind");
10021022
} else if (child->getKind() == NodeKind::ImplDifferentiabilityKind) {
10031023
ImplFunctionDifferentiabilityKind implDiffKind;
10041024
switch ((MangledDifferentiabilityKind)child->getIndex()) {
@@ -1019,10 +1039,14 @@ class TypeDecoder {
10191039
if (decodeImplFunctionParam(child, depth + 1, parameters))
10201040
return MAKE_NODE_TYPE_ERROR0(child,
10211041
"failed to decode function parameter");
1042+
} else if (child->getKind() == NodeKind::ImplYield) {
1043+
if (decodeImplFunctionParam(child, depth + 1, yields))
1044+
return MAKE_NODE_TYPE_ERROR0(child,
1045+
"failed to decode function yields");
10221046
} else if (child->getKind() == NodeKind::ImplResult) {
10231047
if (decodeImplFunctionParam(child, depth + 1, results))
10241048
return MAKE_NODE_TYPE_ERROR0(child,
1025-
"failed to decode function parameter");
1049+
"failed to decode function results");
10261050
} else if (child->getKind() == NodeKind::ImplErrorResult) {
10271051
if (decodeImplFunctionPart(child, depth + 1, errorResults))
10281052
return MAKE_NODE_TYPE_ERROR0(child,
@@ -1046,11 +1070,10 @@ class TypeDecoder {
10461070

10471071
// TODO: Some cases not handled above, but *probably* they cannot
10481072
// appear as the types of values in SIL (yet?):
1049-
// - functions with yield returns
10501073
// - functions with generic signatures
10511074
// - foreign error conventions
1052-
return Builder.createImplFunctionType(calleeConvention,
1053-
parameters, results,
1075+
return Builder.createImplFunctionType(calleeConvention, coroutineKind,
1076+
parameters, yields, results,
10541077
errorResult, flags);
10551078
}
10561079

include/swift/RemoteInspection/TypeRefBuilder.h

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

11321132
const FunctionTypeRef *createImplFunctionType(
11331133
Demangle::ImplParameterConvention calleeConvention,
1134+
Demangle::ImplCoroutineKind coroutineKind,
11341135
llvm::ArrayRef<Demangle::ImplFunctionParam<const TypeRef *>> params,
1136+
llvm::ArrayRef<Demangle::ImplFunctionYield<const TypeRef *>> yields,
11351137
llvm::ArrayRef<Demangle::ImplFunctionResult<const TypeRef *>> results,
11361138
llvm::Optional<Demangle::ImplFunctionResult<const TypeRef *>> errorResult,
11371139
ImplFunctionTypeFlags flags) {

lib/AST/ASTDemangler.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,17 +559,33 @@ getResultOptions(ImplResultInfoOptions implOptions) {
559559
return result;
560560
}
561561

562+
static SILCoroutineKind
563+
getCoroutineKind(ImplCoroutineKind kind) {
564+
switch (kind) {
565+
case ImplCoroutineKind::None:
566+
return SILCoroutineKind::None;
567+
case ImplCoroutineKind::YieldOnce:
568+
return SILCoroutineKind::YieldOnce;
569+
case ImplCoroutineKind::YieldMany:
570+
return SILCoroutineKind::YieldMany;
571+
}
572+
llvm_unreachable("unknown coroutine kind");
573+
}
574+
562575
Type ASTBuilder::createImplFunctionType(
563576
Demangle::ImplParameterConvention calleeConvention,
577+
Demangle::ImplCoroutineKind coroutineKind,
564578
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
579+
ArrayRef<Demangle::ImplFunctionYield<Type>> yields,
565580
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
566581
llvm::Optional<Demangle::ImplFunctionResult<Type>> errorResult,
567582
ImplFunctionTypeFlags flags) {
568583
GenericSignature genericSig;
569584

570-
SILCoroutineKind funcCoroutineKind = SILCoroutineKind::None;
571585
ParameterConvention funcCalleeConvention =
572586
getParameterConvention(calleeConvention);
587+
SILCoroutineKind funcCoroutineKind =
588+
getCoroutineKind(coroutineKind);
573589

574590
SILFunctionTypeRepresentation representation;
575591
switch (flags.getRepresentation()) {
@@ -628,6 +644,13 @@ Type ASTBuilder::createImplFunctionType(
628644
funcParams.emplace_back(type, conv, options);
629645
}
630646

647+
for (const auto &yield : yields) {
648+
auto type = yield.getType()->getCanonicalType();
649+
auto conv = getParameterConvention(yield.getConvention());
650+
auto options = *getParameterOptions(yield.getOptions());
651+
funcParams.emplace_back(type, conv, options);
652+
}
653+
631654
for (const auto &result : results) {
632655
auto type = result.getType()->getCanonicalType();
633656
auto conv = getResultConvention(result.getConvention());

lib/Demangling/Demangler.cpp

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

22552255
const char *CoroAttr = nullptr;
22562256
if (nextIf('A'))
2257-
CoroAttr = "@yield_once";
2257+
CoroAttr = "yield_once";
22582258
else if (nextIf('G'))
2259-
CoroAttr = "@yield_many";
2259+
CoroAttr = "yield_many";
22602260
if (CoroAttr)
2261-
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this);
2261+
type->addChild(createNode(Node::Kind::ImplCoroutineKind, CoroAttr), *this);
22622262

22632263
if (nextIf('h')) {
22642264
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
@@ -430,6 +430,7 @@ class NodePrinter {
430430
case Node::Kind::ImplFunctionConvention:
431431
case Node::Kind::ImplFunctionConventionName:
432432
case Node::Kind::ImplFunctionType:
433+
case Node::Kind::ImplCoroutineKind:
433434
case Node::Kind::ImplInvocationSubstitutions:
434435
case Node::Kind::ImplPatternSubstitutions:
435436
case Node::Kind::ImplicitClosure:
@@ -2680,6 +2681,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
26802681
case Node::Kind::ImplEscaping:
26812682
Printer << "@escaping";
26822683
return nullptr;
2684+
case Node::Kind::ImplCoroutineKind:
2685+
// Skip if text is empty.
2686+
if (Node->getText().empty())
2687+
return nullptr;
2688+
// Otherwise, print with leading @.
2689+
Printer << '@' << Node->getText();
2690+
return nullptr;
26832691
case Node::Kind::ImplConvention:
26842692
Printer << Node->getText();
26852693
return nullptr;

lib/Demangling/OldRemangler.cpp

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

1643-
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
1644-
unsigned depth) {
1643+
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
1644+
unsigned depth) {
16451645
StringRef text = node->getText();
1646-
if (text == "@yield_once") {
1646+
if (text == "yield_once") {
16471647
Buffer << "A";
1648-
} else if (text == "@yield_many") {
1648+
} else if (text == "yield_many") {
16491649
Buffer << "G";
1650-
} else if (text == "@Sendable") {
1650+
} else {
1651+
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind, node);
1652+
}
1653+
return ManglingError::Success;
1654+
}
1655+
1656+
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
1657+
unsigned depth) {
1658+
StringRef text = node->getText();
1659+
if (text == "@Sendable") {
16511660
Buffer << "h";
16521661
} else if (text == "@async") {
16531662
Buffer << "H";

lib/Demangling/Remangler.cpp

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

1861+
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
1862+
unsigned depth) {
1863+
// handled inline
1864+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1865+
}
1866+
18611867
ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
18621868
const char *PseudoGeneric = "";
18631869
Node *GenSig = nullptr;
@@ -1948,10 +1954,21 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
19481954
RETURN_IF_ERROR(mangleImplFunctionConvention(Child, depth + 1));
19491955
break;
19501956
}
1957+
case Node::Kind::ImplCoroutineKind: {
1958+
char CoroAttr = llvm::StringSwitch<char>(Child->getText())
1959+
.Case("yield_once", 'A')
1960+
.Case("yield_many", 'G')
1961+
.Default(0);
1962+
1963+
if (!CoroAttr) {
1964+
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind,
1965+
Child);
1966+
}
1967+
Buffer << CoroAttr;
1968+
break;
1969+
}
19511970
case Node::Kind::ImplFunctionAttribute: {
19521971
char FuncAttr = llvm::StringSwitch<char>(Child->getText())
1953-
.Case("@yield_once", 'A')
1954-
.Case("@yield_many", 'G')
19551972
.Case("@Sendable", 'h')
19561973
.Case("@async", 'H')
19571974
.Default(0);

stdlib/public/runtime/MetadataLookup.cpp

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

20052005
TypeLookupErrorOr<BuiltType> createImplFunctionType(
20062006
Demangle::ImplParameterConvention calleeConvention,
2007+
Demangle::ImplCoroutineKind coroutineKind,
20072008
llvm::ArrayRef<Demangle::ImplFunctionParam<BuiltType>> params,
2009+
llvm::ArrayRef<Demangle::ImplFunctionYield<BuiltType>> yields,
20082010
llvm::ArrayRef<Demangle::ImplFunctionResult<BuiltType>> results,
20092011
llvm::Optional<Demangle::ImplFunctionResult<BuiltType>> errorResult,
20102012
ImplFunctionTypeFlags flags) {

0 commit comments

Comments
 (0)