Skip to content

Commit 4f702fb

Browse files
committed
Add parsing of @yield_once and @yields attributes and corresponding type checks
1 parent 2524be2 commit 4f702fb

21 files changed

+175
-76
lines changed

include/swift/AST/AnyFunctionRef.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -263,25 +263,7 @@ class AnyFunctionRef {
263263
private:
264264
ArrayRef<AnyFunctionType::Yield>
265265
getYieldResultsImpl(SmallVectorImpl<AnyFunctionType::Yield> &buffer,
266-
bool mapIntoContext) const {
267-
assert(buffer.empty());
268-
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
269-
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
270-
if (AD->isCoroutine()) {
271-
auto valueTy = AD->getStorage()->getValueInterfaceType()
272-
->getReferenceStorageReferent();
273-
if (mapIntoContext)
274-
valueTy = AD->mapTypeIntoContext(valueTy);
275-
YieldTypeFlags flags(isYieldingMutableAccessor(AD->getAccessorKind())
276-
? ParamSpecifier::InOut
277-
: ParamSpecifier::LegacyShared);
278-
buffer.push_back(AnyFunctionType::Yield(valueTy, flags));
279-
return buffer;
280-
}
281-
}
282-
}
283-
return {};
284-
}
266+
bool mapIntoContext) const;
285267
};
286268
#if SWIFT_COMPILER_IS_MSVC
287269
#pragma warning(pop)

include/swift/AST/TypeAttr.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ SIMPLE_TYPE_ATTR(_noMetadata, NoMetadata)
6767
TYPE_ATTR(_opaqueReturnTypeOf, OpaqueReturnTypeOf)
6868
TYPE_ATTR(isolated, Isolated)
6969
SIMPLE_TYPE_ATTR(_addressable, Addressable)
70+
SIMPLE_TYPE_ATTR(yields, Yields)
71+
SIMPLE_TYPE_ATTR(yield_once, YieldOnce)
72+
SIMPLE_TYPE_ATTR(yield_once_2, YieldOnce2)
7073

7174
// SIL-specific attributes
7275
SIMPLE_SIL_TYPE_ATTR(async, Async)
@@ -102,9 +105,6 @@ SIL_TYPE_ATTR(opened, Opened)
102105
SIL_TYPE_ATTR(pack_element, PackElement)
103106
SIMPLE_SIL_TYPE_ATTR(pseudogeneric, Pseudogeneric)
104107
SIMPLE_SIL_TYPE_ATTR(unimplementable, Unimplementable)
105-
SIMPLE_SIL_TYPE_ATTR(yields, Yields)
106-
SIMPLE_SIL_TYPE_ATTR(yield_once, YieldOnce)
107-
SIMPLE_SIL_TYPE_ATTR(yield_once_2, YieldOnce2)
108108
SIMPLE_SIL_TYPE_ATTR(yield_many, YieldMany)
109109
SIMPLE_SIL_TYPE_ATTR(captures_generics, CapturesGenerics)
110110
// Used at the SIL level to mark a type as moveOnly.

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,8 @@ NODE(DependentGenericInverseConformanceRequirement)
407407
NODE(Integer)
408408
NODE(NegativeInteger)
409409
NODE(DependentGenericParamValueMarker)
410+
NODE(YieldResult)
411+
NODE(Coroutine)
410412

411413
#undef CONTEXT_NODE
412414
#undef NODE

include/swift/Parse/Parser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,8 +605,8 @@ class Parser {
605605

606606
bool isContextualYieldKeyword() {
607607
return (Tok.isContextualKeyword("yield") &&
608-
isa<AccessorDecl>(CurDeclContext) &&
609-
cast<AccessorDecl>(CurDeclContext)->isCoroutine());
608+
(isa<AbstractFunctionDecl>(CurDeclContext) &&
609+
cast<AbstractFunctionDecl>(CurDeclContext)->isCoroutine()));
610610
}
611611

