Diagnostics

type diagnostic

A diagnostic is an opaque bundle of state for a particular diagnostic that is being constructed in memory.

Lifecycle of a diagnostic

Diagnostics are

  • created from a diagnostic_manager by using diagnostic_begin(), then

  • populated with data, such as physical locations, logical locations, metadata, execution paths, or fix-it hints, then

  • finished, in which a formatting string and arguments are given, via a call to diagnostic_finish() or diagnostic_finish_va(). The diagnostic_manager will emit the diagnostic to all of the manager’s output sinks (either immediately, or at some later time, depending on the sink).

    Once a diagnostic has had one of these “finish” functions called on it, it is freed, and is no longer valid for use.

    The formatting strings use their own syntax; see Message formatting.

diagnostic *diagnostic_begin(diagnostic_manager *diag_mgr, enum diagnostic_level level)

Create a new diagnostic associated with the given diagnostic_manager.

The parameter diag_mgr must be non-NULL.

The parameter level describes the severity of the diagnostic.

enum diagnostic_level

This enum describes the severity of a particular diagnostic.

DIAGNOSTIC_LEVEL_ERROR

A problem sufficiently severe that the program cannot successfully complete, or where the input being analyzed is definitely wrong (e.g. malformed).

DIAGNOSTIC_LEVEL_WARNING

A problem where the input is technically correct, but is likely not what the user intended, such as common mistakes, or other unusual conditions that may indicate trouble, such as use of obsolete features.

DIAGNOSTIC_LEVEL_NOTE

A supplementary message added to another diagnostic, giving extra information that may help the user understand it.

DIAGNOSTIC_LEVEL_SORRY

A problem where the input is valid, but the tool isn’t able to handle it.

void diagnostic_finish(diagnostic *diag, const char *fmt, ...)

Emit diag to all sinks of its manager, and release diag. It is not valid to use diag after this call.

Use parameter fmt for the message. Note that this uses gcc’s pretty-print format, which is not printf. See Message formatting.

Both diag and fmt must be non-NULL.

TODO: who is responsible for putting FMT through gettext?

void diagnostic_finish_va(diagnostic *diag, const char *fmt, va_list *args)

This is equivalent to diagnostic_finish(), but using a va_list rather than directly taking variadic arguments.

All three parameters must be non-NULL.

Diagnostic groups

See the “adding notes” section of the tutorial for an example of a diagnostic group.

void diagnostic_manager_begin_group(diagnostic_manager *diag_mgr)

Begin a diagnostic group. All diagnostics emitted within diag_mgr after the first one will be treated as additional information relating to the initial diagnostic.

The parameter diag_mgr must be non-NULL.

void diagnostic_manager_end_group(diagnostic_manager *diag_mgr)

Finish a diagnostic group.

The parameter diag_mgr must be non-NULL.