@@ -9204,7 +9204,7 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl,
9204
9204
}
9205
9205
9206
9206
DeclContext *ClangImporter::Implementation::importDeclContextImpl (
9207
- const clang::DeclContext *dc) {
9207
+ const clang::Decl *ImportingDecl, const clang:: DeclContext *dc) {
9208
9208
// Every declaration should come from a module, so we should not see the
9209
9209
// TranslationUnit DeclContext here.
9210
9210
assert (!dc->isTranslationUnit ());
@@ -9217,7 +9217,8 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
9217
9217
// leads to the first category of the given name. We'd like to keep these
9218
9218
// categories separated.
9219
9219
auto useCanonical = !isa<clang::ObjCCategoryDecl>(decl);
9220
- auto swiftDecl = importDecl (decl, CurrentVersion, useCanonical);
9220
+ auto swiftDecl = importDeclForDeclContext (ImportingDecl, decl->getName (),
9221
+ decl, CurrentVersion, useCanonical);
9221
9222
if (!swiftDecl)
9222
9223
return nullptr ;
9223
9224
@@ -9270,6 +9271,71 @@ GenericSignature ClangImporter::Implementation::buildGenericSignature(
9270
9271
GenericSignature ());
9271
9272
}
9272
9273
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
+
9273
9339
DeclContext *
9274
9340
ClangImporter::Implementation::importDeclContextOf (
9275
9341
const clang::Decl *decl,
@@ -9287,13 +9353,15 @@ ClangImporter::Implementation::importDeclContextOf(
9287
9353
}
9288
9354
9289
9355
// Import the DeclContext.
9290
- importedDC = importDeclContextImpl (dc);
9356
+ importedDC = importDeclContextImpl (decl, dc);
9291
9357
break ;
9292
9358
}
9293
9359
9294
9360
case EffectiveClangContext::TypedefContext: {
9295
9361
// 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);
9297
9365
if (!importedDecl) return nullptr ;
9298
9366
9299
9367
// Dig out the imported DeclContext.
@@ -9311,17 +9379,19 @@ ClangImporter::Implementation::importDeclContextOf(
9311
9379
if (auto clangDecl
9312
9380
= lookupTable->resolveContext (context.getUnresolvedName ())) {
9313
9381
// 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 ;
9316
9386
9317
9387
// Look through typealiases.
9318
- if (auto typealias = dyn_cast<TypeAliasDecl>(decl ))
9388
+ if (auto typealias = dyn_cast<TypeAliasDecl>(swiftDecl ))
9319
9389
importedDC = typealias->getDeclaredInterfaceType ()->getAnyNominal ();
9320
9390
else // Map to a nominal type declaration.
9321
- importedDC = dyn_cast<NominalTypeDecl>(decl);
9322
- break ;
9391
+ importedDC = dyn_cast<NominalTypeDecl>(swiftDecl);
9323
9392
}
9324
9393
}
9394
+ break ;
9325
9395
}
9326
9396
}
9327
9397
0 commit comments