mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Emitting Swift diagnostics in Clang buffers requires making those buffers valid places to put Swift SourceLocs, which means making a mirror of those buffers in the Swift SourceManager. This isn't a copy; instead, any Clang SourceManagers that are involved are kept alive until the importer is torn down. (There might be more than one because of diagnostics emitted during module building.) For a long time we only emitted diagnostics in Clang buffers if the diagnostics came from Clang, but then we added another case for custom Swift names that fail to import. I'm about to add another such diagnostic, so let's formalize this buffer mapping first. No intended functionality change.
80 lines
2.3 KiB
C++
80 lines
2.3 KiB
C++
//===--- ClangDiagnosticConsumer.h - Handle Clang diagnostics ---*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef SWIFT_CLANG_DIAGNOSTIC_CONSUMER_H
|
|
#define SWIFT_CLANG_DIAGNOSTIC_CONSUMER_H
|
|
|
|
#include "swift/ClangImporter/ClangImporter.h"
|
|
#include "clang/Basic/Diagnostic.h"
|
|
#include "clang/Basic/IdentifierTable.h"
|
|
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
|
|
namespace swift {
|
|
|
|
class ClangDiagnosticConsumer : public clang::TextDiagnosticPrinter {
|
|
struct LoadModuleRAII {
|
|
ClangDiagnosticConsumer *Consumer;
|
|
public:
|
|
LoadModuleRAII(ClangDiagnosticConsumer &consumer,
|
|
const clang::IdentifierInfo *import)
|
|
: Consumer(&consumer) {
|
|
assert(import);
|
|
assert(!Consumer->CurrentImport);
|
|
Consumer->CurrentImport = import;
|
|
}
|
|
|
|
LoadModuleRAII(LoadModuleRAII &) = delete;
|
|
LoadModuleRAII &operator=(LoadModuleRAII &) = delete;
|
|
|
|
LoadModuleRAII(LoadModuleRAII &&other) {
|
|
*this = std::move(other);
|
|
}
|
|
LoadModuleRAII &operator=(LoadModuleRAII &&other) {
|
|
Consumer = other.Consumer;
|
|
other.Consumer = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
~LoadModuleRAII() {
|
|
if (Consumer)
|
|
Consumer->CurrentImport = nullptr;
|
|
}
|
|
};
|
|
|
|
private:
|
|
friend struct LoadModuleRAII;
|
|
|
|
ClangImporter::Implementation &ImporterImpl;
|
|
|
|
const clang::IdentifierInfo *CurrentImport = nullptr;
|
|
SourceLoc DiagLoc;
|
|
const bool DumpToStderr;
|
|
|
|
public:
|
|
ClangDiagnosticConsumer(ClangImporter::Implementation &impl,
|
|
clang::DiagnosticOptions &clangDiagOptions,
|
|
bool dumpToStderr);
|
|
|
|
LoadModuleRAII handleImport(const clang::IdentifierInfo *name,
|
|
SourceLoc diagLoc) {
|
|
DiagLoc = diagLoc;
|
|
return LoadModuleRAII(*this, name);
|
|
}
|
|
|
|
void HandleDiagnostic(clang::DiagnosticsEngine::Level diagLevel,
|
|
const clang::Diagnostic &info) override;
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|