Skip to content

Commit af3b73a

Browse files
Merge pull request #64590 from adrian-prantl/implicit-sillocation
Preserve the Implicit attribute in SILLocation. (NFC)
2 parents 2b31287 + c5efebe commit af3b73a

File tree

3 files changed

+108
-59
lines changed

3 files changed

+108
-59
lines changed

include/swift/SIL/SILLocation.h

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ class SILLocation {
106106
using type = Pattern;
107107
};
108108

109-
using ASTNodeTy = llvm::PointerUnion<Stmt *, Expr *, Decl *, Pattern *>;
109+
/// The int flag indicates whether the node's end location should be used.
110+
using ASTNodeTy = llvm::PointerIntPair<
111+
llvm::PointerUnion<Stmt *, Expr *, Decl *, Pattern *>, 1>;
110112

111113
/// Used in case the location for diagnostics does not match the location for
112114
/// debugging.
@@ -159,7 +161,7 @@ class SILLocation {
159161

160162
const FilenameAndLocation *filePositionLoc;
161163
ASTNodeTy ASTNodeLoc;
162-
const ExtendedASTNodeLoc *extendedASTNodeLoc;
164+
ExtendedASTNodeLoc *extendedASTNodeLoc;
163165
SourceLoc sourceLoc;
164166
};
165167

