@@ -9160,7 +9160,7 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl,
9160
9160
}
9161
9161
9162
9162
DeclContext *ClangImporter::Implementation::importDeclContextImpl (
9163
- const clang::DeclContext *dc) {
9163
+ const clang::Decl *ImportingDecl, const clang:: DeclContext *dc) {
9164
9164
// Every declaration should come from a module, so we should not see the
9165
9165
// TranslationUnit DeclContext here.
9166
9166
assert (!dc->isTranslationUnit ());
@@ -9173,7 +9173,8 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
9173
9173
// leads to the first category of the given name. We'd like to keep these
9174
9174
// categories separated.
9175
9175
auto useCanonical = !isa<clang::ObjCCategoryDecl>(decl);
9176
- auto swiftDecl = importDecl (decl, CurrentVersion, useCanonical);
9176
+ auto swiftDecl = importDeclForDeclContext (ImportingDecl, decl->getName (),
9177
+ decl, CurrentVersion, useCanonical);
9177
9178
if (!swiftDecl)
9178
9179
return nullptr ;
9179
9180
@@ -9226,6 +9227,71 @@ GenericSignature ClangImporter::Implementation::buildGenericSignature(
9226
9227
GenericSignature ());
9227
9228
}
9228
9229
9230
+ Decl *
9231
+ ClangImporter::Implementation::importDeclForDeclContext (
9232
+ const clang::Decl *importingDecl,
9233
+ StringRef writtenName,
9234
+ const clang::NamedDecl *contextDecl,
9235
+ Version version,
9236
+ bool useCanonicalDecl)
9237
+ {
9238
+ auto key = std::make_tuple (importingDecl, writtenName, contextDecl, version,
9239
+ useCanonicalDecl);
9240
+ auto iter = find (llvm::reverse (contextDeclsBeingImported), key);
9241
+
9242
+ // No cycle? Remember that we're importing this, then import normally.
9243
+ if (iter == contextDeclsBeingImported.rend ()) {
9244
+ contextDeclsBeingImported.push_back (key);
9245
+ auto imported = importDecl (contextDecl, version, useCanonicalDecl);
9246
+ contextDeclsBeingImported.pop_back ();
9247
+ return imported;
9248
+ }
9249
+
9250
+ // There's a cycle. Is the declaration imported enough to break the cycle
9251
+ // gracefully? If so, we'll have it in the decl cache.
9252
+ if (auto cached = importDeclCached (contextDecl, version, useCanonicalDecl))
9253
+ return cached;
9254
+
9255
+ // Can't break it? Warn and return nullptr, which is at least better than
9256
+ // stack overflow by recursion.
9257
+
9258
+ // Avoid emitting warnings repeatedly.
9259
+ if (!contextDeclsWarnedAbout.insert (contextDecl).second )
9260
+ return nullptr ;
9261
+
9262
+ auto convertLoc = [&](clang::SourceLocation clangLoc) {
9263
+ return getBufferImporterForDiagnostics ()
9264
+ .resolveSourceLocation (getClangASTContext ().getSourceManager (),
9265
+ clangLoc);
9266
+ };
9267
+
9268
+ auto getDeclName = [](const clang::Decl *D) -> StringRef {
9269
+ if (auto ND = dyn_cast<clang::NamedDecl>(D))
9270
+ return ND->getName ();
9271
+ return " <anonymous>" ;
9272
+ };
9273
+
9274
+ SourceLoc loc = convertLoc (importingDecl->getLocation ());
9275
+ diagnose (loc, diag::swift_name_circular_context_import,
9276
+ writtenName, getDeclName (importingDecl));
9277
+
9278
+ // Diagnose other decls involved in the cycle.
9279
+ for (auto entry : make_range (contextDeclsBeingImported.rbegin (), iter)) {
9280
+ auto otherDecl = std::get<0 >(entry);
9281
+ auto otherWrittenName = std::get<1 >(entry);
9282
+ diagnose (convertLoc (otherDecl->getLocation ()),
9283
+ diag::swift_name_circular_context_import_other,
9284
+ otherWrittenName, getDeclName (otherDecl));
9285
+ }
9286
+
9287
+ if (auto *parentModule = contextDecl->getOwningModule ()) {
9288
+ diagnose (loc, diag::unresolvable_clang_decl_is_a_framework_bug,
9289
+ parentModule->getFullModuleName ());
9290
+ }
9291
+
9292
+ return nullptr ;
9293
+ }
9294
+
9229
9295
DeclContext *
9230
9296
ClangImporter::Implementation::importDeclContextOf (
9231
9297
const clang::Decl *decl,
@@ -9243,13 +9309,15 @@ ClangImporter::Implementation::importDeclContextOf(
9243
9309
}
9244
9310
9245
9311
// Import the DeclContext.
9246
- importedDC = importDeclContextImpl (dc);
9312
+ importedDC = importDeclContextImpl (decl, dc);
9247
9313
break ;
9248
9314
}
9249
9315
9250
9316
case EffectiveClangContext::TypedefContext: {
9251
9317
// Import the typedef-name as a declaration.
9252
- auto importedDecl = importDecl (context.getTypedefName (), CurrentVersion);
9318
+ auto importedDecl = importDeclForDeclContext (
9319
+ decl, context.getTypedefName ()->getName (), context.getTypedefName (),
9320
+ CurrentVersion);
9253
9321
if (!importedDecl) return nullptr ;
9254
9322
9255
9323
// Dig out the imported DeclContext.
@@ -9267,17 +9335,19 @@ ClangImporter::Implementation::importDeclContextOf(
9267
9335
if (auto clangDecl
9268
9336
= lookupTable->resolveContext (context.getUnresolvedName ())) {
9269
9337
// Import the Clang declaration.
9270
- auto decl = importDecl (clangDecl, CurrentVersion);
9271
- if (!decl) return nullptr ;
9338
+ auto swiftDecl = importDeclForDeclContext (decl,
9339
+ context.getUnresolvedName (),
9340
+ clangDecl, CurrentVersion);
9341
+ if (!swiftDecl) return nullptr ;
9272
9342
9273
9343
// Look through typealiases.
9274
- if (auto typealias = dyn_cast<TypeAliasDecl>(decl ))
9344
+ if (auto typealias = dyn_cast<TypeAliasDecl>(swiftDecl ))
9275
9345
importedDC = typealias->getDeclaredInterfaceType ()->getAnyNominal ();
9276
9346
else // Map to a nominal type declaration.
9277
- importedDC = dyn_cast<NominalTypeDecl>(decl);
9278
- break ;
9347
+ importedDC = dyn_cast<NominalTypeDecl>(swiftDecl);
9279
9348
}
9280
9349
}
9350
+ break ;
9281
9351
}
9282
9352
}
9283
9353
0 commit comments