mirror of git://gcc.gnu.org/git/gcc.git
diagnostics: JSON output: use std::unique_ptr throughout
No functional change intended. gcc/ChangeLog: * diagnostic-format-json.cc: Include "make-unique.h". (json_output_format::m_toplevel_array): Convert to std::unique_ptr. (json_output_format::json_output_format): Update accordingly. (json_output_format::~json_output_format): Remove manual "delete" of field. (json_from_expanded_location): Convert return type to std::unique_ptr. (json_from_location_range): Likewise. Use nullptr rather than NULL. (json_from_fixit_hint): Convert return type to std::unique_ptr. (json_from_metadata): Likewise. (make_json_for_path): Likewise. (json_output_format::on_end_diagnostic): Use std::unique_ptr throughout. (json_file_output_format::~json_file_output_format): Use nullptr. (selftest::test_unknown_location): Update to use std::unique_ptr. (selftest::test_bad_endpoints): Likewise. Replace NULL with nullptr. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
8485fe1b54
commit
da87cbedcd
|
|
@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "selftest.h"
|
#include "selftest.h"
|
||||||
#include "logical-location.h"
|
#include "logical-location.h"
|
||||||
|
#include "make-unique.h"
|
||||||
|
|
||||||
/* Subclass of diagnostic_output_format for JSON output. */
|
/* Subclass of diagnostic_output_format for JSON output. */
|
||||||
|
|
||||||
|
|
@ -62,7 +63,7 @@ protected:
|
||||||
json_output_format (diagnostic_context &context,
|
json_output_format (diagnostic_context &context,
|
||||||
bool formatted)
|
bool formatted)
|
||||||
: diagnostic_output_format (context),
|
: diagnostic_output_format (context),
|
||||||
m_toplevel_array (new json::array ()),
|
m_toplevel_array (::make_unique<json::array> ()),
|
||||||
m_cur_group (nullptr),
|
m_cur_group (nullptr),
|
||||||
m_cur_children_array (nullptr),
|
m_cur_children_array (nullptr),
|
||||||
m_formatted (formatted)
|
m_formatted (formatted)
|
||||||
|
|
@ -75,31 +76,30 @@ protected:
|
||||||
{
|
{
|
||||||
m_toplevel_array->dump (outf, m_formatted);
|
m_toplevel_array->dump (outf, m_formatted);
|
||||||
fprintf (outf, "\n");
|
fprintf (outf, "\n");
|
||||||
delete m_toplevel_array;
|
|
||||||
m_toplevel_array = nullptr;
|
m_toplevel_array = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* The top-level JSON array of pending diagnostics. */
|
/* The top-level JSON array of pending diagnostics. */
|
||||||
json::array *m_toplevel_array;
|
std::unique_ptr<json::array> m_toplevel_array;
|
||||||
|
|
||||||
/* The JSON object for the current diagnostic group. */
|
/* The JSON object for the current diagnostic group. */
|
||||||
json::object *m_cur_group;
|
json::object *m_cur_group; // borrowed
|
||||||
|
|
||||||
/* The JSON array for the "children" array within the current diagnostic
|
/* The JSON array for the "children" array within the current diagnostic
|
||||||
group. */
|
group. */
|
||||||
json::array *m_cur_children_array;
|
json::array *m_cur_children_array; // borrowed
|
||||||
|
|
||||||
bool m_formatted;
|
bool m_formatted;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Generate a JSON object for LOC. */
|
/* Generate a JSON object for LOC. */
|
||||||
|
|
||||||
static json::value *
|
static std::unique_ptr<json::object>
|
||||||
json_from_expanded_location (diagnostic_context &context, location_t loc)
|
json_from_expanded_location (diagnostic_context &context, location_t loc)
|
||||||
{
|
{
|
||||||
expanded_location exploc = expand_location (loc);
|
expanded_location exploc = expand_location (loc);
|
||||||
json::object *result = new json::object ();
|
std::unique_ptr<json::object> result = ::make_unique <json::object> ();
|
||||||
if (exploc.file)
|
if (exploc.file)
|
||||||
result->set_string ("file", exploc.file);
|
result->set_string ("file", exploc.file);
|
||||||
result->set_integer ("line", exploc.line);
|
result->set_integer ("line", exploc.line);
|
||||||
|
|
@ -130,26 +130,29 @@ json_from_expanded_location (diagnostic_context &context, location_t loc)
|
||||||
|
|
||||||
/* Generate a JSON object for LOC_RANGE. */
|
/* Generate a JSON object for LOC_RANGE. */
|
||||||
|
|
||||||
static json::object *
|
static std::unique_ptr<json::object>
|
||||||
json_from_location_range (diagnostic_context &context,
|
json_from_location_range (diagnostic_context &context,
|
||||||
const location_range *loc_range, unsigned range_idx)
|
const location_range *loc_range, unsigned range_idx)
|
||||||
{
|
{
|
||||||
location_t caret_loc = get_pure_location (loc_range->m_loc);
|
location_t caret_loc = get_pure_location (loc_range->m_loc);
|
||||||
|
|
||||||
if (caret_loc == UNKNOWN_LOCATION)
|
if (caret_loc == UNKNOWN_LOCATION)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
location_t start_loc = get_start (loc_range->m_loc);
|
location_t start_loc = get_start (loc_range->m_loc);
|
||||||
location_t finish_loc = get_finish (loc_range->m_loc);
|
location_t finish_loc = get_finish (loc_range->m_loc);
|
||||||
|
|
||||||
json::object *result = new json::object ();
|
std::unique_ptr<json::object> result = ::make_unique <json::object> ();
|
||||||
result->set ("caret", json_from_expanded_location (context, caret_loc));
|
result->set ("caret",
|
||||||
|
json_from_expanded_location (context, caret_loc));
|
||||||
if (start_loc != caret_loc
|
if (start_loc != caret_loc
|
||||||
&& start_loc != UNKNOWN_LOCATION)
|
&& start_loc != UNKNOWN_LOCATION)
|
||||||
result->set ("start", json_from_expanded_location (context, start_loc));
|
result->set ("start",
|
||||||
|
json_from_expanded_location (context, start_loc));
|
||||||
if (finish_loc != caret_loc
|
if (finish_loc != caret_loc
|
||||||
&& finish_loc != UNKNOWN_LOCATION)
|
&& finish_loc != UNKNOWN_LOCATION)
|
||||||
result->set ("finish", json_from_expanded_location (context, finish_loc));
|
result->set ("finish",
|
||||||
|
json_from_expanded_location (context, finish_loc));
|
||||||
|
|
||||||
if (loc_range->m_label)
|
if (loc_range->m_label)
|
||||||
{
|
{
|
||||||
|
|
@ -163,15 +166,17 @@ json_from_location_range (diagnostic_context &context,
|
||||||
|
|
||||||
/* Generate a JSON object for HINT. */
|
/* Generate a JSON object for HINT. */
|
||||||
|
|
||||||
static json::object *
|
static std::unique_ptr<json::object>
|
||||||
json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint)
|
json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint)
|
||||||
{
|
{
|
||||||
json::object *fixit_obj = new json::object ();
|
std::unique_ptr<json::object> fixit_obj = ::make_unique <json::object> ();
|
||||||
|
|
||||||
location_t start_loc = hint->get_start_loc ();
|
location_t start_loc = hint->get_start_loc ();
|
||||||
fixit_obj->set ("start", json_from_expanded_location (context, start_loc));
|
fixit_obj->set ("start",
|
||||||
|
json_from_expanded_location (context, start_loc));
|
||||||
location_t next_loc = hint->get_next_loc ();
|
location_t next_loc = hint->get_next_loc ();
|
||||||
fixit_obj->set ("next", json_from_expanded_location (context, next_loc));
|
fixit_obj->set ("next",
|
||||||
|
json_from_expanded_location (context, next_loc). release ());
|
||||||
fixit_obj->set_string ("string", hint->get_string ());
|
fixit_obj->set_string ("string", hint->get_string ());
|
||||||
|
|
||||||
return fixit_obj;
|
return fixit_obj;
|
||||||
|
|
@ -179,10 +184,10 @@ json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint)
|
||||||
|
|
||||||
/* Generate a JSON object for METADATA. */
|
/* Generate a JSON object for METADATA. */
|
||||||
|
|
||||||
static json::object *
|
static std::unique_ptr<json::object>
|
||||||
json_from_metadata (const diagnostic_metadata *metadata)
|
json_from_metadata (const diagnostic_metadata *metadata)
|
||||||
{
|
{
|
||||||
json::object *metadata_obj = new json::object ();
|
std::unique_ptr<json::object> metadata_obj = ::make_unique <json::object> ();
|
||||||
|
|
||||||
if (metadata->get_cwe ())
|
if (metadata->get_cwe ())
|
||||||
metadata_obj->set_integer ("cwe", metadata->get_cwe ());
|
metadata_obj->set_integer ("cwe", metadata->get_cwe ());
|
||||||
|
|
@ -192,16 +197,16 @@ json_from_metadata (const diagnostic_metadata *metadata)
|
||||||
|
|
||||||
/* Make a JSON value for PATH. */
|
/* Make a JSON value for PATH. */
|
||||||
|
|
||||||
static json::value *
|
static std::unique_ptr<json::array>
|
||||||
make_json_for_path (diagnostic_context &context,
|
make_json_for_path (diagnostic_context &context,
|
||||||
const diagnostic_path *path)
|
const diagnostic_path *path)
|
||||||
{
|
{
|
||||||
json::array *path_array = new json::array ();
|
std::unique_ptr<json::array> path_array = ::make_unique<json::array> ();
|
||||||
for (unsigned i = 0; i < path->num_events (); i++)
|
for (unsigned i = 0; i < path->num_events (); i++)
|
||||||
{
|
{
|
||||||
const diagnostic_event &event = path->get_event (i);
|
const diagnostic_event &event = path->get_event (i);
|
||||||
|
|
||||||
json::object *event_obj = new json::object ();
|
std::unique_ptr<json::object> event_obj = ::make_unique <json::object> ();
|
||||||
if (event.get_location ())
|
if (event.get_location ())
|
||||||
event_obj->set ("location",
|
event_obj->set ("location",
|
||||||
json_from_expanded_location (context,
|
json_from_expanded_location (context,
|
||||||
|
|
@ -214,7 +219,7 @@ make_json_for_path (diagnostic_context &context,
|
||||||
event_obj->set_string ("function", name.get ());
|
event_obj->set_string ("function", name.get ());
|
||||||
}
|
}
|
||||||
event_obj->set_integer ("depth", event.get_stack_depth ());
|
event_obj->set_integer ("depth", event.get_stack_depth ());
|
||||||
path_array->append (event_obj);
|
path_array->append (std::move (event_obj));
|
||||||
}
|
}
|
||||||
return path_array;
|
return path_array;
|
||||||
}
|
}
|
||||||
|
|
@ -273,37 +278,41 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic,
|
||||||
{
|
{
|
||||||
/* Otherwise, make diag_obj be the top-level object within the group;
|
/* Otherwise, make diag_obj be the top-level object within the group;
|
||||||
add a "children" array and record the column origin. */
|
add a "children" array and record the column origin. */
|
||||||
m_toplevel_array->append (diag_obj);
|
|
||||||
m_cur_group = diag_obj;
|
m_cur_group = diag_obj;
|
||||||
m_cur_children_array = new json::array ();
|
std::unique_ptr<json::array> children_array
|
||||||
diag_obj->set ("children", m_cur_children_array);
|
= ::make_unique<json::array> ();
|
||||||
|
m_cur_children_array = children_array.get (); // borrowed
|
||||||
|
diag_obj->set ("children", std::move (children_array));
|
||||||
diag_obj->set_integer ("column-origin", m_context.m_column_origin);
|
diag_obj->set_integer ("column-origin", m_context.m_column_origin);
|
||||||
|
m_toplevel_array->append (diag_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* diag_obj is now owned by either m_cur_children_array or
|
||||||
|
m_toplevel_array; further uses of diag_obj are borrowing it. */
|
||||||
|
|
||||||
const rich_location *richloc = diagnostic.richloc;
|
const rich_location *richloc = diagnostic.richloc;
|
||||||
|
|
||||||
json::array *loc_array = new json::array ();
|
{
|
||||||
diag_obj->set ("locations", loc_array);
|
std::unique_ptr<json::array> loc_array = ::make_unique<json::array> ();
|
||||||
|
for (unsigned int i = 0; i < richloc->get_num_locations (); i++)
|
||||||
for (unsigned int i = 0; i < richloc->get_num_locations (); i++)
|
{
|
||||||
{
|
const location_range *loc_range = richloc->get_range (i);
|
||||||
const location_range *loc_range = richloc->get_range (i);
|
if (std::unique_ptr<json::object> loc_obj
|
||||||
json::object *loc_obj
|
= json_from_location_range (m_context, loc_range, i))
|
||||||
= json_from_location_range (m_context, loc_range, i);
|
loc_array->append (std::move (loc_obj));
|
||||||
if (loc_obj)
|
}
|
||||||
loc_array->append (loc_obj);
|
diag_obj->set ("locations", std::move (loc_array));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (richloc->get_num_fixit_hints ())
|
if (richloc->get_num_fixit_hints ())
|
||||||
{
|
{
|
||||||
json::array *fixit_array = new json::array ();
|
std::unique_ptr<json::array> fixit_array = ::make_unique<json::array> ();
|
||||||
diag_obj->set ("fixits", fixit_array);
|
|
||||||
for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++)
|
for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++)
|
||||||
{
|
{
|
||||||
const fixit_hint *hint = richloc->get_fixit_hint (i);
|
const fixit_hint *hint = richloc->get_fixit_hint (i);
|
||||||
json::object *fixit_obj = json_from_fixit_hint (m_context, hint);
|
fixit_array->append (json_from_fixit_hint (m_context, hint));
|
||||||
fixit_array->append (fixit_obj);
|
|
||||||
}
|
}
|
||||||
|
diag_obj->set ("fixits", std::move (fixit_array));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: tree-ish things:
|
/* TODO: tree-ish things:
|
||||||
|
|
@ -312,20 +321,13 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic,
|
||||||
TODO: macro expansion information. */
|
TODO: macro expansion information. */
|
||||||
|
|
||||||
if (diagnostic.metadata)
|
if (diagnostic.metadata)
|
||||||
{
|
diag_obj->set ("metadata", json_from_metadata (diagnostic.metadata));
|
||||||
json::object *metadata_obj = json_from_metadata (diagnostic.metadata);
|
|
||||||
diag_obj->set ("metadata", metadata_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
const diagnostic_path *path = richloc->get_path ();
|
const diagnostic_path *path = richloc->get_path ();
|
||||||
if (path)
|
if (path)
|
||||||
{
|
diag_obj->set ("path", make_json_for_path (m_context, path));
|
||||||
json::value *path_value = make_json_for_path (m_context, path);
|
|
||||||
diag_obj->set ("path", path_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
diag_obj->set ("escape-source",
|
diag_obj->set_bool ("escape-source", richloc->escape_on_output_p ());
|
||||||
new json::literal (richloc->escape_on_output_p ()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class json_stderr_output_format : public json_output_format
|
class json_stderr_output_format : public json_output_format
|
||||||
|
|
@ -359,7 +361,7 @@ public:
|
||||||
|
|
||||||
~json_file_output_format ()
|
~json_file_output_format ()
|
||||||
{
|
{
|
||||||
char *filename = concat (m_base_file_name, ".gcc.json", NULL);
|
char *filename = concat (m_base_file_name, ".gcc.json", nullptr);
|
||||||
free (m_base_file_name);
|
free (m_base_file_name);
|
||||||
m_base_file_name = nullptr;
|
m_base_file_name = nullptr;
|
||||||
FILE *outf = fopen (filename, "w");
|
FILE *outf = fopen (filename, "w");
|
||||||
|
|
@ -441,7 +443,7 @@ static void
|
||||||
test_unknown_location ()
|
test_unknown_location ()
|
||||||
{
|
{
|
||||||
test_diagnostic_context dc;
|
test_diagnostic_context dc;
|
||||||
delete json_from_expanded_location (dc, UNKNOWN_LOCATION);
|
json_from_expanded_location (dc, UNKNOWN_LOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that we gracefully handle attempts to serialize bad
|
/* Verify that we gracefully handle attempts to serialize bad
|
||||||
|
|
@ -457,16 +459,16 @@ test_bad_endpoints ()
|
||||||
location_range loc_range;
|
location_range loc_range;
|
||||||
loc_range.m_loc = bad_endpoints;
|
loc_range.m_loc = bad_endpoints;
|
||||||
loc_range.m_range_display_kind = SHOW_RANGE_WITH_CARET;
|
loc_range.m_range_display_kind = SHOW_RANGE_WITH_CARET;
|
||||||
loc_range.m_label = NULL;
|
loc_range.m_label = nullptr;
|
||||||
|
|
||||||
test_diagnostic_context dc;
|
test_diagnostic_context dc;
|
||||||
json::object *obj = json_from_location_range (dc, &loc_range, 0);
|
std::unique_ptr<json::object> obj
|
||||||
|
= json_from_location_range (dc, &loc_range, 0);
|
||||||
/* We should have a "caret" value, but no "start" or "finish" values. */
|
/* We should have a "caret" value, but no "start" or "finish" values. */
|
||||||
ASSERT_TRUE (obj != NULL);
|
ASSERT_TRUE (obj != nullptr);
|
||||||
ASSERT_TRUE (obj->get ("caret") != NULL);
|
ASSERT_TRUE (obj->get ("caret") != nullptr);
|
||||||
ASSERT_TRUE (obj->get ("start") == NULL);
|
ASSERT_TRUE (obj->get ("start") == nullptr);
|
||||||
ASSERT_TRUE (obj->get ("finish") == NULL);
|
ASSERT_TRUE (obj->get ("finish") == nullptr);
|
||||||
delete obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run all of the selftests within this file. */
|
/* Run all of the selftests within this file. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue