Skip to content

Commit 89d5725

Browse files
committed
ClangImporter: Delay building imported conformances until we ask for them
1 parent be84556 commit 89d5725

File tree

2 files changed

+24
-62
lines changed

2 files changed

+24
-62
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6864,30 +6864,11 @@ void SwiftDeclConverter::addObjCProtocolConformances(
68646864

68656865
Impl.recordImportedProtocols(decl, protocols);
68666866

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

@@ -8690,7 +8671,7 @@ void ClangImporter::Implementation::collectMembersToAdd(
86908671

86918672
SwiftDeclConverter converter(*this, CurrentVersion);
86928673

8693-
SmallVector<ProtocolDecl *, 4> protos = takeImportedProtocols(D);
8674+
auto protos = getImportedProtocols(D);
86948675
if (auto clangClass = dyn_cast<clang::ObjCInterfaceDecl>(objcContainer)) {
86958676
auto swiftClass = cast<ClassDecl>(D);
86968677
objcContainer = clangClass = clangClass->getDefinition();
@@ -8713,9 +8694,22 @@ void ClangImporter::Implementation::collectMembersToAdd(
87138694
}
87148695

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

87218715
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();
@@ -1179,24 +1171,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
11791171
/// 'let' declaration as opposed to 'var'.
11801172
bool shouldImportGlobalAsLet(clang::QualType type);
11811173

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

1210-
auto &recorded = ImportedProtocols[decl];
1211-
recorded.insert(recorded.end(), protocols.begin(), protocols.end());
1184+
ImportedProtocols[decl] = SwiftContext.AllocateCopy(protocols);
12121185
}
12131186

12141187
/// Retrieve the imported protocols for the given declaration.
1215-
SmallVector<ProtocolDecl *, 4> takeImportedProtocols(const Decl *decl) {
1216-
SmallVector<ProtocolDecl *, 4> result;
1217-
1188+
ArrayRef<ProtocolDecl *> getImportedProtocols(const Decl *decl) {
12181189
auto known = ImportedProtocols.find(decl);
1219-
if (known != ImportedProtocols.end()) {
1220-
result = std::move(known->second);
1221-
ImportedProtocols.erase(known);
1222-
}
1223-
1224-
return result;
1190+
if (known != ImportedProtocols.end())
1191+
return known->second;
1192+
return ArrayRef<ProtocolDecl *>();
12251193
}
12261194

12271195
EnumDecl *lookupErrorCodeEnum(const StructDecl *errorWrapper) {

0 commit comments

Comments
 (0)