Skip to content

Commit fa70ec0

Browse files
aslasavonic
authored andcommitted
Add support for coroutines to AST builder & demangler
1 parent cd920a7 commit fa70ec0

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
@@ -553,6 +553,7 @@ struct [[nodiscard]] ManglingError {
553553
UnknownEncoding,
554554
InvalidImplCalleeConvention,
555555
InvalidImplDifferentiability,
556+
InvalidImplCoroutineKind,
556557
InvalidImplFunctionAttribute,
557558
InvalidImplParameterConvention,
558559
InvalidMetatypeRepresentation,

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ NODE(ImplFunctionAttribute)
137137
NODE(ImplFunctionConvention)
138138
NODE(ImplFunctionConventionName)
139139
NODE(ImplFunctionType)
140+
NODE(ImplCoroutineKind)
140141
NODE(ImplInvocationSubstitutions)
141142
CONTEXT_NODE(ImplicitClosure)
142143
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,
@@ -974,9 +983,11 @@ class TypeDecoder {
974983
case NodeKind::ImplFunctionType: {
975984
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
976985
llvm::SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
986+
llvm::SmallVector<ImplFunctionYield<BuiltType>, 8> yields;
977987
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> results;
978988
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
979989
ImplFunctionTypeFlags flags;
990+
ImplCoroutineKind coroutineKind = ImplCoroutineKind::None;
980991

981992
for (unsigned i = 0; i < Node->getNumChildren(); i++) {
982993
auto child = Node->getChild(i);
@@ -1017,6 +1028,15 @@ class TypeDecoder {
10171028
} else if (child->getText() == "@async") {
10181029
flags = flags.withAsync();
10191030
}
1031+
} else if (child->getKind() == NodeKind::ImplCoroutineKind) {
1032+
if (!child->hasText())
1033+
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
1034+
if (child->getText() == "yield_once") {
1035+
coroutineKind = ImplCoroutineKind::YieldOnce;
1036+
} else if (child->getText() == "yield_many") {
1037+
coroutineKind = ImplCoroutineKind::YieldMany;
1038+
} else
1039+
return MAKE_NODE_TYPE_ERROR0(child, "failed to decode coroutine kind");
10201040
} else if (child->getKind() == NodeKind::ImplDifferentiabilityKind) {
10211041
ImplFunctionDifferentiabilityKind implDiffKind;
10221042
switch ((MangledDifferentiabilityKind)child->getIndex()) {
@@ -1039,10 +1059,14 @@ class TypeDecoder {
10391059
if (decodeImplFunctionParam(child, depth + 1, parameters))
10401060
return MAKE_NODE_TYPE_ERROR0(child,
10411061
"failed to decode function parameter");
1062+
} else if (child->getKind() == NodeKind::ImplYield) {
1063+
if (decodeImplFunctionParam(child, depth + 1, yields))
1064+
return MAKE_NODE_TYPE_ERROR0(child,
1065+
"failed to decode function yields");
10421066
} else if (child->getKind() == NodeKind::ImplResult) {
10431067
if (decodeImplFunctionParam(child, depth + 1, results))
10441068
return MAKE_NODE_TYPE_ERROR0(child,
1045-
"failed to decode function parameter");
1069+
"failed to decode function results");
10461070
} else if (child->getKind() == NodeKind::ImplErrorResult) {
10471071
if (decodeImplFunctionPart(child, depth + 1, errorResults))
10481072
return MAKE_NODE_TYPE_ERROR0(child,
@@ -1066,11 +1090,10 @@ class TypeDecoder {
10661090

10671091
// TODO: Some cases not handled above, but *probably* they cannot
10681092
// appear as the types of values in SIL (yet?):
1069-
// - functions with yield returns
10701093
// - functions with generic signatures
10711094
// - foreign error conventions
1072-
return Builder.createImplFunctionType(calleeConvention,
1073-
parameters, results,
1095+
return Builder.createImplFunctionType(calleeConvention, coroutineKind,
1096+
parameters, yields, results,
10741097
errorResult, flags);
10751098
}
10761099

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
@@ -560,17 +560,33 @@ getResultOptions(ImplResultInfoOptions implOptions) {
560560
return result;
561561
}
562562

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

571-
SILCoroutineKind funcCoroutineKind = SILCoroutineKind::None;
572586
ParameterConvention funcCalleeConvention =
573587
getParameterConvention(calleeConvention);
588+
SILCoroutineKind funcCoroutineKind =
589+
getCoroutineKind(coroutineKind);
574590

575591
SILFunctionTypeRepresentation representation;
576592
switch (flags.getRepresentation()) {
@@ -633,6 +649,13 @@ Type ASTBuilder::createImplFunctionType(
633649
funcParams.emplace_back(type, conv, options);
634650
}
635651

652+
for (const auto &yield : yields) {
653+
auto type = yield.getType()->getCanonicalType();
654+
auto conv = getParameterConvention(yield.getConvention());
655+
auto options = *getParameterOptions(yield.getOptions());
656+
funcParams.emplace_back(type, conv, options);
657+
}
658+
636659
for (const auto &result : results) {
637660
auto type = result.getType()->getCanonicalType();
638661
auto conv = getResultConvention(result.getConvention());

lib/Demangling/Demangler.cpp

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

22752275
const char *CoroAttr = nullptr;
22762276
if (nextIf('A'))
2277-
CoroAttr = "@yield_once";
2277+
CoroAttr = "yield_once";
22782278
else if (nextIf('G'))
2279-
CoroAttr = "@yield_many";
2279+
CoroAttr = "yield_many";
22802280
if (CoroAttr)
2281-
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this);
2281+
type->addChild(createNode(Node::Kind::ImplCoroutineKind, CoroAttr), *this);
22822282

22832283
if (nextIf('h')) {
22842284
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
@@ -431,6 +431,7 @@ class NodePrinter {
431431
case Node::Kind::ImplFunctionConvention:
432432
case Node::Kind::ImplFunctionConventionName:
433433
case Node::Kind::ImplFunctionType:
434+
case Node::Kind::ImplCoroutineKind:
434435
case Node::Kind::ImplInvocationSubstitutions:
435436
case Node::Kind::ImplPatternSubstitutions:
436437
case Node::Kind::ImplicitClosure:
@@ -2731,6 +2732,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
27312732
return nullptr;
27322733
case Node::Kind::ImplErasedIsolation:
27332734
Printer << "@isolated(any)";
2735+
return nullptr;
2736+
case Node::Kind::ImplCoroutineKind:
2737+
// Skip if text is empty.
2738+
if (Node->getText().empty())
2739+
return nullptr;
2740+
// Otherwise, print with leading @.
2741+
Printer << '@' << Node->getText();
27342742
return nullptr;
27352743
case Node::Kind::ImplConvention:
27362744
Printer << Node->getText();

lib/Demangling/OldRemangler.cpp

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

1649-
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
1650-
unsigned depth) {
1649+
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
1650+
unsigned depth) {
16511651
StringRef text = node->getText();
1652-
if (text == "@yield_once") {
1652+
if (text == "yield_once") {
16531653
Buffer << "A";
1654-
} else if (text == "@yield_many") {
1654+
} else if (text == "yield_many") {
16551655
Buffer << "G";
1656-
} else if (text == "@Sendable") {
1656+
} else {
1657+
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind, node);
1658+
}
1659+
return ManglingError::Success;
1660+
}
1661+
1662+
ManglingError Remangler::mangleImplFunctionAttribute(Node *node,
1663+
unsigned depth) {
1664+
StringRef text = node->getText();
1665+
if (text == "@Sendable") {
16571666
Buffer << "h";
16581667
} else if (text == "@async") {
16591668
Buffer << "H";

lib/Demangling/Remangler.cpp

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

1866+
ManglingError Remangler::mangleImplCoroutineKind(Node *node,
1867+
unsigned depth) {
1868+
// handled inline
1869+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1870+
}
1871+
18661872
ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
18671873
const char *PseudoGeneric = "";
18681874
Node *GenSig = nullptr;
@@ -1956,10 +1962,21 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
19561962
RETURN_IF_ERROR(mangleImplFunctionConvention(Child, depth + 1));
19571963
break;
19581964
}
1965+
case Node::Kind::ImplCoroutineKind: {
1966+
char CoroAttr = llvm::StringSwitch<char>(Child->getText())
1967+
.Case("yield_once", 'A')
1968+
.Case("yield_many", 'G')
1969+
.Default(0);
1970+
1971+
if (!CoroAttr) {
1972+
return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind,
1973+
Child);
1974+
}
1975+
Buffer << CoroAttr;
1976+
break;
1977+
}
19591978
case Node::Kind::ImplFunctionAttribute: {
19601979
char FuncAttr = llvm::StringSwitch<char>(Child->getText())
1961-
.Case("@yield_once", 'A')
1962-
.Case("@yield_many", 'G')
19631980
.Case("@Sendable", 'h')
19641981
.Case("@async", 'H')
19651982
.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)