aboutsummaryrefslogtreecommitdiff
path: root/gcc/libgdiagnostics.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/libgdiagnostics.cc')
-rw-r--r--gcc/libgdiagnostics.cc482
1 files changed, 372 insertions, 110 deletions
diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc
index d274283..74814c7 100644
--- a/gcc/libgdiagnostics.cc
+++ b/gcc/libgdiagnostics.cc
@@ -31,9 +31,9 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-client-data-hooks.h"
#include "diagnostic-format-sarif.h"
#include "diagnostic-format-text.h"
+#include "diagnostic-output-spec.h"
#include "logical-location.h"
#include "edit-context.h"
-#include "make-unique.h"
#include "libgdiagnostics.h"
class owned_nullable_string
@@ -163,7 +163,7 @@ as_location_t (const diagnostic_physical_location *loc)
/* This has to be a "struct" as it is exposed in the C API. */
-struct diagnostic_logical_location : public logical_location
+struct diagnostic_logical_location
{
diagnostic_logical_location (enum diagnostic_logical_location_kind_t kind,
const diagnostic_logical_location *parent,
@@ -178,55 +178,6 @@ struct diagnostic_logical_location : public logical_location
{
}
- const char *get_short_name () const final override
- {
- return m_short_name.get_str ();
- }
- const char *get_name_with_scope () const final override
- {
- return m_fully_qualified_name.get_str ();
- }
- const char *get_internal_name () const final override
- {
- return m_decorated_name.get_str ();
- }
- enum logical_location_kind get_kind () const final override
- {
- switch (m_kind)
- {
- default:
- gcc_unreachable ();
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION:
- return LOGICAL_LOCATION_KIND_FUNCTION;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_MEMBER:
- return LOGICAL_LOCATION_KIND_MEMBER;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_MODULE:
- return LOGICAL_LOCATION_KIND_MODULE;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_NAMESPACE:
- return LOGICAL_LOCATION_KIND_NAMESPACE;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_TYPE:
- return LOGICAL_LOCATION_KIND_TYPE;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_RETURN_TYPE:
- return LOGICAL_LOCATION_KIND_RETURN_TYPE;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_PARAMETER:
- return LOGICAL_LOCATION_KIND_PARAMETER;
- case DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE:
- return LOGICAL_LOCATION_KIND_VARIABLE;
- }
- }
-
- enum diagnostic_logical_location_kind_t get_external_kind () const
- {
- return m_kind;
- }
-
- const diagnostic_logical_location *get_parent () const { return m_parent; }
-
- label_text get_name_for_path_output () const
- {
- return label_text::borrow (m_short_name.get_str ());
- }
-
bool
operator< (const diagnostic_logical_location &other) const
{
@@ -244,7 +195,6 @@ struct diagnostic_logical_location : public logical_location
return false;
}
-private:
enum diagnostic_logical_location_kind_t m_kind;
const diagnostic_logical_location *m_parent;
owned_nullable_string m_short_name;
@@ -298,7 +248,7 @@ public:
sarif_sink (diagnostic_manager &mgr,
FILE *dst_stream,
const diagnostic_file *main_input_file,
- enum sarif_version version);
+ const sarif_generation_options &sarif_gen_opts);
};
/* Helper for the linemap code. */
@@ -309,6 +259,112 @@ round_alloc_size (size_t s)
return s;
}
+class impl_logical_location_manager : public logical_location_manager
+{
+public:
+ static const diagnostic_logical_location *
+ ptr_from_key (logical_location k)
+ {
+ return k.cast_to<const diagnostic_logical_location *> ();
+ }
+
+ static logical_location
+ key_from_ptr (const diagnostic_logical_location *ptr)
+ {
+ return logical_location::from_ptr (ptr);
+ }
+
+ const char *get_short_name (key k) const final override
+ {
+ if (auto loc = ptr_from_key (k))
+ return loc->m_short_name.get_str ();
+ else
+ return nullptr;
+ }
+
+ const char *get_name_with_scope (key k) const final override
+ {
+ if (auto loc = ptr_from_key (k))
+ return loc->m_fully_qualified_name.get_str ();
+ else
+ return nullptr;
+ }
+
+ const char *get_internal_name (key k) const final override
+ {
+ if (auto loc = ptr_from_key (k))
+ return loc->m_decorated_name.get_str ();
+ else
+ return nullptr;
+ }
+
+ enum logical_location_kind get_kind (key k) const final override
+ {
+ auto loc = ptr_from_key (k);
+ gcc_assert (loc);
+ switch (loc->m_kind)
+ {
+ default:
+ gcc_unreachable ();
+
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION:
+ return logical_location_kind::function;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_MEMBER:
+ return logical_location_kind::member;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_MODULE:
+ return logical_location_kind::module_;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_NAMESPACE:
+ return logical_location_kind::namespace_;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_TYPE:
+ return logical_location_kind::type;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_RETURN_TYPE:
+ return logical_location_kind::return_type;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_PARAMETER:
+ return logical_location_kind::parameter;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE:
+ return logical_location_kind::variable;
+
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_ELEMENT:
+ return logical_location_kind::element;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_ATTRIBUTE:
+ return logical_location_kind::attribute;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_TEXT:
+ return logical_location_kind::text;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_COMMENT:
+ return logical_location_kind::comment;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROCESSING_INSTRUCTION:
+ return logical_location_kind::processing_instruction;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_DTD:
+ return logical_location_kind::dtd;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_DECLARATION:
+ return logical_location_kind::declaration;
+
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_OBJECT:
+ return logical_location_kind::object;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_ARRAY:
+ return logical_location_kind::array;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROPERTY:
+ return logical_location_kind::property;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_VALUE:
+ return logical_location_kind::value;
+ }
+ }
+
+ label_text get_name_for_path_output (key k) const final override
+ {
+ auto loc = ptr_from_key (k);
+ gcc_assert (loc);
+ return label_text::borrow (loc->m_short_name.get_str ());
+ }
+
+ key get_parent (key k) const final override
+ {
+ auto loc = ptr_from_key (k);
+ gcc_assert (loc);
+ return key_from_ptr (loc->m_parent);
+ }
+};
+
class impl_diagnostic_client_data_hooks : public diagnostic_client_data_hooks
{
public:
@@ -317,7 +373,14 @@ public:
{}
const client_version_info *get_any_version_info () const final override;
- const logical_location *get_current_logical_location () const final override;
+
+ const logical_location_manager *
+ get_logical_location_manager () const final override
+ {
+ return &m_logical_location_manager;
+ }
+ logical_location get_current_logical_location () const final override;
+
const char * maybe_get_sarif_source_language (const char *filename)
const final override;
void add_sarif_invocation_properties (sarif_object &invocation_obj)
@@ -325,6 +388,7 @@ public:
private:
diagnostic_manager &m_mgr;
+ impl_logical_location_manager m_logical_location_manager;
};
class impl_client_version_info : public client_version_info
@@ -398,11 +462,11 @@ public:
m_dc.m_client_aux_data = this;
m_dc.set_client_data_hooks
- (::make_unique<impl_diagnostic_client_data_hooks> (*this));
+ (std::make_unique<impl_diagnostic_client_data_hooks> (*this));
diagnostic_text_starter (&m_dc) = diagnostic_text_sink::text_starter;
- m_edit_context = ::make_unique <edit_context> (m_dc.get_file_cache ());
+ m_edit_context = std::make_unique <edit_context> (m_dc.get_file_cache ());
}
~diagnostic_manager ()
@@ -425,6 +489,14 @@ public:
line_maps *get_line_table () { return &m_line_table; }
diagnostic_context &get_dc () { return m_dc; }
+ const logical_location_manager &
+ get_logical_location_manager () const
+ {
+ auto mgr = m_dc.get_logical_location_manager ();
+ gcc_assert (mgr);
+ return *mgr;
+ }
+
void write_patch (FILE *dst_stream);
void add_sink (std::unique_ptr<sink> sink)
@@ -503,11 +575,11 @@ public:
return (*iter).second.get ();
std::unique_ptr<diagnostic_logical_location> logical_loc
- = ::make_unique<diagnostic_logical_location> (kind,
- parent,
- short_name,
- fully_qualified_name,
- decorated_name);
+ = std::make_unique<diagnostic_logical_location> (kind,
+ parent,
+ short_name,
+ fully_qualified_name,
+ decorated_name);
const diagnostic_logical_location *result = logical_loc.get ();
m_logical_locs.insert
(logical_locs_map_t::value_type (std::move (key),
@@ -707,9 +779,9 @@ public:
pp_string (&pp, m_desc_uncolored.get ());
}
- const logical_location *get_logical_location () const
+ logical_location get_logical_location () const final override
{
- return m_logical_loc;
+ return impl_logical_location_manager::key_from_ptr (m_logical_loc);
}
meaning get_meaning () const final override
@@ -773,8 +845,9 @@ private:
struct diagnostic_execution_path : public diagnostic_path
{
- diagnostic_execution_path ()
- : m_thread ("")
+ diagnostic_execution_path (const logical_location_manager &logical_loc_mgr)
+ : diagnostic_path (logical_loc_mgr),
+ m_thread ("")
{
}
@@ -785,11 +858,12 @@ struct diagnostic_execution_path : public diagnostic_path
const char *gmsgid,
va_list *args)
{
- m_events.push_back (::make_unique<libgdiagnostics_path_event> (physical_loc,
- logical_loc,
- stack_depth,
- gmsgid,
- args));
+ m_events.push_back
+ (std::make_unique<libgdiagnostics_path_event> (physical_loc,
+ logical_loc,
+ stack_depth,
+ gmsgid,
+ args));
return m_events.size () - 1;
}
@@ -814,9 +888,9 @@ struct diagnostic_execution_path : public diagnostic_path
same_function_p (int event_idx_a,
int event_idx_b) const final override
{
- const logical_location *logical_loc_a
+ logical_location logical_loc_a
= m_events[event_idx_a]->get_logical_location ();
- const logical_location *logical_loc_b
+ logical_location logical_loc_b
= m_events[event_idx_b]->get_logical_location ();
/* Pointer equality, as we uniqify logical location instances. */
@@ -860,7 +934,7 @@ public:
void add_rule (const char *title,
const char *url)
{
- std::unique_ptr<impl_rule> rule = ::make_unique<impl_rule> (title, url);
+ std::unique_ptr<impl_rule> rule = std::make_unique<impl_rule> (title, url);
m_metadata.add_rule (*rule.get ());
m_rules.push_back (std::move (rule));
}
@@ -882,7 +956,7 @@ public:
const char *text)
{
std::unique_ptr<range_label> label
- = ::make_unique <impl_range_label> (text);
+ = std::make_unique <impl_range_label> (text);
m_rich_loc.add_range (as_location_t (loc),
SHOW_RANGE_WITHOUT_CARET,
label.get ());
@@ -902,7 +976,9 @@ public:
diagnostic_execution_path *
add_execution_path ()
{
- m_path = ::make_unique<diagnostic_execution_path> ();
+ m_path
+ = std::make_unique<diagnostic_execution_path>
+ (m_diag_mgr.get_logical_location_manager ());
m_rich_loc.set_path (m_path.get ());
return m_path.get ();
}
@@ -946,7 +1022,7 @@ diagnostic_t_from_diagnostic_level (enum diagnostic_level level)
void
diagnostic_file::set_buffered_content (const char *buf, size_t sz)
{
- m_content = ::make_unique<content_buffer> (buf, sz);
+ m_content = std::make_unique<content_buffer> (buf, sz);
// Populate file_cache:
file_cache &fc = m_mgr.get_dc ().get_file_cache ();
@@ -973,12 +1049,13 @@ impl_diagnostic_client_data_hooks::get_any_version_info () const
return m_mgr.get_client_version_info ();
}
-const logical_location *
+logical_location
impl_diagnostic_client_data_hooks::get_current_logical_location () const
{
gcc_assert (m_mgr.get_current_diag ());
- return m_mgr.get_current_diag ()->get_logical_location ();
+ return impl_logical_location_manager::key_from_ptr
+ (m_mgr.get_current_diag ()->get_logical_location ());
}
const char *
@@ -1004,8 +1081,8 @@ diagnostic_text_sink::diagnostic_text_sink (diagnostic_manager &mgr,
m_source_printing (mgr.get_dc ().m_source_printing)
{
auto inner_sink
- = ::make_unique<diagnostic_text_output_format> (mgr.get_dc (),
- &m_source_printing);
+ = std::make_unique<diagnostic_text_output_format> (mgr.get_dc (),
+ &m_source_printing);
inner_sink->get_printer ()->set_output_stream (dst_stream);
m_inner_sink = inner_sink.get ();
set_colorize (colorize);
@@ -1046,21 +1123,57 @@ diagnostic_text_sink::text_starter (diagnostic_text_output_format &text_output,
if (diag_logical_loc && diag_logical_loc != mgr.get_prev_diag_logical_loc ())
{
pp_set_prefix (pp, nullptr);
- switch (diag_logical_loc->get_kind ())
+
+ /* This macro is used to ensure that all format strings are visible to gettext
+ and checked at compile time. */
+
+#define CASE(KIND, MSGID) \
+ case KIND: \
+ if (const char *name \
+ = diag_logical_loc->m_fully_qualified_name.get_str ()) \
+ { \
+ pp_printf (pp, (MSGID), name); \
+ pp_character (pp, ':'); \
+ pp_newline (pp); \
+ } \
+ break;
+
+ switch (diag_logical_loc->m_kind)
{
default:
break;
- case LOGICAL_LOCATION_KIND_FUNCTION:
- if (const char *name
- = diag_logical_loc->get_name_with_scope ())
- {
- pp_printf (pp, _("In function %qs"), name);
- pp_character (pp, ':');
- pp_newline (pp);
- }
- break;
- // TODO: handle other cases
+
+ /* Kinds within executable code. */
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION, _("In function %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_MEMBER, _("In member %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_MODULE, _("In module %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_NAMESPACE, _("In namespace %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_TYPE, _("In type %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_RETURN_TYPE,
+ _("In return type %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_PARAMETER, _("In parameter %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE, _("In variable %qs"))
+
+ /* Kinds within XML or HTML documents. */
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_ELEMENT, _("In element %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_ATTRIBUTE, _("In attribute %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_TEXT, _("In text %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_COMMENT, _("In comment %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROCESSING_INSTRUCTION,
+ _("In processing instruction %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_DTD, _("In DTD %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_DECLARATION,
+ _("In declaration %qs"))
+
+ /* Kinds within JSON documents. */
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_OBJECT, _("In JSON object %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_ARRAY, _("In JSON array %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROPERTY,
+ _("In JSON property %qs"))
+ CASE(DIAGNOSTIC_LOGICAL_LOCATION_KIND_VALUE, _("In JSON value %qs"))
}
+
+#undef CASE
}
pp_set_prefix (pp,
text_output.build_prefix (*info));
@@ -1071,16 +1184,18 @@ diagnostic_text_sink::text_starter (diagnostic_text_output_format &text_output,
sarif_sink::sarif_sink (diagnostic_manager &mgr,
FILE *dst_stream,
const diagnostic_file *main_input_file,
- enum sarif_version version)
+ const sarif_generation_options &sarif_gen_opts)
: sink (mgr)
{
diagnostic_output_file output_file (dst_stream, false,
label_text::borrow ("sarif_sink"));
+ auto serialization = std::make_unique<sarif_serialization_format_json> (true);
auto inner_sink = make_sarif_sink (mgr.get_dc (),
*mgr.get_line_table (),
- main_input_file->get_name (),
- version,
+ std::move (serialization),
+ sarif_gen_opts,
std::move (output_file));
+ inner_sink->set_main_input_filename (main_input_file->get_name ());
mgr.get_dc ().add_sink (std::move (inner_sink));
}
@@ -1128,7 +1243,9 @@ GCC_DIAGNOSTIC_POP
diagnostic_execution_path *
diagnostic_manager::new_execution_path ()
{
- return new diagnostic_execution_path ();
+ auto mgr = m_dc.get_logical_location_manager ();
+ gcc_assert (mgr);
+ return new diagnostic_execution_path (*mgr);
}
/* Error-checking at the API boundary. */
@@ -1271,7 +1388,7 @@ diagnostic_manager_add_sarif_sink (diagnostic_manager *diag_mgr,
FAIL_IF_NULL (dst_stream);
FAIL_IF_NULL (main_input_file);
- enum sarif_version internal_version;
+ sarif_generation_options sarif_gen_opts;
switch (version)
{
default:
@@ -1279,17 +1396,17 @@ diagnostic_manager_add_sarif_sink (diagnostic_manager *diag_mgr,
__func__, (int)version);
abort ();
case DIAGNOSTIC_SARIF_VERSION_2_1_0:
- internal_version = sarif_version::v2_1_0;
+ sarif_gen_opts.m_version = sarif_version::v2_1_0;
break;
case DIAGNOSTIC_SARIF_VERSION_2_2_PRERELEASE:
- internal_version = sarif_version::v2_2_prerelease_2024_08_08;
+ sarif_gen_opts.m_version = sarif_version::v2_2_prerelease_2024_08_08;
break;
}
- diag_mgr->add_sink (make_unique<sarif_sink> (*diag_mgr,
- dst_stream,
- main_input_file,
- internal_version));
+ diag_mgr->add_sink (std::make_unique<sarif_sink> (*diag_mgr,
+ dst_stream,
+ main_input_file,
+ sarif_gen_opts));
}
/* Public entrypoint. */
@@ -1456,10 +1573,11 @@ diagnostic_manager_debug_dump_logical_location (const diagnostic_manager *diag_m
if (loc)
{
fprintf (out, "logical_location(kind=");
- switch (loc->get_external_kind ())
+ switch (loc->m_kind)
{
default:
gcc_unreachable ();
+
case DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION:
fprintf (out, "function");
break;
@@ -1484,16 +1602,54 @@ diagnostic_manager_debug_dump_logical_location (const diagnostic_manager *diag_m
case DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE:
fprintf (out, "variable");
break;
+
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_ELEMENT:
+ fprintf (out, "element");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_ATTRIBUTE:
+ fprintf (out, "attribute");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_TEXT:
+ fprintf (out, "text");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_COMMENT:
+ fprintf (out, "comment");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROCESSING_INSTRUCTION:
+ fprintf (out, "processing_instruction");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_DTD:
+ fprintf (out, "dtd");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_DECLARATION:
+ fprintf (out, "declaration");
+ break;
+
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_OBJECT:
+ fprintf (out, "object");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_ARRAY:
+ fprintf (out, "array");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROPERTY:
+ fprintf (out, "property");
+ break;
+ case DIAGNOSTIC_LOGICAL_LOCATION_KIND_VALUE:
+ fprintf (out, "value");
+ break;
+ }
+ if (auto parent = loc->m_parent)
+ {
+ fprintf (out, ", parent=");
+ diagnostic_manager_debug_dump_logical_location (diag_mgr,
+ parent,
+ out);
}
- if (const diagnostic_logical_location *parent = loc->get_parent ())
- diagnostic_manager_debug_dump_logical_location (diag_mgr,
- parent,
- out);
- if (const char *val = loc->get_short_name ())
+ if (const char *val = loc->m_short_name.get_str ())
fprintf (out, ", short_name=\"%s\"", val);
- if (const char *val = loc->get_name_with_scope ())
+ if (const char *val = loc->m_fully_qualified_name.get_str ())
fprintf (out, ", fully_qualified_name=\"%s\"", val);
- if (const char *val = loc->get_internal_name ())
+ if (const char *val = loc->m_decorated_name.get_str ())
fprintf (out, ", decorated_name=\"%s\"", val);
fprintf (out, ")");
}
@@ -1786,3 +1942,109 @@ diagnostic_physical_location_get_file (const diagnostic_physical_location *physi
return physical_loc->get_file ();
}
+
+/* Public entrypoints for accessing logical location data. */
+
+enum diagnostic_logical_location_kind_t
+diagnostic_logical_location_get_kind (const diagnostic_logical_location *loc)
+{
+ FAIL_IF_NULL (loc);
+
+ return loc->m_kind;
+}
+
+const diagnostic_logical_location *
+diagnostic_logical_location_get_parent (const diagnostic_logical_location *loc)
+{
+ FAIL_IF_NULL (loc);
+
+ return loc->m_parent;
+}
+
+const char *
+diagnostic_logical_location_get_short_name (const diagnostic_logical_location *loc)
+{
+ FAIL_IF_NULL (loc);
+
+ return loc->m_short_name.get_str ();
+}
+
+const char *
+diagnostic_logical_location_get_fully_qualified_name (const diagnostic_logical_location *loc)
+{
+ FAIL_IF_NULL (loc);
+
+ return loc->m_fully_qualified_name.get_str ();
+}
+
+const char *
+diagnostic_logical_location_get_decorated_name (const diagnostic_logical_location *loc)
+{
+ FAIL_IF_NULL (loc);
+
+ return loc->m_decorated_name.get_str ();
+}
+
+namespace {
+
+struct spec_context : public diagnostics_output_spec::context
+{
+public:
+ spec_context (const char *option_name,
+ diagnostic_manager &affected_mgr,
+ diagnostic_manager &control_mgr)
+ : context (option_name, affected_mgr.get_line_table ()),
+ m_control_mgr (control_mgr)
+ {}
+
+ void report_error_va (const char *gmsgid, va_list *ap) const final override
+ {
+ diagnostic *diag
+ = diagnostic_begin (&m_control_mgr, DIAGNOSTIC_LEVEL_ERROR);
+ diagnostic_finish_va (diag, gmsgid, ap);
+ }
+
+ const char *
+ get_base_filename () const final override
+ {
+ return nullptr;
+ }
+
+private:
+ diagnostic_manager &m_control_mgr;
+};
+
+} // anon namespace
+
+/* Public entrypoint. */
+
+int
+diagnostic_manager_add_sink_from_spec (diagnostic_manager *affected_mgr,
+ const char *option_name,
+ const char *spec,
+ diagnostic_manager *control_mgr)
+{
+ FAIL_IF_NULL (affected_mgr);
+ FAIL_IF_NULL (option_name);
+ FAIL_IF_NULL (spec);
+ FAIL_IF_NULL (control_mgr);
+
+ spec_context ctxt (option_name, *affected_mgr, *control_mgr);
+ auto inner_sink = ctxt.parse_and_make_sink (spec, affected_mgr->get_dc ());
+ if (!inner_sink)
+ return -1;
+ affected_mgr->get_dc ().add_sink (std::move (inner_sink));
+ return 0;
+}
+
+/* Public entrypoint. */
+
+void
+diagnostic_manager_set_analysis_target (diagnostic_manager *mgr,
+ const diagnostic_file *file)
+{
+ FAIL_IF_NULL (mgr);
+ FAIL_IF_NULL (file);
+
+ mgr->get_dc ().set_main_input_filename (file->get_name ());
+}