Skip to content

Commit 45e5848

Browse files
committed
ClangImporter: Delay building imported conformances until we ask for them
1 parent d76c127 commit 45e5848

File tree

2 files changed

+28
-69
lines changed

2 files changed

+28
-69
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4511,9 +4511,7 @@ namespace {
45114511
/// methods become class methods on NSObject).
45124512
void importMirroredProtocolMembers(const clang::ObjCContainerDecl *decl,
45134513
DeclContext *dc,
4514-
ArrayRef<ProtocolDecl *> protocols,
4515-
SmallVectorImpl<Decl *> &members,
4516-
ASTContext &Ctx);
4514+
SmallVectorImpl<Decl *> &members);
45174515

45184516
void importNonOverriddenMirroredMethods(DeclContext *dc,
45194517
MutableArrayRef<MirroredMethodEntry> entries,
@@ -6861,30 +6859,11 @@ void SwiftDeclConverter::addObjCProtocolConformances(
68616859

68626860
Impl.recordImportedProtocols(decl, protocols);
68636861

6864-
// Synthesize trivial conformances for each of the protocols.
6865-
SmallVector<ProtocolConformance *, 4> conformances;
6866-
6867-
auto dc = decl->getInnermostDeclContext();
6868-
auto &ctx = Impl.SwiftContext;
6869-
for (unsigned i = 0, n = protocols.size(); i != n; ++i) {
6870-
// FIXME: Build a superclass conformance if the superclass
6871-
// conforms.
6872-
auto conformance = ctx.getConformance(dc->getDeclaredInterfaceType(),
6873-
protocols[i], SourceLoc(), dc,
6874-
ProtocolConformanceState::Incomplete);
6875-
conformance->setLazyLoader(&Impl, /*context*/0);
6876-
conformance->setState(ProtocolConformanceState::Complete);
6877-
conformances.push_back(conformance);
6878-
}
6879-
6880-
// Set the conformances.
6881-
// FIXME: This could be lazier.
6882-
unsigned id = Impl.allocateDelayedConformance(std::move(conformances));
68836862
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
6884-
nominal->setConformanceLoader(&Impl, id);
6863+
nominal->setConformanceLoader(&Impl, 0);
68856864
} else {
68866865
auto ext = cast<ExtensionDecl>(decl);
6887-
ext->setConformanceLoader(&Impl, id);
6866+
ext->setConformanceLoader(&Impl, 0);
68886867
}
68896868
}
68906869

