@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "json.h"
#include "selftest.h"
#include "logical-location.h"
+#include "make-unique.h"
/* Subclass of diagnostic_output_format for JSON output. */
@@ -62,7 +63,7 @@ protected:
json_output_format (diagnostic_context &context,
bool formatted)
: diagnostic_output_format (context),
- m_toplevel_array (new json::array ()),
+ m_toplevel_array (::make_unique<json::array> ()),
m_cur_group (nullptr),
m_cur_children_array (nullptr),
m_formatted (formatted)
@@ -75,31 +76,30 @@ protected:
{
m_toplevel_array->dump (outf, m_formatted);
fprintf (outf, "\n");
- delete m_toplevel_array;
m_toplevel_array = nullptr;
}
private:
/* 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. */
- json::object *m_cur_group;
+ json::object *m_cur_group; // borrowed
/* The JSON array for the "children" array within the current diagnostic
group. */
- json::array *m_cur_children_array;
+ json::array *m_cur_children_array; // borrowed
bool m_formatted;
};
/* 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)
{
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)
result->set_string ("file", exploc.file);
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. */
-static json::object *
+static std::unique_ptr<json::object>
json_from_location_range (diagnostic_context &context,
const location_range *loc_range, unsigned range_idx)
{
location_t caret_loc = get_pure_location (loc_range->m_loc);
if (caret_loc == UNKNOWN_LOCATION)
- return NULL;
+ return nullptr;
location_t start_loc = get_start (loc_range->m_loc);
location_t finish_loc = get_finish (loc_range->m_loc);
- json::object *result = new json::object ();
- result->set ("caret", json_from_expanded_location (context, caret_loc));
+ std::unique_ptr<json::object> result = ::make_unique <json::object> ();
+ result->set ("caret",
+ json_from_expanded_location (context, caret_loc));
if (start_loc != caret_loc
&& 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
&& 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)
{
@@ -163,15 +166,17 @@ json_from_location_range (diagnostic_context &context,
/* 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::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 ();
- 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 ();
- 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 ());
return fixit_obj;
@@ -179,10 +184,10 @@ json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint)
/* Generate a JSON object for METADATA. */
-static json::object *
+static std::unique_ptr<json::object>
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 ())
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. */
-static json::value *
+static std::unique_ptr<json::array>
make_json_for_path (diagnostic_context &context,
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++)
{
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 ())
event_obj->set ("location",
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_integer ("depth", event.get_stack_depth ());
- path_array->append (event_obj);
+ path_array->append (std::move (event_obj));
}
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;
add a "children" array and record the column origin. */
- m_toplevel_array->append (diag_obj);
m_cur_group = diag_obj;
- m_cur_children_array = new json::array ();
- diag_obj->set ("children", m_cur_children_array);
+ std::unique_ptr<json::array> 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);
+ m_toplevel_array->append (diag_obj);
}
- const rich_location *richloc = diagnostic.richloc;
+ /* diag_obj is now owned by either m_cur_children_array or
+ m_toplevel_array; further uses of diag_obj are borrowing it. */
- json::array *loc_array = new json::array ();
- diag_obj->set ("locations", loc_array);
+ const rich_location *richloc = diagnostic.richloc;
- for (unsigned int i = 0; i < richloc->get_num_locations (); i++)
- {
- const location_range *loc_range = richloc->get_range (i);
- json::object *loc_obj
- = json_from_location_range (m_context, loc_range, i);
- if (loc_obj)
- loc_array->append (loc_obj);
- }
+ {
+ std::unique_ptr<json::array> loc_array = ::make_unique<json::array> ();
+ for (unsigned int i = 0; i < richloc->get_num_locations (); i++)
+ {
+ const location_range *loc_range = richloc->get_range (i);
+ if (std::unique_ptr<json::object> loc_obj
+ = json_from_location_range (m_context, loc_range, i))
+ loc_array->append (std::move (loc_obj));
+ }
+ diag_obj->set ("locations", std::move (loc_array));
+ }
if (richloc->get_num_fixit_hints ())
{
- json::array *fixit_array = new json::array ();
- diag_obj->set ("fixits", fixit_array);
+ std::unique_ptr<json::array> fixit_array = ::make_unique<json::array> ();
for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++)
{
const fixit_hint *hint = richloc->get_fixit_hint (i);
- json::object *fixit_obj = json_from_fixit_hint (m_context, hint);
- fixit_array->append (fixit_obj);
+ fixit_array->append (json_from_fixit_hint (m_context, hint));
}
+ diag_obj->set ("fixits", std::move (fixit_array));
}
/* TODO: tree-ish things:
@@ -312,20 +321,13 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic,
TODO: macro expansion information. */
if (diagnostic.metadata)
- {
- json::object *metadata_obj = json_from_metadata (diagnostic.metadata);
- diag_obj->set ("metadata", metadata_obj);
- }
+ diag_obj->set ("metadata", json_from_metadata (diagnostic.metadata));
const diagnostic_path *path = richloc->get_path ();
if (path)
- {
- json::value *path_value = make_json_for_path (m_context, path);
- diag_obj->set ("path", path_value);
- }
+ diag_obj->set ("path", make_json_for_path (m_context, path));
- diag_obj->set ("escape-source",
- new json::literal (richloc->escape_on_output_p ()));
+ diag_obj->set_bool ("escape-source", richloc->escape_on_output_p ());
}
class json_stderr_output_format : public json_output_format
@@ -359,7 +361,7 @@ public:
~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);
m_base_file_name = nullptr;
FILE *outf = fopen (filename, "w");
@@ -441,7 +443,7 @@ static void
test_unknown_location ()
{
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
@@ -457,16 +459,16 @@ test_bad_endpoints ()
location_range loc_range;
loc_range.m_loc = bad_endpoints;
loc_range.m_range_display_kind = SHOW_RANGE_WITH_CARET;
- loc_range.m_label = NULL;
+ loc_range.m_label = nullptr;
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. */
- ASSERT_TRUE (obj != NULL);
- ASSERT_TRUE (obj->get ("caret") != NULL);
- ASSERT_TRUE (obj->get ("start") == NULL);
- ASSERT_TRUE (obj->get ("finish") == NULL);
- delete obj;
+ ASSERT_TRUE (obj != nullptr);
+ ASSERT_TRUE (obj->get ("caret") != nullptr);
+ ASSERT_TRUE (obj->get ("start") == nullptr);
+ ASSERT_TRUE (obj->get ("finish") == nullptr);
}
/* Run all of the selftests within this file. */
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> --- gcc/diagnostic-format-json.cc | 122 +++++++++++++++++----------------- 1 file changed, 62 insertions(+), 60 deletions(-)