Skip to content

Commit e316a8e

Browse files
committed
[Importer] While pretty-printing decls for diagnostics, don't emit diagnostics.
The diagnostics system doesn't allow a diagnostic to be emitted while another diagnostic is in flight. Doing so will cause an assertion in the diagnostics machinery. There's a longstanding cycle here when diagnostics emission pretty-prints declarations that are imported from a Clang module, and the Clang Importer emits a diagnostic. Squash this cycle forcefully, dropping the diagnostic that the Clang importer would emit.
1 parent dbc021a commit e316a8e

File tree

6 files changed

+45
-30
lines changed

6 files changed

+45
-30
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,10 @@ namespace swift {
740740
/// Path to diagnostic documentation directory.
741741
std::string diagnosticDocumentationPath = "";
742742

743+
/// Whether we are actively pretty-printing a declaration as part of
744+
/// diagnostics.
745+
bool IsPrettyPrintingDecl = false;
746+
743747
friend class InFlightDiagnostic;
744748
friend class DiagnosticTransaction;
745749
friend class CompoundDiagnosticTransaction;
@@ -796,6 +800,8 @@ namespace swift {
796800
return diagnosticDocumentationPath;
797801
}
798802

803+
bool isPrettyPrintingDecl() const { return IsPrettyPrintingDecl; }
804+
799805
void setLocalization(std::string locale, std::string path) {
800806
assert(!locale.empty());
801807
assert(!path.empty());

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,8 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
10391039
// Pretty-print the declaration we've picked.
10401040
llvm::raw_svector_ostream out(buffer);
10411041
TrackingPrinter printer(entries, out, bufferAccessLevel);
1042+
llvm::SaveAndRestore<bool> isPrettyPrinting(
1043+
IsPrettyPrintingDecl, true);
10421044
ppDecl->print(
10431045
printer,
10441046
PrintOptions::printForDiagnostics(

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ bool ClangImporter::Implementation::importHeader(
13661366
// to correct. The fix would be explicitly importing on the command line.
13671367
if (implicitImport && !allParsedDecls.empty() &&
13681368
BridgingHeaderExplicitlyRequested) {
1369-
SwiftContext.Diags.diagnose(
1369+
diagnose(
13701370
diagLoc, diag::implicit_bridging_header_imported_from_module,
13711371
llvm::sys::path::filename(headerName), adapter->getName());
13721372
}
@@ -1401,8 +1401,7 @@ bool ClangImporter::Implementation::importHeader(
14011401

14021402
// FIXME: What do we do if there was already an error?
14031403
if (!hadError && clangDiags.hasErrorOccurred()) {
1404-
SwiftContext.Diags.diagnose(diagLoc, diag::bridging_header_error,
1405-
headerName);
1404+
diagnose(diagLoc, diag::bridging_header_error, headerName);
14061405
return true;
14071406
}
14081407

@@ -1450,8 +1449,7 @@ bool ClangImporter::importBridgingHeader(StringRef header, ModuleDecl *adapter,
14501449
clang::FileManager &fileManager = Impl.Instance->getFileManager();
14511450
auto headerFile = fileManager.getFile(header, /*OpenFile=*/true);
14521451
if (!headerFile) {
1453-
Impl.SwiftContext.Diags.diagnose(diagLoc, diag::bridging_header_missing,
1454-
header);
1452+
Impl.diagnose(diagLoc, diag::bridging_header_missing, header);
14551453
return true;
14561454
}
14571455

@@ -1519,8 +1517,7 @@ std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
15191517

15201518
success |= !rewriteInstance.getDiagnostics().hasErrorOccurred();
15211519
if (!success) {
1522-
Impl.SwiftContext.Diags.diagnose({},
1523-
diag::could_not_rewrite_bridging_header);
1520+
Impl.diagnose({}, diag::could_not_rewrite_bridging_header);
15241521
return "";
15251522
}
15261523

@@ -1607,9 +1604,8 @@ ClangImporter::emitBridgingPCH(StringRef headerPath,
16071604
emitInstance->ExecuteAction(*action);
16081605

16091606
if (emitInstance->getDiagnostics().hasErrorOccurred()) {
1610-
Impl.SwiftContext.Diags.diagnose({},
1611-
diag::bridging_header_pch_error,
1612-
outputPCHPath, headerPath);
1607+
Impl.diagnose({}, diag::bridging_header_pch_error,
1608+
outputPCHPath, headerPath);
16131609
return true;
16141610
}
16151611
return false;
@@ -1668,9 +1664,7 @@ bool ClangImporter::emitPrecompiledModule(StringRef moduleMapPath,
16681664
emitInstance->ExecuteAction(*action);
16691665

16701666
if (emitInstance->getDiagnostics().hasErrorOccurred()) {
1671-
Impl.SwiftContext.Diags.diagnose({},
1672-
diag::emit_pcm_error,
1673-
outputPath, moduleMapPath);
1667+
Impl.diagnose({}, diag::emit_pcm_error, outputPath, moduleMapPath);
16741668
return true;
16751669
}
16761670
return false;
@@ -1693,7 +1687,7 @@ bool ClangImporter::dumpPrecompiledModule(StringRef modulePath,
16931687
dumpInstance->ExecuteAction(*action);
16941688

16951689
if (dumpInstance->getDiagnostics().hasErrorOccurred()) {
1696-
Impl.SwiftContext.Diags.diagnose({}, diag::dump_pcm_error, modulePath);
1690+
Impl.diagnose({}, diag::dump_pcm_error, modulePath);
16971691
return true;
16981692
}
16991693
return false;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3985,18 +3985,15 @@ namespace {
39853985

39863986
if (dc->getSelfProtocolDecl() && !selfIdx) {
39873987
// FIXME: source location...
3988-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
3989-
/*isInit=*/false);
3990-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
3991-
decl->getName());
3988+
Impl.diagnose({}, diag::swift_name_protocol_static, /*isInit=*/false);
3989+
Impl.diagnose({}, diag::note_while_importing, decl->getName());
39923990
return nullptr;
39933991
}
39943992

39953993
if (!decl->hasPrototype()) {
39963994
// FIXME: source location...
3997-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_no_prototype);
3998-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
3999-
decl->getName());
3995+
Impl.diagnose({}, diag::swift_name_no_prototype);
3996+
Impl.diagnose({}, diag::note_while_importing, decl->getName());
40003997
return nullptr;
40013998
}
40023999

@@ -6302,10 +6299,8 @@ Decl *SwiftDeclConverter::importGlobalAsInitializer(
63026299
// Check for some invalid imports
63036300
if (dc->getSelfProtocolDecl()) {
63046301
// FIXME: clang source location
6305-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
6306-
/*isInit=*/true);
6307-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
6308-
decl->getName());
6302+
Impl.diagnose({}, diag::swift_name_protocol_static, /*isInit=*/true);
6303+
Impl.diagnose({}, diag::note_while_importing, decl->getName());
63096304
return nullptr;
63106305
}
63116306

@@ -8217,9 +8212,8 @@ void ClangImporter::Implementation::importAttributes(
82178212
getBufferImporterForDiagnostics();
82188213
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
82198214
clangSrcMgr, swiftAttr->getLocation());
8220-
SwiftContext.Diags.diagnose(
8221-
attrLoc, diag::clang_swift_attr_without_at,
8222-
swiftAttr->getAttribute());
8215+
diagnose(attrLoc, diag::clang_swift_attr_without_at,
8216+
swiftAttr->getAttribute());
82238217
}
82248218
continue;
82258219
}

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,12 +2450,12 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
24502450
SourceLoc methodLoc =
24512451
bufferImporter.resolveSourceLocation(srcMgr, clangDecl->getLocation());
24522452
if (methodLoc.isValid()) {
2453-
SwiftContext.Diags.diagnose(methodLoc, diag::invalid_swift_name_method,
2453+
diagnose(methodLoc, diag::invalid_swift_name_method,
24542454
swiftParams.size() < argNames.size(),
24552455
swiftParams.size(), argNames.size());
24562456
ModuleDecl *parentModule = dc->getParentModule();
24572457
if (parentModule != ImportedHeaderUnit->getParentModule()) {
2458-
SwiftContext.Diags.diagnose(
2458+
diagnose(
24592459
methodLoc, diag::unresolvable_clang_decl_is_a_framework_bug,
24602460
parentModule->getName().str());
24612461
}

lib/ClangImporter/ImporterImpl.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,25 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
747747
bool fullyQualified,
748748
llvm::raw_ostream &os);
749749

750+
/// Emit a diagnostic, taking care not to interrupt a diagnostic that's
751+
/// already in flight.
752+
template<typename ...Args>
753+
void diagnose(Args &&...args) {
754+
// If we're in the middle of pretty-printing, suppress diagnostics.
755+
if (SwiftContext.Diags.isPrettyPrintingDecl()) {
756+
return;
757+
}
758+
759+
SwiftContext.Diags.diagnose(std::forward<Args>(args)...);
760+
}
761+
762+
/// Emit a diagnostic, taking care not to interrupt a diagnostic that's
763+
/// already in flight.
764+
template<typename ...Args>
765+
void diagnose(SourceLoc loc, Args &&...args) {
766+
diagnose(loc, std::forward<Args>(args)...);
767+
}
768+
750769
/// Import the given Clang identifier into Swift.
751770
///
752771
/// \param identifier The Clang identifier to map into Swift.

0 commit comments

Comments
 (0)