Skip to content

Commit 7d2ff43

Browse files
committed
Update mangling to support lifetime dependence in parameter position
1 parent 1549894 commit 7d2ff43

File tree

11 files changed

+109
-146
lines changed

11 files changed

+109
-146
lines changed

docs/ABI/Mangling.rst

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ Types
727727
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
728728
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
729729

730-
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? self-lifetime-dependence? // results and parameters
730+
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? // results and parameters
731731

732732
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
733733
// with optional inout convention, shared convention. parameters don't have labels,
@@ -749,10 +749,8 @@ Types
749749
differentiable ::= 'Yjd' // @differentiable on function type
750750
differentiable ::= 'Yjl' // @differentiable(_linear) on function type
751751
#if SWIFT_RUNTIME_VERSION >= 5.TBD
752-
lifetime-dependence ::= 'Yli' // inherit lifetime dependence on param
753-
lifetime-dependence ::= 'Yls' // scoped lifetime dependence on param
754-
self-lifetime-dependence ::= 'YLi' // inherit lifetime dependence on self
755-
self-lifetime-dependence ::= 'YLs' // scoped lifetime dependence on self
752+
lifetime-dependence ::= 'Yli' INDEX-SUBSET '_' // inherit lifetime dependence
753+
lifetime-dependence ::= 'Yls' INDEX-SUBSET '_' // scoped lifetime dependence
756754
#endif
757755
type-list ::= list-type '_' list-type* // list of types
758756
type-list ::= empty-list

include/swift/AST/ASTMangler.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -556,14 +556,15 @@ class ASTMangler : public Mangler {
556556
FunctionManglingKind functionMangling,
557557
bool isRecursedInto = true);
558558

