Skip to content

Commit d2d786a

Browse files
committed
[NFC] Add ClangImporter header diagnostic helper
1 parent 0842795 commit d2d786a

File tree

4 files changed

+59
-52
lines changed

4 files changed

+59
-52
lines changed

lib/ClangImporter/ClangDiagnosticConsumer.cpp

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -121,21 +121,13 @@ void ClangDiagnosticConsumer::HandleDiagnostic(
121121
return;
122122
}
123123

124-
const ASTContext &ctx = ImporterImpl.SwiftContext;
125-
ClangSourceBufferImporter &bufferImporter =
126-
ImporterImpl.getBufferImporterForDiagnostics();
127-
128124
if (clangDiag.getID() == clang::diag::err_module_not_built &&
129125
CurrentImport && clangDiag.getArgStdStr(0) == CurrentImport->getName()) {
130-
SourceLoc loc = DiagLoc;
131-
if (clangDiag.getLocation().isValid()) {
132-
loc = bufferImporter.resolveSourceLocation(clangDiag.getSourceManager(),
133-
clangDiag.getLocation());
134-
}
135-
136-
ctx.Diags.diagnose(loc, diag::clang_cannot_build_module,
137-
ctx.LangOpts.EnableObjCInterop,
138-
CurrentImport->getName());
126+
HeaderLoc loc(clangDiag.getLocation(), DiagLoc,
127+
&clangDiag.getSourceManager());
128+
ImporterImpl.diagnose(loc, diag::clang_cannot_build_module,
129+
ImporterImpl.SwiftContext.LangOpts.EnableObjCInterop,
130+
CurrentImport->getName());
139131
return;
140132
}
141133

