Skip to content

Commit 260a80f

Browse files
authored
Merge pull request #60315 from beccadax/revert-selector-conflict-5.7
2 parents edffc3d + 22df0dd commit 260a80f

32 files changed

+141
-353
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 type that produce
229+
/// Load the methods within the given class that produce
230230
/// Objective-C class or instance methods with the given selector.
231231
///
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
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
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-
NominalTypeDecl *typeDecl,
249+
ClassDecl *classDecl,
250250
ObjCSelector selector,
251251
bool isInstanceMethod,
252252
unsigned previousGeneration,

include/swift/AST/SourceFile.h

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "swift/AST/Import.h"
1818
#include "swift/AST/SynthesizedFileUnit.h"
1919
#include "swift/Basic/Debug.h"
20-
#include "llvm/ADT/Hashing.h"
2120
#include "llvm/ADT/SetVector.h"
2221
#include "llvm/ADT/SmallPtrSet.h"
2322

@@ -244,20 +243,11 @@ class SourceFile final : public FileUnit {
244243
std::vector<ObjCUnsatisfiedOptReq> ObjCUnsatisfiedOptReqs;
245244

246245
/// A selector that is used by two different declarations in the same class.
247-
struct ObjCMethodConflict {
248-
NominalTypeDecl *typeDecl;
249-
ObjCSelector selector;
250-
bool isInstanceMethod;
251-
252-
ObjCMethodConflict(NominalTypeDecl *typeDecl, ObjCSelector selector,
253-
bool isInstanceMethod)
254-
: typeDecl(typeDecl), selector(selector),
255-
isInstanceMethod(isInstanceMethod)
256-
{}
257-
};
246+
/// Fields: typeDecl, selector, isInstanceMethod.
247+
using ObjCMethodConflict = std::tuple<NominalTypeDecl *, ObjCSelector, bool>;
258248

259249
/// List of Objective-C member conflicts we have found during type checking.
260-
llvm::SetVector<ObjCMethodConflict> ObjCMethodConflicts;
250+
std::vector<ObjCMethodConflict> ObjCMethodConflicts;
261251

262252
/// List of attributes added by access notes, used to emit remarks for valid
263253
/// ones.
@@ -646,30 +636,4 @@ inline void simple_display(llvm::raw_ostream &out, const SourceFile *SF) {
646636
}
647637
} // end namespace swift
648638

649-
namespace llvm {
650-
651-
template<>
652-
struct DenseMapInfo<swift::SourceFile::ObjCMethodConflict> {
653-
using ObjCMethodConflict = swift::SourceFile::ObjCMethodConflict;
654-
655-
static inline ObjCMethodConflict getEmptyKey() {
656-
return ObjCMethodConflict(nullptr, {}, false);
657-
}
658-
static inline ObjCMethodConflict getTombstoneKey() {
659-
return ObjCMethodConflict(nullptr, {}, true);
660-
}
661-
static inline unsigned getHashValue(ObjCMethodConflict a) {
662-
return hash_combine(hash_value(a.typeDecl),
663-
DenseMapInfo<swift::ObjCSelector>::getHashValue(a.selector),
664-
hash_value(a.isInstanceMethod));
665-
}
666-
static bool isEqual(ObjCMethodConflict a, ObjCMethodConflict b) {
667-
return a.typeDecl == b.typeDecl && a.selector == b.selector &&
668-
a.isInstanceMethod == b.isInstanceMethod;
669-
}
670-
};
671-
672-
}
673-
674-
675639
#endif

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-
NominalTypeDecl *typeDecl,
312+
ClassDecl *classDecl,
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-
NominalTypeDecl *typeDecl,
88+
ClassDecl *classDecl,
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-
NominalTypeDecl *typeDecl,
193+
ClassDecl *classDecl,
194194
ObjCSelector selector,
195195
bool isInstanceMethod,
196196
unsigned previousGeneration,