559-
void appendFunctionInputType(ArrayRef<AnyFunctionType::Param> params,
560-
LifetimeDependenceInfo lifetimeDependenceInfo,
559+
void appendFunctionInputType(AnyFunctionType *fnType,
560+
ArrayRef<AnyFunctionType::Param> params,
561561
GenericSignature sig,
562562
const ValueDecl *forDecl = nullptr,
563563
bool isRecursedInto = true);
564-
void appendFunctionResultType(Type resultType,
565-
GenericSignature sig,
566-
const ValueDecl *forDecl = nullptr);
564+
void appendFunctionResultType(
565+
Type resultType, GenericSignature sig,
566+
std::optional<LifetimeDependenceInfo> lifetimeDependence,
567+
const ValueDecl *forDecl = nullptr);
567568

568569
void appendTypeList(Type listTy, GenericSignature sig,
569570
const ValueDecl *forDecl = nullptr);
@@ -573,7 +574,7 @@ class ASTMangler : public Mangler {
573574
const ValueDecl *forDecl = nullptr);
574575
void appendParameterTypeListElement(
575576
Identifier name, Type elementType, ParameterTypeFlags flags,
576-
std::optional<LifetimeDependenceKind> lifetimeDependenceKind,
577+
std::optional<LifetimeDependenceInfo> lifetimeDependence,
577578
GenericSignature sig, const ValueDecl *forDecl = nullptr);
578579
void appendTupleTypeListElement(Identifier name, Type elementType,
579580
GenericSignature sig,
@@ -749,8 +750,7 @@ class ASTMangler : public Mangler {
749750
void appendConstrainedExistential(Type base, GenericSignature sig,
750751
const ValueDecl *forDecl);
751752

752-
void appendLifetimeDependenceKind(LifetimeDependenceKind kind,
753-
bool isSelfDependence);
753+
void appendLifetimeDependence(LifetimeDependenceInfo info);
754754
};
755755

756756
} // end namespace Mangle

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,7 @@ NODE(AsyncRemoved)
389389

390390
// Added in Swift 5.TBD
391391
NODE(ObjectiveCProtocolSymbolicReference)
392-
NODE(ParamLifetimeDependence)
393-
NODE(SelfLifetimeDependence)
392+
NODE(LifetimeDependence)
394393

395394
NODE(OutlinedInitializeWithCopyNoValueWitness)
396395
NODE(OutlinedAssignWithTakeNoValueWitness)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ class Demangler : public NodeFactory {
635635
bool demangleBoundGenerics(Vector<NodePointer> &TypeListList,
636636
NodePointer &RetroactiveConformances);
637637

638-
NodePointer demangleLifetimeDependenceKind(bool isSelfDependence);
638+
NodePointer demangleLifetimeDependence();
639639

640640
void dump();
641641

lib/AST/ASTDemangler.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,14 @@ Type ASTBuilder::createFunctionType(
469469
representation);
470470

471471
// TODO: Handle LifetimeDependenceInfo here.
472-
auto einfo = FunctionType::ExtInfoBuilder(
473-
representation, noescape, flags.isThrowing(), thrownError,
474-
resultDiffKind, clangFunctionType, isolation,
475-
LifetimeDependenceInfo(), extFlags.hasSendingResult())
476-
.withAsync(flags.isAsync())
477-
.withSendable(flags.isSendable())
478-
.build();
472+
auto einfo =
473+
FunctionType::ExtInfoBuilder(
474+
representation, noescape, flags.isThrowing(), thrownError,
475+
resultDiffKind, clangFunctionType, isolation,
476+
/*LifetimeDependenceInfo*/ std::nullopt, extFlags.hasSendingResult())
477+
.withAsync(flags.isAsync())
478+
.withSendable(flags.isSendable())
479+
.build();
479480

480481
return FunctionType::get(funcParams, output, einfo);
481482
}
@@ -688,11 +689,12 @@ Type ASTBuilder::createImplFunctionType(
688689
clangFnType = getASTContext().getCanonicalClangFunctionType(
689690
funcParams, result, representation);
690691
}
691-
auto einfo = SILFunctionType::ExtInfoBuilder(
692-
representation, flags.isPseudogeneric(), !flags.isEscaping(),
693-
flags.isSendable(), flags.isAsync(), unimplementable,
694-
isolation, diffKind, clangFnType, LifetimeDependenceInfo())
695-
.build();
692+
auto einfo =
693+
SILFunctionType::ExtInfoBuilder(
694+
representation, flags.isPseudogeneric(), !flags.isEscaping(),
695+
flags.isSendable(), flags.isAsync(), unimplementable, isolation,
696+
diffKind, clangFnType, /*LifetimeDependenceInfo*/ std::nullopt)
697+
.build();
696698

697699
return SILFunctionType::get(genericSig, einfo, funcCoroutineKind,
698700
funcCalleeConvention, funcParams, funcYields,

lib/AST/ASTMangler.cpp

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,9 +3052,11 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
30523052
const ValueDecl *forDecl,
30533053
FunctionManglingKind functionMangling,
30543054
bool isRecursedInto) {
3055-
appendFunctionResultType(fn->getResult(), sig, forDecl);
3056-
appendFunctionInputType(fn->getParams(), fn->getLifetimeDependenceInfo(), sig,
3057-
forDecl, isRecursedInto);
3055+
appendFunctionResultType(fn->getResult(), sig,
3056+
forDecl ? fn->getLifetimeDependenceForResult(forDecl)
3057+
: std::nullopt,
3058+
forDecl);
3059+
appendFunctionInputType(fn, fn->getParams(), sig, forDecl, isRecursedInto);
30583060
if (fn->isAsync())
30593061
appendOperator("Ya");
30603062
if (fn->isSendable())
@@ -3105,18 +3107,6 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
31053107
if (isRecursedInto && fn->hasSendingResult()) {
31063108
appendOperator("YT");
31073109
}
3108-
3109-
if (auto *afd = dyn_cast_or_null<AbstractFunctionDecl>(forDecl)) {
3110-
if (afd->hasImplicitSelfDecl()) {
3111-
auto lifetimeDependenceKind =
3112-
fn->getLifetimeDependenceInfo().getLifetimeDependenceOnParam(
3113-
/*selfIndex*/ afd->getParameters()->size());
3114-
if (lifetimeDependenceKind) {
3115-
appendLifetimeDependenceKind(*lifetimeDependenceKind,
3116-
/*isSelfDependence*/ true);
3117-
}
3118-
}
3119-
}
31203110
}
31213111

31223112
static ParamSpecifier
@@ -3189,9 +3179,8 @@ getParameterFlagsForMangling(ParameterTypeFlags flags,
31893179
}
31903180

31913181
void ASTMangler::appendFunctionInputType(
3192-
ArrayRef<AnyFunctionType::Param> params,
3193-
LifetimeDependenceInfo lifetimeDependenceInfo, GenericSignature sig,
3194-
const ValueDecl *forDecl, bool isRecursedInto) {
3182+
AnyFunctionType *fnType, ArrayRef<AnyFunctionType::Param> params,
3183+
GenericSignature sig, const ValueDecl *forDecl, bool isRecursedInto) {
31953184
auto defaultSpecifier = getDefaultOwnership(forDecl);
31963185

31973186
switch (params.size()) {
@@ -3215,8 +3204,8 @@ void ASTMangler::appendFunctionInputType(
32153204
Identifier(), type,
32163205
getParameterFlagsForMangling(param.getParameterFlags(),
32173206
defaultSpecifier, isRecursedInto),
3218-
lifetimeDependenceInfo.getLifetimeDependenceOnParam(/*paramIndex*/ 0),
3219-
sig, nullptr);
3207+
getLifetimeDependenceFor(fnType->getLifetimeDependencies(), 0), sig,
3208+
nullptr);
32203209
break;
32213210
}
32223211

@@ -3237,8 +3226,9 @@ void ASTMangler::appendFunctionInputType(
32373226
Identifier(), param.getPlainType(),
32383227
getParameterFlagsForMangling(param.getParameterFlags(),
32393228
defaultSpecifier, isRecursedInto),
3240-
lifetimeDependenceInfo.getLifetimeDependenceOnParam(paramIndex), sig,
3241-
nullptr);
3229+
getLifetimeDependenceFor(fnType->getLifetimeDependencies(),
3230+
paramIndex),
3231+
sig, nullptr);
32423232
appendListSeparator(isFirstParam);
32433233
paramIndex++;
32443234
}
@@ -3247,10 +3237,19 @@ void ASTMangler::appendFunctionInputType(
32473237
}
32483238
}
32493239

