Skip to content

Commit 7f6fcf6

Browse files
committed
[cxx-interop] Avoid a ClangImporter dependency on Sema
My recent change started linking ClangImporter with Sema, which accidentally introduced a circular dependency between the two. This patch avoid the usage of type checker logic from ClangImporter's automatic protocol conformance logic. rdar://101763817
1 parent 89c032c commit 7f6fcf6

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

lib/ClangImporter/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ add_swift_host_library(swiftClangImporter STATIC
2828
target_link_libraries(swiftClangImporter PRIVATE
2929
swiftAST
3030
swiftParse
31-
swiftSema
3231
clangTooling
3332
LLVMBitstreamReader)
3433

lib/ClangImporter/ClangDerivedConformances.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ lookupDirectWithoutExtensions(NominalTypeDecl *decl, Identifier id) {
4141
return result;
4242
}
4343

44+
/// Similar to ModuleDecl::conformsToProtocol, but doesn't introduce a
45+
/// dependency on Sema.
46+
static bool isConcreteAndValid(ProtocolConformanceRef conformanceRef,
47+
ModuleDecl *module) {
48+
if (conformanceRef.isInvalid())
49+
return false;
50+
if (!conformanceRef.isConcrete())
51+
return false;
52+
auto conformance = conformanceRef.getConcrete();
53+
auto subMap = conformance->getSubstitutions(module);
54+
return llvm::all_of(subMap.getConformances(),
55+
[&](ProtocolConformanceRef each) -> bool {
56+
return isConcreteAndValid(each, module);
57+
});
58+
}
59+
4460
static clang::TypeDecl *
4561
getIteratorCategoryDecl(const clang::CXXRecordDecl *clangDecl) {
4662
clang::IdentifierInfo *iteratorCategoryDeclName =
@@ -126,7 +142,9 @@ static ValueDecl *getMinusOperator(NominalTypeDecl *decl) {
126142
if (lhsNominal != rhsNominal || lhsNominal != decl)
127143
return false;
128144
auto returnTy = minus->getResultInterfaceType();
129-
if (!module->conformsToProtocol(returnTy, binaryIntegerProto))
145+
auto conformanceRef =
146+
module->lookupConformance(returnTy, binaryIntegerProto);
147+
if (!isConcreteAndValid(conformanceRef, module))
130148
return false;
131149
return true;
132150
};
@@ -331,9 +349,10 @@ void swift::conformToCxxSequenceIfNeeded(
331349
return;
332350

333351
// Check if RawIterator conforms to UnsafeCxxInputIterator.
334-
auto rawIteratorConformanceRef = decl->getModuleContext()->conformsToProtocol(
335-
rawIteratorTy, cxxIteratorProto);
336-
if (!rawIteratorConformanceRef || !rawIteratorConformanceRef.isConcrete())
352+
ModuleDecl *module = decl->getModuleContext();
353+
auto rawIteratorConformanceRef =
354+
module->lookupConformance(rawIteratorTy, cxxIteratorProto);
355+
if (!isConcreteAndValid(rawIteratorConformanceRef, module))
337356
return;
338357
auto rawIteratorConformance = rawIteratorConformanceRef.getConcrete();
339358
auto pointeeDecl =
@@ -356,7 +375,7 @@ void swift::conformToCxxSequenceIfNeeded(
356375
return declSelfTy;
357376
return Type(dependentType);
358377
},
359-
LookUpConformanceInModule(decl->getModuleContext()));
378+
LookUpConformanceInModule(module));
360379

361380
impl.addSynthesizedTypealias(decl, ctx.Id_Element, pointeeTy);
362381
impl.addSynthesizedTypealias(decl, ctx.Id_Iterator, iteratorTy);

0 commit comments

Comments
 (0)