Skip to content

Commit 00843da

Browse files
authored
Merge pull request #17752 from rjmccall/minor-nfc
2 parents 471af31 + a3bdc89 commit 00843da

15 files changed

+98
-48
lines changed

include/swift/AST/ASTScope.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,14 @@ class ASTScope {
489489
/// introduced by this statement.
490490
static ASTScope *createIfNeeded(const ASTScope *parent, Stmt *stmt);
491491

492-
/// Create a new AST scope if one is needed for the given expression.
492+
/// Create a new AST scope if one is needed for the given child expression(s).
493+
/// In the first variant, the expression can be \c null.
493494
///
494495
/// \returns the newly-created AST scope, or \c null if there is no scope
495496
/// introduced by this expression.
496-
static ASTScope *createIfNeeded(const ASTScope *parent, Expr *Expr);
497+
static ASTScope *createIfNeeded(const ASTScope *parent, Expr *expr);
498+
static ASTScope *createIfNeeded(const ASTScope *parent,
499+
ArrayRef<Expr *> exprs);
497500

498501
/// Create a new AST scope if one is needed for the given AST node.
499502
///

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4134,6 +4134,9 @@ class AbstractStorageDecl : public ValueDecl {
41344134
/// is a member. Currently only variables can be static.
41354135
inline bool isStatic() const; // defined in this header
41364136

4137+
/// \brief Return the interface type of the stored value.
4138+
Type getValueInterfaceType() const;
4139+
41374140
/// \brief Determine how this storage is implemented.
41384141
StorageImplInfo getImplInfo() const {
41394142
if (auto ptr = Accessors.getPointer())

lib/AST/ASTScope.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,9 +1070,8 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Stmt *stmt) {
10701070
}
10711071

10721072
/// Find all of the (non-nested) closures referenced within this expression.
1073-
static SmallVector<ClosureExpr *, 4> findClosures(Expr *expr) {
1074-
SmallVector<ClosureExpr *, 4> closures;
1075-
if (!expr) return closures;
1073+
static void findClosures(Expr *expr, SmallVectorImpl<ClosureExpr *> &closures) {
1074+
if (!expr) return;
10761075

10771076
/// AST walker that finds top-level closures in an expression.
10781077
class ClosureFinder : public ASTWalker {
@@ -1110,14 +1109,20 @@ static SmallVector<ClosureExpr *, 4> findClosures(Expr *expr) {
11101109
};
11111110

11121111
expr->walk(ClosureFinder(closures));
1113-
return closures;
11141112
}
11151113

11161114
ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Expr *expr) {
11171115
if (!expr) return nullptr;
1116+
return createIfNeeded(parent, llvm::makeArrayRef(expr));
1117+
}
1118+
1119+
ASTScope *ASTScope::createIfNeeded(const ASTScope *parent,
1120+
ArrayRef<Expr *> exprs) {
1121+
SmallVector<ClosureExpr*, 4> closures;
11181122

1119-
// Dig out closure expressions within the given expression.
1120-
auto closures = findClosures(expr);
1123+
// Dig out closure expressions within the given expressions.
1124+
for (auto expr: exprs)
1125+
findClosures(expr, closures);
11211126
if (closures.empty())
11221127
return nullptr;
11231128

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4071,6 +4071,12 @@ SourceLoc AbstractStorageDecl::getOverrideLoc() const {
40714071
return SourceLoc();
40724072
}
40734073

4074+
Type AbstractStorageDecl::getValueInterfaceType() const {
4075+
if (auto var = dyn_cast<VarDecl>(this))
4076+
return var->getInterfaceType();
4077+
return cast<SubscriptDecl>(this)->getElementInterfaceType();
4078+
}
4079+
40744080
Type VarDecl::getType() const {
40754081
if (!typeInContext) {
40764082
const_cast<VarDecl *>(this)->typeInContext =

lib/ClangImporter/ImporterImpl.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -625,11 +625,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
625625
} else if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
626626
assert(CD->getInterfaceType());
627627
ty = CD->getResultInterfaceType();
628-
} else if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
629-
ty = SD->getElementInterfaceType();
630628
} else {
631-
auto *VD = cast<VarDecl>(decl);
632-
ty = VD->getInterfaceType()->getReferenceStorageReferent();
629+
ty = cast<AbstractStorageDecl>(decl)->getValueInterfaceType()
630+
->getReferenceStorageReferent();
633631
}
634632
#endif
635633

lib/SILGen/Cleanup.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void CleanupManager::popTopDeadCleanups(CleanupsDepth end) {
5656
}
5757

5858
void CleanupManager::emitCleanups(CleanupsDepth depth, CleanupLocation loc,
59-
bool popCleanups) {
59+
ForUnwind_t forUnwind, bool popCleanups) {
6060
auto begin = stack.stable_begin();
6161
while (begin != depth) {
6262
auto iter = stack.find(begin);
@@ -76,7 +76,7 @@ void CleanupManager::emitCleanups(CleanupsDepth depth, CleanupLocation loc,
7676
stack.pop();
7777

7878
if (cleanup.isActive() && SGF.B.hasValidInsertionPoint())
79-
cleanup.emit(SGF, loc);
79+
cleanup.emit(SGF, loc, forUnwind);
8080

8181
stack.checkIterator(begin);
8282
}
@@ -95,7 +95,7 @@ void CleanupManager::endScope(CleanupsDepth depth, CleanupLocation loc) {
9595

9696
// Iteratively mark cleanups dead and pop them.
9797
// Maybe we'd get better results if we marked them all dead in one shot?
98-
emitCleanups(depth, loc);
98+
emitCleanups(depth, loc, NotForUnwind);
9999
}
100100

101101
bool CleanupManager::hasAnyActiveCleanups(CleanupsDepth from,
@@ -111,35 +111,37 @@ bool CleanupManager::hasAnyActiveCleanups(CleanupsDepth from) {
111111
/// threading out through any cleanups we might need to run. This does not
112112
/// pop the cleanup stack.
113113
void CleanupManager::emitBranchAndCleanups(JumpDest dest, SILLocation branchLoc,
114-
ArrayRef<SILValue> args) {
114+
ArrayRef<SILValue> args,
115+
ForUnwind_t forUnwind) {
115116
SILGenBuilder &builder = SGF.getBuilder();
116117
assert(builder.hasValidInsertionPoint() && "Emitting branch in invalid spot");
117118
emitCleanups(dest.getDepth(), dest.getCleanupLocation(),
118-
/*popCleanups=*/false);
119+
forUnwind, /*popCleanups=*/false);
119120
builder.createBranch(branchLoc, dest.getBlock(), args);
120121
}
121122

122123
void CleanupManager::emitCleanupsForReturn(CleanupLocation loc) {
123124
SILGenBuilder &builder = SGF.getBuilder();
124125
assert(builder.hasValidInsertionPoint() && "Emitting return in invalid spot");
125126
(void)builder;
126-
emitCleanups(stack.stable_end(), loc, /*popCleanups=*/false);
127+
emitCleanups(stack.stable_end(), loc, NotForUnwind, /*popCleanups=*/false);
127128
}
128129

129130
/// Emit a new block that jumps to the specified location and runs necessary
130131
/// cleanups based on its level. If there are no cleanups to run, this just
131132
/// returns the dest block.
132133
SILBasicBlock *CleanupManager::emitBlockForCleanups(JumpDest dest,
133134
SILLocation branchLoc,
134-
ArrayRef<SILValue> args) {
135+
ArrayRef<SILValue> args,
136+
ForUnwind_t forUnwind) {
135137
// If there are no cleanups to run, just return the Dest block directly.
136138
if (!hasAnyActiveCleanups(dest.getDepth()))
137139
return dest.getBlock();
138140

139141
// Otherwise, create and emit a new block.
140142
auto *newBlock = SGF.createBasicBlock();
141143
SILGenSavedInsertionPoint IPRAII(SGF, newBlock);
142-
emitBranchAndCleanups(dest, branchLoc, args);
144+
emitBranchAndCleanups(dest, branchLoc, args, forUnwind);
143145
return newBlock;
144146
}
145147

lib/SILGen/Cleanup.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ class ManagedValue;
3737
class SharedBorrowFormalAccess;
3838
class FormalEvaluationScope;
3939

40+
/// Is a cleanup being executed as a result of some sort of forced
41+
/// unwinding, such as an error being thrown, or are we just cleaning up
42+
/// after some operation?
43+
///
44+
/// Most cleanups don't care, but the cleanups tied to l-value accesses do:
45+
/// the access will be aborted rather than ended normally, which may cause
46+
/// e.g. writebacks to be skipped. It is also important that no actions
47+
/// be undertaken by an unwind cleanup that might change control flow,
48+
/// such as throwing an error. In contrast, non-unwinding cleanups are
49+
/// permitted to change control flow.
50+
enum ForUnwind_t : bool {
51+
NotForUnwind,
52+
IsForUnwind
53+
};
54+
4055
/// The valid states that a cleanup can be in.
4156
enum class CleanupState {
4257
/// The cleanup is inactive but may be activated later.
@@ -80,7 +95,8 @@ class LLVM_LIBRARY_VISIBILITY Cleanup {
8095
bool isActive() const { return state >= CleanupState::Active; }
8196
bool isDead() const { return state == CleanupState::Dead; }
8297

83-
virtual void emit(SILGenFunction &SGF, CleanupLocation loc) = 0;
98+
virtual void emit(SILGenFunction &SGF, CleanupLocation loc,
99+
ForUnwind_t forUnwind) = 0;
84100
virtual void dump(SILGenFunction &SGF) const = 0;
85101
};
86102

@@ -120,6 +136,7 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager {
120136

121137
void popTopDeadCleanups(CleanupsDepth end);
122138
void emitCleanups(CleanupsDepth depth, CleanupLocation l,
139+
ForUnwind_t forUnwind,
123140
bool popCleanups=true);
124141
void endScope(CleanupsDepth depth, CleanupLocation l);
125142

@@ -151,7 +168,8 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager {
151168
/// \param branchLoc The location of the branch instruction.
152169
/// \param args Arguments to pass to the destination block.
153170
void emitBranchAndCleanups(JumpDest dest, SILLocation branchLoc,
154-
ArrayRef<SILValue> args = {});
171+
ArrayRef<SILValue> args = {},
172+
ForUnwind_t forUnwind = NotForUnwind);
155173

156174
/// emitCleanupsForReturn - Emit the top-level cleanups needed prior to a
157175
/// return from the function.
@@ -161,7 +179,8 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager {
161179
/// cleanups based on its level. If there are no cleanups to run, this just
162180
/// returns the dest block.
163181
SILBasicBlock *emitBlockForCleanups(JumpDest dest, SILLocation branchLoc,
164-
ArrayRef<SILValue> args = {});
182+
ArrayRef<SILValue> args = {},
183+
ForUnwind_t forUnwind = NotForUnwind);
165184

166185
/// pushCleanup - Push a new cleanup.
167186
template<class T, class... A>

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3338,7 +3338,7 @@ class DeallocateUninitializedBox : public Cleanup {
33383338
public:
33393339
DeallocateUninitializedBox(SILValue box) : box(box) {}
33403340

3341-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
3341+
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
33423342
SGF.B.createDeallocBox(l, box);
33433343
}
33443344

@@ -4830,7 +4830,7 @@ namespace {
48304830
DeallocateUninitializedArray(SILValue array)
48314831
: Array(array) {}
48324832

4833-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
4833+
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
48344834
SGF.emitUninitializedArrayDeallocation(l, Array);
48354835
}
48364836

lib/SILGen/SILGenDecl.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ namespace {
131131
SILValue closure;
132132
public:
133133
CleanupClosureConstant(SILValue closure) : closure(closure) {}
134-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
134+
void emit(SILGenFunction &SGF, CleanupLocation l,
135+
ForUnwind_t forUnwind) override {
135136
SGF.B.emitDestroyValueOperation(l, closure);
136137
}
137138
void dump(SILGenFunction &) const override {
@@ -250,7 +251,8 @@ class EndBorrowCleanup : public Cleanup {
250251
EndBorrowCleanup(SILValue original, SILValue borrowed)
251252
: original(original), borrowed(borrowed) {}
252253

253-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
254+
void emit(SILGenFunction &SGF, CleanupLocation l,
255+
ForUnwind_t forUnwind) override {
254256
SGF.B.createEndBorrow(l, borrowed, original);
255257
}
256258

@@ -271,7 +273,8 @@ class ReleaseValueCleanup : public Cleanup {
271273
public:
272274
ReleaseValueCleanup(SILValue v) : v(v) {}
273275

274-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
276+
void emit(SILGenFunction &SGF, CleanupLocation l,
277+
ForUnwind_t forUnwind) override {
275278
if (v->getType().isAddress())
276279
SGF.B.createDestroyAddr(l, v);
277280
else
@@ -295,7 +298,8 @@ class DeallocStackCleanup : public Cleanup {
295298
public:
296299
DeallocStackCleanup(SILValue addr) : Addr(addr) {}
297300

298-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
301+
void emit(SILGenFunction &SGF, CleanupLocation l,
302+
ForUnwind_t forUnwind) override {
299303
SGF.B.createDeallocStack(l, Addr);
300304
}
301305

@@ -316,7 +320,8 @@ class DestroyLocalVariable : public Cleanup {
316320
public:
317321
DestroyLocalVariable(VarDecl *var) : Var(var) {}
318322

319-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
323+
void emit(SILGenFunction &SGF, CleanupLocation l,
324+
ForUnwind_t forUnwind) override {
320325
SGF.destroyLocalVariable(l, Var);
321326
}
322327

@@ -349,7 +354,8 @@ class DeallocateUninitializedLocalVariable : public Cleanup {
349354
public:
350355
DeallocateUninitializedLocalVariable(VarDecl *var) : Var(var) {}
351356

352-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
357+
void emit(SILGenFunction &SGF, CleanupLocation l,
358+
ForUnwind_t forUnwind) override {
353359
SGF.deallocateUninitializedLocalVariable(l, Var);
354360
}
355361

@@ -1304,7 +1310,8 @@ namespace {
13041310
concreteFormalType(concreteFormalType),
13051311
repr(repr) {}
13061312

1307-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
1313+
void emit(SILGenFunction &SGF, CleanupLocation l,
1314+
ForUnwind_t forUnwind) override {
13081315
switch (repr) {
13091316
case ExistentialRepresentation::None:
13101317
case ExistentialRepresentation::Class:
@@ -1481,7 +1488,8 @@ struct FormalAccessReleaseValueCleanup : Cleanup {
14811488
state = newState;
14821489
}
14831490

1484-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
1491+
void emit(SILGenFunction &SGF, CleanupLocation l,
1492+
ForUnwind_t forUnwind) override {
14851493
getEvaluation(SGF).finish(SGF);
14861494
}
14871495

lib/SILGen/SILGenExpr.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ struct EndBorrowCleanup : Cleanup {
168168
EndBorrowCleanup(SILValue originalValue, SILValue borrowedValue)
169169
: originalValue(originalValue), borrowedValue(borrowedValue) {}
170170

171-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
171+
void emit(SILGenFunction &SGF, CleanupLocation l,
172+
ForUnwind_t forUnwind) override {
172173
SGF.B.createEndBorrow(l, borrowedValue, originalValue);
173174
}
174175

@@ -187,7 +188,7 @@ struct FormalEvaluationEndBorrowCleanup : Cleanup {
187188

188189
FormalEvaluationEndBorrowCleanup() : Depth() {}
189190

190-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
191+
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
191192
getEvaluation(SGF).finish(SGF);
192193
}
193194

@@ -276,7 +277,8 @@ struct EndBorrowArgumentCleanup : Cleanup {
276277

277278
EndBorrowArgumentCleanup(SILPHIArgument *arg) : arg(arg) {}
278279

279-
void emit(SILGenFunction &SGF, CleanupLocation l) override {
280+
void emit(SILGenFunction &SGF, CleanupLocation l,
281+
ForUnwind_t forUnwind) override {
280282
SGF.B.createEndBorrowArgument(l, arg);
281283
}
282284

@@ -708,7 +710,7 @@ struct DelegateInitSelfWritebackCleanup : Cleanup {
708710
SILValue value)
709711
: loc(loc), lvalueAddress(lvalueAddress), value(value) {}
710712

711-
void emit(SILGenFunction &SGF, CleanupLocation) override {
713+
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
712714
SILValue valueToStore = value;
713715
SILType lvalueObjTy = lvalueAddress->getType().getObjectType();
714716

lib/SILGen/SILGenLValue.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ struct LValueWritebackCleanup : Cleanup {
4444

4545
LValueWritebackCleanup() : Depth() {}
4646

47-
void emit(SILGenFunction &SGF, CleanupLocation loc) override {
47+
void emit(SILGenFunction &SGF, CleanupLocation loc,
48+
ForUnwind_t forUnwind) override {
49+
// TODO: honor forUnwind!
4850
auto &evaluation = *SGF.FormalEvalContext.find(Depth);
4951
assert(evaluation.getKind() == FormalAccess::Exclusive);
5052
auto &lvalue = static_cast<ExclusiveBorrowFormalAccess &>(evaluation);
@@ -554,7 +556,8 @@ struct UnenforcedAccessCleanup : Cleanup {
554556

555557
UnenforcedAccessCleanup() : Depth() {}
556558

557-
void emit(SILGenFunction &SGF, CleanupLocation loc) override {
559+
void emit(SILGenFunction &SGF, CleanupLocation loc,
560+
ForUnwind_t forUnwind) override {
558561
auto &evaluation = *SGF.FormalEvalContext.find(Depth);
559562
assert(evaluation.getKind() == FormalAccess::Unenforced);
560563
auto &formalAccess = static_cast<UnenforcedFormalAccess &>(evaluation);

lib/SILGen/SILGenMaterializeForSet.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,8 @@ namespace {
952952
public:
953953
DeallocateValueBuffer(SILType valueType, SILValue buffer)
954954
: Buffer(buffer), ValueType(valueType) {}
955-
void emit(SILGenFunction &SGF, CleanupLocation loc) override {
955+
void emit(SILGenFunction &SGF, CleanupLocation loc,
956+
ForUnwind_t forUnwind) override {
956957
SGF.B.createDeallocValueBuffer(loc, ValueType, Buffer);
957958
}
958959
void dump(SILGenFunction &) const override {

0 commit comments

Comments
 (0)