/** @page diagnostics Diagnostics
@brief APIs that support issuing diagnostics

@section diagnostic-class Diagnostic Class

The slang::Diagnostic class represents a diagnostic that has been created in
response to some issue with the user's source code. It contains a
slang::DiagCode that indicates what that issue is, a collection of arguments
that may be used to format a human-friendly message describing the issue,
and some other metadata like the location where the issue occurred.
The Diagnostic class provides several operator<< overloads that can be used to
add arguments and metadata when constructing a new diagnostic.

There is a slang::Diagnostics class, which derives from slang::SmallVectorSized
and adds a few helper methods for creating diagnostics. An example of
constructing a new diagnostic:

@code{.cpp}
Diagnostics diags;
Diagnostic& diag = diags.add(diag::SomeDiagCode, location);
diag << arg1 << arg2;
@endcode

The slang::diag namespace contains all of the DiagCodes that are generated
automatically as part of the build (sourced from the diagnostics.txt file).
Each DiagCode is a combination of a slang::DiagSubsystem that indicates the
general system that creates that kind of diagnostic and a simple index within
that subsystem. It's also possible for a consumer of the slang library to
create its own DiagCode and issue them via the diagnostic system.

@section diagnostic-engine Diagnostic Engine

The slang::Diagnostics class is just a simple collection of diagnostics.
A richer set of functionality for formatting, filtering, and controlling those
diagnostics is provided by the slang::DiagnosticEngine class. The engine
provides methods for things like setting limits on the number of diagnostics to
issue, options that can hide all or some subset of warnings, and the ability to
remap the default severity of a given diagnostic code.

Each Diagnostic that is issued to a DiagnosticEngine is formatted and, assuming
it's not supressed, forwarded to all registered slang::DiagnosticClient
instances. Clients are registered with the engine via
slang::DiagnosticEngine::addClient. It's the client's job to actually do
something with the diagnostic; for example, it may write the text to an internal
buffer, or dump the diagnostic to a JSON file, or send it over a pipe to
another process.

You can make a DiagnosticClient to do whatever you want, but the built in
slang::TextDiagnosticClient formats each diagnostic to an internal string
buffer that you can then access to get a report. It can also add terminal color
codes to the report if you're going to be outputing it to a console.

A basic example of setting up a diagnostic engine along with a text client:

@code{.cpp}
DiagnosticEngine diagEngine(sourceManager);

auto client = std::make_shared<TextDiagnosticClient>();
diagEngine.addClient(client);

for (Diagnostic& diag : diags)
	diagEngine.issue(diag);

std::string report = client->getString();
@endcode

*/