@@ -173,7 +175,7 @@ class SILLocation {
173175
union KindAndFlags {
174176
KindAndFlags() : packedKindAndFlags(0) {}
175177
KindAndFlags(LocationKind kind, StorageKind storageKind)
176-
: fields({kind, storageKind, 0, 0, 0 }) {
178+
: fields({kind, storageKind, 0, 0, 0}) {
177179
assert(fields.kind == kind && "LocationKind overflow");
178180
assert(fields.storageKind == storageKind && "StorageKind overflow");
179181
}
@@ -184,7 +186,7 @@ class SILLocation {
184186
uint8_t kind: 3;
185187
uint8_t storageKind: 2;
186188
uint8_t autoGenerated: 1;
187-
uint8_t pointsToEnd: 1;
189+
uint8_t implicit: 1;
188190
uint8_t inPrologue: 1;
189191
} fields;
190192
};
@@ -222,21 +224,21 @@ class SILLocation {
222224
template <typename T>
223225
T *getNodeAs(ASTNodeTy Node) const {
224226
using base = typename base_type<T>::type*;
225-
return dyn_cast_or_null<T>(Node.dyn_cast<base>());
227+
return dyn_cast_or_null<T>(Node.getPointer().dyn_cast<base>());
226228
}
227229

228230
template <typename T>
229231
bool isNode(ASTNodeTy Node) const {
230232
assert(isASTNode());
231233
ASTNodeTy primaryNd = getPrimaryASTNode();
232-
if (primaryNd.is<typename base_type<T>::type*>())
233-
return isa<T>(Node.get<typename base_type<T>::type*>());
234+
if (primaryNd.getPointer().is<typename base_type<T>::type*>())
235+
return isa<T>(Node.getPointer().get<typename base_type<T>::type*>());
234236
return false;
235237
}
236238

237239
template <typename T>
238240
T *castNodeTo(ASTNodeTy Node) const {
239-
return cast<T>(Node.get<typename base_type<T>::type*>());
241+
return cast<T>(Node.getPointer().get<typename base_type<T>::type*>());
240242
}
241243

242244
SourceLoc getSourceLoc(ASTNodeTy N) const;
@@ -269,8 +271,7 @@ class SILLocation {
269271
: storage(ext), kindAndFlags(K, ExtendedASTNodeKind) {
270272
}
271273

272-
SILLocation(SourceLoc L, LocationKind K)
273-
: storage(L), kindAndFlags(K, SourceLocKind) {}
274+
SILLocation(SourceLoc L, LocationKind K);
274275

275276
// Used by SILInstruction.
276277
SILLocation(Storage storage, uint8_t packedKindAndFlags) :
@@ -283,10 +284,10 @@ class SILLocation {
283284
//
284285
// It is okay to pass a nullptr to these constructors, but preferably, a
285286
// null-location should be created with `invalid()`.
286-
SILLocation(Stmt *S) : SILLocation(ASTNodeTy(S), RegularKind) {}
287-
SILLocation(Expr *E) : SILLocation(ASTNodeTy(E), RegularKind) {}
288-
SILLocation(Decl *D) : SILLocation(ASTNodeTy(D), RegularKind) {}
289-
SILLocation(Pattern *P) : SILLocation(ASTNodeTy(P), RegularKind) {}
287+
SILLocation(Stmt *S);
288+
SILLocation(Expr *E);
289+
SILLocation(Decl *D);
290+
SILLocation(Pattern *P);
290291

291292
/// Returns a null location.
292293
static SILLocation invalid() { return SILLocation(); }
@@ -299,7 +300,7 @@ class SILLocation {
299300
bool isNull() const {
300301
switch (getStorageKind()) {
301302
case ASTNodeKind:
302-
case ExtendedASTNodeKind: return !getPrimaryASTNode();
303+
case ExtendedASTNodeKind: return !getPrimaryASTNode().getPointer();
303304
case FilenameAndLocationKind: return storage.filePositionLoc == nullptr;
304305
case SourceLocKind: return storage.sourceLoc.isInvalid();
305306
}
@@ -353,6 +354,11 @@ class SILLocation {
353354
/// body, such as thunks or default destructors.
354355
bool isAutoGenerated() const { return kindAndFlags.fields.autoGenerated; }
355356

357+
/// Returns true if the location was created from an implicit AST node.
358+
/// TODO: This is very similar to autogenerated,
359+
/// and these two properties should be merged.
360+
bool isImplicit() const { return kindAndFlags.fields.implicit; }
361+
356362
/// Returns false if the location should be represented in debuginfo.
357363
bool isHiddenFromDebugInfo() const {
358364
return isAutoGenerated() && !hasASTNodeForDebugging();
@@ -365,7 +371,7 @@ class SILLocation {
365371

366372
/// Changes the default source location position to point to the end of
367373
/// the AST node.
368-
void pointToEnd() { kindAndFlags.fields.pointsToEnd = true; }
374+
void pointToEnd();
369375

370376
/// Mark this location as being part of the function
371377
/// prologue, which means that it deals with setting up the stack
@@ -378,7 +384,7 @@ class SILLocation {
378384

379385
/// Check if the corresponding source code location definitely points
380386
/// to the end of the AST node.
381-
bool alwaysPointsToEnd() const { return kindAndFlags.fields.pointsToEnd; }
387+
bool pointsToEnd() const;
382388

383389
template <typename T> bool is() const { return T::isKind(*this); }
384390

lib/SIL/IR/SILLocation.cpp

Lines changed: 83 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,33 @@ using namespace swift;
2525
static_assert(sizeof(SILLocation) <= 2 * sizeof(void *),
2626
"SILLocation must stay small");
2727

28-
SILLocation::FilenameAndLocation *SILLocation::FilenameAndLocation::
29-
alloc(unsigned line, unsigned column, StringRef filename, SILModule &module) {
28+
SILLocation::SILLocation(Stmt *S) : SILLocation(ASTNodeTy(S), RegularKind) {
29+
if (S->isImplicit())
30+
kindAndFlags.fields.implicit = true;
31+
}
32+
33+
SILLocation::SILLocation(Expr *E) : SILLocation(ASTNodeTy(E), RegularKind) {
34+
if (E->isImplicit())
35+
kindAndFlags.fields.implicit = true;
36+
}
37+
SILLocation::SILLocation(Decl *D) : SILLocation(ASTNodeTy(D), RegularKind) {
38+
if (D && D->isImplicit())
39+
kindAndFlags.fields.implicit = true;
40+
}
41+
42+
SILLocation::SILLocation(Pattern *P) : SILLocation(ASTNodeTy(P), RegularKind) {
43+
if (P->isImplicit())
44+
kindAndFlags.fields.implicit = true;
45+
}
46+
47+
SILLocation::SILLocation(SourceLoc L, LocationKind K)
48+
: storage(L), kindAndFlags(K, SourceLocKind) {
49+
kindAndFlags.fields.implicit = true;
50+
}
51+
52+
SILLocation::FilenameAndLocation *
53+
SILLocation::FilenameAndLocation::alloc(unsigned line, unsigned column,
54+
StringRef filename, SILModule &module) {
3055
return new (module) FilenameAndLocation(line, column, filename);
3156
}
3257

@@ -36,6 +61,28 @@ void SILLocation::FilenameAndLocation::print(raw_ostream &OS) const {
3661
OS << filename << ':' << line << ':' << column;
3762
}
3863

64+
void SILLocation::pointToEnd() {
65+
switch (getStorageKind()) {
66+
case ASTNodeKind:
67+
return storage.ASTNodeLoc.setInt(1);
68+
case ExtendedASTNodeKind:
69+
return storage.extendedASTNodeLoc->primary.setInt(1);
70+
default:
71+
assert(false && "only AST nodes can be pointed to end");
72+
}
73+
}
74+
75+
bool SILLocation::pointsToEnd() const {
76+
switch (getStorageKind()) {
77+
case ASTNodeKind:
78+
return storage.ASTNodeLoc.getInt();
79+
case ExtendedASTNodeKind:
80+
return storage.extendedASTNodeLoc->primary.getInt();
81+
default:
82+
return false;
83+
}
84+
}
85+
3986
SourceLoc SILLocation::getSourceLoc() const {
4087
if (isSILFile())
4188
return storage.sourceLoc;
@@ -49,25 +96,24 @@ SourceLoc SILLocation::getSourceLoc() const {
4996
}
5097

5198
SourceLoc SILLocation::getSourceLoc(ASTNodeTy N) const {
52-
if (N.isNull())
99+
auto P = N.getPointer();
100+
if (P.isNull())
53101
return SourceLoc();
54102

55-
if (alwaysPointsToEnd() ||
56-
is<CleanupLocation>() ||
57-
is<ImplicitReturnLocation>())
103+
if (pointsToEnd() || is<CleanupLocation>() || is<ImplicitReturnLocation>())
58104
return getEndSourceLoc(N);
59105

60106
// Use the start location for the ReturnKind.
61107
if (is<ReturnLocation>())
62108
return getStartSourceLoc(N);
63109

64-
if (auto *decl = N.dyn_cast<Decl*>())
110+
if (auto *decl = P.dyn_cast<Decl*>())
65111
return decl->getLoc();
66-
if (auto *expr = N.dyn_cast<Expr*>())
112+
if (auto *expr = P.dyn_cast<Expr*>())
67113
return expr->getLoc();
68-
if (auto *stmt = N.dyn_cast<Stmt*>())
114+
if (auto *stmt = P.dyn_cast<Stmt*>())
69115
return stmt->getStartLoc();
70-
if (auto *patt = N.dyn_cast<Pattern*>())
116+
if (auto *patt = P.dyn_cast<Pattern*>())
71117
return patt->getStartLoc();
72118
llvm_unreachable("impossible SILLocation");
73119
}
@@ -94,13 +140,14 @@ SourceLoc SILLocation::getStartSourceLoc() const {
94140
}
95141

96142
SourceLoc SILLocation::getStartSourceLoc(ASTNodeTy N) {
97-
if (auto *decl = N.dyn_cast<Decl*>())
143+
auto P = N.getPointer();
144+
if (auto *decl = P.dyn_cast<Decl*>())
98145
return decl->getStartLoc();
99-
if (auto *expr = N.dyn_cast<Expr*>())
146+
if (auto *expr = P.dyn_cast<Expr*>())
100147
return expr->getStartLoc();
101-
if (auto *stmt = N.dyn_cast<Stmt*>())
148+
if (auto *stmt = P.dyn_cast<Stmt*>())
102149
return stmt->getStartLoc();
103-
if (auto *patt = N.dyn_cast<Pattern*>())
150+
if (auto *patt = P.dyn_cast<Pattern*>())
104151
return patt->getStartLoc();
105152
llvm_unreachable("impossible SILLocation");
106153
}
@@ -114,13 +161,14 @@ SourceLoc SILLocation::getEndSourceLoc() const {
114161
}
115162

116163
SourceLoc SILLocation::getEndSourceLoc(ASTNodeTy N) {
117-
if (auto decl = N.dyn_cast<Decl*>())
164+
auto P = N.getPointer();
165+
if (auto decl = P.dyn_cast<Decl*>())
118166
return decl->getEndLoc();
119-
if (auto expr = N.dyn_cast<Expr*>())
167+
if (auto expr = P.dyn_cast<Expr*>())
120168
return expr->getEndLoc();
121-
if (auto stmt = N.dyn_cast<Stmt*>())
169+
if (auto stmt = P.dyn_cast<Stmt*>())
122170
return stmt->getEndLoc();
123-
if (auto patt = N.dyn_cast<Pattern*>())
171+
if (auto patt = P.dyn_cast<Pattern*>())
124172
return patt->getEndLoc();
125173
llvm_unreachable("impossible SILLocation");
126174
}
@@ -186,10 +234,11 @@ void SILLocation::dump() const {
186234
printSourceLoc(getSourceLoc(), llvm::dbgs());
187235
}
188236

189-
if (isAutoGenerated()) llvm::dbgs() << ":auto";
190-
if (alwaysPointsToEnd()) llvm::dbgs() << ":end";
191-
if (isInPrologue()) llvm::dbgs() << ":prologue";
192-
if (isSILFile()) llvm::dbgs() << ":sil";
237+
if (isAutoGenerated()) llvm::dbgs() << ":auto";
238+
if (isImplicit()) llvm::dbgs() << ":implicit";
239+
if (pointsToEnd()) llvm::dbgs() << ":end";
240+
if (isInPrologue()) llvm::dbgs() << ":prologue";
241+
if (isSILFile()) llvm::dbgs() << ":sil";
193242
if (hasASTNodeForDebugging()) {
194243
llvm::dbgs() << ":debug[";
195244
printSourceLoc(getSourceLocForDebugging(), llvm::dbgs());
@@ -219,33 +268,35 @@ void SILLocation::print(raw_ostream &OS) const {
219268
}
220269
}
221270

222-
RegularLocation::RegularLocation(Stmt *S, Pattern *P, SILModule &Module) :
223-
SILLocation(new (Module) ExtendedASTNodeLoc(S, P), RegularKind) {}
271+
RegularLocation::RegularLocation(Stmt *S, Pattern *P, SILModule &Module)
272+
: SILLocation(new(Module) ExtendedASTNodeLoc({S, 0}, {P, 0}), RegularKind) {}
224273

225274
SILLocation::ExtendedASTNodeLoc *
226275
RegularLocation::getDebugOnlyExtendedASTNodeLoc(SILLocation L,
227276
SILModule &Module) {
277+
ASTNodeTy Empty({(Decl *)nullptr, 0});
228278
if (auto D = L.getAsASTNode<Decl>())
229-
return new (Module) ExtendedASTNodeLoc((Decl *)nullptr, D);
279+
return new (Module) ExtendedASTNodeLoc(Empty, {D, 0});
230280
if (auto E = L.getAsASTNode<Expr>())
231-
return new (Module) ExtendedASTNodeLoc((Decl *)nullptr, E);
281+
return new (Module) ExtendedASTNodeLoc(Empty, {E, 0});
232282
if (auto S = L.getAsASTNode<Stmt>())
233-
return new (Module) ExtendedASTNodeLoc((Decl *)nullptr, S);
283+
return new (Module) ExtendedASTNodeLoc(Empty, {S, 0});
234284
auto P = L.getAsASTNode<Pattern>();
235-
return new (Module) ExtendedASTNodeLoc((Decl *)nullptr, P);
285+
return new (Module) ExtendedASTNodeLoc(Empty, {P, 0});
236286
}
237287

238288
SILLocation::ExtendedASTNodeLoc *
239289
RegularLocation::getDiagnosticOnlyExtendedASTNodeLoc(SILLocation L,
240290
SILModule &Module) {
291+
ASTNodeTy Empty({(Decl *)nullptr, 0});
241292
if (auto D = L.getAsASTNode<Decl>())
242-
return new (Module) ExtendedASTNodeLoc(D, (Decl *)nullptr);
293+
return new (Module) ExtendedASTNodeLoc({D, 0}, Empty);
243294
if (auto E = L.getAsASTNode<Expr>())
244-
return new (Module) ExtendedASTNodeLoc(E, (Decl *)nullptr);
295+
return new (Module) ExtendedASTNodeLoc({E, 0}, Empty);
245296
if (auto S = L.getAsASTNode<Stmt>())
246-
return new (Module) ExtendedASTNodeLoc(S, (Decl *)nullptr);
297+
return new (Module) ExtendedASTNodeLoc({S, 0}, Empty);
247298
auto P = L.getAsASTNode<Pattern>();
248-
return new (Module) ExtendedASTNodeLoc(P, (Decl *)nullptr);
299+
return new (Module) ExtendedASTNodeLoc({P, 0}, Empty);
249300
}
250301

251302
RegularLocation::RegularLocation(SILLocation ForDebuggingOrDiagnosticsOnly,

lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -647,16 +647,8 @@ static bool isUserCode(const SILInstruction *I) {
647647

648648
// If the instruction corresponds to user-written return or some other
649649
// statement, we know it corresponds to user code.
650-
if (Loc.is<RegularLocation>() || Loc.is<ReturnLocation>()) {
651-
if (auto *E = Loc.getAsASTNode<Expr>())
652-
return !E->isImplicit();
653-
if (auto *D = Loc.getAsASTNode<Decl>())
654-
return !D->isImplicit();
655-
if (auto *S = Loc.getAsASTNode<Stmt>())
656-
return !S->isImplicit();
657-
if (auto *P = Loc.getAsASTNode<Pattern>())
658-
return !P->isImplicit();
659-
}
650+
if (Loc.is<RegularLocation>() || Loc.is<ReturnLocation>())
651+
return !Loc.isImplicit();
660652
return false;
661653
}
662654

0 commit comments

Comments
 (0)