aboutsummaryrefslogtreecommitdiff
path: root/gcc/libgdiagnostics.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/libgdiagnostics.cc')
-rw-r--r--gcc/libgdiagnostics.cc357
1 files changed, 276 insertions, 81 deletions
diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc
index c2eb975..70b0f36 100644
--- a/gcc/libgdiagnostics.cc
+++ b/gcc/libgdiagnostics.cc
@@ -162,7 +162,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,
@@ -177,55 +177,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
{
@@ -243,7 +194,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;
@@ -308,6 +258,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:
@@ -316,7 +372,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)
@@ -324,6 +387,7 @@ public:
private:
diagnostic_manager &m_mgr;
+ impl_logical_location_manager m_logical_location_manager;
};
class impl_client_version_info : public client_version_info
@@ -424,6 +488,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)
@@ -706,9 +778,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
@@ -772,8 +844,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 ("")
{
}
@@ -814,9 +887,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. */
@@ -902,7 +975,9 @@ public:
diagnostic_execution_path *
add_execution_path ()
{
- m_path = std::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 ();
}
@@ -973,12 +1048,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 *
@@ -1046,21 +1122,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));
@@ -1130,7 +1242,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. */
@@ -1458,10 +1572,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;
@@ -1486,16 +1601,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 (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 (auto parent = loc->m_parent)
+ {
+ fprintf (out, ", parent=");
+ diagnostic_manager_debug_dump_logical_location (diag_mgr,
+ parent,
+ out);
+ }
+ 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, ")");
}
@@ -1788,3 +1941,45 @@ 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 ();
+}