Skip to content

Commit 9acaa14

Browse files
committed
Add parsing of @yield_once and @yields attributes and corresponding type checks
1 parent 58bfe07 commit 9acaa14

21 files changed

+176
-76
lines changed

include/swift/AST/AnyFunctionRef.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -311,25 +311,7 @@ class AnyFunctionRef {
311311
private:
312312
ArrayRef<AnyFunctionType::Yield>
313313
getYieldResultsImpl(SmallVectorImpl<AnyFunctionType::Yield> &buffer,
314-
bool mapIntoContext) const {
315-
assert(buffer.empty());
316-
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
317-
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
318-
if (AD->isCoroutine()) {
319-
auto valueTy = AD->getStorage()->getValueInterfaceType()
320-
->getReferenceStorageReferent();
321-
if (mapIntoContext)
322-
valueTy = AD->mapTypeIntoContext(valueTy);
323-
YieldTypeFlags flags(isYieldingMutableAccessor(AD->getAccessorKind())
324-
? ParamSpecifier::InOut
325-
: ParamSpecifier::LegacyShared);
326-
buffer.push_back(AnyFunctionType::Yield(valueTy, flags));
327-
return buffer;
328-
}
329-
}
330-
}
331-
return {};
332-
}
314+
bool mapIntoContext) const;
333315
};
334316
#if SWIFT_COMPILER_IS_MSVC
335317
#pragma warning(pop)

include/swift/AST/TypeAttr.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ TYPE_ATTR(isolated, Isolated)
6868
SIMPLE_TYPE_ATTR(nonisolated, Nonisolated)
6969
SIMPLE_TYPE_ATTR(_addressable, Addressable)
7070
SIMPLE_TYPE_ATTR(concurrent, Concurrent)
71+
SIMPLE_TYPE_ATTR(yields, Yields)
72+
SIMPLE_TYPE_ATTR(yield_once, YieldOnce)
73+
SIMPLE_TYPE_ATTR(yield_once_2, YieldOnce2)
7174

7275
// SIL-specific attributes
7376
SIMPLE_SIL_TYPE_ATTR(async, Async)
@@ -103,9 +106,6 @@ SIL_TYPE_ATTR(opened, Opened)
103106
SIL_TYPE_ATTR(pack_element, PackElement)
104107
SIMPLE_SIL_TYPE_ATTR(pseudogeneric, Pseudogeneric)
105108
SIMPLE_SIL_TYPE_ATTR(unimplementable, Unimplementable)
106-
SIMPLE_SIL_TYPE_ATTR(yields, Yields)
107-
SIMPLE_SIL_TYPE_ATTR(yield_once, YieldOnce)
108-
SIMPLE_SIL_TYPE_ATTR(yield_once_2, YieldOnce2)
109109
SIMPLE_SIL_TYPE_ATTR(yield_many, YieldMany)
110110
SIMPLE_SIL_TYPE_ATTR(captures_generics, CapturesGenerics)
111111
// 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
@@ -418,6 +418,8 @@ NODE(DependentGenericParamValueMarker)
418418
NODE(CoroFunctionPointer)
419419
NODE(DefaultOverride)
420420
NODE(ConstValue)
421+
NODE(YieldResult)
422+
NODE(Coroutine)
421423

422424
#undef CONTEXT_NODE
423425
#undef NODE

include/swift/Parse/Parser.h

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

584584
bool isContextualYieldKeyword() {
585585
return (Tok.isContextualKeyword("yield") &&
586-
isa<AccessorDecl>(CurDeclContext) &&
587-
cast<AccessorDecl>(CurDeclContext)->isCoroutine());
586+
(isa<AbstractFunctionDecl>(CurDeclContext) &&
587+
cast<AbstractFunctionDecl>(CurDeclContext)->isCoroutine()));
588588
}
589589

