mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 19:41:07 +01:00
What this really does is avoids shadowing names, so that we can comfortable have things like `Check::DiagnosticEmitter` or `Check::DiagnosticLoc` without shadowing being a concern. Note, down this path I'm also thinking about: - Renaming misc DiagnosticConsumer/DiagnosticEmitter classes, possibly just to DiagnosticConsumer/DiagnosticEmitter (so `Check::DiagnosticEmitter` instead of `SemIRLocDiagnosticEmitter`). - Dropping `Diagnostic` from `Emitter::DiagnosticBuilder`. - But not for `Check::DiagnosticBuilder`, because `Check::Builder` would be ambiguous. - Renaming diagnostics/diagnostic_* to drop "diagnostic". [Discussion about SemIRLoc -> DiagnosticLoc](https://discord.com/channels/655572317891461132/655578254970716160/1353771570463768698) reminded me of this (in particular the older [Check::DiagnosticBuilder discussion](https://discord.com/channels/655572317891461132/655578254970716160/1344363562608627763)), but I'd only do that rename if there's matching consensus about a path forward where we keep SemIRLoc, and in a way that it's only ever used for diagnostics (the divergence from which is at the root of current LocId discussion). I'm trying to keep that separate from a namespace addition for clarity.
73 lines
2.4 KiB
C++
73 lines
2.4 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_TOOLCHAIN_DIAGNOSTICS_FORMAT_PROVIDERS_H_
|
|
#define CARBON_TOOLCHAIN_DIAGNOSTICS_FORMAT_PROVIDERS_H_
|
|
|
|
#include "common/ostream.h"
|
|
#include "llvm/Support/FormatVariadicDetails.h"
|
|
|
|
namespace Carbon::Diagnostics {
|
|
|
|
// Selects a formatv string based on the value.
|
|
//
|
|
// Supported format styles are:
|
|
// - None, as in `{0}`. This uses standard integer formatting.
|
|
// - Selector, as in `{0:true|false}`. The output string used is separated by a
|
|
// `|`, with the true case first. the example would yield standard bool
|
|
// formatting.
|
|
struct BoolAsSelect {
|
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
BoolAsSelect(bool value) : value(value) {}
|
|
|
|
bool value;
|
|
};
|
|
|
|
// Selects a formatv string based on the value.
|
|
//
|
|
// Supported format styles are:
|
|
// - None, as in `{0}`. This uses standard integer formatting.
|
|
// - Selector, as in `{0:=0:zero|:default}`. This is detailed below.
|
|
// - Plural `s`, as in `{0:s}`. This outputs an `s` when the value is not 1,
|
|
// equivalent to `{0:=1:|:s}`.
|
|
//
|
|
// The style is a series of match cases, separated by `|`. Each case is a pair
|
|
// formatted as `<selector>:<output string>`.
|
|
//
|
|
// Supported selectors are:
|
|
// - `=<value>`: Matches when the value is correct.
|
|
// - Empty for the default. This is optional, although it's a fatal error to not
|
|
// handle a value. If provided, it must be last.
|
|
//
|
|
// For example, `{0:=0:zero|=1:one|:other}` breaks down into:
|
|
// - `=0` -> `zero`
|
|
// - `=1` -> `one`
|
|
// - default -> `other`
|
|
//
|
|
// As another example, `{0:=1:is|:are}` is a way to handle plural-based output.
|
|
struct IntAsSelect {
|
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
IntAsSelect(int value) : value(value) {}
|
|
|
|
int value;
|
|
};
|
|
|
|
} // namespace Carbon::Diagnostics
|
|
|
|
// See Diagnostics::BoolAsSelect.
|
|
template <>
|
|
struct llvm::format_provider<Carbon::Diagnostics::BoolAsSelect> {
|
|
static auto format(const Carbon::Diagnostics::BoolAsSelect& wrapper,
|
|
raw_ostream& out, StringRef style) -> void;
|
|
};
|
|
|
|
// See Diagnostics::IntAsSelect.
|
|
template <>
|
|
struct llvm::format_provider<Carbon::Diagnostics::IntAsSelect> {
|
|
static auto format(const Carbon::Diagnostics::IntAsSelect& wrapper,
|
|
raw_ostream& out, StringRef style) -> void;
|
|
};
|
|
|
|
#endif // CARBON_TOOLCHAIN_DIAGNOSTICS_FORMAT_PROVIDERS_H_
|