3250-
void ASTMangler::appendFunctionResultType(Type resultType, GenericSignature sig,
3251-
const ValueDecl *forDecl) {
3252-
return resultType->isVoid() ? appendOperator("y")
3253-
: appendType(resultType, sig, forDecl);
3240+
void ASTMangler::appendFunctionResultType(
3241+
Type resultType, GenericSignature sig,
3242+
std::optional<LifetimeDependenceInfo> lifetimeDependence,
3243+
const ValueDecl *forDecl) {
3244+
if (resultType->isVoid()) {
3245+
appendOperator("y");
3246+
} else {
3247+
appendType(resultType, sig, forDecl);
3248+
}
3249+
3250+
if (lifetimeDependence.has_value()) {
3251+
appendLifetimeDependence(*lifetimeDependence);
3252+
}
32543253
}
32553254

32563255
void ASTMangler::appendTypeList(Type listTy, GenericSignature sig,
@@ -3272,7 +3271,7 @@ void ASTMangler::appendTypeList(Type listTy, GenericSignature sig,
32723271

32733272
void ASTMangler::appendParameterTypeListElement(
32743273
Identifier name, Type elementType, ParameterTypeFlags flags,
3275-
std::optional<LifetimeDependenceKind> lifetimeDependenceKind,
3274+
std::optional<LifetimeDependenceInfo> lifetimeDependence,
32763275
GenericSignature sig, const ValueDecl *forDecl) {
32773276
if (auto *fnType = elementType->getAs<FunctionType>())
32783277
appendFunctionType(fnType, sig, flags.isAutoClosure(), forDecl);
@@ -3303,9 +3302,8 @@ void ASTMangler::appendParameterTypeListElement(
33033302
if (flags.isCompileTimeConst())
33043303
appendOperator("Yt");
33053304

3306-
if (lifetimeDependenceKind) {
3307-
appendLifetimeDependenceKind(*lifetimeDependenceKind,
3308-
/*isSelfDependence*/ false);
3305+
if (lifetimeDependence) {
3306+
appendLifetimeDependence(*lifetimeDependence);
33093307
}
33103308

33113309
if (!name.empty())
@@ -3314,21 +3312,18 @@ void ASTMangler::appendParameterTypeListElement(
33143312
appendOperator("d");
33153313
}
33163314

3317-
void ASTMangler::appendLifetimeDependenceKind(LifetimeDependenceKind kind,
3318-
bool isSelfDependence) {
3319-
if (kind == LifetimeDependenceKind::Scope) {
3320-
if (isSelfDependence) {
3321-
appendOperator("YLs");
3322-
} else {
3323-
appendOperator("Yls");
3324-
}
3325-
} else {
3326-
assert(kind == LifetimeDependenceKind::Inherit);
3327-
if (isSelfDependence) {
3328-
appendOperator("YLi");
3329-
} else {
3330-
appendOperator("Yli");
3331-
}
3315+
void ASTMangler::appendLifetimeDependence(LifetimeDependenceInfo info) {
3316+
if (auto *inheritIndices = info.getInheritIndices()) {
3317+
assert(!inheritIndices->isEmpty());
3318+
appendOperator("Yli");
3319+
appendIndexSubset(inheritIndices);
3320+
appendOperator("_");
3321+
}
3322+
if (auto *scopeIndices = info.getScopeIndices()) {
3323+
assert(!scopeIndices->isEmpty());
3324+
appendOperator("Yls");
3325+
appendIndexSubset(scopeIndices);
3326+
appendOperator("_");
33323327
}
33333328
}
33343329

lib/Demangling/Demangler.cpp

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -990,10 +990,11 @@ NodePointer Demangler::demangleTypeAnnotation() {
990990
case 'u':
991991
return createType(
992992
createWithChild(Node::Kind::Sending, popTypeAndGetChild()));
993-
case 'l':
994-
return demangleLifetimeDependenceKind(/*isSelfDependence*/ false);
995-
case 'L':
996-
return demangleLifetimeDependenceKind(/*isSelfDependence*/ true);
993+
case 'l': {
994+
auto *node = demangleLifetimeDependence();
995+
addChild(node, popTypeAndGetChild());
996+
return createType(node);
997+
}
997998
default:
998999
return nullptr;
9991000
}
@@ -1594,7 +1595,6 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
15941595
ClangType = demangleClangType();
15951596
}
15961597
addChild(FuncType, ClangType);
1597-
addChild(FuncType, popNode(Node::Kind::SelfLifetimeDependence));
15981598
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
15991599
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
16001600
addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType));
@@ -1637,9 +1637,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16371637
return nullptr;
16381638

16391639
unsigned FirstChildIdx = 0;
1640-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1641-
Node::Kind::SelfLifetimeDependence)
1642-
++FirstChildIdx;
16431640
if (FuncType->getChild(FirstChildIdx)->getKind()
16441641
== Node::Kind::GlobalActorFunctionType)
16451642
++FirstChildIdx;
@@ -1663,9 +1660,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16631660
if (FuncType->getChild(FirstChildIdx)->getKind()
16641661
== Node::Kind::AsyncAnnotation)
16651662
++FirstChildIdx;
1666-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1667-
Node::Kind::ParamLifetimeDependence)
1668-
++FirstChildIdx;
16691663
auto ParameterType = FuncType->getChild(FirstChildIdx);
16701664

16711665
assert(ParameterType->getKind() == Node::Kind::ArgumentTuple);
@@ -3161,26 +3155,29 @@ NodePointer Demangler::demangleDifferentiableFunctionType() {
31613155
Node::Kind::DifferentiableFunctionType, (Node::IndexType)kind);
31623156
}
31633157

3164-
NodePointer Demangler::demangleLifetimeDependenceKind(bool isSelfDependence) {
3165-
MangledLifetimeDependenceKind kind;
3166-
switch (auto c = nextChar()) {
3158+
static std::optional<MangledLifetimeDependenceKind>
3159+
getMangledLifetimeDependenceKind(char nextChar) {
3160+
switch (auto c = nextChar) {
31673161
case 's':
3168-
kind = MangledLifetimeDependenceKind::Scope;
3169-
break;
3162+
return MangledLifetimeDependenceKind::Scope;
31703163
case 'i':
3171-
kind = MangledLifetimeDependenceKind::Inherit;
3172-
break;
3173-
default:
3174-
return nullptr;
3164+
return MangledLifetimeDependenceKind::Inherit;
31753165
}
3176-
if (isSelfDependence) {
3177-
return createNode(Node::Kind::SelfLifetimeDependence,
3178-
(Node::IndexType)kind);
3166+
return std::nullopt;
3167+
}
3168+
3169+
NodePointer Demangler::demangleLifetimeDependence() {
3170+
auto kind = getMangledLifetimeDependenceKind(nextChar());
3171+
if (!kind.has_value()) {
3172+
return nullptr;
31793173
}
3180-
auto node = createWithChildren(Node::Kind::ParamLifetimeDependence,
3181-
createNode(Node::Kind::Index, unsigned(kind)),
3182-
popTypeAndGetChild());
3183-
return createType(node);
3174+
auto result = createNode(Node::Kind::LifetimeDependence);
3175+
result =
3176+
addChild(result, createNode(Node::Kind::Index, (Node::IndexType)*kind));
3177+
result = addChild(result, demangleIndexSubset());
3178+
if (!nextIf('_'))
3179+
return nullptr;
3180+
return result;
31843181
}
31853182

31863183
std::string Demangler::demangleBridgedMethodParams() {

0 commit comments

Comments
 (0)