Skip to content

Commit 4ba2f6e

Browse files
committed
[NFC] Fix objcImpl request cache
Several offsetting bugs both broke the caching of `ObjCInterfaceAndImplementationRequest` and caused it to usually miss. Fix this whole painful mess. Also has collateral improvements to simple_display().
1 parent 07b2b9a commit 4ba2f6e

File tree

4 files changed

+24
-20
lines changed

4 files changed

+24
-20
lines changed

include/swift/ClangImporter/ClangImporterRequests.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ struct ObjCInterfaceAndImplementation final {
256256
ObjCInterfaceAndImplementation()
257257
: interfaceDecls(), implementationDecl(nullptr) {}
258258

259-
operator bool() const {
259+
bool empty() const {
260260
return interfaceDecls.empty();
261261
}
262262

lib/AST/Decl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11291,7 +11291,7 @@ void swift::simple_display(llvm::raw_ostream &out, const Decl *decl) {
1129111291
}
1129211292

1129311293
if (auto value = dyn_cast<ValueDecl>(decl)) {
11294-
simple_display(out, value);
11294+
return simple_display(out, value);
1129511295
} else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
1129611296
out << "extension of ";
1129711297
if (auto typeRepr = ext->getExtendedTypeRepr())
@@ -11301,13 +11301,13 @@ void swift::simple_display(llvm::raw_ostream &out, const Decl *decl) {
1130111301
} else if (auto med = dyn_cast<MacroExpansionDecl>(decl)) {
1130211302
out << '#' << med->getMacroName() << " in ";
1130311303
printContext(out, med->getDeclContext());
11304-
if (med->getLoc().isValid()) {
11305-
out << '@';
11306-
med->getLoc().print(out, med->getASTContext().SourceMgr);
11307-
}
1130811304
} else {
1130911305
out << "(unknown decl)";
1131011306
}
11307+
if (decl->getLoc().isValid()) {
11308+
out << '@';
11309+
decl->getLoc().print(out, decl->getASTContext().SourceMgr);
11310+
}
1131111311
}
1131211312

1131311313
void swift::simple_display(llvm::raw_ostream &out,

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6139,15 +6139,15 @@ evaluate(Evaluator &evaluator, Decl *decl) const {
61396139

61406140
void swift::simple_display(llvm::raw_ostream &out,
61416141
const ObjCInterfaceAndImplementation &pair) {
6142-
if (!pair) {
6142+
if (pair.empty()) {
61436143
out << "no clang interface or @_objcImplementation";
61446144
return;
61456145
}
61466146

6147-
out << "clang interface ";
6148-
simple_display(out, pair.interfaceDecls);
6149-
out << " with @_objcImplementation ";
6147+
out << "@implementation ";
61506148
simple_display(out, pair.implementationDecl);
6149+
out << " matches clang interfaces ";
6150+
simple_display(out, pair.interfaceDecls);
61516151
}
61526152

61536153
SourceLoc
@@ -6163,7 +6163,8 @@ llvm::TinyPtrVector<Decl *> Decl::getAllImplementedObjCDecls() const {
61636163
return {};
61646164

61656165
ObjCInterfaceAndImplementationRequest req{const_cast<Decl *>(this)};
6166-
return evaluateOrDefault(getASTContext().evaluator, req, {}).interfaceDecls;
6166+
auto result = evaluateOrDefault(getASTContext().evaluator, req, {});
6167+
return result.interfaceDecls;
61676168
}
61686169

61696170
DeclContext *DeclContext::getImplementedObjCContext() const {
@@ -6179,8 +6180,8 @@ Decl *Decl::getObjCImplementationDecl() const {
61796180
return nullptr;
61806181

61816182
ObjCInterfaceAndImplementationRequest req{const_cast<Decl *>(this)};
6182-
return evaluateOrDefault(getASTContext().evaluator, req, {})
6183-
.implementationDecl;
6183+
auto result = evaluateOrDefault(getASTContext().evaluator, req, {});
6184+
return result.implementationDecl;
61846185
}
61856186

61866187
llvm::TinyPtrVector<Decl *>

lib/ClangImporter/ClangImporterRequests.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ using namespace swift;
2525
std::optional<ObjCInterfaceAndImplementation>
2626
ObjCInterfaceAndImplementationRequest::getCachedResult() const {
2727
auto passedDecl = std::get<0>(getStorage());
28-
if (!passedDecl)
28+
if (!passedDecl) {
2929
return {};
30+
}
3031

31-
if (!passedDecl->getCachedLacksObjCInterfaceOrImplementation())
32+
if (passedDecl->getCachedLacksObjCInterfaceOrImplementation()) {
3233
// We've computed this request and found that this is a normal declaration.
3334
return {};
35+
}
3436

3537
// Either we've computed this request and cached a result in the ImporterImpl,
3638
// or we haven't computed this request. Check the caches.
@@ -44,20 +46,21 @@ ObjCInterfaceAndImplementationRequest::getCachedResult() const {
4446
// `ImplementationsByInterface`.
4547

4648
Decl *implDecl = nullptr;
47-
if (!passedDecl->hasClangNode()) {
48-
// `passedDecl` *could* be an implementation.
49+
if (passedDecl->hasClangNode()) {
50+
// `passedDecl` *could* be an interface.
4951
auto iter = impl.ImplementationsByInterface.find(passedDecl);
5052
if (iter != impl.ImplementationsByInterface.end())
5153
implDecl = iter->second;
5254
} else {
53-
// `passedDecl` *could* be an interface.
55+
// `passedDecl` *could* be an implementation.
5456
implDecl = passedDecl;
5557
}
5658

5759
if (implDecl) {
5860
auto iter = impl.InterfacesByImplementation.find(implDecl);
59-
if (iter != impl.InterfacesByImplementation.end())
61+
if (iter != impl.InterfacesByImplementation.end()) {
6062
return ObjCInterfaceAndImplementation(iter->second, implDecl);
63+
}
6164
}
6265

6366
// Nothing in the caches, so we must need to compute this.
@@ -68,7 +71,7 @@ void ObjCInterfaceAndImplementationRequest::
6871
cacheResult(ObjCInterfaceAndImplementation value) const {
6972
Decl *passedDecl = std::get<0>(getStorage());
7073

71-
if (!value) {
74+
if (value.empty()) {
7275
// `decl` is neither an interface nor an implementation; remember this.
7376
passedDecl->setCachedLacksObjCInterfaceOrImplementation(true);
7477
return;

0 commit comments

Comments
 (0)