@@ -6950,13 +6929,14 @@ Optional<GenericParamList *> SwiftDeclConverter::importObjCGenericParams(
69506929

69516930
void SwiftDeclConverter::importMirroredProtocolMembers(
69526931
const clang::ObjCContainerDecl *decl, DeclContext *dc,
6953-
ArrayRef<ProtocolDecl *> protocols, SmallVectorImpl<Decl *> &members,
6954-
ASTContext &Ctx) {
6932+
SmallVectorImpl<Decl *> &members) {
69556933
assert(dc);
69566934
const clang::ObjCInterfaceDecl *interfaceDecl = nullptr;
69576935
const ClangModuleUnit *declModule;
69586936
const ClangModuleUnit *interfaceModule;
69596937

6938+
auto protocols = Impl.getImportedProtocols(dc->getAsDecl());
6939+
69606940
// 'protocols' is, for some reason, the full recursive expansion of
69616941
// the protocol hierarchy, so there's no need to recursively descend
69626942
// into inherited protocols.
@@ -8696,7 +8676,6 @@ void ClangImporter::Implementation::collectMembersToAdd(
86968676
insertMembersAndAlternates(nd, members);
86978677
}
86988678

8699-
SmallVector<ProtocolDecl *, 4> protos = takeImportedProtocols(D);
87008679
if (auto clangClass = dyn_cast<clang::ObjCInterfaceDecl>(objcContainer)) {
87018680
importInheritedConstructors(cast<ClassDecl>(D), members);
87028681

@@ -8710,14 +8689,26 @@ void ClangImporter::Implementation::collectMembersToAdd(
87108689
// or extension conforms.
87118690
// FIXME: This is supposed to be a short-term hack.
87128691
SwiftDeclConverter converter(*this, CurrentVersion);
8713-
converter.importMirroredProtocolMembers(objcContainer, DC,
8714-
protos, members, SwiftContext);
8692+
converter.importMirroredProtocolMembers(objcContainer, DC, members);
87158693
}
87168694

87178695
void ClangImporter::Implementation::loadAllConformances(
8718-
const Decl *D, uint64_t contextData,
8696+
const Decl *decl, uint64_t contextData,
87198697
SmallVectorImpl<ProtocolConformance *> &Conformances) {
8720-
Conformances = takeDelayedConformance(contextData);
8698+
auto dc = decl->getInnermostDeclContext();
8699+
8700+
// Synthesize trivial conformances for each of the protocols.
8701+
for (auto *protocol : getImportedProtocols(decl)) {
8702+
// FIXME: Build a superclass conformance if the superclass
8703+
// conforms.
8704+
auto conformance = SwiftContext.getConformance(
8705+
dc->getDeclaredInterfaceType(),
8706+
protocol, SourceLoc(), dc,
8707+
ProtocolConformanceState::Incomplete);
8708+
conformance->setLazyLoader(this, /*context*/0);
8709+
conformance->setState(ProtocolConformanceState::Complete);
8710+
Conformances.push_back(conformance);
8711+
}
87218712
}
87228713

87238714
Optional<MappedTypeNameKind>

lib/ClangImporter/ImporterImpl.h

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -559,17 +559,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
559559
/// Records those modules that we have looked up.
560560
llvm::DenseMap<Identifier, ModuleDecl *> checkedModules;
561561

562-
/// Mapping from delayed conformance IDs to the set of delayed
563-
/// protocol conformances.
564-
llvm::DenseMap<unsigned, SmallVector<ProtocolConformance *, 4>>
565-
DelayedConformances;
566-
567-
/// The next delayed conformance ID to use with \c DelayedConformances.
568-
unsigned NextDelayedConformanceID = 0;
569-
570562
/// The set of imported protocols for a declaration, used only to
571563
/// load all members of the declaration.
572-
llvm::DenseMap<const Decl *, SmallVector<ProtocolDecl *, 4>>
564+
llvm::DenseMap<const Decl *, ArrayRef<ProtocolDecl *>>
573565
ImportedProtocols;
574566

575567
void startedImportingEntity();
@@ -1182,24 +1174,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
11821174
/// 'let' declaration as opposed to 'var'.
11831175
bool shouldImportGlobalAsLet(clang::QualType type);
11841176

1185-
/// Allocate a new delayed conformance ID with the given set of
1186-
/// conformances.
1187-
unsigned allocateDelayedConformance(
1188-
SmallVector<ProtocolConformance *, 4> &&conformances) {
1189-
unsigned id = NextDelayedConformanceID++;
1190-
DelayedConformances[id] = std::move(conformances);
1191-
return id;
1192-
}
1193-
1194-
/// Take the delayed conformances associated with the given id.
1195-
SmallVector<ProtocolConformance *, 4> takeDelayedConformance(unsigned id) {
1196-
auto conformances = DelayedConformances.find(id);
1197-
SmallVector<ProtocolConformance *, 4> result
1198-
= std::move(conformances->second);
1199-
DelayedConformances.erase(conformances);
1200-
return result;
1201-
}
1202-
12031177
/// Record the set of imported protocols for the given declaration,
12041178
/// to be used by member loading.
12051179
///
@@ -1210,21 +1184,15 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
12101184
if (protocols.empty())
12111185
return;
12121186

1213-
auto &recorded = ImportedProtocols[decl];
1214-
recorded.insert(recorded.end(), protocols.begin(), protocols.end());
1187+
ImportedProtocols[decl] = SwiftContext.AllocateCopy(protocols);
12151188
}
12161189

12171190
/// Retrieve the imported protocols for the given declaration.
1218-
SmallVector<ProtocolDecl *, 4> takeImportedProtocols(const Decl *decl) {
1219-
SmallVector<ProtocolDecl *, 4> result;
1220-
1191+
ArrayRef<ProtocolDecl *> getImportedProtocols(const Decl *decl) {
12211192
auto known = ImportedProtocols.find(decl);
1222-
if (known != ImportedProtocols.end()) {
1223-
result = std::move(known->second);
1224-
ImportedProtocols.erase(known);
1225-
}
1226-
1227-
return result;
1193+
if (known != ImportedProtocols.end())
1194+
return known->second;
1195+
return ArrayRef<ProtocolDecl *>();
12281196
}
12291197

12301198
EnumDecl *lookupErrorCodeEnum(const StructDecl *errorWrapper) {

0 commit comments

Comments
 (0)