Skip to content

Commit dcb1d66

Browse files
committed
[NFC] Serialize ObjC selectors for protocols
The ObjCMethodLookupTable for protocols was not being serialized and rebuilt on load, so NominalTypeDecl::lookupDirect() on selectors was not working correctly for deserialized types. Correct this oversight. # Conflicts: # lib/Serialization/ModuleFormat.h
1 parent 4c5c674 commit dcb1d66

File tree

12 files changed

+40
-30
lines changed

12 files changed

+40
-30
lines changed

include/swift/AST/ModuleLoader.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ class ModuleLoader {
226226
virtual void loadExtensions(NominalTypeDecl *nominal,
227227
unsigned previousGeneration) { }
228228

229-
/// Load the methods within the given class that produce
229+
/// Load the methods within the given type that produce
230230
/// Objective-C class or instance methods with the given selector.
231231
///
232-
/// \param classDecl The class in which we are searching for @objc methods.
233-
/// The search only considers this class and its extensions; not any
232+
/// \param typeDecl The type in which we are searching for @objc methods.
233+
/// The search only considers this type and its extensions; not any
234234
/// superclasses.
235235
///
236236
/// \param selector The selector to search for.
@@ -246,7 +246,7 @@ class ModuleLoader {
246246
/// selector and are instance/class methods as requested. This list will be
247247
/// extended with any methods found in subsequent generations.
248248
virtual void loadObjCMethods(
249-
ClassDecl *classDecl,
249+
NominalTypeDecl *typeDecl,
250250
ObjCSelector selector,
251251
bool isInstanceMethod,
252252
unsigned previousGeneration,

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class ClangImporter final : public ClangModuleLoader {
309309
unsigned previousGeneration) override;
310310

311311
virtual void loadObjCMethods(
312-
ClassDecl *classDecl,
312+
NominalTypeDecl *typeDecl,
313313
ObjCSelector selector,
314314
bool isInstanceMethod,
315315
unsigned previousGeneration,

include/swift/Sema/SourceLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class SourceLoader : public ModuleLoader {
8585
unsigned previousGeneration) override;
8686

8787
virtual void loadObjCMethods(
88-
ClassDecl *classDecl,
88+
NominalTypeDecl *typeDecl,
8989
ObjCSelector selector,
9090
bool isInstanceMethod,
9191
unsigned previousGeneration,

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
190190
unsigned previousGeneration) override;
191191

192192
virtual void loadObjCMethods(
193-
ClassDecl *classDecl,
193+
NominalTypeDecl *typeDecl,
194194
ObjCSelector selector,
195195
bool isInstanceMethod,
196196
unsigned previousGeneration,

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,24 +1916,12 @@ void ASTContext::loadObjCMethods(
19161916
PrettyStackTraceSelector stackTraceSelector("looking for", selector);
19171917
PrettyStackTraceDecl stackTraceDecl("...in", tyDecl);
19181918

1919-
// @objc protocols cannot have @objc extension members, so if we've recorded
1920-
// everything in the protocol definition, we've recorded everything. And we
1921-
// only ever use the ObjCSelector version of `NominalTypeDecl::lookupDirect()`
1922-
// on protocols in primary file typechecking, so we don't care about protocols
1923-
// that need to be loaded from files.
1924-
// TODO: Rework `ModuleLoader::loadObjCMethods()` to support protocols too if
1925-
// selector-based `NominalTypeDecl::lookupDirect()` ever needs to work
1926-
// in more situations.
1927-
ClassDecl *classDecl = dyn_cast<ClassDecl>(tyDecl);
1928-
if (!classDecl)
1929-
return;
1930-
19311919
for (auto &loader : getImpl().ModuleLoaders) {
19321920
// Ignore the Clang importer if we've been asked for Swift-only results.
19331921
if (swiftOnly && loader.get() == getClangModuleLoader())
19341922
continue;
19351923

1936-
loader->loadObjCMethods(classDecl, selector, isInstanceMethod,
1924+
loader->loadObjCMethods(tyDecl, selector, isInstanceMethod,
19371925
previousGeneration, methods);
19381926
}
19391927
}

lib/AST/NameLookup.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,24 @@ class swift::ObjCMethodLookupTable
13101310
: public llvm::DenseMap<std::pair<ObjCSelector, char>,
13111311
StoredObjCMethods>,
13121312
public ASTAllocated<ObjCMethodLookupTable>
1313-
{};
1313+
{
1314+
SWIFT_DEBUG_DUMP {
1315+
llvm::errs() << "ObjCMethodLookupTable:\n";
1316+
for (auto pair : *this) {
1317+
auto selector = pair.getFirst().first;
1318+
auto isInstanceMethod = pair.getFirst().second;
1319+
auto &methods = pair.getSecond();
1320+
1321+
llvm::errs() << " \"" << (isInstanceMethod ? "-" : "+") << selector
1322+
<< "\":\n";
1323+
for (auto method : methods.Methods) {
1324+
llvm::errs() << " - \"";
1325+
method->dumpRef(llvm::errs());
1326+
llvm::errs() << "\"\n";
1327+
}
1328+
}
1329+
}
1330+
};
13141331

13151332
MemberLookupTable::MemberLookupTable(ASTContext &ctx) {
13161333
// Register a cleanup with the ASTContext to call the lookup table

lib/ClangImporter/ClangImporter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3435,11 +3435,16 @@ void ClangImporter::loadExtensions(NominalTypeDecl *nominal,
34353435
}
34363436

34373437
void ClangImporter::loadObjCMethods(
3438-
ClassDecl *classDecl,
3438+
NominalTypeDecl *typeDecl,
34393439
ObjCSelector selector,
34403440
bool isInstanceMethod,
34413441
unsigned previousGeneration,
34423442
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods) {
3443+
// TODO: We don't currently need to load methods from imported ObjC protocols.
3444+
auto classDecl = dyn_cast<ClassDecl>(typeDecl);
3445+
if (!classDecl)
3446+
return;
3447+
34433448
const auto *objcClass =
34443449
dyn_cast_or_null<clang::ObjCInterfaceDecl>(classDecl->getClangDecl());
34453450
if (!objcClass)

lib/Serialization/ModuleFile.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ void ModuleFile::loadExtensions(NominalTypeDecl *nominal) {
613613
}
614614

615615
void ModuleFile::loadObjCMethods(
616-
ClassDecl *classDecl,
616+
NominalTypeDecl *typeDecl,
617617
ObjCSelector selector,
618618
bool isInstanceMethod,
619619
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods) {
@@ -627,7 +627,7 @@ void ModuleFile::loadObjCMethods(
627627
return;
628628
}
629629

630-
std::string ownerName = Mangle::ASTMangler().mangleNominalType(classDecl);
630+
std::string ownerName = Mangle::ASTMangler().mangleNominalType(typeDecl);
631631
auto results = *known;
632632
for (const auto &result : results) {
633633
// If the method is the wrong kind (instance vs. class), skip it.

lib/Serialization/ModuleFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ class ModuleFile
631631
///
632632
/// \param methods The list of @objc methods in this class that have this
633633
/// selector and are instance/class methods as requested.
634-
void loadObjCMethods(ClassDecl *classDecl,
634+
void loadObjCMethods(NominalTypeDecl *typeDecl,
635635
ObjCSelector selector,
636636
bool isInstanceMethod,
637637
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods);

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 691; // witness enter isolation
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 692; // add @objc protocol methods to objc method tables
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///

lib/Serialization/Serialization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5531,10 +5531,10 @@ static void collectInterestingNestedDeclarations(
55315531
if (isLocal)
55325532
return;
55335533

5534-
if (auto owningClass = func->getDeclContext()->getSelfClassDecl()) {
5534+
if (auto owningType = func->getDeclContext()->getSelfNominalTypeDecl()) {
55355535
if (func->isObjC()) {
55365536
Mangle::ASTMangler mangler;
5537-
std::string ownerName = mangler.mangleNominalType(owningClass);
5537+
std::string ownerName = mangler.mangleNominalType(owningType);
55385538
assert(!ownerName.empty() && "Mangled type came back empty!");
55395539

55405540
objcMethods[func->getObjCSelector()].push_back(

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,15 +1320,15 @@ void SerializedModuleLoaderBase::loadExtensions(NominalTypeDecl *nominal,
13201320
}
13211321

13221322
void SerializedModuleLoaderBase::loadObjCMethods(
1323-
ClassDecl *classDecl,
1323+
NominalTypeDecl *typeDecl,
13241324
ObjCSelector selector,
13251325
bool isInstanceMethod,
13261326
unsigned previousGeneration,
13271327
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods) {
13281328
for (auto &modulePair : LoadedModuleFiles) {
13291329
if (modulePair.second <= previousGeneration)
13301330
continue;
1331-
modulePair.first->loadObjCMethods(classDecl, selector, isInstanceMethod,
1331+
modulePair.first->loadObjCMethods(typeDecl, selector, isInstanceMethod,
13321332
methods);
13331333
}
13341334
}

0 commit comments

Comments
 (0)