Skip to content

Commit f591680

Browse files
committed
Update SIL printing of @Lifetime
Lifetime dependencies in SIL tests continue to be represented as a type modifier on the target. As before, they are represented as a LifetimeDependentTypeRepr in the AST.
1 parent 8e8b21e commit f591680

File tree

4 files changed

+54
-36
lines changed

4 files changed

+54
-36
lines changed

include/swift/Parse/Parser.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,9 @@ class Parser {
12011201

12021202
bool isParameterSpecifier() {
12031203
if (Tok.is(tok::kw_inout)) return true;
1204+
if (Context.LangOpts.hasFeature(Feature::NonescapableTypes) &&
1205+
isSILLifetimeDependenceToken())
1206+
return true;
12041207
if (!canHaveParameterSpecifierContextualKeyword()) return false;
12051208
if (Tok.isContextualKeyword("__shared") ||
12061209
Tok.isContextualKeyword("__owned") ||
@@ -1212,9 +1215,6 @@ class Parser {
12121215
if (Context.LangOpts.hasFeature(Feature::SendingArgsAndResults) &&
12131216
Tok.isContextualKeyword("sending"))
12141217
return true;
1215-
if (Context.LangOpts.hasFeature(Feature::NonescapableTypes) &&
1216-
isLifetimeDependenceToken())
1217-
return true;
12181218
return false;
12191219
}
12201220

@@ -1225,9 +1225,9 @@ class Parser {
12251225
consumeToken();
12261226
}
12271227

1228-
bool isLifetimeDependenceToken() {
1229-
return isInSILMode() && (Tok.isContextualKeyword("_inherit") ||
1230-
Tok.isContextualKeyword("_scope"));
1228+
bool isSILLifetimeDependenceToken() {
1229+
return isInSILMode() && Tok.is(tok::at_sign) &&
1230+
(peekToken().isContextualKeyword("lifetime"));
12311231
}
12321232

12331233
bool canHaveParameterSpecifierContextualKeyword() {
@@ -1248,7 +1248,7 @@ class Parser {
12481248
return true;
12491249
}
12501250

1251-
return isLifetimeDependenceToken();
1251+
return false;
12521252
}
12531253

12541254
bool parseConventionAttributeInternal(SourceLoc atLoc, SourceLoc attrLoc,

lib/AST/LifetimeDependence.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,39 @@ getLifetimeDependenceFor(ArrayRef<LifetimeDependenceInfo> lifetimeDependencies,
4545
}
4646

4747
std::string LifetimeDependenceInfo::getString() const {
48-
std::string lifetimeDependenceString;
49-
auto getOnIndices = [](IndexSubset *bitvector) {
48+
std::string lifetimeDependenceString = "@lifetime(";
49+
auto getSourceString = [](IndexSubset *bitvector, StringRef kind) {
5050
std::string result;
5151
bool isFirstSetBit = true;
5252
for (unsigned i = 0; i < bitvector->getCapacity(); i++) {
5353
if (bitvector->contains(i)) {
5454
if (!isFirstSetBit) {
5555
result += ", ";
5656
}
57+
result += kind;
5758
result += std::to_string(i);
5859
isFirstSetBit = false;
5960
}
6061
}
6162
return result;
6263
};
63-
if (inheritLifetimeParamIndices && !inheritLifetimeParamIndices->isEmpty()) {
64-
lifetimeDependenceString =
65-
"_inherit(" + getOnIndices(inheritLifetimeParamIndices) + ") ";
64+
if (inheritLifetimeParamIndices) {
65+
assert(!inheritLifetimeParamIndices->isEmpty());
66+
lifetimeDependenceString +=
67+
getSourceString(inheritLifetimeParamIndices, "copy ");
6668
}
67-
if (scopeLifetimeParamIndices && !scopeLifetimeParamIndices->isEmpty()) {
69+
if (scopeLifetimeParamIndices) {
70+
assert(!scopeLifetimeParamIndices->isEmpty());
71+
if (inheritLifetimeParamIndices) {
72+
lifetimeDependenceString += ", ";
73+
}
6874
lifetimeDependenceString +=
69-
"_scope(" + getOnIndices(scopeLifetimeParamIndices) + ") ";
75+
getSourceString(scopeLifetimeParamIndices, "borrow ");
76+
}
77+
if (isImmortal()) {
78+
lifetimeDependenceString += "immortal";
7079
}
80+
lifetimeDependenceString += ") ";
7181
return lifetimeDependenceString;
7282
}
7383

lib/Parse/ParseDecl.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5138,17 +5138,24 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
51385138
llvm_unreachable("bad attribute kind");
51395139
}
51405140

5141-
static ParsedLifetimeDependenceKind getSILLifetimeDependenceKind(const Token &T) {
5142-
if (T.isContextualKeyword("_inherit")) {
5143-
return ParsedLifetimeDependenceKind::Inherit;
5144-
}
5145-
assert(T.isContextualKeyword("_scope"));
5146-
return ParsedLifetimeDependenceKind::Scope;
5147-
}
5148-
51495141
ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
51505142
ParserStatus status;
51515143

5144+
auto getLifetimeDependenceKind =
5145+
[&](Token Tok) -> std::optional<ParsedLifetimeDependenceKind> {
5146+
if (Tok.isContextualKeyword("copy") &&
5147+
peekToken().isAny(tok::identifier, tok::integer_literal,
5148+
tok::kw_self)) {
5149+
return ParsedLifetimeDependenceKind::Inherit;
5150+
}
5151+
if (Tok.isContextualKeyword("borrow") &&
5152+
peekToken().isAny(tok::identifier, tok::integer_literal,
5153+
tok::kw_self)) {
5154+
return ParsedLifetimeDependenceKind::Scope;
5155+
}
5156+
return std::nullopt;
5157+
};
5158+
51525159
if (!Tok.isFollowingLParen()) {
51535160
diagnose(loc, diag::expected_lparen_after_lifetime_dependence);
51545161
status.setIsParseError();
@@ -5176,13 +5183,14 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
51765183
diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
51775184
ParserStatus listStatus;
51785185
foundParamId = true;
5186+
51795187
auto lifetimeDependenceKind = ParsedLifetimeDependenceKind::Default;
5180-
if (Tok.isContextualKeyword("borrow") &&
5181-
peekToken().isAny(tok::identifier, tok::integer_literal,
5182-
tok::kw_self)) {
5183-
lifetimeDependenceKind = ParsedLifetimeDependenceKind::Scope;
5188+
auto result = getLifetimeDependenceKind(Tok);
5189+
if (result.has_value()) {
5190+
lifetimeDependenceKind = *result;
51845191
consumeToken();
51855192
}
5193+
51865194
auto sourceDescriptor =
51875195
parseLifetimeDescriptor(*this, lifetimeDependenceKind);
51885196
if (!sourceDescriptor) {
@@ -5462,7 +5470,6 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
54625470
PatternBindingInitializer *initContext = nullptr;
54635471
auto &Tok = P.Tok;
54645472
while (P.isParameterSpecifier()) {
5465-
54665473
if (Tok.isContextualKeyword("isolated")) {
54675474
Tok.setKind(tok::contextual_keyword);
54685475
auto kwLoc = P.consumeToken();
@@ -5506,13 +5513,14 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
55065513
continue;
55075514
}
55085515

5509-
if (P.isLifetimeDependenceToken()) {
5516+
if (P.isSILLifetimeDependenceToken()) {
55105517
if (!P.Context.LangOpts.hasFeature(Feature::NonescapableTypes)) {
55115518
P.diagnose(Tok, diag::requires_experimental_feature,
55125519
"lifetime dependence specifier", false,
55135520
getFeatureName(Feature::NonescapableTypes));
55145521
}
5515-
auto loc = P.consumeToken();
5522+
P.consumeToken(); // consume '@'
5523+
auto loc = P.consumeToken(); // consume 'lifetime'
55165524
auto result = P.parseLifetimeEntry(loc);
55175525
if (result.isNull()) {
55185526
status |= result;

test/Interop/Cxx/class/nonescapable-lifetimebound.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ private:
6969
};
7070

7171
// CHECK: sil [clang makeOwner] {{.*}}: $@convention(c) () -> Owner
72-
// CHECK: sil [clang getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> _scope(0) @autoreleased View
73-
// CHECK: sil [clang getViewFromFirst] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> _scope(0) @autoreleased View
74-
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> _scope(0, 1) @autoreleased View
75-
// CHECK: sil [clang Owner.handOutView] {{.*}} : $@convention(cxx_method) (@in_guaranteed Owner) -> _scope(0) @autoreleased View
76-
// CHECK: sil [clang Owner.handOutView2] {{.*}} : $@convention(cxx_method) (View, @in_guaranteed Owner) -> _scope(1) @autoreleased View
77-
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@guaranteed View, @guaranteed View) -> _inherit(0, 1) @autoreleased View
72+
// CHECK: sil [clang getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> _lifetime(_borrow 0) @autoreleased View
73+
// CHECK: sil [clang getViewFromFirst] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> _lifetime(_borrow 0) @autoreleased View
74+
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> _lifetime(_borrow 0, _borrow 1) @autoreleased View
75+
// CHECK: sil [clang Owner.handOutView] {{.*}} : $@convention(cxx_method) (@in_guaranteed Owner) -> _lifetime(_borrow 0) @autoreleased View
76+
// CHECK: sil [clang Owner.handOutView2] {{.*}} : $@convention(cxx_method) (View, @in_guaranteed Owner) -> _lifetime(_borrow 1) @autoreleased View
77+
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@guaranteed View, @guaranteed View) -> _lifetime(_copy 0, _copy 1) @autoreleased View
7878
// CHECK: sil [clang View.init] {{.*}} : $@convention(c) () -> @out View
7979

8080
//--- test.swift
@@ -91,4 +91,4 @@ public func test() {
9191
let _ = o.handOutView2(v1)
9292
let _ = getViewFromEither(v1, v2)
9393
let defaultView = View()
94-
}
94+
}

0 commit comments

Comments
 (0)