Skip to content

[NFC] Clean the ClangImporter a bit #29093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 8 additions & 50 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4492,11 +4492,6 @@ namespace {
const clang::ObjCProtocolList &clangProtocols,
SmallVectorImpl<TypeLoc> &inheritedTypes);

/// Add conformances to the given Objective-C protocols to the
/// given declaration.
void addObjCProtocolConformances(Decl *decl,
ArrayRef<ProtocolDecl*> protocols);

// Returns None on error. Returns nullptr if there is no type param list to
// import or we suppress its import, as in the case of NSArray, NSSet, and
// NSDictionary.
Expand All @@ -4517,7 +4512,6 @@ namespace {
/// methods become class methods on NSObject).
void importMirroredProtocolMembers(const clang::ObjCContainerDecl *decl,
DeclContext *dc,
ArrayRef<ProtocolDecl *> protocols,
SmallVectorImpl<Decl *> &members);

void importNonOverriddenMirroredMethods(DeclContext *dc,
Expand Down Expand Up @@ -6860,22 +6854,7 @@ void SwiftDeclConverter::importObjCProtocols(
}
}

addObjCProtocolConformances(decl, protocols);
}

void SwiftDeclConverter::addObjCProtocolConformances(
Decl *decl, ArrayRef<ProtocolDecl *> protocols) {
// Nothing to do for protocols.
if (isa<ProtocolDecl>(decl)) return;

Impl.recordImportedProtocols(decl, protocols);

if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
nominal->setConformanceLoader(&Impl, 0);
} else {
auto ext = cast<ExtensionDecl>(decl);
ext->setConformanceLoader(&Impl, 0);
}
}

Optional<GenericParamList *> SwiftDeclConverter::importObjCGenericParams(
Expand Down Expand Up @@ -6940,22 +6919,18 @@ Optional<GenericParamList *> SwiftDeclConverter::importObjCGenericParams(

void SwiftDeclConverter::importMirroredProtocolMembers(
const clang::ObjCContainerDecl *decl, DeclContext *dc,
ArrayRef<ProtocolDecl *> protocols, SmallVectorImpl<Decl *> &members) {
SmallVectorImpl<Decl *> &members) {
assert(dc);
const clang::ObjCInterfaceDecl *interfaceDecl = nullptr;
const ClangModuleUnit *declModule;
const ClangModuleUnit *interfaceModule;

// 'protocols' is, for some reason, the full recursive expansion of
// the protocol hierarchy, so there's no need to recursively descend
// into inherited protocols.

// Try to import only the most specific methods with a particular name.
// We use a MapVector to get deterministic iteration order later.
llvm::MapVector<clang::Selector, std::vector<MirroredMethodEntry>>
methodsByName;

for (auto proto : protocols) {
for (auto proto : Impl.getImportedProtocols(dc->getAsDecl())) {
auto clangProto =
cast_or_null<clang::ObjCProtocolDecl>(proto->getClangDecl());
if (!clangProto)
Expand Down Expand Up @@ -8600,20 +8575,6 @@ bool ClangImporter::Implementation::addMemberAndAlternatesToExtension(
return true;
}

static ExtensionDecl *
figureOutTheDeclarationContextToImportInto(Decl *D, DeclContext *&DC,
IterableDeclContext *&IDC) {
if (auto *nominal = dyn_cast<NominalTypeDecl>(D)) {
DC = nominal;
IDC = nominal;
return nullptr;
}
ExtensionDecl *ext = cast<ExtensionDecl>(D);
DC = ext;
IDC = ext;
return ext;
}

static void loadMembersOfBaseImportedFromClang(ExtensionDecl *ext) {
const NominalTypeDecl *base = ext->getExtendedNominal();
auto *clangBase = base->getClangDecl();
Expand All @@ -8635,19 +8596,18 @@ void ClangImporter::Implementation::loadAllMembersOfObjcContainer(
Instance->getSourceManager(),
"loading members for");

DeclContext *DC;
IterableDeclContext *IDC;
if (ExtensionDecl *ext =
figureOutTheDeclarationContextToImportInto(D, DC, IDC)) {
// If the base is also imported from Clang, load its members first.
assert(isa<ExtensionDecl>(D) || isa<NominalTypeDecl>(D));
if (auto *ext = dyn_cast<ExtensionDecl>(D)) {
// If the extended type is also imported from Clang, load its members first.
loadMembersOfBaseImportedFromClang(ext);
}

startedImportingEntity();

SmallVector<Decl *, 16> members;
collectMembersToAdd(objcContainer, D, DC, members);
collectMembersToAdd(objcContainer, D, cast<DeclContext>(D), members);

auto *IDC = cast<IterableDeclContext>(D);
for (auto member : members) {
if (!isa<AccessorDecl>(member))
IDC->addMember(member);
Expand Down Expand Up @@ -8701,8 +8661,6 @@ void ClangImporter::Implementation::collectMembersToAdd(
}

SwiftDeclConverter converter(*this, CurrentVersion);

auto protos = getImportedProtocols(D);
if (auto clangClass = dyn_cast<clang::ObjCInterfaceDecl>(objcContainer)) {
objcContainer = clangClass = clangClass->getDefinition();
importInheritedConstructors(clangClass, cast<ClassDecl>(D), members);
Expand All @@ -8713,7 +8671,7 @@ void ClangImporter::Implementation::collectMembersToAdd(
// Import mirrored declarations for protocols to which this category
// or extension conforms.
// FIXME: This is supposed to be a short-term hack.
converter.importMirroredProtocolMembers(objcContainer, DC, protos, members);
converter.importMirroredProtocolMembers(objcContainer, DC, members);
}

void ClangImporter::Implementation::loadAllConformances(
Expand Down
12 changes: 11 additions & 1 deletion lib/ClangImporter/ImporterImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1180,12 +1180,22 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
///
/// FIXME: This is all a hack; we should have lazier deserialization
/// of protocols separate from their conformances.
void recordImportedProtocols(const Decl *decl,
void recordImportedProtocols(Decl *decl,
ArrayRef<ProtocolDecl *> protocols) {
// Nothing to do for protocols.
if (isa<ProtocolDecl>(decl)) return;

if (protocols.empty())
return;

ImportedProtocols[decl] = SwiftContext.AllocateCopy(protocols);

if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
nominal->setConformanceLoader(this, 0);
} else {
auto ext = cast<ExtensionDecl>(decl);
ext->setConformanceLoader(this, 0);
}
}

/// Retrieve the imported protocols for the given declaration.
Expand Down