@@ -9204,7 +9204,7 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl,
92049204}
92059205
92069206DeclContext *ClangImporter::Implementation::importDeclContextImpl (
9207- const clang::DeclContext *dc) {
9207+ const clang::Decl *ImportingDecl, const clang:: DeclContext *dc) {
92089208 // Every declaration should come from a module, so we should not see the
92099209 // TranslationUnit DeclContext here.
92109210 assert (!dc->isTranslationUnit ());
@@ -9217,7 +9217,8 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
92179217 // leads to the first category of the given name. We'd like to keep these
92189218 // categories separated.
92199219 auto useCanonical = !isa<clang::ObjCCategoryDecl>(decl);
9220- auto swiftDecl = importDecl (decl, CurrentVersion, useCanonical);
9220+ auto swiftDecl = importDeclForDeclContext (ImportingDecl, decl->getName (),
9221+ decl, CurrentVersion, useCanonical);
92219222 if (!swiftDecl)
92229223 return nullptr ;
92239224
@@ -9270,6 +9271,71 @@ GenericSignature ClangImporter::Implementation::buildGenericSignature(
92709271 GenericSignature ());
92719272}
92729273
9274+ Decl *
9275+ ClangImporter::Implementation::importDeclForDeclContext (
9276+ const clang::Decl *importingDecl,
9277+ StringRef writtenName,
9278+ const clang::NamedDecl *contextDecl,
9279+ Version version,
9280+ bool useCanonicalDecl)
9281+ {
9282+ auto key = std::make_tuple (importingDecl, writtenName, contextDecl, version,
9283+ useCanonicalDecl);
9284+ auto iter = find (llvm::reverse (contextDeclsBeingImported), key);
9285+
9286+ // No cycle? Remember that we're importing this, then import normally.
9287+ if (iter == contextDeclsBeingImported.rend ()) {
9288+ contextDeclsBeingImported.push_back (key);
9289+ auto imported = importDecl (contextDecl, version, useCanonicalDecl);
9290+ contextDeclsBeingImported.pop_back ();
9291+ return imported;
9292+ }
9293+
9294+ // There's a cycle. Is the declaration imported enough to break the cycle
9295+ // gracefully? If so, we'll have it in the decl cache.
9296+ if (auto cached = importDeclCached (contextDecl, version, useCanonicalDecl))
9297+ return cached;
9298+
9299+ // Can't break it? Warn and return nullptr, which is at least better than
9300+ // stack overflow by recursion.
9301+
9302+ // Avoid emitting warnings repeatedly.
9303+ if (!contextDeclsWarnedAbout.insert (contextDecl).second )
9304+ return nullptr ;
9305+
9306+ auto convertLoc = [&](clang::SourceLocation clangLoc) {
9307+ return getBufferImporterForDiagnostics ()
9308+ .resolveSourceLocation (getClangASTContext ().getSourceManager (),
9309+ clangLoc);
9310+ };
9311+
9312+ auto getDeclName = [](const clang::Decl *D) -> StringRef {
9313+ if (auto ND = dyn_cast<clang::NamedDecl>(D))
9314+ return ND->getName ();
9315+ return " <anonymous>" ;
9316+ };
9317+
9318+ SourceLoc loc = convertLoc (importingDecl->getLocation ());
9319+ diagnose (loc, diag::swift_name_circular_context_import,
9320+ writtenName, getDeclName (importingDecl));
9321+
9322+ // Diagnose other decls involved in the cycle.
9323+ for (auto entry : make_range (contextDeclsBeingImported.rbegin (), iter)) {
9324+ auto otherDecl = std::get<0 >(entry);
9325+ auto otherWrittenName = std::get<1 >(entry);
9326+ diagnose (convertLoc (otherDecl->getLocation ()),
9327+ diag::swift_name_circular_context_import_other,
9328+ otherWrittenName, getDeclName (otherDecl));
9329+ }
9330+
9331+ if (auto *parentModule = contextDecl->getOwningModule ()) {
9332+ diagnose (loc, diag::unresolvable_clang_decl_is_a_framework_bug,
9333+ parentModule->getFullModuleName ());
9334+ }
9335+
9336+ return nullptr ;
9337+ }
9338+
92739339DeclContext *
92749340ClangImporter::Implementation::importDeclContextOf (
92759341 const clang::Decl *decl,
@@ -9287,13 +9353,15 @@ ClangImporter::Implementation::importDeclContextOf(
92879353 }
92889354
92899355 // Import the DeclContext.
9290- importedDC = importDeclContextImpl (dc);
9356+ importedDC = importDeclContextImpl (decl, dc);
92919357 break ;
92929358 }
92939359
92949360 case EffectiveClangContext::TypedefContext: {
92959361 // Import the typedef-name as a declaration.
9296- auto importedDecl = importDecl (context.getTypedefName (), CurrentVersion);
9362+ auto importedDecl = importDeclForDeclContext (
9363+ decl, context.getTypedefName ()->getName (), context.getTypedefName (),
9364+ CurrentVersion);
92979365 if (!importedDecl) return nullptr ;
92989366
92999367 // Dig out the imported DeclContext.
@@ -9311,17 +9379,19 @@ ClangImporter::Implementation::importDeclContextOf(
93119379 if (auto clangDecl
93129380 = lookupTable->resolveContext (context.getUnresolvedName ())) {
93139381 // Import the Clang declaration.
9314- auto decl = importDecl (clangDecl, CurrentVersion);
9315- if (!decl) return nullptr ;
9382+ auto swiftDecl = importDeclForDeclContext (decl,
9383+ context.getUnresolvedName (),
9384+ clangDecl, CurrentVersion);
9385+ if (!swiftDecl) return nullptr ;
93169386
93179387 // Look through typealiases.
9318- if (auto typealias = dyn_cast<TypeAliasDecl>(decl ))
9388+ if (auto typealias = dyn_cast<TypeAliasDecl>(swiftDecl ))
93199389 importedDC = typealias->getDeclaredInterfaceType ()->getAnyNominal ();
93209390 else // Map to a nominal type declaration.
9321- importedDC = dyn_cast<NominalTypeDecl>(decl);
9322- break ;
9391+ importedDC = dyn_cast<NominalTypeDecl>(swiftDecl);
93239392 }
93249393 }
9394+ break ;
93259395 }
93269396 }
93279397
0 commit comments