612612
/// Whether the current token is the contextual keyword for a \c then

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,7 @@ namespace {
17051705
void printCommonFD(FuncDecl *FD, const char *type, StringRef Label) {
17061706
printCommonAFD(FD, type, Label);
17071707
printFlag(FD->isStatic(), "type");
1708+
printFlag(FD->isCoroutine(), "@yield_once");
17081709
}
17091710

17101711
void visitFuncDecl(FuncDecl *FD, StringRef label) {

lib/AST/Decl.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,58 @@ bool AbstractFunctionDecl::isCoroutine() const {
11661166
return false;
11671167
}
11681168

1169+
ArrayRef<AnyFunctionType::Yield>
1170+
AnyFunctionRef::getYieldResultsImpl(SmallVectorImpl<AnyFunctionType::Yield> &buffer,
1171+
bool mapIntoContext) const {
1172+
assert(buffer.empty());
1173+
if (auto *AFD = getAbstractFunctionDecl()) {
1174+
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
1175+
// FIXME: AccessorDecl case is not necessary
1176+
if (AD->isCoroutine()) {
1177+
auto valueTy = AD->getStorage()->getValueInterfaceType()
1178+
->getReferenceStorageReferent();
1179+
if (mapIntoContext)
1180+
valueTy = AFD->mapTypeIntoContext(valueTy);
1181+
YieldTypeFlags flags(isYieldingMutableAccessor(AD->getAccessorKind())
1182+
? ParamSpecifier::InOut
1183+
: ParamSpecifier::LegacyShared);
1184+
buffer.push_back(AnyFunctionType::Yield(valueTy, flags));
1185+
return buffer;
1186+
}
1187+
} else if (AFD->isCoroutine()) {
1188+
auto resType = AFD->getInterfaceType()->castTo<FunctionType>()->getResult();
1189+
if (auto *resFnType = resType->getAs<FunctionType>())
1190+
resType = resFnType->getResult();
1191+
1192+
if (resType->hasError())
1193+
return {};
1194+
1195+
auto addYieldInfo =
1196+
[&](const YieldResultType *yieldResultTy) {
1197+
Type valueTy = yieldResultTy->getResultType();
1198+
if (mapIntoContext)
1199+
valueTy = AFD->mapTypeIntoContext(valueTy);
1200+
YieldTypeFlags flags(yieldResultTy->isInOut() ?
1201+
ParamSpecifier::InOut : ParamSpecifier::LegacyShared);
1202+
buffer.push_back(AnyFunctionType::Yield(valueTy, flags));
1203+
};
1204+
1205+
if (auto *tupleResTy = resType->getAs<TupleType>())
1206+
for (const auto &elt : tupleResTy->getElements()) {
1207+
Type eltTy = elt.getType();
1208+
if (auto *yieldResTy = eltTy->getAs<YieldResultType>())
1209+
addYieldInfo(yieldResTy);
1210+
}
1211+
else
1212+
addYieldInfo(resType->castTo<YieldResultType>());
1213+
1214+
return buffer;
1215+
}
1216+
}
1217+
return {};
1218+
}
1219+
1220+
11691221
bool ParameterList::hasInternalParameter(StringRef Prefix) const {
11701222
for (auto param : *this) {
11711223
if (param->hasName() && param->getNameStr().starts_with(Prefix))

lib/Demangling/Demangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,9 @@ NodePointer Demangler::demangleTypeAnnotation() {
10061006
case 'u':
10071007
return createType(
10081008
createWithChild(Node::Kind::Sending, popTypeAndGetChild()));
1009+
case 'y':
1010+
return createType(
1011+
createWithChild(Node::Kind::YieldResult, popTypeAndGetChild()));
10091012
default:
10101013
return nullptr;
10111014
}
@@ -3761,6 +3764,8 @@ NodePointer Demangler::demangleSpecialType() {
37613764
return popFunctionType(Node::Kind::ObjCBlock);
37623765
case 'C':
37633766
return popFunctionType(Node::Kind::CFunctionPointer);
3767+
case 'y':
3768+
return popFunctionType(Node::Kind::Coroutine);
37643769
case 'g':
37653770
case 'G':
37663771
return demangleExtendedExistentialShape(specialChar);

lib/Demangling/NodePrinter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,8 @@ class NodePrinter {
656656
case Node::Kind::ObjectiveCProtocolSymbolicReference:
657657
case Node::Kind::DependentGenericInverseConformanceRequirement:
658658
case Node::Kind::DependentGenericParamValueMarker:
659+
case Node::Kind::YieldResult:
660+
case Node::Kind::Coroutine:
659661
return false;
660662
}
661663
printer_unreachable("bad node kind");
@@ -1804,6 +1806,14 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
18041806
Printer << "inout ";
18051807
print(Node->getChild(0), depth + 1);
18061808
return nullptr;
1809+
case Node::Kind::YieldResult:
1810+
Printer << "@yields ";
1811+
print(Node->getChild(0), depth + 1);
1812+
return nullptr;
1813+
case Node::Kind::Coroutine:
1814+
Printer << "@yield_once ";
1815+
print(Node->getChild(0), depth + 1);
1816+
return nullptr;
18071817
case Node::Kind::Isolated:
18081818
Printer << "isolated ";
18091819
print(Node->getChild(0), depth + 1);

lib/Demangling/OldRemangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,16 @@ ManglingError Remangler::mangleImplInvocationSubstitutions(Node *node,
17951795
return ManglingError::Success;
17961796
}
17971797

1798+
ManglingError Remangler::mangleYieldResult(Node *node, unsigned depth) {
1799+
// The old mangler does not encode yield result.
1800+
return ManglingError::Success;
1801+
}
1802+
1803+
ManglingError Remangler::mangleCoroutine(Node *node, unsigned depth) {
1804+
// The old mangler does not encode coroutines.
1805+
return ManglingError::Success;
1806+
}
1807+
17981808
ManglingError Remangler::mangleImplConvention(Node *node, unsigned depth) {
17991809
DEMANGLER_ASSERT(node->getKind() == Node::Kind::ImplConvention, node);
18001810
StringRef text = node->getText();

lib/Demangling/Remangler.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,14 @@ ManglingError Remangler::mangleNoEscapeFunctionType(Node *node,
839839
return ManglingError::Success;
840840
}
841841

842+
ManglingError Remangler::mangleCoroutine(Node *node,
843+
unsigned depth) {
844+
RETURN_IF_ERROR(
845+
mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type
846+
Buffer << "Xy";
847+
return ManglingError::Success;
848+
}
849+
842850
ManglingError Remangler::mangleBoundGenericClass(Node *node, unsigned depth) {
843851
return mangleAnyNominalType(node, depth + 1);
844852
}
@@ -2275,6 +2283,12 @@ ManglingError Remangler::mangleNoDerivative(Node *node, unsigned depth) {
22752283
return ManglingError::Success;
22762284
}
22772285

2286+
ManglingError Remangler::mangleYieldResult(Node *node, unsigned depth) {
2287+
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
2288+
Buffer << "Yy";
2289+
return ManglingError::Success;
2290+
}
2291+
22782292
ManglingError Remangler::mangleInfixOperator(Node *node, unsigned depth) {
22792293
mangleIdentifierImpl(node, /*isOperator*/ true);
22802294
Buffer << "oi";

0 commit comments

Comments
 (0)