590590
/// 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
@@ -2805,6 +2805,7 @@ namespace {
28052805
void printCommonFD(FuncDecl *FD, const char *type, Label label) {
28062806
printCommonAFD(FD, type, label);
28072807
printFlag(FD->isStatic(), "static", DeclModifierColor);
2808+
printFlag(FD->isCoroutine(), "@yield_once", DeclModifierColor);
28082809
}
28092810

28102811
void visitFuncDecl(FuncDecl *FD, Label label) {

lib/AST/Decl.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,58 @@ bool AbstractFunctionDecl::isCoroutine() const {
13861386
return false;
13871387
}
13881388

1389+
ArrayRef<AnyFunctionType::Yield>
1390+
AnyFunctionRef::getYieldResultsImpl(SmallVectorImpl<AnyFunctionType::Yield> &buffer,
1391+
bool mapIntoContext) const {
1392+
assert(buffer.empty());
1393+
if (auto *AFD = getAbstractFunctionDecl()) {
1394+
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
1395+
// FIXME: AccessorDecl case is not necessary
1396+
if (AD->isCoroutine()) {
1397+
auto valueTy = AD->getStorage()->getValueInterfaceType()
1398+
->getReferenceStorageReferent();
1399+
if (mapIntoContext)
1400+
valueTy = AFD->mapTypeIntoContext(valueTy);
1401+
YieldTypeFlags flags(isYieldingMutableAccessor(AD->getAccessorKind())
1402+
? ParamSpecifier::InOut
1403+
: ParamSpecifier::LegacyShared);
1404+
buffer.push_back(AnyFunctionType::Yield(valueTy, flags));
1405+
return buffer;
1406+
}
1407+
} else if (AFD->isCoroutine()) {
1408+
auto resType = AFD->getInterfaceType()->castTo<FunctionType>()->getResult();
1409+
if (auto *resFnType = resType->getAs<FunctionType>())
1410+
resType = resFnType->getResult();
1411+
1412+
if (resType->hasError())
1413+
return {};
1414+
1415+
auto addYieldInfo =
1416+
[&](const YieldResultType *yieldResultTy) {
1417+
Type valueTy = yieldResultTy->getResultType();
1418+
if (mapIntoContext)
1419+
valueTy = AFD->mapTypeIntoContext(valueTy);
1420+
YieldTypeFlags flags(yieldResultTy->isInOut() ?
1421+
ParamSpecifier::InOut : ParamSpecifier::LegacyShared);
1422+
buffer.push_back(AnyFunctionType::Yield(valueTy, flags));
1423+
};
1424+
1425+
if (auto *tupleResTy = resType->getAs<TupleType>())
1426+
for (const auto &elt : tupleResTy->getElements()) {
1427+
Type eltTy = elt.getType();
1428+
if (auto *yieldResTy = eltTy->getAs<YieldResultType>())
1429+
addYieldInfo(yieldResTy);
1430+
}
1431+
else
1432+
addYieldInfo(resType->castTo<YieldResultType>());
1433+
1434+
return buffer;
1435+
}
1436+
}
1437+
return {};
1438+
}
1439+
1440+
13891441
bool ParameterList::hasInternalParameter(StringRef Prefix) const {
13901442
for (auto param : *this) {
13911443
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
@@ -1018,6 +1018,9 @@ NodePointer Demangler::demangleTypeAnnotation() {
10181018
case 'u':
10191019
return createType(
10201020
createWithChild(Node::Kind::Sending, popTypeAndGetChild()));
1021+
case 'y':
1022+
return createType(
1023+
createWithChild(Node::Kind::YieldResult, popTypeAndGetChild()));
10211024
default:
10221025
return nullptr;
10231026
}
@@ -3870,6 +3873,8 @@ NodePointer Demangler::demangleSpecialType() {
38703873
return popFunctionType(Node::Kind::ObjCBlock);
38713874
case 'C':
38723875
return popFunctionType(Node::Kind::CFunctionPointer);
3876+
case 'y':
3877+
return popFunctionType(Node::Kind::Coroutine);
38733878
case 'g':
38743879
case 'G':
38753880
return demangleExtendedExistentialShape(specialChar);

lib/Demangling/NodePrinter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,8 @@ bool NodePrinter::isSimpleType(NodePointer Node) {
622622
case Node::Kind::DependentGenericParamValueMarker:
623623
case Node::Kind::CoroFunctionPointer:
624624
case Node::Kind::DefaultOverride:
625+
case Node::Kind::YieldResult:
626+
case Node::Kind::Coroutine:
625627
return false;
626628
}
627629
printer_unreachable("bad node kind");
@@ -1798,6 +1800,14 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
17981800
Printer << "inout ";
17991801
print(Node->getChild(0), depth + 1);
18001802
return nullptr;
1803+
case Node::Kind::YieldResult:
1804+
Printer << "@yields ";
1805+
print(Node->getChild(0), depth + 1);
1806+
return nullptr;
1807+
case Node::Kind::Coroutine:
1808+
Printer << "@yield_once ";
1809+
print(Node->getChild(0), depth + 1);
1810+
return nullptr;
18011811
case Node::Kind::Isolated:
18021812
Printer << "isolated ";
18031813
print(Node->getChild(0), depth + 1);

lib/Demangling/OldRemangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,16 @@ ManglingError Remangler::mangleImplInvocationSubstitutions(Node *node,
18231823
return ManglingError::Success;
18241824
}
18251825

1826+
ManglingError Remangler::mangleYieldResult(Node *node, unsigned depth) {
1827+
// The old mangler does not encode yield result.
1828+
return ManglingError::Success;
1829+
}
1830+
1831+
ManglingError Remangler::mangleCoroutine(Node *node, unsigned depth) {
1832+
// The old mangler does not encode coroutines.
1833+
return ManglingError::Success;
1834+
}
1835+
18261836
ManglingError Remangler::mangleImplConvention(Node *node, unsigned depth) {
18271837
DEMANGLER_ASSERT(node->getKind() == Node::Kind::ImplConvention, node);
18281838
StringRef text = node->getText();

lib/Demangling/Remangler.cpp

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

843+
ManglingError Remangler::mangleCoroutine(Node *node,
844+
unsigned depth) {
845+
RETURN_IF_ERROR(
846+
mangleChildNodesReversed(node, depth + 1)); // argument tuple, result type
847+
Buffer << "Xy";
848+
return ManglingError::Success;
849+
}
850+
843851
ManglingError Remangler::mangleBoundGenericClass(Node *node, unsigned depth) {
844852
return mangleAnyNominalType(node, depth + 1);
845853
}
@@ -2330,6 +2338,12 @@ ManglingError Remangler::mangleNoDerivative(Node *node, unsigned depth) {
23302338
return ManglingError::Success;
23312339
}
23322340

2341+
ManglingError Remangler::mangleYieldResult(Node *node, unsigned depth) {
2342+
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
2343+
Buffer << "Yy";
2344+
return ManglingError::Success;
2345+
}
2346+
23332347
ManglingError Remangler::mangleInfixOperator(Node *node, unsigned depth) {
23342348
mangleIdentifierImpl(node, /*isOperator*/ true);
23352349
Buffer << "oi";

0 commit comments

Comments
 (0)