@@ -146,10 +138,9 @@ void ClangDiagnosticConsumer::HandleDiagnostic(
146138
DiagnosticConsumer::HandleDiagnostic(clangDiagLevel, clangDiag);
147139

148140
// FIXME: Map over source ranges in the diagnostic.
149-
auto emitDiag =
150-
[&ctx, &bufferImporter](clang::FullSourceLoc clangNoteLoc,
151-
clang::DiagnosticsEngine::Level clangDiagLevel,
152-
StringRef message) {
141+
auto emitDiag = [this](clang::FullSourceLoc clangNoteLoc,
142+
clang::DiagnosticsEngine::Level clangDiagLevel,
143+
StringRef message) {
153144
decltype(diag::error_from_clang) diagKind;
154145
switch (clangDiagLevel) {
155146
case clang::DiagnosticsEngine::Ignored:
@@ -170,11 +161,9 @@ void ClangDiagnosticConsumer::HandleDiagnostic(
170161
break;
171162
}
172163

173-
SourceLoc noteLoc;
174-
if (clangNoteLoc.isValid())
175-
noteLoc = bufferImporter.resolveSourceLocation(clangNoteLoc.getManager(),
176-
clangNoteLoc);
177-
ctx.Diags.diagnose(noteLoc, diagKind, message);
164+
HeaderLoc noteLoc(clangNoteLoc, SourceLoc(),
165+
clangNoteLoc.hasManager() ? &clangNoteLoc.getManager() : nullptr);
166+
ImporterImpl.diagnose(noteLoc, diagKind, message);
178167
};
179168

180169
llvm::SmallString<128> message;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8607,12 +8607,7 @@ void ClangImporter::Implementation::importAttributes(
86078607
if (SeenMainActorAttr) {
86088608
// Cannot add main actor annotation twice. We'll keep the first
86098609
// one and raise a warning about the duplicate.
8610-
auto &clangSrcMgr = getClangASTContext().getSourceManager();
8611-
ClangSourceBufferImporter &bufferImporter =
8612-
getBufferImporterForDiagnostics();
8613-
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
8614-
clangSrcMgr, swiftAttr->getLocation());
8615-
8610+
HeaderLoc attrLoc(swiftAttr->getLocation());
86168611
diagnose(attrLoc, diag::import_multiple_mainactor_attr,
86178612
swiftAttr->getAttribute(),
86188613
SeenMainActorAttr.getValue()->getAttribute());
@@ -8668,11 +8663,7 @@ void ClangImporter::Implementation::importAttributes(
86688663

86698664
if (hadError) {
86708665
// Complain about the unhandled attribute or modifier.
8671-
auto &clangSrcMgr = getClangASTContext().getSourceManager();
8672-
ClangSourceBufferImporter &bufferImporter =
8673-
getBufferImporterForDiagnostics();
8674-
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
8675-
clangSrcMgr, swiftAttr->getLocation());
8666+
HeaderLoc attrLoc(swiftAttr->getLocation());
86768667
diagnose(attrLoc, diag::clang_swift_attr_unhandled,
86778668
swiftAttr->getAttribute());
86788669
}
@@ -9246,27 +9237,21 @@ ClangImporter::Implementation::importDeclForDeclContext(
92469237
if (!contextDeclsWarnedAbout.insert(contextDecl).second)
92479238
return nullptr;
92489239

9249-
auto convertLoc = [&](clang::SourceLocation clangLoc) {
9250-
return getBufferImporterForDiagnostics()
9251-
.resolveSourceLocation(getClangASTContext().getSourceManager(),
9252-
clangLoc);
9253-
};
9254-
92559240
auto getDeclName = [](const clang::Decl *D) -> StringRef {
92569241
if (auto ND = dyn_cast<clang::NamedDecl>(D))
92579242
return ND->getName();
92589243
return "<anonymous>";
92599244
};
92609245

9261-
SourceLoc loc = convertLoc(importingDecl->getLocation());
9246+
HeaderLoc loc(importingDecl->getLocation());
92629247
diagnose(loc, diag::swift_name_circular_context_import,
92639248
writtenName, getDeclName(importingDecl));
92649249

92659250
// Diagnose other decls involved in the cycle.
92669251
for (auto entry : make_range(contextDeclsBeingImported.rbegin(), iter)) {
92679252
auto otherDecl = std::get<0>(entry);
92689253
auto otherWrittenName = std::get<1>(entry);
9269-
diagnose(convertLoc(otherDecl->getLocation()),
9254+
diagnose(HeaderLoc(otherDecl->getLocation()),
92709255
diag::swift_name_circular_context_import_other,
92719256
otherWrittenName, getDeclName(otherDecl));
92729257
}

lib/ClangImporter/ImportType.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,20 +2579,15 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
25792579

25802580
if (importedName.hasCustomName() && argNames.size() != swiftParams.size()) {
25812581
// Note carefully: we're emitting a warning in the /Clang/ buffer.
2582-
auto &srcMgr = getClangASTContext().getSourceManager();
2583-
ClangSourceBufferImporter &bufferImporter =
2584-
getBufferImporterForDiagnostics();
2585-
SourceLoc methodLoc =
2586-
bufferImporter.resolveSourceLocation(srcMgr, clangDecl->getLocation());
2587-
if (methodLoc.isValid()) {
2582+
if (clangDecl->getLocation().isValid()) {
2583+
HeaderLoc methodLoc(clangDecl->getLocation());
25882584
diagnose(methodLoc, diag::invalid_swift_name_method,
2589-
swiftParams.size() < argNames.size(),
2590-
swiftParams.size(), argNames.size());
2585+
swiftParams.size() < argNames.size(),
2586+
swiftParams.size(), argNames.size());
25912587
ModuleDecl *parentModule = dc->getParentModule();
25922588
if (parentModule != ImportedHeaderUnit->getParentModule()) {
2593-
diagnose(
2594-
methodLoc, diag::unresolvable_clang_decl_is_a_framework_bug,
2595-
parentModule->getName().str());
2589+
diagnose(methodLoc, diag::unresolvable_clang_decl_is_a_framework_bug,
2590+
parentModule->getName().str());
25962591
}
25972592
}
25982593
return {Type(), false};

lib/ClangImporter/ImporterImpl.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,19 @@ class ImportedType {
317317
explicit operator bool() const { return type.getPointer() != nullptr; }
318318
};
319319

320+
/// Wraps a Clang source location with additional optional information used to
321+
/// resolve it for diagnostics.
322+
struct HeaderLoc {
323+
clang::SourceLocation clangLoc;
324+
SourceLoc fallbackLoc;
325+
const clang::SourceManager *sourceMgr;
326+
327+
explicit HeaderLoc(clang::SourceLocation clangLoc,
328+
SourceLoc fallbackLoc = SourceLoc(),
329+
const clang::SourceManager *sourceMgr = nullptr)
330+
: clangLoc(clangLoc), fallbackLoc(fallbackLoc), sourceMgr(sourceMgr) {}
331+
};
332+
320333
/// Implementation of the Clang importer.
321334
class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
322335
: public LazyMemberLoader,
@@ -778,6 +791,31 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
778791
SwiftContext.Diags.diagnose(loc, std::forward<Args>(args)...);
779792
}
780793

794+
/// Emit a diagnostic at a clang source location, falling back to a Swift
795+
/// location if the clang one is invalid.
796+
///
797+
/// The diagnostic will appear in the header file rather than in a generated
798+
/// interface. Use this to diagnose issues with declarations that are not
799+
/// imported or that are not reflected in a generated interface.
800+
template<typename ...Args>
801+
void diagnose(HeaderLoc loc, Args &&...args) {
802+
// If we're in the middle of pretty-printing, suppress diagnostics.
803+
if (SwiftContext.Diags.isPrettyPrintingDecl()) {
804+
return;
805+
}
806+
807+
auto swiftLoc = loc.fallbackLoc;
808+
if (loc.clangLoc.isValid()) {
809+
auto &clangSrcMgr = loc.sourceMgr ? *loc.sourceMgr
810+
: getClangASTContext().getSourceManager();
811+
auto &bufferImporter = getBufferImporterForDiagnostics();
812+
swiftLoc = bufferImporter.resolveSourceLocation(clangSrcMgr,
813+
loc.clangLoc);
814+
}
815+
816+
SwiftContext.Diags.diagnose(swiftLoc, std::forward<Args>(args)...);
817+
}
818+
781819
/// Import the given Clang identifier into Swift.
782820
///
783821
/// \param identifier The Clang identifier to map into Swift.

0 commit comments

Comments
 (0)