Skip to content

Commit b372ff6

Browse files
committed
[NFC] Add ClangImporter header diagnostic helper
1 parent 953ffc3 commit b372ff6

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
@@ -8605,12 +8605,7 @@ void ClangImporter::Implementation::importAttributes(
86058605
if (SeenMainActorAttr) {
86068606
// Cannot add main actor annotation twice. We'll keep the first
86078607
// one and raise a warning about the duplicate.
8608-
auto &clangSrcMgr = getClangASTContext().getSourceManager();
8609-
ClangSourceBufferImporter &bufferImporter =
8610-
getBufferImporterForDiagnostics();
8611-
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
8612-
clangSrcMgr, swiftAttr->getLocation());
8613-
8608+
HeaderLoc attrLoc(swiftAttr->getLocation());
86148609
diagnose(attrLoc, diag::import_multiple_mainactor_attr,
86158610
swiftAttr->getAttribute(),
86168611
SeenMainActorAttr.getValue()->getAttribute());
@@ -8666,11 +8661,7 @@ void ClangImporter::Implementation::importAttributes(
86668661

86678662
if (hadError) {
86688663
// Complain about the unhandled attribute or modifier.
8669-
auto &clangSrcMgr = getClangASTContext().getSourceManager();
8670-
ClangSourceBufferImporter &bufferImporter =
8671-
getBufferImporterForDiagnostics();
8672-
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
8673-
clangSrcMgr, swiftAttr->getLocation());
8664+
HeaderLoc attrLoc(swiftAttr->getLocation());
86748665
diagnose(attrLoc, diag::clang_swift_attr_unhandled,
86758666
swiftAttr->getAttribute());
86768667
}
@@ -9244,27 +9235,21 @@ ClangImporter::Implementation::importDeclForDeclContext(
92449235
if (!contextDeclsWarnedAbout.insert(contextDecl).second)
92459236
return nullptr;
92469237

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

9259-
SourceLoc loc = convertLoc(importingDecl->getLocation());
9244+
HeaderLoc loc(importingDecl->getLocation());
92609245
diagnose(loc, diag::swift_name_circular_context_import,
92619246
writtenName, getDeclName(importingDecl));
92629247

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

lib/ClangImporter/ImportType.cpp

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

26022602
if (importedName.hasCustomName() && argNames.size() != swiftParams.size()) {
26032603
// Note carefully: we're emitting a warning in the /Clang/ buffer.
2604-
auto &srcMgr = getClangASTContext().getSourceManager();
2605-
ClangSourceBufferImporter &bufferImporter =
2606-
getBufferImporterForDiagnostics();
2607-
SourceLoc methodLoc =
2608-
bufferImporter.resolveSourceLocation(srcMgr, clangDecl->getLocation());
2609-
if (methodLoc.isValid()) {
2604+
if (clangDecl->getLocation().isValid()) {
2605+
HeaderLoc methodLoc(clangDecl->getLocation());
26102606
diagnose(methodLoc, diag::invalid_swift_name_method,
2611-
swiftParams.size() < argNames.size(),
2612-
swiftParams.size(), argNames.size());
2607+
swiftParams.size() < argNames.size(),
2608+
swiftParams.size(), argNames.size());
26132609
ModuleDecl *parentModule = dc->getParentModule();
26142610
if (parentModule != ImportedHeaderUnit->getParentModule()) {
2615-
diagnose(
2616-
methodLoc, diag::unresolvable_clang_decl_is_a_framework_bug,
2617-
parentModule->getName().str());
2611+
diagnose(methodLoc, diag::unresolvable_clang_decl_is_a_framework_bug,
2612+
parentModule->getName().str());
26182613
}
26192614
}
26202615
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,
@@ -791,6 +804,31 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
791804
SwiftContext.Diags.diagnose(loc, std::forward<Args>(args)...);
792805
}
793806

807+
/// Emit a diagnostic at a clang source location, falling back to a Swift
808+
/// location if the clang one is invalid.
809+
///
810+
/// The diagnostic will appear in the header file rather than in a generated
811+
/// interface. Use this to diagnose issues with declarations that are not
812+
/// imported or that are not reflected in a generated interface.
813+
template<typename ...Args>
814+
void diagnose(HeaderLoc loc, Args &&...args) {
815+
// If we're in the middle of pretty-printing, suppress diagnostics.
816+
if (SwiftContext.Diags.isPrettyPrintingDecl()) {
817+
return;
818+
}
819+
820+
auto swiftLoc = loc.fallbackLoc;
821+
if (loc.clangLoc.isValid()) {
822+
auto &clangSrcMgr = loc.sourceMgr ? *loc.sourceMgr
823+
: getClangASTContext().getSourceManager();
824+
auto &bufferImporter = getBufferImporterForDiagnostics();
825+
swiftLoc = bufferImporter.resolveSourceLocation(clangSrcMgr,
826+
loc.clangLoc);
827+
}
828+
829+
SwiftContext.Diags.diagnose(swiftLoc, std::forward<Args>(args)...);
830+
}
831+
794832
/// Import the given Clang identifier into Swift.
795833
///
796834
/// \param identifier The Clang identifier to map into Swift.

0 commit comments

Comments
 (0)