lib/AST/ASTContext.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1925,12 +1925,24 @@ void ASTContext::loadObjCMethods(
19251925
PrettyStackTraceSelector stackTraceSelector("looking for", selector);
19261926
PrettyStackTraceDecl stackTraceDecl("...in", tyDecl);
19271927

1928+
// @objc protocols cannot have @objc extension members, so if we've recorded
1929+
// everything in the protocol definition, we've recorded everything. And we
1930+
// only ever use the ObjCSelector version of `NominalTypeDecl::lookupDirect()`
1931+
// on protocols in primary file typechecking, so we don't care about protocols
1932+
// that need to be loaded from files.
1933+
// TODO: Rework `ModuleLoader::loadObjCMethods()` to support protocols too if
1934+
// selector-based `NominalTypeDecl::lookupDirect()` ever needs to work
1935+
// in more situations.
1936+
ClassDecl *classDecl = dyn_cast<ClassDecl>(tyDecl);
1937+
if (!classDecl)
1938+
return;
1939+
19281940
for (auto &loader : getImpl().ModuleLoaders) {
19291941
// Ignore the Clang importer if we've been asked for Swift-only results.
19301942
if (swiftOnly && loader.get() == getClangModuleLoader())
19311943
continue;
19321944

1933-
loader->loadObjCMethods(tyDecl, selector, isInstanceMethod,
1945+
loader->loadObjCMethods(classDecl, selector, isInstanceMethod,
19341946
previousGeneration, methods);
19351947
}
19361948
}

lib/AST/NameLookup.cpp

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
#include "swift/Basic/Statistic.h"
3737
#include "swift/ClangImporter/ClangImporterRequests.h"
3838
#include "swift/Parse/Lexer.h"
39-
#include "swift/Strings.h"
4039
#include "clang/AST/DeclObjC.h"
4140
#include "clang/Basic/Specifiers.h"
4241
#include "llvm/ADT/DenseMap.h"
@@ -1311,24 +1310,7 @@ class swift::ObjCMethodLookupTable
13111310
: public llvm::DenseMap<std::pair<ObjCSelector, char>,
13121311
StoredObjCMethods>,
13131312
public ASTAllocated<ObjCMethodLookupTable>
1314-
{
1315-
SWIFT_DEBUG_DUMP {
1316-
llvm::errs() << "ObjCMethodLookupTable:\n";
1317-
for (auto pair : *this) {
1318-
auto selector = pair.getFirst().first;
1319-
auto isInstanceMethod = pair.getFirst().second;
1320-
auto &methods = pair.getSecond();
1321-
1322-
llvm::errs() << " \"" << (isInstanceMethod ? "-" : "+") << selector
1323-
<< "\":\n";
1324-
for (auto method : methods.Methods) {
1325-
llvm::errs() << " - \"";
1326-
method->dumpRef(llvm::errs());
1327-
llvm::errs() << "\"\n";
1328-
}
1329-
}
1330-
}
1331-
};
1313+
{};
13321314

13331315
MemberLookupTable::MemberLookupTable(ASTContext &ctx) {
13341316
// Register a cleanup with the ASTContext to call the lookup table
@@ -1686,7 +1668,7 @@ bool NominalTypeDecl::createObjCMethodLookup() {
16861668
assert(!ObjCMethodLookup && "Already have an Objective-C member table");
16871669

16881670
// Most types cannot have ObjC methods.
1689-
if (!(isa<ClassDecl>(this) || isa<ProtocolDecl>(this)))
1671+
if (!(isa<ClassDecl>(this)))
16901672
return false;
16911673

16921674
auto &ctx = getASTContext();
@@ -1717,36 +1699,6 @@ NominalTypeDecl::lookupDirect(ObjCSelector selector, bool isInstance) {
17171699
return stored.Methods;
17181700
}
17191701

1720-
/// If there is an apparent conflict between \p newDecl and one of the methods
1721-
/// in \p vec, should we diagnose it?
1722-
static bool
1723-
shouldDiagnoseConflict(NominalTypeDecl *ty, AbstractFunctionDecl *newDecl,
1724-
llvm::TinyPtrVector<AbstractFunctionDecl *> &vec) {
1725-
// Are all conflicting methods imported from ObjC and in our ObjC half or a
1726-
// bridging header? Some code bases implement ObjC methods in Swift even
1727-
// though it's not exactly supported.
1728-
auto newDeclModuleName = newDecl->getModuleContext()->getName();
1729-
if (llvm::all_of(vec, [&](AbstractFunctionDecl *oldDecl) {
1730-
if (!oldDecl->hasClangNode())
1731-
return false;
1732-
auto oldDeclModuleName = oldDecl->getModuleContext()->getName();
1733-
return oldDeclModuleName == newDeclModuleName
1734-
|| oldDeclModuleName.str() == CLANG_HEADER_MODULE_NAME;
1735-
}))
1736-
return false;
1737-
1738-
// If we're looking at protocol requirements, is the new method an async
1739-
// alternative of any existing method, or vice versa?
1740-
if (isa<ProtocolDecl>(ty) &&
1741-
llvm::any_of(vec, [&](AbstractFunctionDecl *oldDecl) {
1742-
return newDecl->getAsyncAlternative(/*isKnownObjC=*/true) == oldDecl
1743-
|| oldDecl->getAsyncAlternative(/*isKnownObjC=*/true) == newDecl;
1744-
}))
1745-
return false;
1746-
1747-
return true;
1748-
}
1749-
17501702
void NominalTypeDecl::recordObjCMethod(AbstractFunctionDecl *method,
17511703
ObjCSelector selector) {
17521704
if (!ObjCMethodLookup && !createObjCMethodLookup())
@@ -1762,11 +1714,12 @@ void NominalTypeDecl::recordObjCMethod(AbstractFunctionDecl *method,
17621714
return;
17631715

17641716
if (auto *sf = method->getParentSourceFile()) {
1765-
if (vec.empty()) {
1766-
sf->ObjCMethodList.push_back(method);
1767-
} else if (shouldDiagnoseConflict(this, method, vec)) {
1717+
if (vec.size() == 1) {
17681718
// We have a conflict.
1769-
sf->ObjCMethodConflicts.insert({ this, selector, isInstanceMethod });
1719+
sf->ObjCMethodConflicts.push_back(std::make_tuple(this, selector,
1720+
isInstanceMethod));
1721+
} if (vec.empty()) {
1722+
sf->ObjCMethodList.push_back(method);
17701723
}
17711724
}
17721725

lib/ClangImporter/ClangImporter.cpp

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

34373437
void ClangImporter::loadObjCMethods(
3438-
NominalTypeDecl *typeDecl,
3438+
ClassDecl *classDecl,
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-
34483443
const auto *objcClass =
34493444
dyn_cast_or_null<clang::ObjCInterfaceDecl>(classDecl->getClangDecl());
34503445
if (!objcClass)

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,31 +2019,12 @@ auto DeclAndTypePrinter::getImpl() -> Implementation {
20192019
return Implementation(os, *this, outputLang);
20202020
}
20212021

2022-
static bool isAsyncAlternativeOfOtherDecl(const ValueDecl *VD) {
2023-
auto AFD = dyn_cast<AbstractFunctionDecl>(VD);
2024-
if (!AFD || !AFD->isAsyncContext() || !AFD->getObjCSelector())
2025-
return false;
2026-
2027-
auto type = AFD->getDeclContext()->getSelfNominalTypeDecl();
2028-
if (!type)
2029-
return false;
2030-
auto others = type->lookupDirect(AFD->getObjCSelector(),
2031-
AFD->isInstanceMember());
2032-
2033-
for (auto other : others)
2034-
if (other->getAsyncAlternative() == AFD)
2035-
return true;
2036-
2037-
return false;
2038-
}
2039-
20402022
bool DeclAndTypePrinter::shouldInclude(const ValueDecl *VD) {
20412023
return !VD->isInvalid() &&
20422024
(outputLang == OutputLanguageMode::Cxx
20432025
? cxx_translation::isVisibleToCxx(VD, minRequiredAccess)
20442026
: isVisibleToObjC(VD, minRequiredAccess)) &&
2045-
!VD->getAttrs().hasAttribute<ImplementationOnlyAttr>() &&
2046-
!isAsyncAlternativeOfOtherDecl(VD);
2027+
!VD->getAttrs().hasAttribute<ImplementationOnlyAttr>();
20472028
}
20482029

20492030
void DeclAndTypePrinter::print(const Decl *D) {

lib/PrintAsClang/PrintAsClang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
8080
"# include <swift/objc-prologue.h>\n"
8181
"#endif\n"
8282
"\n"
83+
"#pragma clang diagnostic ignored \"-Wduplicate-method-match\"\n"
8384
"#pragma clang diagnostic ignored \"-Wauto-import\"\n";
8485
emitObjCConditional(out,
8586
[&] { out << "#include <Foundation/Foundation.h>\n"; });

0 commit comments

Comments
 (0)