Skip to content

Commit e50096f

Browse files
authored
Merge pull request #30080 from nkcsgexi/ObjCCategoryDecl-canonical
ClangImporter: import non-canonical ObjCCategoryDecl after recent clang changes
2 parents b80b21b + 3fe4b89 commit e50096f

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2749,8 +2749,10 @@ void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
27492749
// Add the extensions produced by importing categories.
27502750
for (auto category : lookupTable->categories()) {
27512751
if (auto extension = cast_or_null<ExtensionDecl>(
2752-
owner.importDecl(category, owner.CurrentVersion)))
2752+
owner.importDecl(category, owner.CurrentVersion,
2753+
/*UseCanonical*/false))) {
27532754
results.push_back(extension);
2755+
}
27542756
}
27552757

27562758
auto findEnclosingExtension = [](Decl *importedDecl) -> ExtensionDecl * {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4613,7 +4613,7 @@ namespace {
46134613

46144614
// Create the extension declaration and record it.
46154615
objcClass->addExtension(result);
4616-
Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
4616+
Impl.ImportedDecls[{decl, getVersion()}] = result;
46174617
SmallVector<TypeLoc, 4> inheritedTypes;
46184618
importObjCProtocols(result, decl->getReferencedProtocols(),
46194619
inheritedTypes);
@@ -7380,8 +7380,10 @@ void SwiftDeclConverter::importInheritedConstructors(
73807380

73817381
Decl *ClangImporter::Implementation::importDeclCached(
73827382
const clang::NamedDecl *ClangDecl,
7383-
ImportNameVersion version) {
7384-
auto Known = ImportedDecls.find({ClangDecl->getCanonicalDecl(), version});
7383+
ImportNameVersion version,
7384+
bool UseCanonical) {
7385+
auto Known = ImportedDecls.find(
7386+
{ UseCanonical? ClangDecl->getCanonicalDecl(): ClangDecl, version });
73857387
if (Known != ImportedDecls.end())
73867388
return Known->second;
73877389

@@ -7970,7 +7972,8 @@ void ClangImporter::Implementation::finishNormalConformance(
79707972
Decl *ClangImporter::Implementation::importDeclAndCacheImpl(
79717973
const clang::NamedDecl *ClangDecl,
79727974
ImportNameVersion version,
7973-
bool SuperfluousTypedefsAreTransparent) {
7975+
bool SuperfluousTypedefsAreTransparent,
7976+
bool UseCanonicalDecl) {
79747977
if (!ClangDecl)
79757978
return nullptr;
79767979

@@ -7979,9 +7982,9 @@ Decl *ClangImporter::Implementation::importDeclAndCacheImpl(
79797982
clang::PrettyStackTraceDecl trace(ClangDecl, clang::SourceLocation(),
79807983
Instance->getSourceManager(), "importing");
79817984

7982-
auto Canon = cast<clang::NamedDecl>(ClangDecl->getCanonicalDecl());
7985+
auto Canon = cast<clang::NamedDecl>(UseCanonicalDecl? ClangDecl->getCanonicalDecl(): ClangDecl);
79837986

7984-
if (auto Known = importDeclCached(Canon, version)) {
7987+
if (auto Known = importDeclCached(Canon, version, UseCanonicalDecl)) {
79857988
if (!SuperfluousTypedefsAreTransparent &&
79867989
SuperfluousTypedefs.count(Canon))
79877990
return nullptr;
@@ -8082,8 +8085,11 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
80828085
auto decl = dyn_cast<clang::NamedDecl>(dc);
80838086
if (!decl)
80848087
return nullptr;
8085-
8086-
auto swiftDecl = importDecl(decl, CurrentVersion);
8088+
// Category decls with same name can be merged and using canonical decl always
8089+
// leads to the first category of the given name. We'd like to keep these
8090+
// categories separated.
8091+
auto useCanonical = !isa<clang::ObjCCategoryDecl>(decl);
8092+
auto swiftDecl = importDecl(decl, CurrentVersion, useCanonical);
80878093
if (!swiftDecl)
80888094
return nullptr;
80898095

lib/ClangImporter/ImporterImpl.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -775,24 +775,28 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
775775

776776
/// If we already imported a given decl, return the corresponding Swift decl.
777777
/// Otherwise, return nullptr.
778-
Decl *importDeclCached(const clang::NamedDecl *ClangDecl, Version version);
778+
Decl *importDeclCached(const clang::NamedDecl *ClangDecl, Version version,
779+
bool UseCanonicalDecl = true);
779780

780781
Decl *importDeclImpl(const clang::NamedDecl *ClangDecl, Version version,
781782
bool &TypedefIsSuperfluous, bool &HadForwardDeclaration);
782783

783784
Decl *importDeclAndCacheImpl(const clang::NamedDecl *ClangDecl,
784785
Version version,
785-
bool SuperfluousTypedefsAreTransparent);
786+
bool SuperfluousTypedefsAreTransparent,
787+
bool UseCanonicalDecl);
786788

787789
/// Same as \c importDeclReal, but for use inside importer
788790
/// implementation.
789791
///
790792
/// Unlike \c importDeclReal, this function for convenience transparently
791793
/// looks through superfluous typedefs and returns the imported underlying
792794
/// decl in that case.
793-
Decl *importDecl(const clang::NamedDecl *ClangDecl, Version version) {
795+
Decl *importDecl(const clang::NamedDecl *ClangDecl, Version version,
796+
bool UseCanonicalDecl = true) {
794797
return importDeclAndCacheImpl(ClangDecl, version,
795-
/*SuperfluousTypedefsAreTransparent=*/true);
798+
/*SuperfluousTypedefsAreTransparent=*/true,
799+
/*UseCanonicalDecl*/UseCanonicalDecl);
796800
}
797801

798802
/// Import the given Clang declaration into Swift. Use this function
@@ -803,7 +807,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
803807
/// not be represented in Swift.
804808
Decl *importDeclReal(const clang::NamedDecl *ClangDecl, Version version) {
805809
return importDeclAndCacheImpl(ClangDecl, version,
806-
/*SuperfluousTypedefsAreTransparent=*/false);
810+
/*SuperfluousTypedefsAreTransparent=*/false,
811+
/*UseCanonicalDecl*/true);
807812
}
808813

809814
/// Import a cloned version of the given declaration, which is part of

0 commit comments

Comments
 (0)